No2.添加音频,gopher 冲!!

简介: No2.添加音频,gopher 冲!!

Go必知必会五连问

1.Go 语言最主要的特性:

  • 自动垃圾回收
  • 更丰富的内置类型
  • 函数多返回值
  • 错误处理
  • 匿名函数和闭包
  • 类型和接口
  • 并发编程
  • 反射
  • 语言交互性


2.讲讲go关键词的使用

   go关键词可以开启一个协程,底层使用的是runtime.newproc(size,f,args),size为参数占用的空间大小,f 为要调用的函数,args为 f 的参数。每次协程获得cpu执行的时候会先进行检测,查看当前栈的大小是否足够,如果不足则会暂停执行,通过go的运行时库获取一个新的足够大的栈空间,将旧的内容拷贝到新栈中,然后恢复函数执行。栈的收缩则是在垃圾回收的过程中实现的,当检测到栈只使用了1/4不到时,栈缩小为原来的1/2.


3.了解go中的fallthrough的用法吗

用法:Go里面switch默认相当于每个case最后带有break,匹配成功后不会自动向下执行其他case,而是跳出整个switch, 但是可以使用fallthrough强制执行后面的case代码。

func GoFallthrough(x int) string {
  switch x {
  case 1:
    fmt.Println("111")
    fallthrough
  case 2:
    fmt.Println("222")
    fallthrough
  case 3:
    fmt.Println("333")
    fallthrough
  default:
    fmt.Println("switch end...")
  }
  return  ""
}
func main() {
  fmt.Println(GoFallthrough(1))
}
/*
运行结果:
111
222
333
switch end...
Process finished with the exit code 0
*/


func GoFallthrough(x int) string {
  switch x {
  case 1:
    fmt.Println("111")
    fallthrough
  case 2:
    fmt.Println("222")
    fallthrough
  case 3:
    fmt.Println("333")
    fallthrough
  default:
    fmt.Println("switch end...")
  }
  return  ""
}
func main() {
  fmt.Println(GoFallthrough(1))
}
/*
运行结果:
111
222
333
switch end...
Process finished with the exit code 0
*/

Tips:作者第一次接触这个关键字还是看同事的代码,然后自己跑了测试用例感受一下也就记住了,这个关键词的用法给我的感觉就是“贯穿伤”,记住这个词就够了。比对两个代码结果 仅注释了一行的fallthrough结果也大有不同,当然 default 分支可以出现在任何顺序,但最好将它放在最后。

4.讲讲defer关键词的使用

defer一般用于资源的释放和异常的捕捉, 作为Go语言的特性之一.
defer关键词会将其后面跟随的语句进行延迟处理.意思就是说跟在defer后面的语句将会在程序进行最后的return后再执行。在defer归属的函数即将返回时,将延迟处理的语句按defer的逆序执行,也就是说,先被defer的语句最后执行最后被 defer 的语句,最先被执行当有多个 defer 行为被注册时,它们会以逆序执行(类似栈,即后进先出), 相当于开辟了一个延时调用栈

常用于的地方:

1.资源的释放

//一般在读取文件中
func CopyFile(dstName, srcName string) (written int64, err error) {
  src, err := os.Open(srcName)
  if err != nil {
    return
  }
  dst, err := os.Create(dstName)
  if err != nil {
    return 
  }
  dst.Close()
  src.Close()
  return
}
/*
在程序最开始,
os.Open及os.Create打开了两个文件资源描述符,
并在最后通过file.Close方法得到释放,在正常情况下,该程序能正常运行,
一旦在dstName文件创建过程中出现错误,
程序就直接返回,src资源将得不到释放。
因此需要在所有错误退出时释放资源,
即修改为如下代码才能保证其在异常情况下的正确性。
dst,err :=os.Create(dstName)
  if err !=nil {
    src.Close()
    return 
  }
*/

2.异常的捕捉

  程序在运行时可能在任意的地方发生panic异常,例如算术除0错误、内存无效访问、数组越界等,这些错误会导致程序异常退出。在很多时候,我们希望能够捕获这样的错误,同时希望程序能够继续正常执行。一些语言采用try…catch语法,当try块中发生异常时,可以通过catch块捕获,Go语言使用了特别的方式处理这一问题defer的特性是无论后续函数的执行路径如何以及是否发生了panic在函数结束后一定会得到执行,这为异常捕获提供了很好的时机。异常捕获通常结合recover函数一起使用.

640.png


5.讲讲go语言中的panic和err有什么区别?

错误:指的是可能出现问题的地方出现了问题。比如在打开一个文件时失败,这种情况在人们的意料之中 。

异常:指的是不应该出现问题的地方出现了问题。比如引用了空指针,这种情况在人们的意料之外。可见,错误是业务过程的一部分,而异常不是.

go语言中,错误是一种数据类型,内置有error类型,和其他数据类型一样使用。且内置了error接口,提供了非常简单的错误处理机制

Go必知必会力扣每日一题

《1047. 删除字符串中的所有相邻重复项》

题目:给出由小写字母组成的字符串 S,重复项删除操作会选择两个相邻且相同的字母,并删除它们。在 S 上反复执行重复项删除操作,直到无法继续删除。在完成所有重复项删除操作后返回最终的字符串。答案保证唯一。

示例:

输入:"abbaca"
输出:"ca"
解释:

例如,在 "abbaca" 中,我们可以删除 "bb" 由于两字母相邻且相同,这是此时唯一可以执行删除操作的重复项。之后我们得到字符串 "aaca",其中又只有 "aa" 可以执行重复项删除操作,所以最后的字符串为 "ca"。

解题思路:(栈)

1.多组相邻重复项,我们无论先删除哪一项,都不会影响最终结果。
2.删除当前项是需要拿上一项出来对比的,所以我们需要用临时栈存放之前的内容。
3.当前项和栈顶一致,弹出栈顶抵消即可。若不一致,压入栈留存,供后续使用。

(感觉可以有更好的解题方法,但是可以看看击败了5%的我怎么做得吧,全网寻找5%)

func removeDuplicates(s string) (res string) {
  //用栈的思想,用切片最后不用逆置
  //用切片起到一个过渡作用
  temp :=make([]byte,0)
  for _,v :=range s {
        //当用于过渡的temp长度为0,或者 遍历的元素不等于temp的尾元素
    if len(temp) == 0|| byte(v) !=temp[len(temp)-1]  {
      //就将这个元素加入到temp
      temp =append(temp,byte(v))
      continue
    }
    //如果temp的尾元素等于遍历的元素v 那就将temp尾元素裁掉
    if byte(v) == temp[len(temp)-1]{
      temp =temp[0:len(temp)-1]
      continue
    }
  }
  //注意这里用的切片,存进去的顺序是正确的,不用再逆置,如果是栈需要逆置
  //将byte类型转成string然后再拼装起来
  //用栈的话 for 循环就要这么写(因为栈只能先进后出,尾巴上一个出口) for i:=len(temp)-1; i>=0 ;i--{
  //法一:自己这么写的,最后感觉自己是傻子
  //for i:=0;i<len(temp) ;i++{
  //  sss :=  string(temp[i])
  //  res +=sss
  //}
  //return res
  //法二:
  return string(temp)
}


分享工作随笔,记录

今天讲的内容太多了,那就下一期让我们轻松点,发一篇好朋友33w天翼云的面经吧~

三道go面试题并进行解答

1、WaitGroup 用法

一个 WaitGroup 对象可以等待一组协程结束。使用方法是:

  1. main 协程通过调用 wg.Add(delta int) 设置 worker 协程的个数,然后创建 worker 协程;
  2. worker 协程执行结束以后,都要调用 wg.Done();

3.main 协程调用 wg.Wait() 且被 block,直到所有 worker 协程全部执行结束后返回。

2、WaitGroup 实现原理

1.WaitGroup 主要维护了 2 个计数器,一个是请求计数器 v,一个是等待计数器 w,二者组成一个 64bit 的值,请求计数器占高 32bit,等待计数器占低32bit

2.每次 Add 执行,请求计数器 v 加 1,Done 方法执行,请求计数器减 1v 为0 时通过信号量唤醒 Wait()。

3、什么是 sync.Once

1.Once 可以用来执行且仅仅执行一次动作,常常用于单例对象的初始化场景。

2.Once 常常用来初始化单例资源,或者并发访问只需初始化一次的共享资源,或者在测试的时候初始化一次测试资源。

3.sync.Once 只暴露了一个方法 Do,你可以多次调用 Do 方法,但是只有第一次调用 Do 方法时 f 参数才会执行,这里的 f 是一个无参数无返回值的函数。

4、什么操作叫做原子操作

 原子操作即是进行过程中不能被中断的操作,针对某个值的原子操作在被进行的过程中,CPU 绝不会再去进行其他的针对该值的操作。为了实现这样的严谨性,原子操作仅会由一个独立的 CPU 指令代表和完成。原子操作是无锁的,常常直接通过 CPU 指令直接实现。事实上,其它同步技术的实现常常依赖于原子操作。

对No.1订正

 文章发出后@smile同学引用文章:https://www.tapirgames.com/blog/golang-has-no-reference-values 对go语言是否有“引用类型”产生讨论,在该文中提出用go底层实现方式“引用类型”也并非引用类型,提出了“值类型和非值类型”的概念,是一个很好的观点,对@smile致以感谢,其他同学怎么理解go640.png语言中的“值类型和引用类型”欢迎在评论区给出讨论!下面是文章重点两处翻译的图片,请大家参考。


相关文章
|
1月前
|
编解码 Shell Python
使用lame以多进程方式转码wav为mp3
使用lame以多进程方式转码wav为mp3
|
4月前
|
编解码 Linux C语言
实现一个传输aac音频的rtsp服务器
实现一个传输aac音频的rtsp服务器
84 0
|
存储 应用服务中间件 nginx
FFmpeg+Nginx将视频转为hls点播视频流
FFmpeg+Nginx将视频转为hls点播视频流
585 0
FFmpeg+Nginx将视频转为hls点播视频流
|
存储
FLV封装格式
FLV封装格式介绍及解释,本文介绍 FLV 里面各种tag的作用。
121 0
FreeSWITCH的SDP读取与设置
在对接第三方SIP客户端和网关时,常常需要修改手工修改SDP信息。 下面给出设置修改SDP信息的两种方法,如下: – 通过拨号方案修改SDP信息 – 通过API命令修改SDP信息
|
存储 编解码 索引
Bluetooth Profile Specification之1.2 A2DP 之Audio Codec(音频编解码器)-MPEG-1,2 Audio和MPEG-2, 4 AAC
Bluetooth Profile Specification之1.2 A2DP 之Audio Codec(音频编解码器)-MPEG-1,2 Audio和MPEG-2, 4 AAC
265 0
Bluetooth Profile Specification之1.2 A2DP 之Audio Codec(音频编解码器)-MPEG-1,2 Audio和MPEG-2, 4 AAC
|
存储 编解码 数据安全/隐私保护
FLV 封装格式解析
FLV (Flash Video) 是由 Adobe 公司推出的一种封装格式,主要用于流媒体系统。FLV 封装的媒体文件具有体积轻巧、封装播放简单等特点,很适合网络应用。目前各浏览器普遍使用 Flash Player 作为网页播放器,使得安装有浏览器的计算机终端不需要另外安装播放器,这也是 FLV 格式广为流行的原因之一。
387 0
FLV 封装格式解析
|
应用服务中间件 nginx