https://tiancaiamao.gitbooks.io/go-internals/content/zh/10.1.html
https://www.jianshu.com/p/5e44168f47a3
分布式锁
Linux操作系统:写时复制技术
了解COW
写时复制(copy-on-write,又称COW)是一种可以推迟甚至免除拷贝数据的技术。
Linux的fork()使用写时拷贝(copy-on-write)内存页实现。fork后父子进程两者的虚拟内存地址不同,但通过页表映射关系,最终物理地址是同一个,子进程的代码段、数据段、堆栈都是指向父进程的物理空间。当父子进程中某段数据修改时,子进程才真正分配物理空间。
效果
1.减少拷贝次数,降低开销。
在页根本不会被写入的情况下—举例来说,fork()后立即调用exec()—它们就无需复制了。fork()的实际开销就是复制父进程的页表以及给子进程创建唯一的进程描述符。在一般情况下,进程创建后都会马上运行一个可执行的文件,这种优化可以避免拷贝大量根本就不会被使用的数据(地址空间里常常包含数十兆的数据)。
COW应用场景
redis的COW
redis中借助了fork内部的COW,达到降低内存拷贝的目的
redis运行时通常是单进程的,在bgsave或bgrewriteof时会fork出一个进程, 如果子进程存在期间发生大量写操作,会出现很多缺页异常,导致耗费不少性能在内存复制上
为了尽量避免子进程存在期间触发rehash操作(rehash会对原key所有数据进行迁移),此时redis会将负载因子阈值提高到5,避免不必要的内存拷贝
C++
实际上COW技术不仅仅在Linux进程上有应用,其他例如C++的String在有的IDE环境下也支持COW技术,即例如:
|
|
之后执行代码:
|
|
在开始的两个语句后,str1和str2存放数据的地址是一样的,而在修改内容后,str1的地址发生了变化,而str2的地址还是原来的,这就是C++中的COW技术的应用,不过VS2005似乎已经不支持COW。
mcq接收数据乱码的坑
问题描述
今天有同事反馈,我们推送到mcq队列中的数据有一些获取到的是乱码。
同事使用C语言读取队列,起初认为是他们代码编写有问题,后来自己尝试用php写入同样的数据后立即读取,也会出现乱码数据。并且乱码的数据通常长度比较长。
interface和struct
go数据类型转换
数值间转换
|
|
报错:
invalid operation: a + b (mismatched types int and int32)
正确用法
|
|
数据溢出: 超过类型的bit将会被丢弃,剩下的可能是负值
字符串与其他类型
strconv
其他类型转向字符串时方法前缀是Format,从字符串转为其他类型则方法前缀是Parse
strconv.Atoi 字符串转整数
strconv.Itoa 整数转字符串
strconv.ParseBool 字符串转布尔
strconv.FormatBool 布尔转字符串
strconv.ParseFloat 字符串转浮点数
strconv.FormatFloat 浮点数转字符串\
go条件编译
背景
golang官方为我们提供了标准的json解析库–encoding/json,大部分情况下,使用它已经够用了。不过这个解析包有个很大的问题–性能。它不够快,如果我们开发高性能、高并发的网络服务就无法满足,这时就需要高性能的json解析库,目前性能比较高的有json-iterator和easyjson。
现在我们需要引进一个高性能的json解析库,这里以json-iterator为例,但是我们全部换掉又不放心,所以可以先小范围的测试下,这时候我们就需要两个解析库并存,那么这时候我们如何选择我们需要的解析库编译和运行呢?
解决上面问题的办法就是条件编译。做过C/C++开发的都了解它有预编译可以解决这个问题,那么对于Go是没有预编译的,但是Go语言为我们提供了基于tags的编译约束来解决这个问题。
go基准测试
什么是基准测试
基准测试,是一种测试代码性能的方法,比如你有多种不同的方案,都可以解决问题,那么到底是那种方案性能更好呢?这时候基准测试就派上用场了。
基准测试主要是通过测试CPU和内存的效率问题,来评估被测试代码的性能,进而找到更好的解决方案。比如链接池的数量不是越多越好,那么哪个值才是最优值呢,这就需要配合基准测试不断调优了。