Ryo's blog

归档 · 全部

首页

关于

归档

BackendGolang

Golang Memory Model

一、背景1.1 一个 Code Review 引发的思考一个同学在 Golang 项目里面用 Double Check(不清楚的同学可以去百度搜下,Java中比较常见)的方式实现了一个单例。具体实现如下: var ( lock sync.Mutex instance *UserInfo ) func getInstance() (*UserInfo, error) { if instance == nil { //---Lock lock.Lock() defer lock.Unlock() if instance == nil { instance = &UserInfo{ ..

更多
BackendGolang

深入理解 Golang Stack

基础知识Linux 进程地址空间布局我们知道CPU有实模式和保护模式,系统刚刚启动的时候是运行在实模式下,然后经过一系列初始化工作以后,Linux会把CPU的实模式改为保护模式(具体就是修改CPU的CR0寄存器相关标记位),在保护模式下,CPU访问的地址都是虚拟地址(逻辑地址)。Linux 为了每个进程维护了一个单独的虚拟地址空间,虚拟地址空间又分为“用户空间”和“内核空间”。 虚拟地址空间更多相关可以看Linux内核虚拟地址空间这篇文章。 Golang 栈内存在虚拟地址空间哪个区域Golang 的内存管理是用的 TCMalloc(Thread-Caching Malloc)算法, 简单点说就是 Golang 是使用 mmap 函数去操作系统申请一大块内存,然后把内存按照 8Byte~32KB 6..

更多
BackendMiddlewareMySQL

MySQL Insert 死锁问题研究

背景不想看废话的,建议直接去最后看死锁的本质原因。 问题背景线上一个很简单结构的表,报insert死锁,这个表基本上只有insert操作,所以引出一个问题insert 和insert之间为什么会死锁? 顺便说下我们线上库的隔离级别都是RC,日志格式是ROW,我下面所有测试都是在RC下。 *** (1) TRANSACTION: TRANSACTION 2404187192, ACTIVE 0 sec inserting mysql tables in use 1, locked 1 LOCK WAIT 8 lock struct(s), heap size 1136, 2 row lock(s) MySQL thread id 118913019, OS thread handle 140411115681..

更多
loading..
SystemLinuxMemory

Linux内核虚拟地址空间

x86-32位虚拟地址空间就我们所知,Linux内核一般将处理器的虚拟地址空间划分为两个部分。底部比较大的部分用于用户进程,顶部则专用于内核。虽然(在两个用户进程之间的)上下文切换期间会改变下半部分,但虚拟地址空间的内核部分总是保持不变。 Linux将虚拟地址空间划分为:0~3G为用户空间,3~4G为内核空间 点我查看原图 用户地址空间 保留区 - 0x08048000位于虚拟地址空间的最低部分,未赋予物理地址。任何对它的引用都是非法的,用于捕捉使用空指针和小整型值指针引用内存的异常情况。 它并不是一个单一的内存区域,而是对地址空间中受到操作系统保护而禁止用户进程访问的地址区域的总称。大多数操作系统中,极小的地址通常都是不允许访问的,如NULL。C语言将无效指针赋值为0也是出于这种考虑,..

更多
BackendMySQL

MySQL DateTime和Timespan时区问题

一、背景最近负责一个数据传输的项目,其中一个需求就是能把一个DB里面的数据拉出来 ,然后回放到另外一个同构的DB。两个DB的服务不在一个时区(其实这不是重点),可能配置不同。之前有过类似的项目,当时是基建的同事负责做数据同步,同步过去以后DateTime、Timespan字段的时区信息都丢了。老板让我调研下问题根因,不要踩之前的坑。 最早的时候看了下同事写的当时MySQL时区信息丢失的问题总结文档,文档里面当时把DateTime和Timespan两个时区问题混为一起了,也没分析本质原因,导致我当时没看太明白,然后的武断的认为,之所以时区丢失了,是因为基础组件同步DateTime和TimeSpan的时候同步的是字符串,比如2021-11-27 10:49:35.857969这种信息,我们传输的时候,只要转Un..

更多
NoteLiterature

《黑客与画家》

第一章节:为什么书呆子不受欢迎首先这里“书呆子”指的“高智商”的人。 解开这个谜的关键是把问题换一种提法。为什么聪明的小孩没有让自己变得受欢迎?如果他们真的很聪明,为什么找不到受欢迎的诀窍呢?他们在标准化测试中表现得这么好,为什么就不能在这方面也大获成功呢? 有一种观点认为,其他小孩妒忌聪明学生,所以聪明的学生不可能受到欢迎。我倒希望这种解释是对的。回想起来,要是初中里真的有人妒忌我,那么他们一定费了很大力气才把这种妒忌隐藏得无法发现。而且,在任何情况下,如果聪明真的令他人妒忌,这反而会招来女生。因为女生喜欢被其他男生妒忌的男生。 在我就读过的学校,聪明根本就是无足轻重的一样东西。同学们既不看重它,也不唾弃它。如果别的事情都相同,那么大家还是愿意自己变得聪明一点,因为这总比做个笨人好。但是总的来说,智力在大..

更多
NoteLiterature

《清醒思考的艺术》

1. 幸存偏误为什么你该去逛逛墓地 幸存偏误是指:由于日常生活中更容易看到成功、看不到失败,你会系统性地高估成功的希望。不了解现实的你(与雷托一样)对成功抱有一种幻想,认识不到成功的概率有多微弱。每位成功的作家背后都有100个作品卖不出去的作家,每个作品卖不出去的作家背后又有100个找不到出版社的作者,每个找不到出版社的作者背后又有数百个抽屉里沉睡着刚动笔的手稿的写作爱好者。而我们总是听到成功者的故事,认识不到作家的成功概率有多小。摄影师、企业家、艺术家、运动员、建筑师、诺贝尔奖得主、电视制作人和选美冠军的情况也是一样。媒体没兴趣去刨挖失败者的墓地,这事也不归他们负责。这意味着:要想缓解幸存偏误,你就得了解这些。 幸存偏误意味着:你系统性地高估了成功概率。解决办法:尽可能常去逛逛曾经大有希望的项目、投资和事..

更多
NoteLiterature

《被讨厌的勇气》

引言提出论点:“人可以改变,而且人人都可以获得幸福。” 青年:世界是简单的,人生也是如此。假若这种命题中含有几分真理,那也是对于孩子的世界而言。孩子的世界没有劳动或纳税之类的现实义务,他们每天都在父母或社会的呵护下自由自在地生活,未来充满无限希望,自己也似乎无所不能。孩子们的眼睛被遮盖了,不必去面对丑恶的现实。的确,孩子眼中的世界呈现出简单的姿态。 但是,随着年龄的增长,世界便逐渐露出真面目。人们不得不接受“我只不过如此”之类的现实,原以为等候在人生路上的一切“可能”都会变成“不可能”。幸福的浪漫主义季节转瞬即逝,残酷的现实主义时代终将到来。 人一旦长大,就会被复杂的人际关系所困扰,被诸多的责任所牵绊。工作、家庭或者社会责任,一切都是。当然,孩提时代无法理解的歧视、战争或阶级之类的各种社会问题也会摆在你眼前..

更多
Maths

MIT - 线性代数

一、Lesson 11.1 方程组的几何解释 上面方程组我们可以写成矩阵形式 上面的矩阵可以看成 Ax = b的形式 : 系数矩阵(A):将方程系数按行提取出来,构成一个矩阵 未知向量(x):将方程未知数提取出来,按列构成一个向量。 向量(b) :将等号右侧结果按列提取,构成一个向量 1.1.1 行图像在坐标系上画出“行图像”,可以知两个线交点就是我们要求的解 1.1.2 列图像从列图像的角度,我们再求这个方程可以看成矩阵: 1.2 方程组的几何形式推广1.2.1 高维行图像我们将方程维数推广,从三维开始,如果我们继续做行图像求解,那么会的到一个很复杂的图像。 矩阵如下: 如果绘制行图像,很明显这是一个三个平面相交得到一点,我们想直接看出 这个点的性质可谓是难上加难,比较靠谱的思路是先联..

更多
BackendMiddlewareEnvoy

Envoy 编译调试

Debian9 上编译调试主要参考Envoy官方的Bazel编译文档 下载bazelisk-linux-amd64 sudo wget -O /usr/local/bin/bazel https://github.com/bazelbuild/bazelisk/releases/latest/download/bazelisk-linux-amd64 sudo chmod +x /usr/local/bin/bazel 安装依赖 sudo apt-get install \ autoconf \ automake \ cmake \ curl \ libtool \ make \ ninja-build \ patch \ ..

更多
ArchitectureNote

Clean Code

什么是整洁代码 能通过所有测试; 没有重复代码; 体现系统中的全部设计理念; 包括尽量少的实体,比如类、方法、函数等。 童子军军规光把代码写好可不够。必须时时保持代码整洁。我们都见过代码随时间流逝而腐坏。我们应当更积极地阻止腐坏的发生。 让营地比你来时更干净。 有意义的命名名副其实名副其实说起来简单。我们想要强调,这事很严肃。选个好名字要花时间,但省下来的时间比花掉的多。注意命名,而且一旦发现有更好的名称,就换掉旧的。这么做,读你代码的人(包括你自己)都会更开心。 变量、函数或类的名称应该已经答复了所有的大问题。它该告诉你,它为什么会存在,它做什么事,应该怎么用。如果名称需要注释来补充,那就不算是名副其实。 避免误导程序员必须避免留下掩藏代码本意的错误线索。应当避免使用与本意相悖的词。例如,hp、aix ..

更多
ArchitectureNote

Clean Architecture

零、概述软件架构设计是一件非常困难的事情,这通常需要大多数程序员所不具备的经验和技能。同时,也不是所有人都愿意花时间来学习和钻研这个方向。做一个好的软件架构师所需要的自律和专注程度可能会让大部分程序员始料未及,更别提软件架构师这个职业本身的社会认同感与人们投身其中的热情了。 采用好的软件架构可以大大节省软件项目构建与维护的人力成本。让每次变更都短小简单,易于实施,并且避免缺陷,用最小的成本,最大程度地满足功能性和灵活性的要求。 0.1 设计与架构究竟是什么?一直以来,设计(Design)与架构(Architecture)这两个概念让大多数人十分迷惑——什么是设计?什么是架构?二者究竟有什么区别? 本书的一个重要目标就是要清晰、明确地对二者进行定义。首先我要明确地说,二者没有任何区别。一丁点区别都没有! “架..

更多
ArchitectureNote

DDD-领域驱动设计

一、DDD的基础概念1.1 什么是 DDD 2004 年埃里克·埃文斯(Eric Evans)发表了《领域驱动设计》(Domain-Driven Design –Tackling Complexity in the Heart of Software)这本书,从此领域驱动设计(Domain Driven Design,简称 DDD)诞生。DDD 核心思想是通过领域驱动设计方法定义领域模型,从而确定业务和应用边界,保证业务模型与代码模型的一致性。领域驱动设计,主要是用来指导如何解耦业务系统,划分业务模块,定义业务领域模型及其交互。领域驱动设计这个概念并不新颖,早在 2004 年就被提出了,到现在已经有十几年的历史了。不过,它被大众熟知,还是基于另一个概念的兴起,那就是微服务。不过,我个人觉得,领域驱动设计有点..

更多
NoteSystemChip

《说透芯片》

基础知识晶体管想了解晶体管,你得先了解它的“前身”——电子管。电子管是中文翻译后的名称,英文原文其实是真空管。从这个名字,你可以想象,它其实是把参与工作的金属薄片,也就是电极,封装在一个真空的容器内,真空容器一般指的是玻璃瓶。 整个电子行业,并不是从芯片开始的,而是从电子管开始。电子管最鼎盛时期的代表作,就是世界上的第一台电子计算机。这台 1946 年诞生的电子计算机,占地 150 平方米,重达 30 吨,里面的电路使用了 17468 只电子管、7200 只电阻、10000 只电容、50 万条线。 这台计算机虽然运算速度不快,但基本具备了现代计算机的主要结构和功能,这也是电子管能达到的最高成就了。其实从上图你也可以看出来,电子管最大的缺点就是,真空容器对于电子产品来说体积太大了。 如果人类停留在电子管技术上..

更多
BackendGolang

Golang RWMutext 代码走读

type RWMutex struct { w Mutex // held if there are pending writers writerSem uint32 // 写的信号量 readerSem uint32 // 读的信号量 readerCount int32 // 等待写的个数 readerWait int32 // 等待读的个数 } // 加“读锁” // 对readerCount + 1 。 // 然后看 readerCount是不是小于0 // 小于0表示 正在加写锁,然后阻塞到rw.readerSem 这个信号上。 func (rw *RWMutex) RLock() { if atomic.AddInt32(..

更多
NoteMiddlewareSystem

K8S学习笔记

环境配置Docker File 编写#源镜像 FROM golang:latest # 容器环境变量添加,会覆盖默认的变量值 ENV GOPROXY=https://goproxy.cn,direct ENV GO111MODULE="on" ENV test="on" # 作者 LABEL author="fanlv" LABEL email="fanlvlgh@gmail.com" #设置工作目录 WORKDIR /go/src/gitee.com/fanlv/GolangDemo/GoTest/docker # 复制仓库源文件到容器里 COPY . . # 编译可执行二进制文件(一定要写这些编译参数,指定了可执行程序的运行平台,参考:https://www.jianshu.com/p/4b345a..

更多
ArithmeticSort

常用的排序算法

插入排序func insertSort(nums []int) { for i := 1; i < len(nums); i++ { tmp := nums[i] for j := i; j >= 0; j-- { if j > 0 && tmp < nums[j-1] { nums[j] = nums[j-1] } else { nums[j] = tmp break } } } } 折半插入排序func binaryInsertSor..

更多
BackendMiddlewareRedis

Redis 高可用解决方案总结

一、主从复制什么是主从复制我们正常在项目中对redis进行应用,一般都不会是单点的。因为,单点的宕机即不可用,不能保证可用性。另外,单点redis读写指令都会打到同一个服务里面,也会影响性能。在通常的应用中,对redis的读操作远远多于写操作,所以,我们一般会选择“一主多从”的集群策略。 主中的数据有两个副本(replication)即从redis1和从redis2,即使一台服务器宕机其它两台服务也可以继续提供服务。 主中的数据和从上的数据保持实时同步,当主写入数据时通过主从复制机制会复制到两个从服务上。 只有一个主redis,可以有多个从 redis。 主从复制不会阻塞master,在同步数据时,master可以继续处理client请求。 一个可以即是主又是从,如下图: 主从复制过程一般当slav..

更多
BackendMiddlewareRedis

Redis 源码分析(七) :skiplist

一、skiplist由来skiplist本质上也是一种查找结构,用于解决算法中的查找问题(Searching),即根据给定的key,快速查到它所在的位置(或者对应的value)。 我们在《Redis内部数据结构详解》系列的第一篇中介绍dict的时候,曾经讨论过:一般查找问题的解法分为两个大类:一个是基于各种平衡树,一个是基于哈希表。但skiplist却比较特殊,它没法归属到这两大类里面。 这种数据结构是由William Pugh发明的,最早出现于他在1990年发表的论文《Skip Lists: A Probabilistic Alternative to Balanced Trees》。对细节感兴趣的同学可以下载论文原文来阅读。 skiplist,顾名思义,首先它是一个list。实际上,它是在有序链表的基础..

更多
BackendMiddlewareRedis

Redis 源码分析(六) :quciklist

一、什么是quicklist由于考虑到链表adlist的附加空间相对太高,prev和next指针就要占去 16 个字节 (64bit系统的指针是8个字节),另外每个节点的内存都是单独分配,会加剧内存的碎片化,影响内存管理效率。 quicklist是一个3.2版本之后新增的基础数据结构,是redis自定义的一种复杂数据结构,将ziplist和adlist结合到了一个数据结构中。主要是作为list的基础数据结构。在3.2之前,list是根据元素数量的多少采用ziplist或者adlist作为基础数据结构,3.2之后统一改用quicklist,从数据结构的角度来说quicklist结合了两种数据结构的优缺点,复杂但是实用: 链表在插入,删除节点的时间复杂度很低;但是内存利用率低,且由于内存不连续容易产生内存碎片..

更多
BackendMiddlewareRedis

Redis 源码分析(五) :ziplist

一、前言ziplist是redis节省内存的典型例子之一,这个数据结构通过特殊的编码方式将数据存储在连续的内存中。在3.2之前是list的基础数据结构之一,在3.2之后被quicklist替代。但是仍然是zset底层实现之一。 二、存储结构压缩表没有数据结构代码定义,完全是通过内存的特殊编码方式实现的一种紧凑存储数据结构。我们可以通过ziplist的初始化函数和操作api来倒推其内存分布。 #define ZIP_END 255 #define ZIPLIST_BYTES(zl) (*((uint32_t*)(zl))) // 获取ziplist的bytes指针 #define ZIPLIST_TAIL_OFFSET(zl) (*((uint32_t*)((zl)+sizeof(uint..

更多
BackendMiddlewareRedis

Redis 源码分析(四) :intset

一、什么是intsetintset是Redis内存数据结构之一,用来实现Redis的Set结构(当集合元素不大于设定值并且元素都是整数时,就会用intset作为set的底层数据结构),它的特点有: 元素类型只能为数字。 元素有三种类型:int16_t、int32_t、int64_t。 元素有序,不可重复。 intset和sds一样,内存连续,就像数组一样。 二、数据结构定义typedef struct intset { uint32_t encoding; // 编码类型 int16_t、int32_t、int64_t uint32_t length; // 长度 最大长度:2^32 int8_t contents[]; // 柔性数组 } intset; enco..

更多
BackendMiddlewareRedis

Redis 源码分析(三) :dict

一、什么是dictdict (dictionary 字典),通常的存储结构是Key-Value形式的,通过Hash函数对key求Hash值来确定Value的位置,因此也叫Hash表,是一种用来解决算法中查找问题的数据结构,默认的算法复杂度接近O(1),Redis本身也叫Remote Dictionary Server(远程字典服务器),其实也就是一个大字典,它的key通常来说是String类型的,但是Value可以是String、Set、ZSet、Hash、List等不同的类型,下面我们看下dict的数据结构定义。 二、Redis Dict数据结构 从上图可以看出与dict相关的关键数据结构有三个,分别是: dict是Redis中的字典结构,包含两个dictht。 dictht表示一个Hash表。 dic..

更多
BackendMiddlewareRedis

Redis 源码分析(二) :ADList

概述ADList(A generic doubly linked list)是 redis 自定义的一种双向链表,广泛运用于 redisClients 、 redisServer 、发布订阅、慢查询、监视器等。(注:3.0及以前还会被运用于list结构中,在3.2以后被quicklist取代)。 链表提供了高效的节点重排能力,以及顺序性的节点访问方式,并且可以通过增删节点来灵活地调整链表的长度。 链表在Redis 中的应用非常广泛,比如列表键的底层实现之一就是链表。当一个列表键包含了数量较多的元素,又或者列表中包含的元素都是比较长的字符串时,Redis 就会使用链表作为列表键的底层实现。 链表结构是 Redis 中一个常用的结构,它可以存储多个字符串 它是有序的 能够存储2的32次方减一个节点(超过 40..

更多
BackendMiddlewareRedis

Redis 源码分析(一) :sds

什么是sds字符串是Redis中最为常见的数据存储类型,其底层实现是简单动态字符串sds(simple dynamic string),是可以修改的字符串。 它类似于Java中的ArrayList,它采用预分配冗余空间的方式来减少内存的频繁分配。 数据结构// 3.0及以前 struct sdshdr { // 记录buf数组中已使用字节数量 unsigned int len; // 记录buf数组中未使用的字节数量 unsigned int free; // 字节数组,存储字符串 char buf[]; }; // >=3.2 struct __attribute__ ((__packed__)) sdshdr5 { unsigned cha..

更多
BackendMiddlewareMySQL

MySQL 索引那些事

1. MySQL 常见几种索引类型1.1 普通索引,是最基本的索引,它没有任何限制。它有以下几种创建方式: (1)直接创建索引 CREATE INDEX index_name ON table(column(length)) (2)修改表结构的方式添加索引 ALTER TABLE table_name ADD INDEX index_name ON (column(length)) (3)创建表的时候同时创建索引 CREATE TABLE `table` ( `id` int(11) NOT NULL AUTO_INCREMENT , `title` char(255) CHARACTER NOT NULL , `conten..

更多
SystemLinuxMemory

内存管理、寻址方式那些事

一、内存1.1 什么是内存  简单地说,内存就是一个数据货架。内存有一个最小的存储单位,大多数都是一个字节。内存用内存地址(memory address)来为每个字节的数据顺序编号。因此,内存地址说明了数据在内存中的位置。内存地址从0开始,每次增加1。这种线性增加的存储器地址称为线性地址(linear address)。   内存地址的编号有上限。地址空间的范围和地址总线(address bus)的位数直接相关。CPU通过地址总线来向内存说明想要存取数据的地址。以英特尔32位的80386型CPU为例,这款CPU有32个针脚可以传输地址信息。每个针脚对应了一位。如果针脚上是高电压,那么这一位是1。如果是低电压,那么这一位是0。32位的电压高低信息通过地址总线传到内存的32个针脚,内存就能把电压高低信息转换成3..

更多
DataStructureArithmetic

B-Tree、B+Tree、B*Tree

一、B-Tree1.1 什么是B-Tree 1970年,R.Bayer和E.mccreight提出了一种适用于外查找的树,它是一种平衡的多叉树,称为B树,其定义如下 根结点至少有两个子女。 每个中间节点都包含k-1个元素和k个孩子,其中 m/2 <= k <= m 每一个叶子节点都包含k-1个元素,其中 m/2 <= k <= m 所有的叶子结点都位于同一层。 每个节点中的元素从小到大排列,节点当中k-1个元素正好是k个孩子包含的元素的值域分划。 M = 3 1.2 B-Tree 查找假设我们要查找的数据是 5 二、B+Tree2.1 什么是B+TreeB+ 树是一种树数据结构,是一个n叉树,每个节点通常有多个孩子,一棵B+树包含根节点、内部节点和叶子节点。根节点可..

更多
BackendMiddlewareMySQL

MyISAM和InnoDB区别和应用场景

什么是MyISAM 和InnoDB MyISAM是MySQL的默认数据库引擎(5.5版之前),由早期的ISAM所改良。虽然性能极佳,但却有一个缺点:不支持事务处理(transaction)。 InnoDB,是MySQL的数据库引擎之一,为MySQL AB发行binary的标准之一。InnoDB由Innobase Oy公司所开发,2006年五月时由甲骨文公司并购。与传统的ISAM与MyISAM相比,InnoDB的最大特色就是支持了ACID兼容的事务(Transaction)功能,类似于PostgreSQL。 MyISAM:它是基于传统的ISAM类型,ISAM是Indexed Sequential Access Method (有索引的顺序访问方法) 的缩写,它是存储记录和文件的标准方法。不是事务安全的,而且..

更多
BackendGolang

Golang 内存对齐问题

什么是内存对齐?CPU把内存当成是一块一块的,块的大小可以是2,4,8,16字节大小,因此CPU在读取内存时是一块一块进行读取的。块大小成为memory access granularity(粒度)。 假设CPU访问粒度是4,也就是一次性可以读取内存中的四个字节内容;当我们不采用内存对齐策略,如果需要访问A中的b元素,CPU需要先取出0-3四个字节的内容,发现没有读取完,还需要再次读取,一共需要进行两次访问内存的操作;而有了内存对齐,参考左图,可一次性取出4-7四个字节的元素也即是b,这样就只需要进行一次访问内存的操作。所以操作系统这样做的原因也就是所谓的拿空间换时间,提高效率。 为什么要内存对齐?会了关于结构体内存大小的计算,可是为什么系统要对于结构体数据进行内存对齐呢,很明显所占用的空间大小要更多。原..

更多
BackendMiddlewareConsul

服务发现之Consul

consul是一个可以提供服务发现,健康检查,多数据中心,Key/Value存储等功能的分布式服务框架 用于实现分布式系统的服务发现与配置。与其他分布式服务注册与发现的方案,Consul的方案更”一站式”,内置了服务注册与发现框架、分布一致性协议实现、健康检查、Key/Value存储、多数据中心方案,不再需要依赖其他工具(比如ZooKeeper等)。使用起来也较为简单。Consul用Golang实现,因此具有天然可移植性(支持Linux、Windows和Mac OS X);安装包仅包含一个可执行文件,方便部署,与Docker等轻量级容器可无缝配合。 Consul 的使用场景 docker 实例的注册与配置共享 coreos 实例的注册与配置共享 vitess 集群 SaaS 应用的配置共享 与 confd ..

更多
Backend

分布式id几种生成方案

一、UUIDUUID 是 通用唯一识别码(Universally Unique Identifier)的缩写,是一种软件建构的标准,亦为开放软件基金会组织在分布式计算环境领域的一部分。其目的,是让分布式系统中的所有元素,都能有唯一的辨识信息,而不需要通过中央控制端来做辨识信息的指定。如此一来,每个人都可以创建不与其它人冲突的UUID。在这样的情况下,就不需考虑数据库创建时的名称重复问题。目前最广泛应用的UUID,是微软公司的全局唯一标识符(GUID),而其他重要的应用,则有Linux ext2/ext3文件系统、LUKS加密分区、GNOME、KDE、Mac OS X等等。另外我们也可以在e2fsprogs包中的UUID库找到实现。 UUID的标准形式包含32个16进制数字,以连字号分为五段,形式为8-4-4..

更多
BackendGolang

Go 执行Lua脚本和JS脚本测试

最近有个需求需要在Go项目里面执行动态脚本,github上有好几个lua执行解释器,但是有很多要不就很久没维护了,要不就没有什么文档,经过几个对比我最后用的是 https://github.com/yuin/gopher-lua。JS解析器用的github.com/robertkrimen/otto。 具体测试代码如下,给有需求的朋友参考。 github地址 package main import ( "fmt" "github.com/robertkrimen/otto" "github.com/yuin/gluamapper" "github.com/yuin/gopher-lua" "time" ) //function add(a, b) //return..

更多
BackendProtobufNetHTPP

测试Protobuf在Http传输测试

Demo:https://github.com/fanlv/ProtobufOnHttpGo 一、编写Proto文件syntax = "proto3"; // 生成go代码 //protoc --go_out=. user.proto // 生成oc代码 //protoc --objc_out=. user.proto package user; message LoginRequest { string username = 1; string password = 2; } message BaseResponse{ int64 code = 1; string msg = 2; } message User{ string uid = 1; string..

更多
DataStructureArithmetic

二叉树、2-3 树、红黑树

有序数组的优势在于二分查找,链表的优势在于数据项的插入和数据项的删除。但是在有序数组中插入数据就会很慢,同样在链表中查找数据项效率就很低。综合以上情况,二叉树可以利用链表和有序数组的优势,同时可以合并有序数组和链表的优势,二叉树也是一种常用的数据结构。 一、满二叉树一个二叉树,如果每一个层的结点数都达到最大值,则这个二叉树就是满二叉树。也就是说,如果一个二叉树的层数为 K,且结点总数是(2^k) -1 ,则它就是满二叉树。 二、完全二叉树若设二叉树的深度为 h,除第 h 层外,其它各层 (1 ~ h-1) 的结点数都达到最大个数,第 h 层所有的结点都连续集中在最左边,这就是完全二叉树。 三、二叉查找树二叉查找树(Binary Search Tree),(又:二叉搜索树,二叉排序树)它或者是一棵空树..

更多
BackendIO

高并发服务器IO模型

服务端IO模型总结 草稿 网络框架视角零、Nginx 一、Netty(主从Reactor)MainReactor负责客户端的连接请求,并将请求转交给SubReactor SubReactor负责相应通道的IO读写请求 非IO请求(具体逻辑处理)的任务则会直接写入队列,等待worker threads进行处理 二、GRPC-GO (Goroutine Per Connection)net.Listen -> Serve() -> lis.Accept() net库的accept -> 一个连接开个一个goroutine -> s.handleRawConn(rawConn) -> newHTTP2Transport(conn, authInfo) -> newH..

更多
iOSGRPCFrontend

iOS之GRPC 测试(附代码)

背景最近在用gRPC框架测试,想起去年调研Protocol Buffer在HTTP的时候传输,了解过这个框架,当时没深入。这次做gRPC服务器端,随便看下iOS这边实现方式,附上测试代码。 demo地址: https://github.com/fanlv/gRPCDemo proto文件package user; message LoginRequest { string username = 1; string password = 2; } message BaseResponse{ int64 code = 1; string msg = 2; } message User{ string uid = 1; string name = 2; string ..

更多
BackendGolang

跨域请求的几种解决方案

需求背景最近做的Apigate优化,前端的同学要求能在配置后台页面上加上一键测试接口的功能,但是由于浏览器的同源策略防止跨域攻击,所以前端的页面默认是不能请求其他域名的接口。 方案一 Nginx配置代理location /proxy { if ($arg_url) { proxy_pass $arg_url?; } } 最开始为了简单就配置了一个简单的代理,通过url传入想要访问的接口例如: http://nginxserver/proxy?url=http://10.23.39.140:8080/app/list 这样前端需要什么测试什么接口只需要通过url传过来,Nginx会方向代理到对应的url上返回结果。 但是这个方法有个问题,url中的地址支持IP访问,不支持域名的..

更多
Maths

概率论基础

样本空间与事件A⊂B 事件 B 包含了事件 A,A 被包含于 B A∩B A 与 B 的交集,表示事件 A 和事件 B 同时发生 A∪B A 与 B 的并集,表示事件 A 或事件 B 或他们二者同事发生 P(A|B) 在事件 B 发生下,事件 A 发生的概率 对偶公式 随机事件运算(1)交换律:A∪B=B∪A、AB=BA (2)结合律:( A∪B )∪C=A∪( B∪C ) (3)分配律:A∪( BC )=( A∪B )( A∪C )A( B∪C )=( AB )∪( AC ) (4)摩根律:A B=A∪B、A ∪ B=A B 概率的三个基本性质 二项系数 蒙特卡罗(Monte Carlo) 乘法公式P(AB)=P(B)P(A|B) = P(A)P(B|A) 全概率公式 贝叶斯公式(Bayes)

更多
NoteBackendMiddlewareETCD

《ETCD实战》

背景ectd 常见问题 etcd 基础 etcd 实践 etcd v2 功能 etcd v2 存在的问题 第一,etcd v2 不支持范围查询和分页。分页对于数据较多的场景是必不可少的。在 Kubernetes 中,在集群规模增大后,Pod、Event 等资源可能会出现数千个以上,但是 etcd v2 不支持分页,不支持范围查询,大包等 expensive request 会导致严重的性能乃至雪崩问题。 第二,etcd v2 不支持多 key 事务。在实际转账等业务场景中,往往我们需要在一个事务中同时更新多个 key。 然后是 Watch 机制可靠性问题。Kubernetes 项目严重依赖 etcd Watch 机制,然而 etcd v2 是内存型、不支持保存 key 历史版本的数据库,只在内存中使用滑动..

更多
ArchitectureNote

《设计模式》

前言什么是设计模式设计模式讲的是如何写出可扩展、可读、可维护的高质量代码,所以,它们跟平时的编码会有直接的关系,也会直接影响到你的开发能力。 为什么要学习设计模式 应对面试中的设计模式相关问题。 告别写被人吐槽的烂代码。我见过太多的烂代码,比如命名不规范、类设计不合理、分层不清晰、没有模块化概念、代码结构混乱、高度耦合等等。这样的代码维护起来非常费劲,添加或者修改一个功能,常常会牵一发而动全身,让你无从下手,恨不得将全部的代码删掉重写! 提高复杂代码的设计和开发能力。 让读源码、学框架事半功倍。 为你的职场发展做铺垫 如何评价代码质量的高低?仔细看前面罗列的所有代码质量评价标准,你会发现,有些词语过于笼统、抽象,比较偏向对于整体的描述,比如优雅、好、坏、整洁、清晰等;有些过于细节、偏重方法论,比如模块化、..

更多
NoteSystem

《30天自制操作系统》

30天自制操作系统启动区(boot sector)软盘第一个的扇区称为启动区。那么什么是扇区呢?计算机读写软盘的时候,并不是一个字节一个字节地读写的,而是以512字节为一个单位进行读写。因此,软盘的512字节就称为一个扇区。一张软盘的空间共有1440KB,也就是1474560字节,除以512得2880,这也就是说一张软盘共有2880个扇区。那为什么第一个扇区称为启动区呢?那是因为计算机首先从最初一个扇区开始读软盘,然后去检查这个扇区最后2个字节的内容。如果这最后2个字节不是0x55 AA,计算机会认为这张盘上没有所需的启动程序,就会报一个不能启动的错误。(也许有人会问为什么一定是0x55 AA呢?那是当初的设计者随便定的,笔者也没法解释)。如果计算机确认了第一个扇区的最后两个字节正好是0x55 AA,那它就..

更多
ArchitectureNote

《数据密集型应用系统设计》

数据密集型应用(data-intensive applications)正在通过使用这些技术进步来推动可能性的 边界。一个应用被称为数据密集型的,如果数据是其主要挑战(数据量,数据复杂度或数据变化速度)—— 与之相对的是计算密集型,即处理器速度是其瓶颈。 数据系统的基石可靠性、可扩展性、可维护性现今很多应用程序都是数据密集型(data-intensive)的,而非计算密集型(compute-intensive)的。因此CPU很少成为这类应用的瓶颈,更大的问题通常来自数据量、数据复杂性、以及数据的变更速度。 可靠性(Reliability)系统在困境(adversity)(硬件故障、软件故障、人为错误)中仍可正常工作(正确完成功 能,并能达到期望的性能水准)。 人们对于一个东西是否可靠,都有一个直观的想法。人..

更多
ArchitectureNote

《从0开始学架构》

架构设计理念架构设计理念,可以提炼为下面几个关键点: 架构是系统的顶层结构。 架构设计的主要目的是为了解决软件系统复杂度带来的问题。 架构设计需要遵循三个主要原则:合适原则、简单原则、演化原则。 架构设计首先要掌握业界已经成熟的各种架构模式,然后再进行优化、调整、创新。 框架设计需要考的因素/影响架构复杂性的几个因素 高性能, 衡量软件性能包括了响应时间、TPS、服务器资源利用率等客观指标,也可以是用户的主观感受。 高可用,高可用性就是技术实力的象征,高可用性就是竞争力。99.99%(俗称4个9)网站不可用时间=52.56分钟 可扩展性,设计具备良好可扩展性的系统,有两个基本条件:“正确预测变化、完美封装变化”。 低成本,语言选择、方案选择。 安全,功能安全XSS、CSRF等,架构安全、访问策略。 规模..

更多
NoteSystemLinux

《Linux内核技术实战》

Page Cache什么是 Page Cache? 通过这张图片你可以清楚地看到,红色的地方就是 Page Cache,很明显,Page Cache 是内核管理的内存,也就是说,它属于内核不属于用户。 $ cat /proc/meminfo ... Buffers: 1224 kB Cached: 111472 kB SwapCached: 36364 kB Active: 6224232 kB Inactive: 979432 kB Active(anon): 6173036 kB Inactive(anon): 927932 kB Active(file): 51196 kB Inactive(..

更多
NoteSystemLinux

《Linux性能优化实战》

CPU性能篇uptime 什么是平均负载?简单来说,平均负载是指单位时间内,系统处于可运行状态和不可中断状态的平均进程数,也就是平均活跃进程数,它和 CPU 使用率并没有直接关系。这里我先解释下,可运行状态和不可中断状态这俩词儿。 所谓可运行状态的进程,是指正在使用 CPU 或者正在等待 CPU 的进程,也就是我们常用 ps 命令看到的,处于 R 状态(Running 或 Runnable)的进程。 不可中断状态的进程则是正处于内核态关键流程中的进程,并且这些流程是不可打断的,比如最常见的是等待硬件设备的 I/O 响应,也就是我们在 ps 命令中看到的 D 状态(Uninterruptible Sleep,也称为 Disk Sleep)的进程。 比如,当一个进程向磁盘读写数据时,为了保证数据的一致性,在得到..

更多
NoteNet

《趣谈网络协议》

通信协议综述IP && MACIP 地址是一个网卡在网络世界的通讯地址,相当于我们现实世界的门牌号码。既然是门牌号码,不能大家都一样,不然就会起冲突。比方说,假如大家都叫六单元 1001 号,那快递就找不到地方了。所以,有时候咱们的电脑弹出网络地址冲突,出现上不去网的情况,多半是 IP 地址冲突了。 下面这个表格,详细地展示了 A、B、C 三类地址所能包含的主机的数量。在后文中,我也会多次借助这个表格来讲解。 无类型域间选路(CIDR) 于是有了一个折中的方式叫作无类型域间选路,简称 CIDR。这种方式打破了原来设计的几类地址的做法,将 32 位的 IP 地址一分为二,前面是网络号,后面是主机号。从哪里分呢?你如果注意观察的话可以看到,10.100.122.2/24,这个 IP 地址中有..

更多
NoteBackendSystemComputer

《深入浅出计算机组成原理》

基础篇计算机的基本硬件组成 第一,广。组成原理中的概念非常多,每个概念的信息量也非常大。比如想要理解 CPU 中的算术逻辑单元(也就是 ALU)是怎么实现加法的,需要牵涉到如何把整数表示成二进制,还需要了解这些表示背后的电路、逻辑门、CPU 时钟、触发器等知识。 第二,深。组成原理中的很多概念,阐述开来就是计算机学科的另外一门核心课程。比如,计算机的指令是怎么从你写的 C、Java 这样的高级语言,变成计算机可以执行的机器码的?如果我们展开并深入讲解这个问题,就会变成《编译原理》这样一门核心课程。 第三,学不能致用。学东西是要拿来用的,但因为这门课本身的属性,很多人在学习时,常常沉溺于概念和理论中,无法和自己日常的开发工作联系起来,以此来解决工作中遇到的问题,所以,学习往往没有成就感,就很难有动力坚持下去。..

更多
NoteBackendMiddlewareMySQL

《MySQL实战45讲》

binlog && redo log什么是 binlog binlog 是逻辑日志,记录的是这个语句的原始逻辑/变化,比如“给 ID=2 这一行的 c 字段加 1 ”。 binlog 是追加写,不会覆盖之前的数据,可以提供完整的数据归档的能力。 什么是 redo log redo log 是物理日志,记录的是“在某个数据页上做了什么修改”; redo log 提供 crash-safe 能力。 一般只有4G ,4个文件,循环复写。 binlog 和 redo log 不同点因为最开始 MySQL 里并没有 InnoDB 引擎。MySQL 自带的引擎是 MyISAM,但是 MyISAM 没有 crash-safe 的能力,binlog 日志只能用于归档。而 InnoDB 是另一个公司以插..

更多
12