Redis 学习笔记
Redis 序列化协议使用的是文本协议,客户端的开发非常简单,易于解析。 常见的一些数据库和缓存性能对比MYSQL QPS:8000 读,4000 写; redis 10W 读写。 memcached 的瓶颈在于libevent,而 redis 用了 epoll。 一些典型的使用场景 最新 N 个数据的操作。例如取网站的最新文章,我们可以将最新的5000条评论的id放入到 redis 的 list 中,并将超出链表的部分从 DB 获取(热数据缓存)。 构建队列系统。使用list可构建队列,使用sorted set可以构建优先级队列。 使用 setbit 记录连续登陆 7 天的用户(每天一个 key,用户登陆就把对应的位设置 1,最后将 7 天的 key 做按位 and),使用 DB 的话表大,并且要 sum,group 计算。和《编程珠玑》中的位图排序有异曲同工之妙。 使用 srandommember 做有放回的抽奖,spop...
memcached 初窥
内存分配机制考虑这样一种情形:申请20M内存,释放15M内存,然后又需要申请12M内存,这样就产生了3M的内存碎片,随着程序的运行,碎片会越来越多。memcached采用了Slab Allocator分配机制:基本原理是按照预先规定的大小,将分配的内存分割成特定长度的块(chunk),并将尺寸相同的chunk分成组(chunk的集合),尽可能(完全解决内存碎片是不可能的)解决内存碎片问题。 根据收到的数据大小自动选择最合适的slab(具体实现是memcached中保存着slab空闲chunk的列表,根据这个列表选择空的chunk并将数据缓存其中),例如100bytes的item将会被存放在上图中的Slab2,但是剩下的12字节同样被浪费了,无法重新利用,这种做法只是尽可能减少内存碎片。使用memcached -vvv启动服务的时候可以看到类似以下的输出: 12345678slab class 1: chunk size 96 perslab 10922slab class 2: chunk size 120 perslab ...
前端杂谈
为什么js要放在body最下面二css要放在head中?浏览器拿到css就知道该怎么渲染HTML了,如果把css放在body下面则会先按照默认样式进行渲染,当css加载完成的时候会按照css的样式再渲染一遍,即发生了reflow。由于js会阻塞代码执行,所以js一般放在body最下面,还有一个原因:js放在最下面的时候就可以取得页面中所有的元素了。 window.onload和DomContentLoaded有什么区别前者是页面的资源加载完成(包括图片、视频),后者是DOM渲染完即可,此时图片、视频可能还没加载完。 图片懒加载的实现原理先用一张默认的图片代替(这张默认的图片因为使用太频繁,浏览器可能缓存了)然后再更改img的src属性。 跨域可以跨域的3个标签: img:可以用于打点统计,统计网站可能是其他域,使用img标签有一个好处:没有浏览器兼容性问题 link:可以使用CDN script:可以使用CDN,可以JSONP 本地3000端口开启了一个服务: 12345678const http =...
布隆过滤器
特点 精确判断不存在,但是可能会误判一个不在集合中的元素为存在(即:假阳) 不支持删除元素(几个hash函数计算出来的下标可能别的key也用到了) 总结来说就是:判断不存在的时候一定不存在,判断存在的时候大概率存在。 误判率可以通过调整参数来降低,但是无法完全消除。 数据结构的组成布隆过滤器由一个 bitSet 和一组 hash 函数组成,是一种空间效率非常高的概率算法和数据结构。在初始化的时候,bitSet 的每一位被初始化为 0,同时会定义一组 hash函数,例如有 3 组 hash 函数,hash1,hash2,hash3. 写入流程当我们要写入一个值时,过程如下,以“jionghui”为例: 首先将“jionghui”跟3组 Hash 函数分别计算,得到 bitSet 的下标为:1、7、10。 将 bitSet 的这3个下标标记为1。 假设我们还有另外两个值:java 和 diaosi,按上面的流程跟 3组 Hash 函数分别计算,结果如下: java:Hash 函数计算 bitSet 下标为:1、7、11 diaosi:Hash 函数计算 bitSet...
码农翻身有感
做技术切记“本末倒置”,我非常痛恨那些采用bottom-up方式来讲解技术的资料和文章,一上来就是技术细节、安装步骤、配置丰富,让初学者晕头转向,不知所云,看完以后也不知道为什么要有这个东西、解决了什么问题、它有什么来龙去脉。换句话说,这些资料和文章习惯于讲解How,而不是Why,但是在我看来,Why有时候比How更重要。 当你改变不了别人的时候,抱怨也没有用,还是要先改变一下自己。 程序的局部性原理: 时间局部性:如果程序中某条指令开始执行,则不久之后该指令可能被再次执行;如果某数据被访问,则不久之后该数据可能被再次访问。空间局部性:一旦程序访问了某个存储单元,则不久之后其附近的存储单元也将被再次访问。
计算机网络
ARP网络层和数据链路层的桥梁。 通过IP地址找到MAC地址,只适用于IPv4,不能用于IPv6(可以用ICMPv6替代ARP发送邻居探索消息,融合了IPv4中的ARP,ICMP重定向和ICMP路由选择,甚至还能自动设置IP地址:和DHCPv6结合)。ARP是通过ARP请求和ARP响应两种类型的包来确定MAC地址的。 IPv6中ICMP的作用被放大,如果没有ICMPv6,IPv6无法正常通信。 如上图所示主机A为了获得主机B的MAC地址,要通过广播发送一个ARP请求包,这个包包含了想要了解其MAC地址的主机的IP地址。如果ARP请求包中的目标IP和自己的IP地址一致,那么这个节点就将自己的MAC地址塞入到ARP响应包中返回给主机A。 ARP请求包还有一个作用:将自己的MAC地址告诉对方 TCP中间节点并不承诺提供可靠的连接通道,物资完全可能失序、重复、甚至丢失。所谓可靠完全由两个端点来实现。 TCP要求无论处在何种网络环境下都要提供高性能通信,并且无论网络拥堵情况如何变化,都必须保持这个特性。因此它每次发包都会计算往返时间及其偏差(RTT:Round Trip...
MySQL优化总结
思路 第一步要做的是确定问题的症结,而不是一上来就看表结构和查询语句。 开启profiling MySQL默认会开启缓存池,本地调试的时候清除缓存的命令是:reset query cache。 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950MariaDB [(none)]> show variables like '%profi%'; +------------------------+-------+| Variable_name | Value |+------------------------+-------+| have_profiling | YES || profiling | OFF || profiling_history_size | 15 |+------------------------+-------+3 rows...
面试套路 - 操作系统
文件是如何组织的文件系统将硬盘空间以块为单位进行划分,每个文件占据若干个块,然后再通过一个文件控制块 FCB 记录每个文件占据的硬盘数据块。 这个文件控制块在Linux操作系统中就是inode,要想访问文件,就必须获得文件的inode信息,在inode中查找文件数据块索引表,根据索引中记录的硬盘地址信息访问硬盘,读写数据。 inode中记录着文件权限、所有者、修改时间和文件大小等文件属性信息,以及文件数据块硬盘地址索引。 RAID5将数据划分为N-1片,再利用N-1片数据进行位运算,得到一片校验数据,然后将这N片数据写入到N个硬盘。这样任何一块硬盘损坏都可以利用校验片的数据和其他片的数据进行计算得到丢失的那个数据,而硬盘的利用率也达到了N-1 / N。这样兼顾了磁盘利用率、读写速度和数据可用性,实际生产中用的最多。 RAID5中校验位的生成采用的是异或运算。所有数据的bit位,逐位进行异或,得到的就是校验位。如果丢失部分数据,用校验数据和其余数据逐位进行异或运算,可到丢失部分数据。举例,5块磁盘做RAID5,四块磁盘上的bit为:0 1 1 1 ,那么异或计算后,校验位为...
Nginx 踩坑
NGINX 是 CPU 亲和的,把每个 worker 进程固定在一个 CPU 上执行,减少切换CPU的cache miss,获得更好的性能。处理静态资源效率高的原因是采用了sendFile工作机制:文件从硬盘上读取到网络传输的过程不经过用户空间,也就是常说的零拷贝机制: 防盗链主要是区分合法请求和非法请求,常用的解决方案有以下几种: 基于http_refer防盗链配置模块 url重写网站维护的时候将所有页面重定向到维护页面: 1rewrite ^(.*)$ /pages/maintain.html 301和302的区别:301是永久重定向,客户端会缓存重定向后的地址(即使服务器关闭也能跳转到对应的地址),302请求每次都会访问服务器。所以做重定向的时候最好选择302,301如果跳转的链接改了是无法及时更新的。 https优化: 激活keepalive长连接 设置ssl session缓存 所有的压缩算法对文本的压缩效率是最高的 nginx调优文件描述符修改 /etc/security/limits.conf 123456#...
golang 踩坑
iota可以按照特定的规则执行逻辑: 1234567891011121314151617package mainimport "fmt"const ( b = 1 << (10 * iota) kb mb gb tb pb)func main(){ // 1 1024 1048576 1099511627776 1125899906842624 fmt.Println(b,kb,mb,tb,pb)} go中的slice本身没有数据,是对底层array的view。 闭包12345678910111213141516171819package mainimport "fmt"func adder() func (value int) int { sum:=0 return func (value int)int { sum += value return sum } }func main() { adder:=adder() for i := 0; i...