- 
- 1 复杂度分析
1.1 时间复杂度
1.2 时间复杂度量级
1.3 空间复杂度
1.4 最好最坏平均均摊时间复杂度 - 2 数组
2.1 定义
2.2 插入删除
2.3 查找 - 3 链表
3.1 插入删除
3.2 查找
3.3 单链&双向链表&循环链表
3.4 链表操作 - 4 栈
4.1 入栈出栈
4.2 顺序栈&链式栈
4.3 栈应用 - 5 队列
5.1 队头队尾
5.2 顺序队列&链式队列
5.3 循环队列
5.4 阻塞队列&并发队列 - 6 递归
6.1 堆栈溢出 - 7 排序
7.1 冒泡排序
7.2 插入排序
7.3 选择排序
7.4 归并排序
7.5 快排
7.6 桶排序
7.7 计数排序
7.8 基数排序 - 8 二分查找
 - 9 跳表
 - 10 散列表
10.1 散列冲突
10.2 设计工业级散列表
10.3 LRU缓存淘汰算法
10.4 Redis有序集合
10.5 哈希算法
10.6 一致性哈希算法 - 11 树
11.1 高度深度层
11.2 二叉树&满二叉树&完全二叉树
11.3 二叉查找树
11.4 红黑树
11.5 递归树
11.6 B树&B+树 - 12 堆
12.1 定义
12.2 插入删除
12.3 堆排序 - 13 图
13.1 定义
13.2 图的存储
13.3 深度,广度优先搜索 - 14 字符串匹配算法
 - 15 算法思想
 - 16 其他算法
 - 17 算法实战
 
 - 1 复杂度分析
 
- 建立时间复杂度、空间复杂度意识,写出高质量的代码
 - 性能更优,核心竞争力
 - 数据结构算法导图
 
- 所有代码执行时间与数据规模增长的趋势,叫时间复杂度。
 - 可以理解每行代码执行时间都是unit_time,执行次数和数据量的关系。知道执行次数,就能知道复杂度。
 
- 常数阶、对数阶、线性阶、线性对数阶、指数阶,平方阶,立方阶,k次方阶,阶乘阶。
 
- 算法存储空间与数据量的关系。
 
- 平均:执行次数*概率
 
- 内存连续(随机访问),数据类型相同,线性表。
 
- 插入删除 平均复杂度O(n)
 
- 查找 todo
 - 随机访问 下标访问复杂度O(1)
 
- 插入删除 复杂度为O(1)
 
- 查找 复杂度O(n)
 
- 单链表,双向链表,循环链表. 带头链表,不带头链表
 
- 反转,合并有序链表,是否有环,删除倒数第n个节点,查找中间节点。
 
- 入栈,出栈,栈顶元素。
 
- 数组实现顺序栈,链表实现链式栈。
 
- 用栈实现:表达式求值
 
- 队头出队,队尾入队
 
- 顺序对列,链式队列
 
- 队满:(tail+1)% n = head;
 - 队空: tail== head;
 
- 递归用循环代替
 - 堆栈溢出,重复计算,空间度高,函数调用耗时多。
 
- 判断排序算法效率衡量:
- 1 时间复杂度(最好,最坏,平均)
 - 2 时间复杂度,系数,常熟,低阶
 - 3 内存消耗(原地排序)
 - 4 稳定性(都为3,排序前后位置不变的就是稳定算法)
 
 
- 原地排序,稳定性
 - 有序度,逆序度,满有序度 n*(n-1)/2
 - 时间复杂度。 O(n*n)
 
- 优于冒泡
 
- 低于冒泡和插入
 
- 时间复杂度:都为 nlogn
 - 空间负责度: n
 
- 取分区点,大于在右,小于在左。利用插入排序思想原地排序。
 - 时间复杂度对数阶。
 - 优化:三数取中,随机法取分区点。
 
- 分为多个桶,多个桶之间有排序,桶内快排
 
- 只适合数组
 - 只适合有序
 - 数据太小或太大都不适合
 - 如何在100MB内存之内,在1000W数据中查找。(数组排序,二分查找)
 - 二分查找变形:第一个小于等于某个值。。。
 
- 链表+多级索引+有序
 
- 空间复杂度 O(n)
 - 查找的时间复杂度 O(logn)
 - 插入删除时间复杂度 O(logn) 查找复杂度+操作复杂度
 - 防止跳表退化成链表:通过随机数k,把1-k层添加索引
 
- 为什么不用红黑树? 查询在区间内的数时,跳表效率比红黑树高。
 
- 通过散列函数把元素的键值映射为下标,将数据存储在数组下标中
 
- 哈希冲突: 链表法;开放寻址法;重复哈希
 
- 
- hash函数设计
 
 - 
- hash表初始大小,动态扩容,高效扩容先扩容,然后等插入数据时再拷贝数据到新的散列表
 
 - 
- 散列冲突链表法可以用红黑树替代;
 
 
- LRU缓存淘汰算法:散列表+双向链表;复杂度都是O(1)
 - Redis有序集合:散列表+跳表 ;可以按照添加顺序 顺序访问
 - 插入,删除,查找 时间复杂度可到O(1)
 
- 应用: 安全加密、唯一标识、数据校验、散列函数、负载均衡、数据分片、分布式存储
 
- hash环,算法对2的32次方取模。添加和删除机器只需要对部分数据迁移。
 - 节点太少可以添加虚拟节点
 
- 高度/深度/层
 
- 存储方法:数组,链表;
 - 完全二叉树用数组方式存储浪费的空间少。
 - 前序遍历,中序遍历,后续遍历;用递归实现
 - 遍历时间复杂度O(n)
 
- 插入,查找,删除(如果有两个子节点,找到右节点的最小值,替换。)
 - 重复:链表法或数组动态扩容放在一个节点;放在右子树;
 
- 散列表无序
 - hash表扩容,hash冲突时,性能不稳定
 - 时间复杂度常量级不一定比对数级更优
 - hash表考虑因素多。hash冲突,扩容缩容。
 
- 
根节点是黑色的;
 - 
每个叶子节点都是黑色的空节点(NIL),也就是说,叶子节点不存数据
 - 
任何相邻的节点都不能同时为红色,也就是说,红色节点是被黑色节隔开。
 - 
每个节点,从该节点到达其可达叶子节点的所有路径,都包含相同数的黑色节点
 - 
平衡二叉查找树,任何节点都左右节点高度不大于1.
 - 
查找插入删除 时间复杂度:logn
 - 
插入3种调整方式,删除4种调整方式。
 
- 用来分析时间复杂度
 
- 完全二叉树
 - 每个节点比它的子节点都大或是都小。大顶堆,小顶堆。
 
- 堆插入,删除 ,堆化的过程。
 - 插入删除时间复杂度。logn
 
- 建堆,排序 。复杂度nlogn
 - 堆排序,取最顶堆化再重复。
 - 交换次数比快排多;跳跃访问。所以性能比快排低。
 
- 优先级队列、求 Top K 问题和求中位数问题
 
- 顶点,边,度,有向图,无向图,加权图。
 
- 邻阶矩阵存储。浪费空间。
 - 邻阶表存储(可以把链表换成散列表,跳表,红黑树)
 - 小规模(邻阶表+跳表实现)
 - 大规模(hash分片之后用跳表;或数据库)
 
- 广度:地毯式搜索,一层一层向外搜索。
 - 深度:回溯思想。
 - 时间复杂度O(边数),空间复杂度O(顶点数)
 
- 把模式串和主串 hash,再比较hash值。
 - 每个小串计算hash时不用遍历,有关系表达式。
 
- 坏字符原则
 - 好后缀原则
 
- O(m+n)时间复杂度
 - 字符串匹配算法
 
- 公共的前缀重合在一起,多叉树
 
- 多模式串匹配算法
 - 类似在树结构上加了next数组
 
- 霍夫曼编码。根据字符串频率编码后再存储
 
- MapReduce实现思想就是多台机器分治
 
- 回退再试
 - 时间复杂度 指数级
 
- 分多个阶段,取最后阶段就是最大重量。
 - 思路:状态转移表;状态转移方程;
 - 时间复杂度 线性级
 
- 有权有向图,放到优先级队列中。
 - 应用:地图推荐最短路径
 
- 布隆过滤器:位图 + hash
 - 应用:爬虫URL去重
 
- 应用:过滤垃圾短信
 
- 欧几里得距离
 - 应用:推荐系统
 
- 应用:游戏寻路
 
- hash表:redis,memcache 适合hash表构建索引
 - 红黑树:适合构建内存索引
 - B+树:适合构建磁盘索引。mysql,oracle等数据库
 - 跳表:redis有序集合
 
- list: 压缩列表+循环链表
 - hash: 压缩列表+hash表
 - set: 有序数组+hash表
 - 有序集合: 压缩列表+ 跳表+hash表
 
- 搜索,分析,索引,查询
 
- 交替执行,叠加执行。
 - 单处理系统中:进程切换&共享变量,中断可能会在进程中任何地方停止 引起并发问题!
 - 多处理系统中:多进程,上述问题或 同时执行同时访问同一变量 都会引起并发问题!
 
- 多个进程,线程读写数据时,结果依赖多个进程的指令执行顺序。
 
- 竞争;共享;通信;
 
- 禁用中断(多处理器中无效);
 - 专用机器指令
 - 信号量
 - 管程
 - 消息传递
 
- 
- OSI七层:物理层(IEEE 802.1A, IEEE 802.2到IEEE 802.11)、数据链路层(FDDI, Ethernet, Arpanet, PDN, SLIP, PPP)、网络层(IP, ICMP, ARP, RARP, AKP, UUCP)、传输层(TCP, UDP)、会话层(SMTP, DNS)、表示层(Telnet, Rlogin, SNMP, Gopher)、应用层(HTTP、TFTP, FTP, NFS, WAIS、SMTP)
 - TCP/IP四层:数据链路层、网络层、传输层、应用层
 
 - 
《点对点 ,端到端》
- 端到端:针对传输层,发送端与接收端之间建立连接再发数据。
 - 点到点:针对数据链路层或网络层,数据发给直接相连的设备。
 
 - 
- 链路层:对电信号进行分组并形成具有特定意义的数据帧,然后以广播的形式通过物理介质发送给接收方
 - 网络层:(IP协议,ARP协议,路由协议)定义网络地址,区分网段,子网内MAC寻址,对于不同子网的数据包进行路由
 - 传输层:定义端口,标识应用程序身份,实现端口到端口的通信,TCP协议可以保证数据传输的可靠性。
 - 应用层:定义数据格式并按照对应的格式解读数据
 
 - 
《TCP三次握手,四次挥手》《TCP三次握手,四次挥手详解》
- URG 紧急指针是否有效。为1,表示某一位需要被优先处理。
 - ACK 确认号是否有效,一般置为1。
 - PSH 提示接收端应用程序立即从TCP缓冲区把数据读走。
 - RST 对方要求重新建立连接,复位。
 - SYN 请求建立连接,并在其序列号的字段进行序列号的初始值设定。建立连接,设置为1.
 - FIN 希望断开连接。
 - 三次握手: 1. SYN = 1,seq = j 2. SYN=1,ACK=1,ack= j+1,seq= k 3.ACK=1,ack=k+1
 - 四次挥手: 1. FIN=m 2.ACK=m+1 3.FIN=n 4 ACK=1,ack=n+1
 
 
- 
《HTTP协议详解,抓包分析》《HTTP2.0原理详解》《HTTP2.0二进制帧》
- HTTP2.0二进制桢
 - HTTP2.0:多路复用、压缩头信息、请求划分优先级、支持服务器端主动推送
 - HTTP1.0:每个请求都需单独建立连接(keep-alive能解决部分问题单不能交叉推送)、每个请求和响应都需要完整的头信息、数据未加密
 
 - 
- 
- 浏览器发送HTTPS请求 2 服务器发送数字证书给客户端 3 浏览器CA列表验证证书 4 浏览器产生对称密钥,用公钥加密 5 用私钥揭秘获得对称密钥 6 用对称密钥加密通信。
 
 
 - 
 
- 《web优化必须了解的原理之I/o的五种模型和web的三种工作模式》
- I/O步骤:进程向操作系统请求数据 ;操作系统把外部数据加载到内核的缓冲区中;操作系统把内核的缓冲区拷贝到进程的缓冲区 ;进程获得数据完成自己的功能 ;
 - 五种I/O模型:阻塞I/O,非阻塞I/O,I/O复用、事件(信号)驱动I/O、异步I/O,前四种I/O属于同步操作,I/O的第一阶段不同、第二阶段相同,最后的一种则属于异步操作。
 - 三种 Web Server 工作方式:Prefork(多进程)、Worker方式(线程方式)、Event方式。
 
 - 《一文读懂I/O复用》
- 第一阶段select阻塞,第二阶段recvfrom阻塞
 
 
- 《select、poll、epoll之间的区别总结[整理]》《select、poll、epoll区别》《epoll使用详解》
- 每次调用select,都需要把fd集合从用户态拷贝到内核态,这个开销在fd很多时会很大
 - 同时每次调用select都需要在内核遍历传递进来的所有fd,这个开销在fd很多时也很大
 - select支持的文件描述符数量太小了,默认是1024
 
 
- 《长连接短链接》
 
- 《设计模式的六大原则》
- 开闭原则:对扩展开放,对修改关闭,多使用抽象类和接口。
 - 里氏替换原则:基类可以被子类替换,使用抽象类继承,不使用具体类继承。
 - 依赖倒转原则:要依赖于抽象,不要依赖于具体,针对接口编程,不针对实现编程。
 - 接口隔离原则:使用多个隔离的接口,比使用单个接口好,建立最小的接口。
 - 迪米特法则:一个软件实体应当尽可能少地与其他实体发生相互作用,通过中间类建立联系。
 - 合成复用原则:尽量使用合成/聚合,而不是使用继承。
 
 
- 《23种设计模式》
 - 《23种设计模式全解析》
 - 《23种设计模式类图和示例》
 
TODO
- 
- 进程模型:一个master进程,管理多个worker进程。一个请求只能一个worker进程处理。worker进程抢acceptMutex锁,然后接受请求,处理请求,返回请求,断开连接
 - 事件模型:高并发,异步非阻塞事件机制(例如epoll,循环处理准备好的事件请求,IO事件没有准备好就放回epoll)。
 - connection: TCP三次握手
 - request: 请求行、请求头、请求体、响应行、响应头、响应体
 
 - 
《nginx配置》
 - 
- DNS域名解析;TCP连接;接受请求;处理请求;返回响应;关闭TCP;记录日志;解析HTML展示页面;
 
 
- 
《apache与nginx原理详解及对比》《apache原理》《apache与nginx对比及优缺点》
- apache一个子进程处理一个请求。nginx一个子进程通过异步非阻塞事件模型可以处理多个请求,所以并发能力强。
 - nginx轻量级,占用资源少。反向代理负载均衡。
 - apache模块丰富
 
 - 
- perfork MPM多个进程,无线程设计,每个进程处理一个请求。worker MPM一个进程下有多个线程。每个线程处理一个请求。
 
 - 
- nginx处理静态请求,apache处理动态请求
 
 
- 《浅谈OpenResty》 《官方网站》
- 通过lua模块在nginx上开发。黑名单,防刷,限流等
 
 - 《openResty作者agentzh的Nginx教程》
 - 《跟着开涛学openResty》
- TODO 《亿级流量网站》
 
 
- 《Memcached 教程》
 - 《深入理解Memcached原理》
 - 《Memcached工作原理》
 - 《Memcache技术分享:介绍、使用、存储、算法、优化、命中率》
 - 《memcache 中 add 、 set 、replace 的区别》
 
- 《Redis 教程》
 - 《redis底层原理》
 - 《Redis持久化》
- RDB方式:定期备份快照,常用于灾难恢复。优点:通过fork出的进程进行备份,不影响主进程、RDB 在恢复大数据集时的速度比 AOF 的恢复速度要快。缺点:会丢数据。
 - AOF方式:保存操作日志方式。优点:恢复时数据丢失少,缺点:文件大,回复慢。
 - 也可以两者结合使用。
 
 - 《分布式缓存--序列3--原子操作与CAS乐观锁》
 - 《Redis单线程架构》
 - 《redis的回收策略》
 
- 《tair源码》
 - 《tair与redis比较总结》
 
- 《消息队列简介及好处》
- 提高系统响应速度、提高系统稳定性、异步化、解耦、消除峰值
 
 - 《Kafka、RabbitMQ、RocketMQ等消息中间件的对比 —— 消息发送性能和区别》
- Push方式:优点是可以尽可能快地将消息发送给消费者,缺点是如果消费者处理能力跟不上,消费者的缓冲区可能会溢出。 RabbitMQ 消费者默认是推模式(也支持拉模式)。
 - Pull方式:优点是消费端可以按处理能力进行拉去,缺点是会增加消息延迟。 Kafka 默认是拉模式。
 
 - 《消息顺序和重复问题》
 
- 《RabbitMQ应用场景以及基本原理介绍》《消息队列之 RabbitMQ》- 《RabbitMQ之消息确认机制(事务+Confirm)》
- 支持事务,推拉模式都是支持、适合需要可靠性消息传输的场景。
 
 
- 《RocketMQ 实战之快速入门》《RocketMQ源码分析》
- Java实现,推拉模式都是支持,吞吐量逊于Kafka。可以保证消息顺序。
 
 
- 《ActiveMQ消息队列介绍》
- 纯Java实现,兼容JMS,可以内嵌于Java应用中。
 
 
- 《Kafka深度解析,众人推荐,精彩好文》《Kafka分区机制介绍与示例》
- 高吞吐量、采用拉模式。适合高IO场景,比如日志同步。
 
 
- 《Redis用作消息队列》
- 生产者、消费者模式完全是客户端行为,list 和 拉模式实现,阻塞等待采用 blpop 指令。
 
 
请求转发、安全认证、协议转换、容灾
- 《三大范式五大约束》
 
- 《事务隔离级别》
 - 《数据库事务特性》
 - 《数据库事务隔离级别》
 - 《InnoDB幻读问题》
 
- 原子性,一致性,隔离性,持久性
 - 读不提交,出现脏读
 - 读提交,出现不可重复读
 - 重复读,出现幻读
 - 序列化,--
 
- 连接层,优化/缓存层,存储引擎
 
- frm文件表空间描述
 - ibd文件索引和数据
 - page页:头双向链表,body链表存储记录
 - 索引:B+树
 
- 《索引原理》
 
- 聚族索引与非聚簇索引
 - B+树,非叶子结点不存数据,只存索引键值,叶子结点存数据。
 
- 聚族索引与非聚簇索引
 - 单列索引
 - 索引覆盖
 - 组合索引,索引合并
 - 全文索引
 
- 
1.在经常需要搜索的列上,可以加快索引的速度
 - 
2.主键列上可以确保列的唯一性
 - 
3.在表与表的而连接条件上加上索引,可以加快连接查询的速度
 - 
4.在经常需要排序(order by),分组(group by)和的distinct 列上加索引 可以加快排序查询的时间, (单独order by 用不了索引,索引考虑加where 或加limit)
 - 
5.在一些where 之后的 < <= > >= BETWEEN IN 以及某个情况下的like 建立字段的索引(B-TREE)
 - 
6.like语句的 如果你对nickname字段建立了一个索引.当查询的时候的语句是 nickname lick '%ABC%' 那么这个索引讲不会起到作用.而nickname lick 'ABC%' 那么将可以用到索引
 - 
7.索引不会包含NULL列,如果列中包含NULL值都将不会被包含在索引中,复合索引中如果有一列含有NULL值那么这个组合索引都将失效,一般需要给默认值0或者 ' '字符串
 - 
8.使用短索引,如果你的一个字段是Char(32)或者int(32),在创建索引的时候指定前缀长度 比如前10个字符 (前提是多数值是唯一的..)那么短索引可以提高查询速度,并且可以减少磁盘的空间,也可以减少I/0操作.
 - 
9.不要在列上进行运算,这样会使得mysql索引失效,也会进行全表扫描
 - 
10.选择越小的数据类型越好,因为通常越小的数据类型通常在磁盘,内存,cpu,缓存中 占用的空间很少,处理起来更快
 - 
尽量选择区分度高的列作索引
 
- 索引列 like "%xx"
 - 使用函数计算
 - or 有没有索引的列
 - 类型不一致
 - order by 查询的列不是主键排序就不走索引
 
- 《explain分析SQL》
- select_type:simple,primary,subquery,derived,union,union result
 - type:system > const > eq_ref > ref > fulltext > ref_or_null > index_merge > unique_subquery > index_subquery > range > index > ALL
 
 
- 
《为什么需要并发?》
- 充分利用多核CPU的计算能力
 - 业务拆分,提升性能
 
 - 
- 并发:通过切换时间片的方式多个任务交替进行;并行:真正意义上的“同时进行”
 
 - 
- 硬件,网络,架构设计(各种分布式,缓存,中间件,异步),开发语言,数据结构,算法,数据库优化,代码层(多线程编程,同步异步)
 
 
- 《高并发实现中一种方式:多线程开发及优缺点》
- 优点:耗时任务放入子线程防止阻塞,提升响应速度;充分利用CPU,提高性能;改善程序结构;
 - 缺点:频繁切换上下文;线程安全问题;
 
 
- 《线程安全问题及解决方案》
- 产生原因:CPU切换时间片执行多线程产生竞态条件
 - 原子性,可见性,时序性;原子性:要么都执行,要么都不执行。a++是先查,后加,不是原子操作。
 - 加锁
 
 
- 《锁的分类》
- 乐观锁&悲观锁,互斥锁/写锁,共享锁/读锁,公平锁/非公平锁,重入锁/非重入锁,分段锁等。
 
 
- 《悲观锁与乐观锁》
- select for update
 
 
- 
《乐观锁》
- 是一种思想,提交更新时对冲突检测,让用户决定重试或是其他。
 - ABA问题,解决方法对每次更新加上版本号
 
 - 
《对mysql乐观锁、悲观锁、共享锁、排它锁、行锁、表锁概念的理解》
- 对于update,insert,delete语句会自动加排它锁,只共享读。
 
 
- 
《select.. for update导致的数据库死锁分析》
- mysql的innodb存储引擎实务锁虽然是锁行,但它内部是锁索引的。
 - 锁相同数据的不同索引条件可能会引起死锁。
 
 
- 《15天的性能优化工作,5方面的调优经验》
- 代码层面、业务层面、数据库层面、服务器层面、前端优化。
 
 - 《系统优化的几个方面》
 
- 《互联网架构,如何进行容量设计?》
- 总访问量,平均访问量,高峰QPS,压测获取单机极限QPS,机器配置。
 
 - 《互联网性能与容量评估的方法论和典型案例》
 
- 《搭建简易堡垒机》
 
- 《邪恶的JAVA HASH DOS攻击》
- 利用JsonObject 上传大Json,JsonObject 底层使用HashMap;不同的数据产生相同的hash值,使得构建Hash速度变慢,耗尽CPU。
 
 - 《一种高级的DoS攻击-Hash碰撞攻击》
 - 《关于Hash Collision DoS漏洞:解析与解决方案》
 
- 
- 滑动验证码是根据人在滑动滑块的响应时间,拖拽速度,时间,位置,轨迹,重试次数等来评估风险。
 
 
- 用户密码非明文保存,加动态salt。
 - 身份证号,手机号如果要显示,用 “*” 替代部分字符。
 - 联系方式在的显示与否由用户自己控制。
 - TODO
 
- 《常见对称加密算法》
- DES、3DES、Blowfish、AES
 - DES 采用 56位秘钥,Blowfish 采用1到448位变长秘钥,AES 128,192和256位长度的秘钥。
 - DES 秘钥太短(只有56位)算法目前已经被 AES 取代,并且 AES 有硬件加速,性能很好。
 
 
- 
- MD5 和 SHA-1 已经不再安全,已被弃用。
 - 目前 SHA-256 是比较安全的。
 
 
- 《常见非对称加密算法》
- 
RSA、DSA、ECDSA(螺旋曲线加密算法)
 - 
和 RSA 不同的是 DSA 仅能用于数字签名,不能进行数据加密解密,其安全性和RSA相当,但其性能要比RSA快。
 - 
256位的ECC秘钥的安全性等同于3072位的RSA秘钥。
 
 - 
 
TODO
TODO
在内外环境中通过跳板机登录到线上主机。
2FA - Two-factor authentication,用于加强登录验证
常用做法是 登录密码 + 手机验证码(或者令牌Key,类似于与网银的 USB key)
- 【《双因素认证(2FA)教程》】(http://www.ruanyifeng.com/blog/2017/11/2fa-tutorial.html)
 
- 《【分享】腾讯业务系统监控的修炼之路》
- 监控的方式:主动、被动、旁路(比如舆情监控)
 - 监控类型: 基础监控、服务端监控、客户端监控、 监控、用户端监控
 - 监控的目标:全、快、准
 - 核心指标:请求量、成功率、耗时
 
 - 《开源还是商用?十大云运维监控工具横评》
- Zabbix、Nagios、Ganglia、Zenoss、Open-falcon、监控宝、 360网站服务监控、阿里云监控、百度云观测、小蜜蜂网站监测等。
 
 - 《监控报警系统搭建及二次开发经验》
 
- 《ELKB日志收集系统搭建》《ELK日志收集系统搭建》《日志收集系统》
- Beats日志搬运工。安装在每台需要收集日志的服务器上,将日志发送给Logstash进行处理。Filebeat配置安装
 - LogStash把没条日志解析成每个字段LogStash配置安装
 - ElasticSearch全文搜索日志 ElasticSearch全文搜索引擎《索引搜索查询及增删改查》《ElasticSearch权威指南》
 - Kibana是ElasticSearch全文搜索图形化界面 Kibana安装
 
 - 《FileBeat+kafka进行日志实时传输》
- kafka教程
 
 - logrotate日志切割
 
- 《RPC概述》
- 远程调用程序并返回
 
 - 《分布式RPC框架性能大比拼dubbo、motan、rpcx、gRPC、thrift的性能比较》
 - 《Dubbo官网》《Dubbo实现原理简单介绍》
 - 《Thrift官网》《Thrift详解》
 - 《Grpc官网》《RPC原理介绍》
 
- 《几张图帮你理解 docker 基本原理及快速入门》
- 镜像,容器。一个镜像可以建立多个容器,一个容器最多127层。
 
 - 《docker核心技术与实现》
 - 《docker教程》
 - 项目实例
- TODO
 
 
- 《持续集成是什么?》
- 合并;交付;测试;部署;
 
 - 《8个流行的持续集成工具》
 - 《使用Jenkins进行持续集成》
 
- 《Ansible基础配置和企业级项目实用案例》
- 批量系统配置、批量程序部署、批量运行命令等功能
 
 - 《Ansible中文权威指南》
 - 《自动化运维工具——puppet详解(一)》
 - 《Chef 的安装与使用》
 
- 《VPS的三种虚拟技术OpenVZ、Xen、KVM优缺点比较》
 - 《KVM详解,太详细太深入了,经典》
 - 《KVM 虚拟机安装详解》
 - 《Xen虚拟化基本原理详解》
 - 《开源Linux容器 OpenVZ 快速上手指南》
 
- 
- too many open files (解决方案:ulimit -n; nginx配置events同级 worker_rlimit_nofile 15360;)
 - apr_socket_recv:Operation timed out (解决方法:ab加上-k 开启keepAlive)
 - apr_socket_connect(): Operation already in progress (解决方法:apache/conf/extra/httpd-mpm.conf 修改 ThreadsPerChild)
 - apr_socket_recv: Connection reset by peer (54)
 - setsockopt(TCP_NODELAY) failed (22: Invalid argument) while keepalive
 
 - 
- jmeter
 - 《全链路压测》
 - 资源服务监控《20个命令行工具监控》
 
 
- 《单元测试》
- 单元测试可以有效地测试某个程序模块的行为,是未来重构代码的信心保证。
 - 单元测试的测试用例要覆盖常用的输入组合、边界条件和异常。
 - 单元测试代码要非常简单,如果测试代码太复杂,那么测试代码本身就可能有bug。
 - 单元测试通过了并不意味着程序就没有bug了,但是不通过程序肯定有bug。
 
 
- 《简单说明CGI和动态请求是什么》
- CGI,fastCGI
 - php-cgi,php-fpm
 - web-server,php-fpm,zend引擎,CGI脚本
 
 
- 《架构师技能修炼图》
 
- 《微服务架构设计》《微服务架构选型》
- API网关,RESTFUL,微服务
 
 - 《RESTFUL API架构》
 - 《API网关》
- kong
 
 - 项目实例
- TODO
 
 
- 《说说如何实现可扩展性的大型网站架构》
- 分布式+异步任务
 - 分布式要求:负载均衡,失效转移,高效远程调用,整合异构系统,版本控制,实时监控
 
 
- 《可扩展性设计之数据切分》
- 垂直切分,水平切分,联合切分
 - 垂直切分缺点: join表分页搜索需要程序完成;事务处理复杂;
 - 水平切分缺点: 维护数据变复杂;切分无具体标准;
 - 切分与整合带来的问题:分布式事务;跨节点join(全局表,冗余,数据组装);跨节点合并分页排序(先排序分页,再数据组装);
 
 
- 《分布式事务一致性问题》《分库分表事务一致性》《保证分布式系统数据一致性的6种方案》
- 提供回滚接口
 - 《本地消息表》
 - 非事务MQ
 - 事务MQ
 
 
- 
- 可扩展:水平扩展、垂直扩展。 通过冗余部署,避免单点故障。一主多从。
 - 隔离:避免单一业务占用全部资源。避免业务之间的相互影响 2. 机房隔离避免单点故障。
 - 解耦:降低维护成本,降低耦合风险。减少依赖,减少相互间的影响。
 - 限流:遇到突发流量时,保证系统稳定。
 - 降级:紧急情况下释放非核心功能的资源。牺牲非核心业务,保证核心业务的高可用。
 - 熔断:异常情况超出阈值进入熔断状态,快速失败。减少不稳定的外部依赖对核心服务的影响。
 - 自动化测试:通过完善的测试,减少发布引起的故障。
 - 灰度发布:灰度发布是速度与安全性作为妥协,能够有效减少发布故障。
 
 - 
《关于高可用的系统》
- 数据不丢,就必需要持久化;服务高可用,就必需要有备用;复制,就会有数据一致性
 
 
- 《软/硬件负载均衡产品 你知多少?》《转!!负载均衡器技术Nginx和F5的优缺点对比》
- 硬件,软件负载均衡
 
 - 《负载均衡的几种算法》
- 轮流;比例;优先权; 最小连接;响应最快;服务器性能模式;观察模式 请求数响应时间;
 
 - 《DNS做负载均衡》
- 配置简单;生效慢。
 
 - 《NGINX做负载均衡》
- 成本低。主要适用web应用。
 
 - 《借助LVS+Keepalived实现负载均衡》
- 支持到OSI四层,性能较高
 
 - 《HAProxy用法详解 全网最详细中文文档》《Haproxy+Keepalived+MySQL实现读均衡负载》《rabbitmq+haproxy+keepalived实现高可用集群搭建》
- HAProxy性能和LVS差不多。
 
 
- 《谈谈高并发系统的限流》
- 计数器:通过滑动窗口计数器,控制单位时间内的请求次数,简单粗暴。
 - 漏桶算法:固定容量的漏桶,漏桶满了就丢弃请求,比较常用。
 - 令牌桶算法:固定容量的令牌桶,按照一定速率添加令牌,处理请求前需要拿到令牌,拿不到令牌则丢弃请求,或进入丢队列,可以通过控制添加令牌的速率,来控制整体速度。Guava 中的 RateLimiter 是令牌桶的实现。
 - Nginx 限流:通过 limit_req 等模块限制并发连接数。
 
 
- 
- 雪崩效应原因:硬件故障、程序Bug、缓存击穿、用户大量请求。
 - 雪崩的对策:限流、改进缓存模式(缓存预加载、同步调用改异步)、自动扩容、降级。
 - Hystrix设计原则:
 - 资源隔离:Hystrix通过将每个依赖服务分配独立的线程池进行资源隔离, 从而避免服务雪崩。
 - 熔断开关:服务的健康状况 = 请求失败数 / 请求总数,通过阈值设定和滑动窗口控制开关。
 - 命令模式:通过继承 HystrixCommand 来包装服务调用逻辑。
 
 - 
- 主要策略:失效瞬间:单机使用锁;使用分布式锁;不过期;
 - 热点数据:热点数据单独存储;使用本地缓存;分成多个子key;
 
 - 
《“异地多活”多机房部署经验谈》《异地多活(异地双活)实践经验》《依赖治理、灰度发布、故障演练,阿里电商故障演练系统的设计与实战经验》
 
- 
《【大型网站技术实践】初级篇:搭建MySQL主从复制经典架构》《MySQL主从复制(Master-Slave)实践》
- 一主n从;自动同步数据。
 
 
- 《永不失联!如何实现微服务架构中的服务发现》
- 客户端服务发现模式:客户端直接查询注册表,同时自己负责负载均衡。Eureka 采用这种方式。
 - 服务器端服务发现模式:客户端通过负载均衡查询服务实例。
 
 - 《SpringCloud服务注册中心比较:Consul vs Zookeeper vs Etcd vs Eureka》
 - 《基于Zookeeper的服务注册与发现》
 
- 《从分布式一致性谈到CAP理论、BASE理论》
- 一致性分类:强一致(立即一致);弱一致(可在单位时间内实现一致,比如秒级);最终一致(弱一致的一种,一定时间内最终一致)
 - CAP:一致性、可用性、分区容错性(网络故障引起)
 - BASE:Basically Available(基本可用)、Soft state(软状态)和Eventually consistent(最终一致性)
 - BASE理论的核心思想是:即使无法做到强一致性,但每个应用都可以根据自身业务特点,采用适当的方式来使系统达到最终一致性。
 
 
- 《分布式锁的几种实现方式~》
- 数据库;缓存;zookeeper;
 
 - 《基于Zookeeper的分布式锁》
 - 《jedisLock—redis分布式锁实现》
- 利用setnx
 
 - 《Memcached 和 Redis 分布式锁方案》
- 利用 memcached 的 add(有别于set)操作,当key存在时,返回false。
 
 
例如:
- 广告相关实时统计;
 - 推荐系统用户画像标签实时更新;
 - 线上服务健康状况实时监测;
 - 实时榜单;
 - 实时数据统计。
 
- GOROOT,GOPATH,GOBIN
 - src,bin,pkg
 - go build; go install ; go get;
 
- 如果一个源码文件声明属于main包,并且包含一个无参数声明且无结果声明的main函数,那么它就是命令源码文件
 
- 库源码文件是不能被直接运行的源码文件,它仅用于存放程序实体,这些程序实体可以被其他代码使用
 - internal
 - 函数导出,访问权限
 
- var s string
 - s := "name"
 - 短变量声明
 
- 包级私有的、模块级私有的和公开的
 
- 在无需扩容时,append函数返回的是指向原底层数组的新切片,而在需要扩容时,append函数返回的是指向新底层数组的新切片。
 - slice扩容 2倍,1.25倍。
 - 底层数组不会被替换,直接生产新的数组
 
- container/list
 
- 通道不能一直阻塞
 - goroutine执行完再退出
 - goroutine泄漏
 - channel关闭
 - goroutine不能打开太多,应该有限制
 
- 对于同一个通道,发送操作之间是互斥的,接收操作之间也是互斥的
 - 发送操作和接收操作中对元素值的处理都是不可分割的
 - 发送操作在完全完成之前会被阻塞。接收操作也是如此
 
- Channels的发送操作将导致发送者goroutine阻塞,直到另一个goroutine在相同的Channels上执行接收操作
 - 接收操作先发生,那么接收者goroutine也将阻塞,直到有另一个goroutine在相同的Channels上执行发送操作
 
- 当一个channel被关闭后,再向该channel发送数据将导致panic异常
 - 当一个被关闭的channel中已经发送的数据都被成功接收后,后续的接收操作将不再阻塞,它们会立即返回一个零值
 - 只需要关闭接受者goroutine
 - range是安全接收的,它会判断是否关闭且没有收据接收。
 
- 只有在发送者所在的goroutine才会调用close函数
 - 任何双向channel向单向channel变量的赋值操作都将导致该隐式转换,没有反向转换的语法
 
- 内部缓存队列是满的,那么发送操作将阻塞直到因另一个goroutine执行接收操作
 - channel是空的,接收操作将阻塞直到有另一个goroutine执行发送操作而向队列插入元素。
 - 可以保证go程执行完再退出(??)
 
- 循环时显式的将参数传给go程。
 - wg.wait为什么要在go func(){}中
 - for range channel当channel关闭且流干的时候才退出循环
 
- 同时都满足条件,会随机选择一个执行。是不是有bug
 - Loop goto break
 
- 通过close广播,select去接收。
 
- 数据竞争会在两个以上的goroutine并发访问相同的变量且至少其中一个为写操作时发生。
 - 三种方法避免数据竞争:不要去写变量;避免从多个goroutine访问变量;加锁;
 
- sync.Mutex互斥锁
 
- sync.RMutex读写锁
 
- 内存同步
 - 不使用channel且不使用mutex这样的显式同步操作时,我们就没法保证事件在不同的goroutine中看到的执行顺序是一致的
 
- sync.once
 - 保证loadIcons的变量能够对所有goroutine可见
 
- close(ch)会广播到每个goroutine
 - 两种方式:加锁;channel ;
 
TODO
- 软件,硬件
 - 系统软件;应用软件
 
- 汇编--机器语言-解释操作系统-微程序解释机器语言-执行机器语言
 - 翻译程序两种:编译程序;解释程序;
 
- 运算器,存储器,控制器,输入输出
 - 指令和数据相同地位存放在存储器,可按地址寻访。
 - 指令和数据由二进制码表示
 - 指令由操作码和地址码组成
 - 指令是顺序存放的
 - 以运算器为中心
 - 现代计算机:MM+CPU+IO
 
- 数学建模;确定计算方法;编程序
 - 控制器,存储器,运算器,输入,输出设备
 
TODO
- 计算机组成原理
 - 编译原理和技术
 - 操作系统原理与设计
 - 数据结构算法基础
 - 计算机组成原理实验
 - 数据库系统及应用
 - 并行计算
 - 软件工程
 - 计算机导论
 - 计算机网络