<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>技术随笔 on 涯余的博客</title><link>https://hangyan.github.io/tags/%E6%8A%80%E6%9C%AF%E9%9A%8F%E7%AC%94/</link><description>Recent content in 技术随笔 on 涯余的博客</description><generator>Hugo</generator><language>zh</language><managingEditor>hang.yan@hotmail.com (涯余)</managingEditor><webMaster>hang.yan@hotmail.com (涯余)</webMaster><lastBuildDate>Wed, 01 May 2019 19:03:04 +0000</lastBuildDate><atom:link href="https://hangyan.github.io/tags/%E6%8A%80%E6%9C%AF%E9%9A%8F%E7%AC%94/index.xml" rel="self" type="application/rss+xml"/><item><title>如何防止代码变成 SHIT</title><link>https://hangyan.github.io/post/2019-05-01-great-code/</link><pubDate>Wed, 01 May 2019 19:03:04 +0000</pubDate><author>hang.yan@hotmail.com (涯余)</author><guid>https://hangyan.github.io/post/2019-05-01-great-code/</guid><description>&lt;!-- toc --&gt;
&lt;p&gt;最近发现之前写过的很多项目，不管是 python/go/cpp 的，最终回看起来代码都变的很难看，尤其是多人合作的时候。
这是一个很头疼的问题。自己平时很在意这个，但是代码最终确都变成了 shit。&lt;/p&gt;
&lt;h2 id="问题"&gt;问题&lt;/h2&gt;
&lt;p&gt;当一个人开发的时候，问题主要在于一个人的自律性不够强，不管是代码注释等都是随意写的，即使偶尔意识到了问题，但也难以保证能一直坚持下去。
而当人多的时候，问题经常处在多人风格的不同上。如果没有&lt;code&gt;工具&lt;/code&gt;来强制大家遵守一定的规则，那么大家每个人自己的风格放在一起的时候，就成了垃圾代码。
避免代码变成 shit 的唯一方法，就是让大家写的代码&lt;code&gt;看起来都一个样&lt;/code&gt;。而这个工作除了由开发人员的 Code Review 之外，还需要工具来约束。&lt;/p&gt;
&lt;h2 id="解决方法"&gt;解决方法&lt;/h2&gt;
&lt;h3 id="cicd"&gt;CI/CD&lt;/h3&gt;
&lt;p&gt;最开始接触 CI/CD，我只是认为它主要是用于部署方面的一个工具。现在发现，它对于代码质量的改进也是意义巨大的。所有代码通用规范上的约束，静态分析，复杂度分析等都可以通过自动化工具来执行。
一方面，我们可以组合尽可能多的代码静态分析工具，来约束提交代码的错误，提供代码改进的建议，形成统一的代码风格。另一方面，最于 Code Review 来说，不再需要关注基本的代码风格以及基础部分，而只用关注于具体的业务以及代码架构层面的问题。&lt;/p&gt;
&lt;h3 id="静态分析"&gt;静态分析&lt;/h3&gt;
&lt;p&gt;Python 这样的代码，在多人合作的大型项目上，如果没有非常严格的代码约束，最终出来的项目时非常难以维护的。可能经常部署出来的代码连跑都跑不起来。相对来说，静态类型语言在这方面的优势是巨大的，编译器在编译代码阶段能发现大多数比较明显的问题，最终线上的问题一般都是需要人来参与分析的。&lt;/p&gt;
&lt;p&gt;代码的静态分析是一个非常古老但是重视程度不够的技术。静态类型语言的代码分析技术能够极大地减少代码中可能存在的 bug,并给出很多的建议。以 Golang 为例，目前已经有几十款静态分析工具。
而像&lt;a href="https://github.com/golangci/golangci-lint"&gt;golangci-lint&lt;/a&gt;这样的工具，可以将多种分析工具结合起来，在各个层面给出代码改进的建议。比如：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;代码的简化写法&lt;/li&gt;
&lt;li&gt;可能的 bug&lt;/li&gt;
&lt;li&gt;Dead Code&lt;/li&gt;
&lt;li&gt;未使用的或者被覆盖的变量&lt;/li&gt;
&lt;li&gt;&amp;hellip;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;SonarQube 其实是类似的产品，只不过是 Client/Server 的架构，提供了诸如复杂度分析，单元测试覆盖率等指标。良好的 UI，以及插件式的架构，与普通的 cli 工具结合起来之后，对于代码质量的提高是非常有益的。&lt;/p&gt;
&lt;p&gt;总之，工具能处理的事情越多，人的精力就更多的能去关注更上的层面和业务层面。&lt;/p&gt;
&lt;h3 id="code-review"&gt;Code Review&lt;/h3&gt;
&lt;p&gt;Code Review 虽然成为一个共识，但真正的效率确实难以保证的。莫名其妙的改动，形式化的 approve,现有工具的局限等等问题都造成了参与的人在这方面的低效率。所以总是需要有各种规范来指导人们如何进行 Code Review。一般来讲，我们可以将代码的改动拆分为三个问题&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Why? 为什么要做这个改动&lt;/li&gt;
&lt;li&gt;How? 怎么做这个改动&lt;/li&gt;
&lt;li&gt;What? 具体做了哪些改动。&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;这几个问题，工具能参与的只是&lt;code&gt;What&lt;/code&gt;的一部分。其他的部分都需要人来 review。一般的 Code Review 提交的模板也都要求提交 PR 的人尽量说清楚 Why,通过文档 link 或者文字等形式。具体的 How 以及 What，则需要具体的人来参与 review。&lt;/p&gt;</description></item><item><title>Google 的经验</title><link>https://hangyan.github.io/post/2019-04-14-google/</link><pubDate>Sun, 14 Apr 2019 11:30:07 +0800</pubDate><author>hang.yan@hotmail.com (涯余)</author><guid>https://hangyan.github.io/post/2019-04-14-google/</guid><description>&lt;p&gt;看了一篇讲谷歌公司内部的软件管理的&lt;a href="https://Arxiv.Org/Abs/1702.01715"&gt;论文&lt;/a&gt;，虽然对很多东西已经很熟悉了，但还是觉得有了一些新的启发。&lt;/p&gt;
&lt;p&gt;业内对 Google 其实大多数都是一种追随者的态度。单说最近这些年的几大热门产业，大数据由 Google 的三篇论文起始，云计算由 Kubernetes 引领热潮，
Alphago 在 AI 领域让人震撼。Google 比其他公司更早面临了很多技术发展的瓶颈之处，解决之后在某个时机将部分成果开源出来共享给业内。技术问题大家很容易采纳学习，但能解决这些问题的软件工程模式，
则不是那么容易学习的。&lt;/p&gt;
&lt;h2 id="single-repo"&gt;Single Repo&lt;/h2&gt;
&lt;p&gt;Google 在公开这种模式之后，大部分人的态度是震惊的。因为这跟大部分人的使用模式差别很大。不管是大公司小公司，不同功能的 Repo 对应不同的功能，非常便于维护，便于划清职责。Google 的单一 Repo 模式，尤其在其规模之上，初看起来是非常难以理解的。上 Tb 的仓库数据，每天上万次的 Commit,它是如何管理的呢?&lt;/p&gt;
&lt;p&gt;问题的答案自然是一套更为复杂的 CI/CD 系统，每一次的提交，自动化的构建、自动化的测试、自动化的 Review Check 等等，有了这些之后，代码的基本质量就有了保证，其他的就靠更为严格，精确的 Code Review 流程了。之所以大部分公司无法这样做，因为基础的 CI/CD 系统从来都不是一个公司在成长过程中优先考虑的问题，功能 -&amp;gt; 性能 -&amp;gt; Bug, 这些问题解决的差不多了，才有考虑其他的空闲。而往往此时，开发模式已经固定下来，没有了往 Single Repo 迁移的动力。&lt;/p&gt;
&lt;p&gt;另一方面，Single Repo 带来的优势初看起来也是比较模糊的。它更多的不是一个技术上的问题，而是一个管理模式,或者企业文化上的问题。&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;是否能允许员工查看几乎所有的源码 Repo&lt;/li&gt;
&lt;li&gt;如何在 Single Repo 中划分各个项目的职责边界&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;对 Google 来讲，去掉这个边界是必须的。他希望员工能够熟悉整个系统，不受限于自己所主要维护的&lt;code&gt;组件&lt;/code&gt;的束缚，保持一个开放的心态。每个人都有创造的天性，当他发现有一个&lt;code&gt;其他项目&lt;/code&gt;的问题或者优化他很想修复，或者有更好的解决方式，没有了项目的边界，他很自然地认为可以这样做也应该这样做。这种开放的模式保证了 Google 的所有项目能受惠于公司所有人的才智,也造就了 Google 在技术和商业上的成功。&lt;/p&gt;
&lt;h2 id="personal-time"&gt;Personal Time&lt;/h2&gt;
&lt;p&gt;这也是人人熟知，但几乎没有任何经常自称有 Google 背景的管理人员愿意尝试的模式。给员工留一些时间，让他做自己想做他任何想做的事。对于 Google 来说，有很多项目和改善都是来自于员工在这个时间的 Side Project。&lt;/p&gt;</description></item><item><title>Github 与编程语言</title><link>https://hangyan.github.io/post/2019-04-12-github-language/</link><pubDate>Fri, 12 Apr 2019 15:22:54 +0800</pubDate><author>hang.yan@hotmail.com (涯余)</author><guid>https://hangyan.github.io/post/2019-04-12-github-language/</guid><description>&lt;p&gt;一个语言的流行程度与多种因素相关,语法的简易性，package 的数量，性能，适用的场景等等。Perl 因为语法的&lt;code&gt;怪异&lt;/code&gt;而逐渐无人问津，&lt;code&gt;ROR&lt;/code&gt;因性能等问题也用的人越来越少。
一向处于主流地位的 C/CPP 在这几年也比不上 JavaScript 以及 Golang 的热度。在 Github 上，我们可以看到热门的项目中，JS 以及 Golang 等热门语言占据了相当瞩目的位置。
语言之间的较量从来就不是在单纯的语言层面本身，而是整个生态系统的对比。而不知不觉间，Github 也成了每个语言生态体系的一部分。&lt;/p&gt;
&lt;p&gt;当代的主流程序员中，大多数都有 C/CPP 的语言背景。但在大部分的工作选择上，python 与 Golang 的数量越来越多，也越来越占主流。究其原因，一方面是在语法层面上，采用了与 C 相似而更简单的表达方式。但更重要的是，从一开始，他们就考虑到了包管理系统的重要性，因为它是语言生态系统的&lt;code&gt;发动机&lt;/code&gt;，而 C/CPP 等语言到现在仍未有一个内建的实现。&lt;/p&gt;
&lt;p&gt;对 Python 而言，在 Github 流行之前，pip 已经非常成熟。这让他成为了一个在任何需求面前都是被优先选择的语言之一。http 请求、web 框架、爬虫、图片解析等等，只要你想要的任何功能，都可以在 pip 里找到已经有的实现。有了 Github 之后，python 的 package 的数量的扩充进一步加快。代码在 github,二进制包在 pip,文档在 readthedocs,这是一个非常完善而让人信任的体系。&lt;/p&gt;
&lt;p&gt;对于 Golang 来说，它就是生于 Github,流行于 Github 的。从一开始 docker/kubernetes 项目的流行，以及整个容器生态的成熟，给了 golang 一个良好的开端。go 内置的对于 github 上代码仓库的支持，即使有很多小问题，但总体来讲，这让 golang 以极快的速度建立起来了超越于 c/cpp 甚至能赶上 python/pip 的生态体系。在常规的开发场景以及业务需求上，golang 以及没有短板了。&lt;/p&gt;
&lt;p&gt;而反观 c/cpp，在 github 之前，假设我们想要去找一个 package，只能借助于搜索引擎。也许在某些奇怪的网站上，能找到一个实现方案。但是相比于 golang/github 模式，这样的方式有明显的缺陷:&lt;/p&gt;</description></item><item><title>Emacs is drugs</title><link>https://hangyan.github.io/post/2019-03-28-emacs-is-drugs/</link><pubDate>Thu, 28 Mar 2019 21:06:19 +0800</pubDate><author>hang.yan@hotmail.com (涯余)</author><guid>https://hangyan.github.io/post/2019-03-28-emacs-is-drugs/</guid><description>&lt;blockquote&gt;
&lt;p&gt;每个程序员都会遇到这一天，他要做一个决定，vim 还是 emacs,还是 IDE。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;近来一直主要用 Golang, 早已不再年轻的我自然是选择功能强大的 Goland, 日常工作无压力。即使没有免费的注册码了，我也毫不犹豫地买了正版。只是，它太慢了，太卡了，16GB 内存的 Mac 跑起来都不轻松。&lt;/p&gt;
&lt;p&gt;在无数次的痛苦的等待中，我终于决定换一个 Editor 试一试。Atom 也慢，Code 看起来都很不错，插件多，界面舒服，速度也快，但我面对它总有一种无所适从的感觉。我偶尔会用它来做些零碎的工作，但从来没法把它当作
一个主要的开发工具。&lt;/p&gt;
&lt;p&gt;这几天偶然翻起来一直装在电脑里确很久没有打开的 Emacs, 才明白了 Code 的问题在哪。&lt;/p&gt;
&lt;p&gt;Code 是一个优秀的 Editor, 但也仅此而以。我们用它来写代码，代码和 Editor 是两个东西。我们要学习怎么去使用这个软件，这个学习的过程和写代码是两套系统。它像 PS,像 Word，是一个精巧的软件，是编程的产物。&lt;/p&gt;
&lt;p&gt;而 Emacs 不同，它是一个 Editor, 但又和任何的 Editor 不同。它即是一个精巧的软件，也是一个操作系统，也是编程本身。&lt;/p&gt;
&lt;p&gt;首先，它基于 Elisp 编写，是 lisp 到今天少有的面向大众的软件产品。他的所有扩展也都是 lisp 代码。lisp 良好的可读性能让人很容易理解一个扩展是怎么写出来的，你可以如何修改它，照着它写一个新的。你在用它的时候，能明确地感觉到你在写的代码和编辑器不是分离的两个东西。它不是一个服务于你的黑盒子，而是一个对你透明的软体。你可以随时打开它看看他的内在，修改它，调整它，让他的形态更适用于你的需求。在很多人使用 emacs 的时候，会经常发现，你打开的文件列表经常会有 lisp 代码。好像他们属于一个项目似的。&lt;/p&gt;
&lt;p&gt;elisp 主要的功能都是面向文本编辑的，所以它比普通的 editor 有更多的概念: 缓冲区/ring buffer/minibuf/mode-line 等等。这些概念加起来，造就了最为精准丰富的文本处理和表现系统。无数在其他 editor 无法实现或者很难实现的功能，在这里都可以很容地用代码写出来。是的，就是用 elisp 代码。最终，是 elisp 代码组成了 emacs, 而对其他的 editor 来说，组成他们的是基本功能 + 扩展。&lt;/p&gt;
&lt;p&gt;Editor/IDE 的分化，是因为用常规的软件设计思路，无法作出一个满足以下功能的开发工具:&lt;/p&gt;</description></item><item><title>istio</title><link>https://hangyan.github.io/post/2019-03-25-istio/</link><pubDate>Mon, 25 Mar 2019 19:16:44 +0800</pubDate><author>hang.yan@hotmail.com (涯余)</author><guid>https://hangyan.github.io/post/2019-03-25-istio/</guid><description>&lt;p&gt;整个容器化浪潮诞生了三个胜利者,分别是 docker, kubernetes, istio。
一个额外的胜利者是 golang。&lt;/p&gt;
&lt;h2 id="docker"&gt;Docker&lt;/h2&gt;
&lt;p&gt;docker 的作用是：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;用标准语法描述出一个服务的静态/运行时环境，无关语言与操作系统&lt;/li&gt;
&lt;li&gt;资源隔离&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;被打死的是 lxc, 它有资源隔离的功能，但是缺点太明显：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;没有上面的 docker 提供的第一个功能&lt;/li&gt;
&lt;li&gt;架构不如 docker 的 cli/server 的简洁明了，易于学习&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;受威胁的是 VM&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;太慢了&lt;/li&gt;
&lt;li&gt;性能损耗大&lt;/li&gt;
&lt;li&gt;无法 API 化&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="kubernetes"&gt;Kubernetes&lt;/h2&gt;
&lt;p&gt;真正的 DCOS，核心优势:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;统一资源模型&lt;/li&gt;
&lt;li&gt;统一 API 模型 (引导业务 API 向其靠拢)&lt;/li&gt;
&lt;li&gt;Node 横向扩展&lt;/li&gt;
&lt;li&gt;插件化&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;被打死的是 Mesos/Marathon，缺点&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;两层架构的低效率 (仁慈独裁与低效民主)&lt;/li&gt;
&lt;li&gt;C++&lt;/li&gt;
&lt;li&gt;C++ 导致的难以 debug&lt;/li&gt;
&lt;li&gt;难以扩展以增加新功能&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;另一个被打死的是 swarm/compose, 缺点&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;架构不清晰&lt;/li&gt;
&lt;li&gt;自下而上地缓慢地堆功能&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;受威胁的是 YARN, 不如 kubernetes 通用性强&lt;/p&gt;
&lt;h2 id="istio"&gt;Istio&lt;/h2&gt;
&lt;p&gt;微服务相比于单体服务的一切问题都应该在这层解决, trace, 限流, metrics 等等&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;不需要修改业务代码&lt;/li&gt;
&lt;li&gt;比手工的实现更完善，功能更强&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;受影响的：微服务业务代码&lt;/p&gt;</description></item></channel></rss>