1、go中拼接字符串有几种方式
1、"+"
最常用的方法就是,使用"+"将两个字符串进行连接,与Python类似,不过Go语言中的字符串是不可变的类型,因此用"+"进行连接会产生一个新的字符串,这样对效率会有所影响。
a := "字符串" b := "拼接" c := a+b fmt.Print(c) //c = "打印字符串"
2、使用sprintf函数
第二种方法,就是使用sprintf函数,虽然不会像直接使用+那样产生临时的字符串,但效率也不高。
a := "字符串" b := "拼接" c := fmt.Sprintf("%s%s", a, b) //c = "打印字符串"
3、使用Join函数
第三种方法就是,使用Join函数,这里需要先引入strings包才能调用Join函数,此函数会先根据字符串数组的内容,计算出一个拼接之后的长度,然后申请对应大小的内存,一个一个字符串填入,在已有一个数组的情况下,这种效率会很高,如果没有的话效率也不高。
//需要先导入strings包 a := "字符串" b := "拼接" //定义一个字符串数组包含上述的字符串 var str []string = []string{a, b} //调用Join函数 c := strings.Join(str, "") fmt.Print(c)
4、调用buffer.WriteString函数
第四种方法就是,调用buffer.WriteString函数,此方法的性能要远远大于上面的方法。
//需要先导入bytes包 a := "字符串" b := "拼接" //定义Buffer类型 var bt bytes.Buffer 向bt中写入字符串 bt.WriteString(a) bt.WriteString(b) //获得拼接后的字符串 c := bt.String()
5、用buffer.Builder
第五种方法是用buffer.Builder,此方法和上面的差不多,不过官方建议使用这个,且使用方法和上面基本一样。
//需要先导入Strings包 a := "字符串" b := "拼接" var build strings.Builder build.WriteString(a) build.WriteString(b) c := build.String()
2、go中"_"的作用
1、import中的下滑线
此时“_”的作用是:当导入一个包的时候,不需要把所有的包都导进来,只需要导入使用该包下的文件里所有的init()的函数。
package main import _ "hello/imp" func main() { //imp.Print() //编译报错,说:undefined: imp
2、下划线在代码中
作用是:下划线在代码中是忽略这个变量也可以理解为占位符,那个位置上本应该赋某个值,但是我们不需要这个值,所以就把该值给下划线,意思是丢掉不要,这样编译器可以更好的优化,任何类型的单个值都可以丢给下划线。
如果方法返回两个值,只想要其中的一个结果,那另一个就用_占位
package main import "fmt" v1, v2, _ := function(...)
3、占位符
"_"是特殊标识符,用来忽略结果
3、使用go实现99乘法表
for i := 1; i < 10; i++ {
for j := 1; j <= i; j++ {
fmt.Printf("%d*%d=%d ", j, i, i*j)
}
fmt.Println("")
}
结果:
1*1=1
1*2=2 2*2=4
1*3=3 2*3=6 3*3=9
1*4=4 2*4=8 3*4=12 4*4=16
1*5=5 2*5=10 3*5=15 4*5=20 5*5=25
1*6=6 2*6=12 3*6=18 4*6=24 5*6=30 6*6=36
1*7=7 2*7=14 3*7=21 4*7=28 5*7=35 6*7=42 7*7=49
1*8=8 2*8=16 3*8=24 4*8=32 5*8=40 6*8=48 7*8=56 8*8=64
1*9=9 2*9=18 3*9=27 4*9=36 5*9=45 6*9=54 7*9=63 8*9=72 9*9=81
4、linux命令,查看端口占用,cpu负载,内存占用,如何发送信号给一个进程、修改文件权限
Linux 查看端口占用情况:
lsof -i:端口号
netstat -tunlp | grep 端口号
cpu负载:
uptime
内存占用:
top
如何发送信号给一个进程:
1. kill() 函数
2. alarm() 函数
修改文件权限:
chmod命令用于修改文件权限
5、Redis redo log, binlog 与 undo log
redo log是属于innoDB层面,binlog属于MySQL Server层面的,这样在数据库用别的存储引擎时可以达到一致性的要求。
redo log是物理日志,记录该数据页更新的内容;binlog是逻辑日志,记录的是这个更新语句的原始逻辑
redo log是循环写,日志空间大小固定;binlog是追加写,是指一份写到一定大小的时候会更换下一个文件,不会覆盖。
binlog可以作为恢复数据使用,主从复制搭建,redo log作为异常宕机或者介质故障后的数据恢复使用。1.redo log通常是物理日志,记录的是数据页的物理修改,而不是某一行或某几行修改成怎样怎样,它用来恢复提交后的物理数据页(恢复数据页,且只能恢复到最后一次提交的位置)。
2.undo用来回滚行记录到某个版本。undo log一般是逻辑日志,根据每行记录进行记录。
6、使用三个协程,每秒钟打印cat dog fish
使用三个协程,每秒钟打印cat dog fish 注意:1、顺序不能变化(协程1打印cat,协程2打印dog,协程3打印fish) 2、无限循环即可/* 使用三个协程,每秒钟打印cat dog fish 注意:顺序不能变化(协程1打印cat,协程2打印dog,协程3打印fish) 无限循环即可 */ func main() { wg := sync.WaitGroup{} wg.Add(3) chcat := make(chan int) chdog := make(chan int) chfish := make(chan int) go printCat(&wg, chcat, chfish) go printDog(&wg, chdog, chcat) go printfash(&wg, chfish, chdog) wg.Wait() } func printDog(wg *sync.WaitGroup, dog chan int, cat chan int) { defer wg.Done() for { <-cat fmt.Println("dog") time.Sleep(time.Second) dog <- 1 } } func printCat(wg *sync.WaitGroup, cat chan int, fish chan int) { defer wg.Done() for { cat <- 1 fmt.Println("cat") time.Sleep(time.Second) <-fish } } func printfash(wg *sync.WaitGroup, fish chan int, dog chan int) { defer wg.Done() for { <-dog fmt.Println("fish") time.Sleep(time.Second) fish <- 1 } }
7、Go出现panic的场景
go中发生panic的场景: - 数组/切片越界 - 空指针调用。比如访问一个 nil 结构体指针的成员 - 过早关闭 HTTP 响应体 - 除以 0 - 向已经关闭的 channel 发送消息 - 重复关闭 channel - 关闭未初始化的 channel - 未初始化 map。注意访问 map 不存在的 key 不会 panic,而是返回 map 类型对应的零值,但是不能直接赋值 - 跨协程的 panic 处理 - sync 计数为负数。 - 类型断言不匹配。`var a interface{} = 1; fmt.Println(a.(string))` 会 panic,建议用 `s,ok := a.(string)`
8、Http是短连接还是长连接?
- 在HTTP/1.0中,默认使用的其实是短连接。也就是说,浏览器和服务器每进行一次HTTP操作,就要建立一次连接,但任务结束后就会中断连接。如果客户端浏览器访问的某个HTML或其他类型的 Web页中包含有其他的Web资源,如JavaScript文件、图像文件、CSS文件等;当浏览器每遇到这样一个Web资源,就会建立一个HTTP会话;
- 但从HTTP/1.1起,默认使用长连接,用以保持会话的连接特性。使用长连接的HTTP协议,会在响应头中加入这行代码:Connection:keep-alive;
- 在使用长连接的情况下,当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的 TCP连接不会关闭,如果客户端再次访问这个服务器上的网页,会继续使用这一条已经建立好的连接。但Keep-Alive也不会永久保持连接,它有一个保持时间,可以在不同的服务器软件(如Apache)中设定这个时间。我们要注意,实现长连接要客户端和服务端都支持长连接。
TCP三次握手和四次挥手过程
既然上面我们说到了三次握手和四次挥手,健哥就再扩展一下说说这两个操作的实现过程。
三次握手:先向HTTP服务器发起TCP的确认请求
- 客户端 --> SYN --> 服务器
- 服务器 --> SYN+ACK --->客户端
- 客户端 --> ACK --> 服务器
四次挥手:客户端要和服务器断开TCP连接
- 客户端 --> FIN +ACK ---> 服务器
- 服务器 --