一、Redis
redis运用处景stringhashset:去重zset: 排行榜list:(壅塞行列步队、通信)HyperLogLog:大量统计(非精确)内部数据构造dict:key[string] VS value (redis obj);拉链法办理冲突(同php);装载因子(哈希表已保存节点数量 / 哈希表大小)超过预定值自动扩充内, 引发(增量式)rehashing根据ht[0]创建一个比原来size大一倍(也可能减少)的hashtable,重新打算hash和index值,根据rehashindex逐步操作到达一定阈值(ht[0]为空)操作停滞期间相应客户端写操作:写到新的ht[1]读操作:先读ht[0],再读ht[1]sds:simple dynamic stringstring的底层实现为sds,但是string存储数字的时候,实行incr decr的时候,内部存储就不是sds了。二进制安全binary safe(5种类型的header+falgs得到详细类型,进而匹配len和alloc)robj:redis object,为多种数据类型供应一种统一的表示办法,同时许可同一类型的数据采取不同的内部表示,支持工具共享和引用计数。sdsstringlongziplistquicklistskiplist typedef struct redisObject { unsigned type:4;【OBJ_STRING, OBJ_LIST, OBJ_SET, OBJ_ZSET, OBJ_HASH】 unsigned encoding:4【上述type的OBJ-ENCODING _XXX常量,四个位解释同一个type可能是不同的encoding,或者说同一个数据类型,可能不同的内部表示】; unsigned lru:LRU_BITS; / lru time (relative to server.lruclock) / int refcount; void ptr【真正指向的数据】; } robjOBJ_ENCODING_stringOBJ_ENCODING_RAW,代表sds ,原生string类型OBJ_ENCODING_INT,long类型OBJ_ENCODING_EMBSTR ,嵌入OBJ_HASHOBJ_ENCODING_HT,表示成dictOBJ_ENCODING_ZIPLIST,hash用ziplist表示OBJ_SETOBJ_ENCODING_INTSET,表示成intestconfigset-max-intset-entries 512【是整型而且数据元素较少时,set利用intset;否则利用dict】OBJ_ZSETOBJ_ENCODING_SKIPLIST,表示成skiplist思想:多层链表,指针来回查找,插入和更新采纳随机层数的方法来规避configzset-max-ziplist-entries 128zset-max-ziplist-value 64OBJ_LISTOBJ_ENCODING_QUICKLISTconfiglist-max-ziplist-size -2list-compress-depth 0内部构造实现stringhash(两种encoding,根据下面的config)ziplistdictconfighash-max-ziplist-entries 512【把稳单位是“对儿”】hash-max-ziplist-value 64【单个value超过64】setzsetlistquicklist定义:是一个ziplist型的双向链表压缩算法:LZFzset如何根据两个属性排序?比如根据id和age可以用位操作,把两个属性合成一个double用zunionstore合并存储为新的key,再zrangeredis是如何担保原子性操作的?由于他是tm单线程的!
(ps:mysql是多线程)在并发脚本中的get set等不是原子的~在并发中的原子命令incr setnx等是原子的事务是担保批量操作的原子性主从复制过程:从做事器向主理事器发送sync主理事器收到sync命令实行BGSAVE,且在这期间新实行的命令保存到一个缓冲区主实行(BGSAVE)完毕后,将.rdb文件发送给从做事器,从做事器将文件载入内存BGSAVE期间到缓冲区的命令会以redis命令协议的办法,将内容发送给从做事器。特性:单线程,自实现(event driver库,见下面四个io多路复用函数)在/src/ae.c中:宏定义的办法
/ Include the best multiplexing layer supported by this system. The following should be ordered by performances, descending. / #ifdef HAVE_EVPORT #include \公众ae_evport.c\"大众 #else #ifdef HAVE_EPOLL #include \公众ae_epoll.c\"大众 #else #ifdef HAVE_KQUEUE #include \公众ae_kqueue.c\"大众 #else #include \公众ae_select.c\"大众 #endif #endifio多路复用,最常用调用函数:select(epoll,kquene,avport等),同时监控多个文件描述符的可读可写reactor办法实现文件处理器(每一个网络连接对应一个文件描述符),同时监听多个fd的accept,read(from client),write(to client),close文件事宜。备份与持久化rdb(fork 进程dump到file,但是把稳触发节点的覆盖问题,导致数据不完全)手动 save bgsave自动 conf:save 900 1 save 300 10 save 60 10000 dbfilename dump.rdb优点:对做事进程影响小,记录原数据文件办法便于管理还原缺陷:可能数据不完全aof(类似binlog)appendfsync noappendfsync everysecappendfsync always (每实行一个命令)优点:数据最完全,支持rewrite缺陷:文件相对rdb更大,导入速率比rdb慢过期策略:定时过期:韶光到了立即删除,cpu不友好,内存友好。惰性过期:访问时判断是否过期:cpu友好,内存不友好定期过期:expires dict中scan,打消已过期的key。cpu和内存最优解内存淘汰机制127.0.0.1:6379> config get maxmemory-policy
1) \公众maxmemory-policy\"大众2) \"大众noeviction\"大众127.0.0.1:6379>noeviction:新写入时回报错allkeys-lru:移除最近最少利用的keyallkeys-random:随机移除某些keyvolatile-lru:设置了过期韶光的key中,移除最近最少利用volatile-random:不阐明volatile-ttl:设置类过期韶光的键中,有更早过期韶光的key优先移除redis行列步队不敷之处行列步队可能丢东西比如redis挂了,producer没有停滞,但是行列步队数据无法写入(除非同步落地到mysql)行列步队的consumer 须要手动处理commit协议如果consumer处理完,表示真正完成如果没有处理完?放回行列步队?直接丢弃?事宜重放机制不支持比如consumer消费错了,那能不能将行列步队回放呢再次处理呢?行列步队最大长度及过期韶光如果producer远大于consumer,撑爆了怎么办如果comsumer 一贯没有处理,producer的数据如何处理exactly once单机分布式锁没问题,集议论形下不靠谱vs memcachememcached上风多线程(listen & woker),利用多核round robincas(check and set,compare and swap)劣势cache coherency、锁key大小有限定(1M)特点内存预分配:slab+trunkredis上风:自己封装了一个AEEvent(epoll+select+kqueue),io多路复用丰富的数据构造(对内+对外)良好的持久化策略(rdb +aof)单机可支配多实例,利用多核劣势:排序、聚合cpu密集操作会等影响吞吐量key 大小最大为1gmore | otherredis ziplist与普通双向链表的差异:普通的链表每一项都占用独立的一块内存,各项之间用地址指针(引用)连接起来,这样会导致大量碎片。而ziplist是将表中每项放在前后连续地址空间内,而且对值存储采纳变长编码。redis msetnx对应的del,可以采纳lua脚本担保get del的原子性redis 单线程如何实现壅塞行列步队?壅塞是壅塞client,又不是壅塞server,server不发数据,client不就壅塞住了,当client想要壅塞在某个key上,server会把这个client放到一个block list里,等key发生变革,就send数据给client。redis 壅塞行列步队的韶光设置实现?blocklist里只存了列表,这个timeout存在连接上,靠serverCron来遍历检测,每次遍历5个,高性能的方案是小堆或者红黑树或者韶光轮实现的定时器构造,epoll wait那块timeout参数就设置成下次超时时间每次poll loop里除了处理io事宜,再把定时器的数据构造里处理下,堆和红黑只要检测到一个未超时就可以break了,韶光轮这是当前槽都触发了就行每次检测5个这种比较折中,由于他场景不是大量并发的做事器,rds cli的连接数量毕竟利用者内部可控,而且不须要精确打击,只要保障相对能及时清理就行,redis的网络部分相比拟较大略,业务场景可控,足够了redis集议论形下如何做到两个key必hash到一个节点?用{}
二、MySql
mysql索引物理存储聚簇索引非聚簇索引数据构造B+树hashfulltextR-tree逻辑角度唯一索引 unique普通索引index主键索引 primary key全文索引 full index(myisam)复合索引 (最左前缀原则)类似 where a and b and c a b c 问题联合索引(a,b,c) 能够精确利用索引的有(a=1), (a=1 and b=1),(a=1 and b=1 and c=1)(b=1 and c =1引擎类型myisaminnodb差异:myisam采取非聚拢索引,innodb采取聚拢索引myisam索引myi与数据myd文件分离,索引文件仅保存数据记录指针地址。myisam的主索引与赞助索引在构造上没差异,而innodb不一样:innodb的所有赞助索引都引用主索引作为data域。innodb支持事务,行级锁。myisam弗成。innodb必须有主键,而myisam可以没有。相同点:都是b+tree 索引存储innodb数据被逻辑的存在tablespace,extend(区)中有多个page,page(默认16kb)里放row(每一行,大概每个page放2-200行记录).frm:table's format.ibd:table data & associated index dataubunut的frm文件和ibd文件可在目录root@udev:/var/lib/mysql# ls中查看,下图为innodb行格式,由下到上,均向上兼容
Antelope 羚羊 对存放bolb或者大varchar存储极长的数据时,将行数据的前768字节存储在数据页中,后面通过偏移量指向溢出页。compact 紧凑的redundant 多余的Barracuda 梭鱼antelope对存放blob的数据完备溢出,在数据页中只存在20个字节的指针,实际数据放在bolb pagecompresseddynamicmoremyisamfrm(与innodb通用),在磁盘的datadir文件myimyd事务原子性atomicity同等性consistency隔离性lsolation持久性durability分表数量级单表在500w旁边,性能最佳。BTREE索引树 在3-5之间隔离级别事务的隔离性是数据库处理数据的根本之一,隔离级别是供应给用户在性能和可靠性做除选择和权衡的配置项目,以下四种情形都有一个条件(在同一个事物中)read_uncommited:脏读,不加任何锁,可能读到未提交的行,见下图read_commit:不可重复读,只对记录加记录锁,而不会在记录间加间隙锁。以是许可新的记录插入到被锁定记录的附近,以是多次利用查询语句时,可能得到不同的结果,non_repeatable_read,见下图repeatable_read【默认级别】:幻读,返回第一次的查询的快照(不会返回不同数据),但是可能有幻读(phantom read),虽然第一次是个空,但是在session2中提交之后,创造已经有了这条数据。见下图serialize:办理了幻读索引机制(算法)hashb+tree(m阶b+tree)所有数据保存在叶子节点,有k个子树的中间节点包含有k个元素所有叶子节点包含了全部的元素信息,及指向这些元素记录的指针,且叶子节点本身依关键字的大小自小而大顺序链接所有的中间节点元素都同时存在于子节点,在子节点元素中都是最大(或最小)元素(或者说:每一个父节点的元素都涌如今子节点中,是子节点的最大或者最小元素)插入的元素,要始终保持最大元素在根节点中,再次说:所有的叶子节点包含了全量元素信息。每个叶子节点都带有指向下个节点的指针,形成了有序链表b-tree【不要念成b减tree】内存操作(单一节点数量很多时,把稳并不比二叉查找树数量少,只是速率比硬盘要快)自平衡左旋、右旋mongoDB用的是balance tree特点(m阶的B树)根节点至少有两个子女每个中间节点都包括k-1个元素和k个孩子(m/2<=k<=m)每个叶子节点都包括k-1个元素,(m/2<=k<=m)所有的叶子节点位于同一层每个节点中的元素从小到大排序,节点当中k-1个元素恰好是k个孩子包含元素的值域划分b+与b-差异b+中间节点没有卫星数据,而b-tree有卫星数据(可以理解为key+data的二维数组),以是前者同样大小可以容纳更多的节点元素。这样又导致了b+比b更“矮胖”,更进一步减少了io查询次数。很好的阐明了下面这句话:在cluster index(聚拢索引中),叶子节点直接包含卫星数据;在非聚拢索引中nonclustered index中,叶子节点带有指向卫星数据的指针。b-只要查找到匹配元素,直接返回,网络匹配元素处理中间节点还是叶子节点。而b+查询必须查找到叶子节,相对付b-,b+无需返回上层节点重复遍历查找事情,以是得出b-查找并不稳定,而b+是稳定的。针对范围查询,b-须要n次中序遍历,而b+只须要通过子节点链表指针遍历即可。锁种类optimistic lock乐不雅观锁(并非真正的锁,先考试测验在,再变动,loop and try)特点:不会真去世锁,一定条件下有较高的冲突频率和重试本钱,但是相对悲观可以有更好的并发量pessimistic lock悲观锁(先霸占,再修正,再开释)粒度划分行锁表锁意向锁 intention lock(表级锁)场景:A对表中一行进行修正,B对全体表修正。如果没有以下的两个锁,B将对全表扫描是否被锁定。反之,A可以对某行添加意向互斥锁(表级),然后再添加互斥锁(行级),然后B只须要等待意向互斥锁开释)意向共享锁意向互斥锁共享锁shard lock 读锁(行锁)排它锁exclusive lock 写锁(行锁)锁的算法record lock:加到索引记录上的锁,如果通过where条件上锁,而不知道详细哪行,这样会锁定全体表gap lock:某个区间的锁定,对索引记录中的一段连续区域的锁。next-key lock:上两者的结合去世锁:把稳区分 deadlock VS lock wait timeout分库分表主从ACID覆盖索引(复合索引)定义:包含两个或多个属性列的索引称为复合索引。如果查询字段是普通索引,或者是联合索引的最左原则字段,查询结果是联合索引的字段或者是主键。这种就不必通过主键(聚拢索引再次查询)目的:减少磁盘io,不用回表b+树索引聚拢索引cluster index 一样平常为primary key定义:按照每张表主键构建一棵B+TREE,叶子节点放的整张表的行记录数据与之相对应的是赞助索引(secondary index)innodb存储引擎支持覆盖索引,即从赞助索引中可以查到查询记录,而不须要查询聚拢索引中的记录。b平衡树+树索引上图对应的表构造:
CREATE TABLE users( id INT NOT NULL, first_name VARCHAR(20) NOT NULL, last_name VARCHAR(20) NOT NULL, age INT NOT NULL, PRIMARY KEY(id), KEY(last_name, first_name, age) KEY(first_name)一张表一定包含一个聚拢索引构成的b+树以及多少赞助索引构成的b+树每次给字段建一个索引,字段中的数据就会被复制一份出来。用于天生索引,(考虑磁盘空间)。不管何种办法查表,终极都会利用主键通过聚拢索引来定位到数据。聚拢索引(主键)是通往真实数据的唯一出路。赞助索引:非聚拢索引都可以被称作赞助索引,其叶子节点不包含行记录的全部数据,仅包含索引中的所有键及一个用于查找对应行记录的【书签(即主键或者说聚拢索引)】,下面两个图为赞助索引(first_name,age)以及通过主键再次查找的过程
联合索引:与覆盖索引没有差异,或者理解为覆盖索引是联合索引的最优解(无需通过主键回表)。explainextrausing index :condition(用了索引,但是回表了)using where :uning index(查询的字段在索引中就能查到,无需回表)using index condition:using filesort(重点优化:表明查到数据后须要再进行排序,只管即便利用索引的有序性。)using where:using indextype(连接类型:join type),以下逐步增大system 系统表,磁盘io忽略不计(有些数据就已经在内存中)const 常量连接(加了where条件限定,命中主键pk或者唯一unique索引)eq_ref 主键索引或者非空唯一索引、等值连接;如果把唯一索引改为普通索引+等值匹配,可能type只为ref,由于可能一对多range 区间范围 between and;where in,gt lt;(把稳必须是索引)index 索引树扫描,即须要扫描索引上的全部数据,比如innodb的countall 全表扫描select 与索引(重视要命中条数与总条数,如果附近,用不到索引,就全回表了,如果是一定范围,那便是range use indexcondition)rows(粗略统计,不是精确)其他:varchar为啥为65535?compact行记录的第一个字段为变长字段长度列表,为2个字节16位。参考一个表最多多少行?1023,详细也是看行格式的数据构造即可,参考上文的参考链接。为什么建议给表加主键?主键的浸染是把数据格式转为索引(平衡树)联合索引在b+树中如何存储?为什么索引不直接用二叉查找树,要用b树,b+树?紧张考虑减少磁盘io(考虑磁盘物理事理及局部性与磁盘预读的特性:)myisam和innodb必须有主键吗?innodb必须有,数据文件须要按照主键聚拢,如果没有innodb会自动天生。
三、算法&数据构造
最小堆:根节点为最小值,且节点比其他孩子小平衡树(avl 红黑树)最大堆:根节点为最大值,且节点比其他孩子大sikplisthashhash 碰撞缘故原由hash 碰撞办理方案拉链,塞到链表里(想到了php max_input_vars)开放寻址,一贯找..线性探测二次探测再散列伪随机数再hash给天命值n,判断n是斐波那契数列的第几项?写算法反转列表如A->B->C->D 到A->D->C->B插入排序数组与链表差异与联系链表操作单链表删除p->next=p->next->next; if(head->next===null){ head=null }单链表插入
new_node->next=p->next; p->next=new_node if(head===null){ head=new_node; }运用问题如何实现一个LRU功能?【双向链表】如何实现浏览器提高退却撤退功能?【两个栈】
四、设计模式
设计模式单例模式 (static ,consturct)static private $instance; private $config; private funciton __construct($config){ $this->config=$config; } private funciton __clone(){ } static public function instance($config){ if(!self::$instance instanceof self){ self::$instance=new self($config); } return self::$instance; }}大略工厂(switch case include new return )
{ public function makeModule($moduleName, $options) { switch ($moduleName) { case 'Fight': return new Fight($options[0], $options[1]); case 'Force': return new Force($options[0]); case 'Shot': return new Shot($options[0], $options[1], $options[2]); } } } # 利用工厂办法 001 class Superman { protected $power; public function __construct() { // 初始化工厂 $factory = new SuperModuleFactory; // 通过工厂供应的方法制造须要的模块 $this->power = $factory->makeModule('Fight', [9, 100]); // $this->power = $factory->makeModule('Force', [45]); // $this->power = $factory->makeModule('Shot', [99, 50, 2]); / $this->power = array( $factory->makeModule('Force', [45]), $factory->makeModule('Shot', [99, 50, 2]) ); / } }# 利用工厂办法 002 class Superman { protected $power; public function __construct(array $modules) { // 初始化工厂 $factory = new SuperModuleFactory; // 通过工厂供应的方法制造须要的模块 foreach ($modules as $moduleName => $moduleOptions) { $this->power[] = $factory->makeModule($moduleName, $moduleOptions); } } } // 创建超人 $superman = new Superman([ 'Fight' => [9, 100], 'Shot' => [99, 50, 2]门面模式对客户屏蔽子系统组件,减少子系统与客户之间的松耦合关系
五、正则表达式
正则表达式运用处景范匹配模版引擎词法剖析器(lex)常见正则六、PHP
php代码阐明过程(大多的非编译措辞)lexical词法剖析,输入为源代码,输出为token语法剖析 工具为文法(LALR),输出为表达式,7.0为AST,涉及:注释分号 & 分隔符变量常量操作数类型检讨、关键字处理、导入,输出为中间代码。工具为选定的的编译器优化工具中间代码天生(Opcodes)机器码天生(编译措辞)session共享配置phpunit用法cookie购物车和session购物车的实现弱类型实当代码规范自动化:sonarquebe+jenkins单元测试php进程间如何通信旗子暗记量行列步队管道socket共享内存php并发模型变量底层存储构造常用的数组函数(列出10个)array_combine(前面数组作为其键,后面数组做为其值)array_merage(合并两个数组,后面覆盖前面,但数字索引会重新索引,不会覆盖)array_multisortphp垃圾回收机制(gc)zend.enable_gc php.inigc_enable() funciton把session放入redis里面还会触发类似文件的state sessionsession.gc_probability (default 1)session.gc_divisor (default 100)session.gc_maxlifetime(单位秒)session.cookie_lifetime(单位秒,0表示直到关闭浏览器)session.save_pathsession_write_close (显示关闭,后期利用须要显示开启)七、操作系统
操作系统多线程多进程协程的理解socket和管道的差异进程间通信手段共享内存rpc管道线程间通信手段读写进程数据段八、网络协议
网络协议http构成:起始行(GET =>200),首部头 (ACCEPT=>CONTENT-TYPE),主体 name =》tongbo版本:1.01.12.0 :多路复用、流量掌握长连接在一个连接上发送多个数据包心跳、如何发送心跳httpdns定义:用http协议代替原始的udp dns协议,可以绕过运营商的local dns办理问题:避免local dns造成的域名挟制问题和调度禁绝确问题(更多是在移动客户端)其他办理方案客户端dns缓存热点域名解析关于TIME_WAIT:time_wait是一种TCP状态,等待2msl可以担保客户端末了一个报文段能够到达做事器,如果未到达,做事器则会超时重传连接开释报文段。使得客户端、做事器都可以正常进入到CLOSE状态。关于'粘包'分包:在一个别或一帧数据时,通过一定的处理,让吸收方能从字节流中识别并截取(还原)出一个个别。短连接tcp分包:发送方关闭连接,吸收方read 0,就知道尾了长连接TCP分包:长度固定or头中加长度字段固定边界,比如http:rn利用本身格式,如xml,json特性协议停等超时重传慢启动滑动窗口快速重传udp无连接、best effort、面向报文(不合并、不拆分,保留边界)无拥塞掌握、流量掌握、首部开销小(8个字节,而tcp有20个首部)支持一对一,一对多,多对一自定义协议rpc九、大前端
js百度统计的实现基于cookie,引入js脚本及baidu个人账户id,读取当前信息,适当节点发送要求给百度做事器十、中间件
中间件rebbitmqkafkaRedis 行列步队十一、php框架
php框架ciyiilaravelAppServiceProvider register:做事供应者注册IocContainer:(工厂模式的升华:ioc容器)掌握反转(inversion of control)可以降落打算机代码之间的耦合,个中最常见的办法叫做依赖注入。(Dependence Injection),还有一种办法为依赖查找。实现办法基于接口:实现特定接口以供外部容器注入所依赖类型的工具。基于set方法:还没搞明白。基于布局函数:实现特定参数的布局函数管理类依赖实行(依赖注入DI):通过布局函数或者某些情形下通过setter方法将类依赖注入到类中,容器并不须要被奉告如何构建工具,由于他会利用php的反射做事自动解析出详细的工具。swoole依赖注入与掌握翻转十二 、运维
运维&架构做事器cpu99%如何剖析mysql 占cpu如何剖析php占cpu较高如何剖析sso实现方法mysql优化方法如何提高监测数据的准确性docker 事理及引用及编排管理十三、golang
golangtodo十四、 Linux
linuxepoll查看负载:cat /proc/loadavg || w || topdftop shift+Mfreeipstatstracegrep [-A ,-B, -C]'HTTP/1.1\"大众 200' access.log |wc -lsocket和管道(pipe)的差异:socket全双工,pipe半双工2awkawk '{print $1}' access.log |sort |uniq |wc -l十五、nginx
nginxworker_connectionsupstream weight卖力均衡实现办法轮询ip 哈希指定权重第三方fairurl_hash十六、分布式 | 微做事
分布式redis 分布式锁问题cap 及常见运用关注cap哪两点微做事最佳原则高内聚:修正一个功能,只须要改一个做事低耦合:修正了一个地方,不须要改其他的地方(下贱消费者不受影响)业务内原则:新做事用新的微做事,确定无误后保留推进,否则调度老的保留,直到新做事稳定再切换必需的的监控与日志|生产-订阅—消费模型考试测验对外不可见的做事先做试点,缺点邮件、日志、系统内调用、api内部分成熟接口考虑问题做事创造是否须要客户端自实现?做事可用性担保要不要拆MySQL表?担保做事底层的高内聚?异或是存到nosql数据同等性问题?主从|缓存做事监控日志存储及查询功能是否须要自实现?基于事宜+生产|消费模型选型rabbitmqkafkaredis 行列步队要求失落败是否须要存入行列步队以便再次发起(最大重试次数与去世信行列步队)?其他
其他两个绝对路径,求之间的相对路径分布式根本cap事理办理多个节点数据同等性的方案实在便是共识算法分布式协议Paxos:Proposer, Acceptor, LearnerZAB:Follower, Leader, Observerraft:leader ,follower,candidate分布式工具zk:zab(base paxos)protocol,etcd:raft protocol(mini PAXOS),k-v database详细
如何对一个大文件排序(装不进内存的)-好未来思路:map reduce分割成小文件(临时文件)去重awk grep end for sort输入输出缓冲区快速排序代码冒泡排序代码外层循环 0到n-1 //掌握比较轮数 n 表示元素的个数内层循环 0到n-i-1 //掌握每一轮比较次数两两比较做交流外层循环开始声明 is_switch flag为false,内层循环有交流为true,外层循环结束时判断无switch break归并排序代码