本文不是纯粹的技术文,用自己的语言来阐述一些观点。
1. 网络基础
先上一个图:
有人说会,这个记住了,有什么用呢?
A用户发送一封电子邮件给B用户,是什么样的过程?这个了解吗?下图摘自《图解TCP IP》
再问你,nginx负载均衡和F5硬件负载均衡是在哪一层做的?
负载均衡也会涉及到该分层模型,判断是在哪一层做的。nginx就是四层负载均衡。
四层可以保证七层的负载均衡的高可用性,但nginx无法保证自身的服务高可用,需要依赖LVS或keepalive。F5也是属于四层负载均衡。
IP、HTTP、SMTP,TELNET,DNS,TCP ,UDP这些常见的协议都位于哪一层?上面的图中也都有答案。
当我们在浏览器输入www.baidu.com
按下回车的时候,发生了什么?
hosts,DNS是不是要工作下?找到IP地址之后是不是要进行连接?就要进行三次握手啦
三次握手(建立连接)、四次挥手(断开连接)不是冷冰冰的单纯的面试题,它是网络连接中不可缺少的一部分。
这里大白话插一下,三次握手,就是客户端发个能收到吗(SYN)?服务端回个能收到,你那能收到吗?(SYN/ACK)客户端再回能收到(ACK)
四次挥手:客户端:啊朋友再见(FIN) 服务端:收到(ACK) 服务端:来而不往非礼也,啊朋友再见(FIN) 客户端:收到(ACK)
每次都要建立连接多麻烦啊?是不是就有了长连接、短连接?
现在常用的HTTP1.1 F12看请求的时候是不是能看到header是什么,能不能用二进制节省些空间,HTTP2不就在路上了?
2. 操作系统
有些人说:操作系统不了解也没事儿,反正不影响开发
刚开始的时候,计算机的内存很小,要运行多段程序,引出了虚拟内存,换页算法(什么FIFO,LRU等,不觉得熟悉吗?Redis的内存淘汰策略也有类似的策略)
mmap,零拷贝,堆外内存,了解有啥用呢?当你去看RocketMQ 存储实现的时候,你会见到MappedByteBuffer
,DirectByteBuffer
的身影。涉及到零拷贝的时候,你又会发现,多次拷贝会有一个用户态和核心态的转换。
为什么一个线程不会一直执行,而会进行一个上下文切换?就牵涉到CPU调度,调度算法,中断
进程和线程区别?并发并行区别?临界区?信号量的P操作V操作?(在Java中是有相关的Semaphore实现的)
3. 数据结构和算法
知道常见的数据结构有: 数组、链表、树、图、Hash、队列
对数据排个序,是不是得用排序算法,那么多排序算法,不大致了解下怎么实现的?特别是快排用到的“分治思想”
Top n,得知道大顶堆、小顶堆吧,别说是Java内存区域中的堆哈,两码事。
都说Redis快,为什么快?单线程、内存存储k-v对,那了不了解,redis支持的几种类型:String,list,set,hash,sorted set , bitMap再底层的数据结构是什么样的?SDS,ziplist,skiplist,intset听过没?Hash那一块又涉及到rehash,是不是再跟HashMap的rehash对照看下,另外,别人还不是一次性就全部完成rehash,渐进式rehash了解下?持久化的RDB/AOF是不是跟MySQL 的binlog/redolog思想上有点类似?AOF重写又是怎么回事?
这些基础的数据结构和算法是支撑高效率,低时间复杂度的基石,不了解,普通开发没影响,了解了,打开另一片天地。
再额外说一个正则表达式。手机号,身份证号码在网上copy一个就行,那么复杂,学了又没什么用?
everything的正则表达式搜索爽歪歪
idea的正则匹配爽歪歪,比如下面这个:有时我们写的@RequestParam String xxx;要批量修改下,正则就派上用场了。不用担心写的正则不够简洁,提高生产力,它的作用、价值就体现到了。
4. 结语
基础的东西,比较容易被人忽略,但正是这些基础的,构建了程序的完美地基。多怀着刨根问底的精神,多去思考下为什么,怎么实现的。
最后附上以前在《儒林外史》中看过的一段话: