Protocol Buffer
是Google提供的一种数据序列化协议,它是一种轻便高效的结构化数据存储格式,可以用于结构化数据序列化,很适合做数据存储或 RPC
数据交换格式。它可用于通讯协议、数据存储等领域的语言无关、平台无关、可扩展的序列化结构数据格式。
对 Context
最初的印象是,在 API 项目代码开发中,从中间件处理前序逻辑、 Controller/Action
接收 HTTP 请求开始,所有后续调用都要传递的第一个参数,可以从中获取到客户端的信息、或者临时存储后续逻辑依赖的全局变量(比如Auth中间件解析出的用户id等),另外也可在异常问题排查时,用于全链路的问题排查跟踪。
然而这些功能,其实是各类网络框架比如 gin
等封装后的功能 , Golang 在 1.7 版本开始引入的 context.Context
标准包,其最初目的是增强 Golang 开发中的并发控制技术。
Channel
在 Go 语言中的地位,相当于 Goroutine
的孪生兄弟,Goroutine
负责并发,而 Channel
就是他们之间的通信机制,它可以在多个 goroutine
之间发送信息。
它也是 Go 语言中最常见的、也是经常被人提及的设计模式:不要通过共享内存的方式进行通信,而是应该通过通信的方式共享内存。在很多主流的编程语言中,多个线程传递数据的方式一般都是共享内存,为了解决线程竞争,我们需要限制同一时间能够读写这些变量的线程数量,然而这与 Go 语言鼓励的设计并不相同。
虽然我们在 Go 语言中也能使用共享内存加互斥锁进行通信,但是 Go 语言提供了一种不同的并发模型,即通信顺序进程(Communicating sequential processes,CSP
)。Goroutine
和 Channel
分别对应 CSP 中的实体和传递信息的媒介,Goroutine
之间会通过 Channel
传递数据。
Channel
在多并发操作里是属于协程安全的,并且遵循了 FIFO (First In First Out, 先入先出) 特性。即先执行读取的 goroutine 会先获取到数据,先发送数据的 goroutine 会先输入数据。另外,channel 的使用将会引起 Go runtime 的调度调用,会有阻塞和唤起 goroutine 的情况产生。
一、概念由浅入深,先说并发/并行:
并发: 逻辑上具有处理多个同时性任务的能力。
并行: 物理上同一时刻执行多个并发任务。
我们通常所说的并发编程,就是说它允许多个任务同时执行,但实际上并不一定在同一时刻被执行。在单核处理器上,通过多线程共享CPU时间片串行执行(并发非并行)。而并行则依赖于多核处理器等物理资源,让多个任务可以实现并行执行(并发且并行)。
多线程或多进程是并行的基本条件,但单线程也可以用协程(coroutine
)做到并发。简单将 Goroutine
归纳为协程并不合适,因为它运行时会创建多个线程来执行并发任务,且任务单元可被调度到其它线程执行。这更像是多线程和协程的结合体,能最大限度提升执行效率,发挥多核处理器能力。
Redis 客户端与服务端通信,使用 RESP
协议,RESP
协议全程: Redis Serialization Protocol
即 Redis 序列化协议,专为 Redis 设计。RESP 协议是非TCP 专用的技术,但在 Redis 的环境中,该协议仅用于 TCP 连接。
RESP 可以序列化不同的数据类型,如整数(integers),字符串(strings),数组(arrays)。它还使用了一个特殊的类型来表示错误(errors)。请求以字符串数组的形式来表示要执行命令的参数从客户端发送到Redis服务器。Redis使用命令特有(command-specific)数据类型作为回复。RESP协议是二进制安全的,并且不需要处理从一个进程传输到另一个进程的块数据的大小,因为它使用前缀长度(prefixed-length)的方式来传输块数据的。
模拟 Redis 协议首先是要实现一个 TCP
协议的服务,再按照 redis
的参数组织方式(RESP协议)解析和返回。其中 TCP 服务的实现,主要依赖 net
包中的 Listenr
和 Conn
两个接口 。
需求场景:
- 排行榜,优先按照积分排序,相同分数按照达成时间排序
- 用户量极大,需要准确计算当前用户的排名情况及其分数
- 对同一个用户的积分,不会有并发修改的场景
- 实时更新排行榜
Git 是一个分布式的文件管理和版本控制工具,本文主要从 Git 的快照记录方式和分布式工作方式上介绍一些基础。私以为对 Git 的这些工作方式的认知,会对理解和优化 Git 的日常使用的一些命令比较有帮助。
推荐阅读
GitBook : https://git-scm.com/book/zh/v2
BC 是 Binary Calculator
的缩写。bc*
函数的参数都是操作数加上一个可选的 [int scale]
,比如
1 | string bcadd(string $left_operand, string $right_operand[, int $scale]) |
如果 scale 没有提供,就用 bcscale 的缺省值。这里大数直接用一个由 0-9 组成的string表示,计算结果返回的也是一个 string。 默认 scale值在 php.ini
中配置:
1 | [bcmath] |
一、开启 BCMATH 支持
- 编译时指定:
--enable-bcmath
- 如果编译时没有开启,只能使用
phpize
等当做扩展重新安装,并在php.ini
中添加extension=bcmath.so
开启
一、 Charact-Set
& Collation
charset
表示字符集,常用 utf8
格式,需要支持 emoji
等特殊情况的时候,用到其扩展格式 utf8mb4
。
1 | utf8 为3-Byte 宽度 |
1、关于 GBK/UTF8/GB2312
UTF- 8:Unicode Transformation Format-8bit,允许含BOM,但通常不含BOM。是用以解决国际上字符的一种多字节编码,它对英文使用8位(即一个字节),中文使用24为(三个字节)来编码。UTF-8包含全世界所有国家需要用到的字符,是国际编码,通用性强。UTF-8编码的文字可以在各国支持UTF8字符集的浏览器上显示。如,如果是UTF8编码,则在外国人的英文IE上也能显示中文,他们无需下载IE的中文语言支持包。
GBK是国家标准GB2312基础上扩容后兼容GB2312的标准。GBK的文字编码是用双字节来表示的,即不论中、英文字符均使用双字节来表示,为了区分中文,将其最高位都设定成1。GBK包含全部中文字符,是国家编码,通用性比UTF8差,不过UTF8占用的数据库比GBD大。