leevis.com
leevis.com copied to clipboard
关于工作相关的一些思考
关于工作相关的一些思考
没有银弹,任何的情况下都需要你结合当初的情况找一个平衡点。而这个平衡点的选择就是你的经验和思考的结果。
-
关于架构、系统: 所有互联网中的大型系统,都可以拆分为很多小系统解决。而小的系统在互联网界都可以找到可复用的或者其思路是你可以借鉴的。所以技术上并不是难点,真正的难点是结合你的业务怎么拆分,拆分了以后怎么组合。
-
关于算法: 找到时间和空间的平衡点。 最快的算法O(1),hash表、数组。 一般的算法能达到O(N*logN)就可以在生产中使用了。 也不是说O(N*N)就不能用,看场景和数据量。比如:nginx在启动阶段,构件location平衡二叉树用了插入排序。 所以,生产系统中我们是尽可能的把算法时间复杂度降到最低,但是通常情况下,快速排序、二分法查找已经就够了。
-
关于数据结构: 数组、链表、红黑树。数据是可以确定的,那么数组是个很好的选择。当有大量的增删操作存在时就需要用到链表或二叉树。没有顺序要求的时候,链表表现也可以接收,当有顺序要求的时候,链表的时间复杂度太高,需要用到跳表或平衡二叉树。平衡二叉树的实现太复杂,也没必要必须平衡,近平衡就可以,所以用红黑树。例如:nginx定时器就是一颗红黑树,在linux内核中也大量用到红黑树。
-
关于高性能: 最好的情况下是用业务逻辑把CPU性能压榨干,但是这个是不现实的,业务程序是跑在操作系统上面的,操作系统的运行是需要消耗CPU的。所以,能把CPU跑起来,尽可能的减小无谓的CPU消耗就可以了。
-
关于分布式: 不可以逾越的CAP,解决办法:一致性哈希算法、2阶段或3阶段提交。
-
关于回调函数: 合理的回调函数设计,一定是这个程序最精彩的地方。如果没有nginx的回调、没有openssl的回调,也就没有openresty的玩法。
-
关于我的技术栈: 接口用openresty写,后台服务用golang写。
-
关于代码规范: 代码是写给人看的,而不是机器执行的。所以,少用你自己的小技巧。好的架构是设计出来的,好的代码一定是重构优化出来的。 一个代码格式化工具:https://sourceforge.net/projects/astyle/files/astyle/
-
关于设计: 在能解析当前业务的情况下,也能解析未来业务的情况下,越简单越好。
-
关于重复造轮子问题: 不到万不得已,不要重复造轮子。开源的系统,市场上大量牛逼熟练的人才,而自己的系统只有自己的团队在维护。一个大型系统没有3个月熟悉不下来,再加上设计的不规范性就更难了。
-
关于nginx、openresty: nginx的模块想写烂不容易,想写好更不容易。nginx自己定义了一个小的语言环境,自己实现了dict vector等数据结构,变量定义也是非常规范、模块划分也非常规范。比较头疼的就是回调函数不符合人类的思维,进程中不能有阻塞的操作。 openresty基于nginx的回调和openssl的回调,添加了可以写lua代码修改业务逻辑。尤其是对子请求的封装(Capture)、对upstream的封装(Cosocket)、对定时器(Timer)的封装非常赞。
-
关于后台服务: 异步非阻塞、多线程、多协程。 语言级别能支持协程也挺多了,近年流行起来的golang。在写后台服务是个不错的选择。 语言级别本身不支持协程,单线程多进程的异步非阻塞或多线程。 拿C语言来说,git上成熟的线程池实现非常多,拿过来改改就可以用了。但是线程之间数据交互需要加锁,调度线程需要消耗cpu。 异步非阻塞,可以理解为死循环+状态机,epoll也可以看作是一个状态机。总功一定的情况下,无用功做的少了有用功就多了。
-
关于Tcp协议和Http协议: 虽然目前的协议有非常多的缺陷,也支撑了三四十年了,再加上全球网络设备成本,推倒重新设计根本不可能。再加上三四十年的改良和考验,其中很多的设计思路是可以借鉴的。所以,目前在用的基础的东西很重要。
-
关于未来: 未来是大数据+人工智能的时代。 当内容量小的时候,我们根本用不着搜索引擎。当内容量大的时候我们需要搜索引擎来找我们需要的内容。当内容量再大的时候,我们需要智能搜索引擎和智能推荐引擎。而能让搜索引擎有智能的东西就是大数据+人工智能。
-
关于防CC攻击: 基于时间序列的回归算法(例如:Prophet)预测域名是否存在攻击,使用分类算法识别哪些IP是攻击IP。单IP访问占比、访问URL情况、访问UA情况、访问Referer情况、访问的status情况,和历史对比等作为特征。