1. 同步和异步,阻塞和非阻塞
2. 线程状态
3. 什么是上下文切换
4. 文件系统格式
- 类 Unix
ext
- ext
- ext2
- ext3
- ext4
- DOM
- FAT32
传统的 windows 平台文件系统格式,兼容性强。
但 FAT32 不支持 4GB 以上的文件,并且没有日志,也就是断电后容易出现文件丢失的情况
- NTFS
sql 语句 > 查询缓存 > 解释器 > 优化器 > 执行器
解释如下可能会用到 2~3 个事务,这里简称 ABC。
脏写
B 写失败了
脏读
B 在 step 2 时读取了脏数据
脏写和脏读类似,都是对未提交事务修改的数据进行操作,在该事务发生错误回滚后,就会导致脏写和脏读发生
不可重复读(update)
A 在执行过程中多次读取数据,但在执行过程中,B 和 C 修改并提交了数据,导致 A 多次读取读取到了不同的值
幻读(insert,delete)
A 在执行过程中多次查询数据,但在执行过程中,B 和 C 插入并提交新的数据,导致 A 多次查询,查到了不同条数的结果
区别:
互斥锁:在加锁失败后,线程会释放 CPU,给其他线程;
互斥锁在加锁失败时,会从用户态陷入到内核态,让内核帮我们切换线程,这样就会造成一定的性能开销。
线程在两次状态的切换中,会有两次线程上下文切换。
线程的上下文切换的是什么?当两个线程是属于同一个进程,因为虚拟内存是共享的,所以在切换时,虚拟内存这些资源就保持不动,只需要切换线程的私有数据、寄存器等不共享的数据。
有大佬统计过,大概在几十纳秒到几微秒之间。如果你能确定被锁住的代码执行时间很短,就应该选用自旋锁,否则使用互斥锁。
自旋锁:在加锁失败后,线程会忙等待,直到它拿到锁;
自旋锁是通过 CAS(Compare And Swap)函数,在用户态完成加锁和解锁,所以不会上下文切换的开销,相对于互斥锁更快,开销更小。
atomic.AddInt64
在 32 位操作系统上内存对齐的问题在32位机器上使用int64可能会出现panic: unaligned 64-bit atomic operation
1 | package main |
redis 是内存型 NoSQL 数据库,因其使用内存存储,性能优越,其读写速度远超其他类型的数据库。
1 | # update or (create if not exist) |
1 | # update or (create if not exist) field |
总结一下
声明:以下 SQL 优化策略适用于数据量较大的场景下,如果数据量较小,没必要以此为准,以免画蛇添足。
1 | # bad |
如果需要在前面使用模糊查询,提供几个解决思路:
INSTR(str, substr)
来匹配like '%xx%'
原文:详解 Go 语言的内存模型及堆的分配管理 ,建议 tm 反复观看
golang 的内存管理是借鉴了 TCMalloc(Thread Cache Malloc),随着 Go 的迭代,Go 的内存管理与 TCMalloc 不一致的地方也在扩大,但其主要思想是一致的。只是比 TCMalloc 多了逃逸分析和垃圾回收。