通过合理的设计降低软件开发复杂度
对于一个程序员来说,日常最常说的词恐怕就是「复杂」了,这段代码太复杂了,这个逻辑太复杂了,所以,在这篇文章里,我们就好好掰扯掰扯「复杂」到底是怎么产生的,又要怎么去避免。 复杂度的产生我们先列一下当我们在说「复杂」的时候,到底在说什么。 没有模块划分,整个一大坨代码摊在那儿 大量的重复代码 代码整体逻辑看不懂 本来一个很简单的需求,改的时候发现这也要改,那也要改 代码没办法迁移,没办法复用 整天有莫名的bug出现 … 上边列的这些问题,其实很多之间是互为因果的,比如模块划分的不好,导致了代码逻辑看不懂,也导致了代码没法复用,代码没法复用,又导致了大量重复代码,重复代码又进一步导致代码逻辑看不懂。 所以,下面我们尝试着规整一下这些问题,看看问题到底在哪。 我觉得,首先可以把代码复杂度的问题简单分个类,一类是代码本身的问题,一类是代码对现实世界的表现力的问题。前者主要关乎代码整体的整洁程度,以及容不容易进行持续的维护;后者则主要影响代码容不容易理解,别人看代码时是否需要大量的背景知识。 对代码本身问题来说,以我的观察,导致代码过度复杂的首要原因就是模块拆分不清晰,甚至没有模块...
信息传播过程中的衰减
看到这个标题,是不是有种要讲信息学的感觉。其实并不是,只是最近观察到一些事情,有些感触所以说一下。最近在网上碰巧看到过两个言论,恰好事实我是比较了解的,所以感慨,二手的信息实在不可信。 第一个,是北京西城德胜片区有一个小学叫三帆附小,因为可以直升三帆中学,这个在西城数一数二的初中,所以一直十分火爆。这个学校今年因为教室不够,招生由七个班缩减到了四个班,所以卡了落户四年,即落户不足四年的都要调剂。其实,调剂也不差,因为调剂校里有西城排名前五,而且学位极度充足的西师附小,也有雷锋消息这样的优质直升校。甚至有人买三帆附小学区房就是为了去调剂,因为西师附小的学区房要更贵。 然后,在一个公众号的高赞评论里,看到了「德胜」今年卡落户「两三年」这样的言论,言论作者还顺便以此为依据表达了对买学区房这种行为从智商上的鄙视。 结合事实和最后言论,其实大概猜的出整个传播链条中信息的变化。德胜的三帆附小逐渐变成了德胜,卡落户四年变成了落户两三年的被调剂,又变成了卡两三年。同时,调剂去的是西师附小这种关键信息被丢失。 第二个事,上周望京地区除了新冠的病例,然后各个社区在周末组织全员的核酸检测。其中有个...
看房小记-2020北京学区
从今年十一左右开始看房,到上个月初就定了下来。其实没想到会定那么快,只能说缘分到了吧。回想起当时的经历,感觉还是要记录一下,毕竟是人生中最大的几件事之一了。 其实从年初孩子出生就在考虑买学区房的事情了,不过自己本来房子要到明年初才满五,没法赶在西城731政策之前上车了,算是有点小遗憾。 首先针对要不要买学区房,我比较认同网上的一类观点:买房子实际上是在买圈子。买的是你的邻居是些什么人,你的孩子要和什么人做同学。同样价格,有的人会选择学区好一点,住的差一点,有的人会想住的舒适一些,学区差点。想了想,我还是愿意和第一类人混一起。 因此最后和爱人定下了基本的基调:在保障基本居住质量的前提下,去追求能力范围内最好的学区。算了下预算,期望控制在850万左右,最高不超过950万。户型别太差的小两居就可以。 首先做了一轮初步筛选,海淀大部分地方因为离我们俩工作地都太远,所以都不再考虑了。金融街的价格压力太大,因此首先将范围缩小到西城的月坛和德胜两个片区,先看看房子情况。 十一期间先去月坛看了次房子,主要是育民对口的小区,白云观、白云路、汽南、真武庙啥的。说实话,心理落差非常大,第一印象真的...
读书感悟:文明、现代化、价值投资与中国
《文明、现代化、价值投资与中国》这本书,是著名的价值投资者李录先生所著的,分别讲述了文明的发展、现代化的产生、价值投资,并且结合中国的实际情况对这些内容作了阐述。个人感觉是一本价值极高的书,值得反复阅读,对于帮助我们认识这个世界的运行逻辑,建立正确的投资理念,都有非常大的帮助。 从书名可以看出,这本书其实讲了两个相对独立的话题,一个是文明、现代化,一个是价值投资,并分别阐述了这些和中国的关系。 文明与现代化农业文明的局限性作者首先用了很大篇幅讲述了文明产生与演化的整个过程。其中尤为精彩的就是对于农业文明天花板的论述。也就是农业文明的产出,本质上来源于光合作用。植物通过光合作用生长,而喂养牲畜也需要消耗植物。而光合作用产生的能量上限,受制于土地面积和土地的单位产出,这两者都有非常明显的上限,所以自然资源也就有了上限。有限的自然资源和近乎无限的人口增长,决定了人口最终只能通过非自然灾害来消化。 现代化的产生与本质现代化的产生源自新大陆带来的环大西洋自由市场经济和同时代的科学革命。1776年是一个重要的年份,这一年发生了三件事情,对现代化的发展都起到了至关重要的作用。一是亚当斯密出...
读书笔记-我曾走在崩溃的边缘
今天讲的这本书,《我曾走在崩溃的边缘:俞敏洪亲述新东方创业发展之路》,是俞敏洪老师写的一本自传性质的书,讲述了他从创立新东方以来的诸多经历和心路历程。今天就总结一下这本书的内容,并且讲一下自己的感悟。 这本书是从俞敏洪创立新东方之前说起的,俞敏洪一开始是北大的老师,在和学校产生矛盾离开了学校。当时恰逢出国留学的热潮,俞敏洪原本打算考给别人培训GRE攒够钱就出国留学,最后却在机缘巧合下,将新东方越做越大。 简单来讲,新东方的发展过程分为这么几个阶段: 俞敏洪自己几乎包办一切的小作坊阶段 获取办学许可证,逐渐向正规化发展; 品牌开始爆炸式传播 徐小平、王强等老同学加入,俞敏洪开始有很多强力的合作伙伴 家族成员离开,借鉴西方管理知识,新东方开始制定明确的制度 公司成立,以及组织架构的不断改革 外部投资的进入到上市 老股东退出,新生代崛起;新的业务领域不断发展,直到今天的新东方 从这本书,我们看到了新东方从一个小的培训班逐步发展成一个国内领先的教育机构的经历,从中也有很多的感悟。 关于成长看所有成功人士的传记,会发现他们都有一个共同的特质:不给自己设限,不会说我只能干这些事,干不...
[翻译][关于分布式架构和系统设计]分布式系统的模式-综述
(最近把这篇文章重新整理了下,欢迎阅读最新版 https://lichuanyang.top/posts/45718/) 本文翻译自https://martinfowler.com/articles/patterns-of-distributed-systems/ ,原作者对目前各类企业级架构中使用的多种分布式系统进行了总结,从中提取出了一些通用的“模式”(pattern)。本文作为系列文章的第一篇,介绍了分布式系统的特点和一些常见问题。 建议好好阅读一下本文以及英文原文,对于分布式系统设计和分布式架构理念,会有非常大的帮助。 What this is about分布式系统给程序设计带来了特殊的挑战。 它们通常要求我们拥有多个数据副本,这些副本需要保持同步。 但是我们无法期望各节点能永远可靠地工作,同时,网络延迟也很容易导致不一致的现象出现。 尽管如此,许多组织仍依赖一系列核心的分布式系统来处理数据存储,消息传递,系统管理和计算等。 这些系统面临很多共同的问题,这些问题也可以通过类似的方案来解决。 本文将这些解决方案定义为模式,通过这些模式,我们对于如何更好地理解,交流和教授...
redis的对象
在上一篇文章中,介绍了redis的底层定义的一些数据结构。接下来,在本文中,我们就结合redis提供的对象,看看这些数据结构是如何使用的。 Redis中主要包括这些对象:字符串、列表、哈希、集合、有序集合、HyperLogLog、GEO等,本文会主要介绍这些对象是如何实现的,对于其命令,可以参考redis官网中对每个命令的说明,这里就不一个一个列了。 在介绍具体的对象之前,先看一下redis中对于对象本身的定义。 123456789typedef struct redisObject { unsigned type:4; unsigned encoding:4; unsigned lru:LRU_BITS; /* LRU time (relative to global lru_clock) or * LFU data (least significant 8 bits frequency * and most significant 16 ...
redis里的数据结构
Redis作为当前使用非常广泛的内存数据库,在代码层面做了很多极致的优化,已获取更好的性能。其中重要的一部分,就是对于底层数据结构的使用。Redis会根据数据量、数据大小等来优化对于不同结构的使用,从而获得更佳的运行效率和内存占用。Redis的核心数据结构包括简单动态字符串、列表、字典、跳跃表、整数集合、压缩列表。 接下来,我们就依次讲讲这些数据结构。 简单动态字符串(SDS)Redis是用C语言实现的。先复习一下C,C里的字符串中不记录字符串长度,以空字符标记结尾。这样会显而易见的带来三个问题:1.获取字符串长度需要O(n)的复杂度;2.操作不慎会导致缓冲区溢出,例如内存中紧邻的两个字符串,如果对前一个调用strcat拼接其他字符串,就会造成溢出;3. 一些特殊内容,如图像、音频等转成二进制时,难免其中夹杂空字符等特殊字符,这样就无法被C字符串存储了,即C字符串不具备二进制安全性。 而这几点,对于Redis的应用场景来说,影响其实都是非常大的。因此,在redis中定义了一个新的结构,用来保存字符串,即SDS。 SDS的核心思想就是额外使用一个字段记录字符串的长度,这样,上面...
设计模式备忘录
众所周知,对于程序员来说,设计模式是一门极其重要的学科。不过,由于设计模式的涉及面太广,也有很多非常抽象的概念,还是很难掌握的。要学习设计模式,最好还是能结合实际。每次做需求,尤其是一些复杂的需求,或者嗅到了烂代码味道的时候,就可以翻一遍设计模式,看看有什么可以应用的模式。所以,我总结了这篇文章,以尽量短的语言描述主要的设计模式,可能是定义中的关键部分,也可能是典型的应用场景,或者只是个英文单词,目的在于帮助回忆起每个设计模式的作用和应用场景。 基本设计原则要说设计模式,一定要先提一遍六大基本设计原则。说白了,设计模式就是在这些原则的基础上被提炼出来得一系列最佳实践。 单一职责原则开放封闭原则通过扩展解决问题,而不是修改已有的实现。(写代码时可以假定变化不会发生,当出现变化时,需要抽象以隔离将来的同类变化) 修改没有破坏原有的单元测试,即可认为不违反开闭原则 里氏替换原则子类应当能代替父类 依赖倒置原则高层模块不能依赖低层模块;应当依赖抽象而非实现 接口隔离原则接口尽量小 迪米特法则类间解耦 #设计模式 工厂方法模式定义一个用于创建对象的接口 抽象工厂模式创建一组相关或者相...
聊聊程序员的职业生涯,我对程序员这个职业的理解
工作这些年来,一直在思考着程序员这个职业究竟是在做什么,随着经验增多,其实也一直在刷新着认知。现在写这篇文章,一方面是为了分享,另一方面也是想留下一份记录,过两年再回头来看看自己的认知又有了什么更新。 我想从两个方面来说。一是从做的事儿上,在我看来,程序员的工作就是发现问题、分析问题、解决问题三类。事实上,世界上绝大多数工作都可以囊括进这三类事中。二是从能力上来看,我把能力分为两种:对现实世界的认知能力,和将现实世界映射成程序语言的能力。 对于三种类型的事,按发现问题,分析问题,解决问题的顺序,是从宏观到细节的区别,平时做的事,肯定是以解决问题为主,各种琐碎的事,也都是在解决问题。发现问题和分析问题对人的思维深度会有更高的要求,不过对于工作来说,我倒并不觉得这三类事有什么高下之分。如果对确定的问题,总能给出恰当的解决方案,这也是职场上非常硬核的核心竞争力。而对于两类能力,一般还是更关注第二种。但是我觉得对现实世界的认知能力,对于程序员的职业发展是非常重要的。就像抠业务,抠CRUD这事,有门槛吗?我觉得是有的,至少把业务做的很好门槛非常高。有些人总是以非常奇特的方式去实现业务,...