个人2015技术学习流水帐

个人2015技术学习流水帐

2015年立刻就要过去了,匆匆忙忙地又是一年。回头总结整理,发现这一年还挺充实的。在正常上班工做之余,学习到了很多新东西,不由感到很欣慰!一个多月前就开始写,终于赶在2016年来临以前写完了这篇文章…… 关于本文,尽管叫作流水帐,可是出于程序员条理性的“强迫症”,仍是进行系统分类,分类方法参照Thoughtworks技术雷达的Tecniques、Languages & Frameworks、Tools、Platforms,将其中的Tecniques改成理论。前端


1.理论

从今年开始逐渐的深刻学习计算机科学的理论,继续按照本身确立的学习路线一步一步走下去。linux

1.1 重拾CSAPP

算上今年此次应该已经“冲击”了两三次CSAPP了,此次的效果还算比较满意,几乎读完了厚厚的整本书,收获颇丰!从汇编语言、计算机组成原理、编译连接、系统编程,都算是系统的学习了一遍。具体学习笔记以下,其中(2)和(3)我的感受仍是整理的不错滴:程序员

1.2 算法 & Leetcode

今年读了几本算法书,但都是按照内容编排一块儿并行看的,都没有看完…… 同时还动手用C++刷了一些Leetcode的题目。C++虽然很是复杂,但作算法题实际上能够只用其中最核心的部分,当作加强版C,就能很快上手了。golang

这段学习中感受最大的收获就是:如何证实程序和算法的正确性,以及实现算法时,如何应对各类CornerCase和思惟漏洞。虽然理解和研究的都还不够深,可是的确开阔了思路,让我开始系统地思考如何用科学的方法写出正确的代码。具体请看《程序员修炼之路》专题以及几篇Leetcode解题笔记:算法

1.3 Netty网络编程

项目缘由接触到了Netty,的确很是强大。经过对Netty的使用,也整理了开发一个网络通讯中间件所需的方方面面的知识。但限于一直没有对TCP/IP等网络知识作系统学习,因此对Netty底层理解的还不够深,但愿将来能补充上这一部分。数据库

1.4 程序员的自我修养

编译连接一直是让我望而却步的领域。今年借着学习CSAAP之势,顺带给编译连接的学习开了个头。如今也能解决一些汇编及C语言的连接错误了,也算是有点成就。同时还试用了ANTLR,确实不错,之后要是写一些小东西就用它了。对这部分最深的感悟就是:原来从高级语言的多态到汇编的jmp是这么一回事啊!编程


2.工具

今年上手了很多新工具,感谢这些工具和做者,让我能更高效地专一于要作的事情。你会发现有时只是简简单单地用上了某一种工具,你的生活却发生了根本的改变。就像只是换成Sublime+Markdown写文章了,才发现原来本身每月能够写这么多文章,并且排版还比之前漂亮十倍!只是开始在豆瓣读书上看看别人推荐的书和记录本身读的书,一不留神,发现原来本身已经读了这么多好书。小程序

2.1 Linux Mint

多亏了Mint的多系统支持,让我终于在本身的电脑上安装了Linux,以前一直在Windows下用Cygwin和虚拟机将就着呢。用上了Linux后感受思惟都开放了,想用什么软件看什么源码都行,深深感觉到了软件世界里的自由!具体请看《Linux Mint 17一周使用体验》sublime-text

2.2 Sublime Text

在展转试用了各类文本编辑器后,终于不用再“漂泊”。Sublime Text几乎知足了个人各类须要,各类语言的开发、代码库管理以及下面要提到的文章编写。具体请看《Sublime Text 3下C/C++开发环境搭建》设计模式

2.3 Markdown

能够说是今年最重要的一项改进了!专心写做内容,减小样式和其余琐碎事情的干扰,配合上Sublime Text的编辑和Preview插件简直就是绝配!回头看看之前用Word写完粘贴到CSDN编辑器里的博文,版式简直“惨不忍睹”…… 如今有了Markdown, 写做效率和排版质量都有很大提高,md纯文本文件比doc小多了。再加上CSDN官方的大力支持,虽然渲染出来的效率不是特别漂亮,但彻底能够放心使用了(在CSDN推广Markdown的征文活动中还赢了一件文化衫:)。


3.语言和框架

3.1 Golang

GitHub上涌现了很多Golang编写的开源项目,让人不得不重视这门语言。趁着研究豌豆荚Codis的机会,也顺带学习了Golang的基础语法。有些地方的确很新颖,比直接用C要方便不少,可能会是一些后台程序员的福音。但有的地方真的仍是不习惯…

3.2 YCSB

今年在对一些新技术作预研时,大量使用了Yahoo的YCSB测试框架。一开始还不太了解,后来熟悉了内部源码后用起来感受驾轻就熟。负载的操做类型和比例、产生数据的分布等等均可以配置或扩展,功能很是齐全!具体请看《YCSB性能测试工具使用》

3.3 jgroups-raft

基于jgroups网络栈对RAFT一致性协议的实现,试用了一下仍是不错的!能够看作是ZooKeeper或Etcd中一致性算法层的对应,算法背后能够链接各类内容,从简单的数据增删改查到复杂的远程操做。这也是今年一个不小的收获,能够在jgroups-raft背后作出各类分布式的小东西,而不用依赖重型的ZooKeeper服务集群。具体请看《分布式一致性协议Raft原理与实例》以及本文最后对分布式开发的一点思考。

3.4 Thrift

Facebook的Thrift仍是挺好用的,很方便就能马上开始多组件以及跨语言的分布式开发,并且对枚举、集合类等数据类型支持的也不错。相比Google的Protobuf,免费提供了从序列化到RPC基础设施的一整套方案。但好像Thrift不提升更加高级的如Watcher等调用方式,同时注意最简单的TSimpleServer是单线程阻塞服务器,一个请求处理完才会接受下一个链接请求,只能用于测试。具体请看《Java程序员的现代RPC指南》

3.5 Cucumber

体验了一把BDD,也许用得不是那么的标准和地道,但的确在使用过程当中能有所启发。同时在Mock框架方面,还被PowerMock的强大震撼到了!private,static,final方法都能Mock,专治各类疑难杂症。并且还可直接配合Mockito或EasyMock,JUnit或TestNG等框架使用,没必要彻底从新学习一套新的API。


4.平台

4.1 In-Memory Computing

IMC是今年的主要研究方向,工做之余写了很多相关的文章,其中不少Redis的文章反响不错,看来Redis依旧是很是火的。个人Redis系列文章的访问连接以下,按内容由浅入深排序:

借着在IMC领域的学习机会,也深刻思考了一下分布式系统,具体请看本文后面对分布式开发的思考。在工做多年以后可以有机会进入一个不错的研究领域是幸运的,但愿将来能对IMC以及分布式系统理论有更深的研究。

4.2 虚拟化

今年抽了一些时间学习了火的不得了的Docker。结果Docker没有让我失望,的确是很好的东西!如今本身写一些东西也会用一下Docker,代码连同环境一块儿打包提交,在不一样地方开发的话简直方便极了!将来还想深刻学习一下Docker底层用了哪些技术。具体请看《Docker新手入门:基本用法》


5.Hacking

除了“一本正经”的学习路线外,固然少不了学习一些有趣的新东西来作调剂。

5.1 缓冲区炸弹

做为CS顶级名校CMU的教材,CSAPP里一些经典的实验都能在网上找到CMU的课件,感受最为有趣的实验当属缓冲区溢出攻击实验。它让你当一把黑客,尝试攻击一个有安全漏洞的小程序,当你攻击成功后看到CMU的祝贺语时,也许会激动得泪流满面,哈哈!

5.2 Linux 0.11内核

Linux内核也是我最为感兴趣的一个领域,尽管平时并不作嵌入式开发。今年从新捡起《Orange’s:一个操做系统的实现》,但并无彻底仿造,而是参考了Orange’s和Linux 0.11两个版本的内核,本身动手实现了一个简化版的内核,最后作到了进程调度器没有作完…… 以此为主题,学习了GitHub、GDB、Make、Docker等工具的使用,了解了一个现代化的汇编或C语言项目所需的各类技术。


6.思考和领悟

6.1 关于分布式开发

第一个关于分布式开发的思考就是:代码和数据。在传统软件开发中,代码和数据的含义再普通不过,代码对应应用程序,而数据呢就对应数据库。进入到分布式的世界后,看到眼花缭乱的各类后台中间件难免有些困惑,如下就简述一下个人主流中间件学习过程:

  • 负载均衡:总听人说虚IP或者VIP,等到真正本身安装配置过LVS才有了直观的印象,原来简单的负载均衡的有很多学问,还要看是在三层、四层仍是七层作分发。
  • Web服务器:这一部分是以前最欠缺的,对Apache和Nginx彻底不了解,后来一点点熟悉甚至还看了些Nginx源码,动手写了插件,才发现Nginx真是好啊!
  • 应用服务器:这一部分应该是传统Java开发人员最熟悉的了,从重量级的WebLogic到最流行的Tomcat甚至最轻量级的Jetty,每一个Java程序员都能说出几个本身用过的应用服务器。后来又接触到了PHP的FastCGI,进一步开阔了眼界。
  • 消息队列:ActiveMQ确定很多人都用过,很早就知道JMS。但消息队列的世界也不小,还有RabbitMQ等等高性能的消息中间件。
  • 缓存中间件:最熟悉的是Ehcache,后来很天然地就过渡到了Memcached和Redis,在几乎任何大型网站后台都有它们的身影。
  • 任务调度:异步执行的后台任务在大型网站中也是必不可少的。最先用的是最流行的Quartz。后来用过商业的Autosys,支持各类复杂的执行条件和Job嵌套依赖,很是强大但不知道内部是怎么个机制。再后来用上了TBSchedule还有Quartz的分布式版本,对分布式调度内部也有了必定了解。

中间件就是应用程序之间的软件胶水,它专一于某一功能,从而使开发者可以集中精力开发业务系统。尽管每款产品的设计初衷和适用场景有很大不一样,但咱们依然能够按照代码和数据的方式划分。分布式的代码其实就是Web服务、调度任务、MR任务等等,分布式的数据呢就是分布式存储、消息队列、分布式缓存等等。这样追本溯源的去想,也许能清晰很多。

第二个思考是关于分布式开发困难的根本缘由,状态管理绝对应该算一个。提到分布式系统的设计目标,咱们的大脑中会马上蹦出性能、伸缩性、可用性、扩展性、安全性等一些耳熟能详的词汇。但仔细思考会发现,其中多个目标都与状态有着千丝万缕的联系。高性能要考虑状态的并发控制,伸缩要考虑状态的一致性保证,高可用要考虑状态的备份和恢复。以开发去中心化(P2P)的分布式系统为例,关于状态管理有以下一些感悟:

  • 一致性保证:使用ZooKeeper做为完整的一致性方案,或者使用jgroups-raft半成品做为协议层的实现。
  • 状态转换:手动实现工做量较大,并且功能不全,可使用Squirrel等开源实现,支持外部状态转换、内部状态转换、事件定时触发、嵌套子状态等功能。
  • 中间状态:像jgroups-raft等一致性协议对通讯时间都要要求,超时会被认为是宕机了。因此若是协议层背后要作远程调用等操做,就要将状态拆分为中间状态和最终状态。从一致性协议层接收到请求后,启动异步任务后就直接返回,此时整个系统进入中间状态,Leader等待全部结点的异步响应。每一个结点的异步任务执行完成后,响应给Leader。当Leader收集全全部响应后,经过一致性协议层通知全部结点进入最终状态
  • 接口防重:分布式系统的组件常常会出现各类问题,因此对接口进行重试调用在所不免。所以接口要具备幂等性,即可以自动防重,对重复的输入数据进行检测。
  • 状态持久化:jgroups-raft提供了两种方式:WAL日志(Write-Ahead Logging)和快照。WAL保证执行真正的操做前先将操做日志成功写到持久化存储,而按期作快照能够压缩日志大小。
  • 状态恢复:重启时每一个结点上的jgroups-raft都会根据日志在本结点“重放”一遍日志操做,这对于异步中间状态是有问题的。因此能够预读日志和快照,提早将状态机恢复到正确的状态,这样作完的日志操做就会被状态机拒绝掉
  • 局部状态:经过一致性协议层发送和接收的消息对各个结点必须是同样的。因此若是每一个结点都须要本身的消息作入参,就经过一致性协议层发送全局的数据,每一个结点根据数据中的标志位提取出本身想要的数据

6.2 关于软件工程

今年只作了一个项目,在最近开发了一个无中心化结构的分布式中间件。因为中间了隔了一段时间没有开发具体的业务系统,因此从新上手作项目又对软件开发过程有了一些新的感悟,尤为是如何根据需求作出合理的设计,根据设计产生正确的代码。今年学习到的就是BDD(行为驱动开发),因而从新梳理一下我的对软件工程的各个步骤的理解:

  • 需求分析:需求的规格可谓多种多样,碰见过的有简略的BRD文档、有详细些的PRD文档,甚至还有直接在邮件里一段话描述的。我以为BDD中的Specification跟BRD文档对应的最准确,都是说明了功能特性、典型场景、以及最重要的对用户的价值。而不是PRD里详细的输入输出参数以及界面设计等内容。涉及角色有BA业务分析师、产品经理等。
  • 架构设计:针对系统及系统内的组件层次,涉及角色有架构师、开发骨干,还要配合项目经理对人员、任务和工时进行分配,作出合理的排期。
    • 技术选型:选用哪些中间件、是否有新技术要预研、技术风险点
    • 外部系统交互:涉及哪些外部系统,系统级别调用的时序图、开发人员的协调
    • 组件划分和交互:内部可划分哪些组件、如何通讯交互、总体的流程图
  • 详细设计:针对各个组件内的模块层次,涉及角色有架构师、开发骨干或者普通开发人员。这一层以前理解的比较模糊,在某些业务系统中可能被淡化,但在技术性较强的开发框架或中间件开发中却相当重要。
    • 模块划分和协做:模块之间的访问控制、每一个模块哪一个核心类作Facade或Mediator
    • 内部数据模型:独立的模型,与系统间通讯用的DTO解耦
    • 核心算法设计
    • 业务和技术术语表:影响到各类元素的命名,全部开发人员要统一
    • 编码规范和注释风格
  • 编码阶段:针对类和方法层次。主要是类的设计(类图、时序图、设计模式),在编码阶段可能会在完善TestCase的同时不断重构。因此这一部分不稳定,要避免过分设计。涉及角色有架构师、全部开发人员。

要想顺利开发出软件还离不开基础设施的搭建。因此在上述软件工程进行时,能够尽早地利用公司技术资产或我的经验,提早准备好基础设施:

  • 环境
    • 依赖管理:Maven/Gradle
    • 构建:Ant/Maven/Make
    • 版本控制:SVN/Git
    • CI持续集成:Jenkins
    • 统一IDE及插件,配合CI
  • 项目结构
    • 工程:脚手架生成或手写
    • 主要的包和文件夹:根据术语表命名,包括Java的、JS的、配置文件的等
    • 主要的类和文件
  • 代码
    • 语法加强:JDK 八、Apache Common、Google Guava
    • 依赖注入:Spring或更轻量的Guice
    • 配置参数和文件解析
    • 异常处理:断言、统一异常类、异常错误码、异常提示语(用于国际化)
    • 并发控制:JDK concurrent提供的Lock和CountdownLatch等都很好用
    • 线程池:一样JDK concurrent便可,Guava提供了加强
    • 事件总线:Guava
    • 日志:Slf4j配合具体实现,为项目定制统一的日志输出格式
    • 数学函数:加密解密算法等

我的理解,无论是用BDD仍是TDD,实践时脑海中都应该至少对关键技术选型、顶层架构设计和中层模块设计有了清晰的认识,而不是直接对着BRD就开始敲代码。此外,不用严格的遵照规则,有一套最适合本身的方法论也很好,你不习惯的实践规则可能确实不那么适用,也可能你的水平还不能理解和驾驭,没有关系慢慢来,不用硬着头皮全盘接受,最后搞得一点写代码的心情都没有了。

如今感受到软件开发过程就像是下棋,最重要的就是掌控力。若是说前期设计靠的是对业务和技术的理解和经验,那么真正开始着手去作时靠的就是对代码的掌控。在高速开发中,在不少地方均可以“点到即止”,按照总体的设计掌控住细节,让代码去到该去的地方,后期再逐渐重构作到完全。

6.3 技术债务

总结事后,发现了本身技术路线外的一些盲区,也能够说是欠下的“债务”:

  • Web和移动开发:一直很羡慕能直观展现本身成果的程序员,但就是对Web和移动开发提不起兴致,准备抽一段时间集中学习Bootstrap、AngularJS、React.js等流行的前端框架,像Codis那样用后台程序的Dashboard来练手
  • Java 8:曾经是那么喜欢Java,Java 五、6有一点儿新特性,都会认真学习半天。可Java 6以后好像就不那么热衷了,甚至Java 8中这么大的变化都无动于衷。什么缘由呢?我想一来是近两年业余时间都在深挖底层,体系结构、Linux、C等等;二是公司项目使用JDK版本升级缓慢,几乎一直停留在了JDK 6。
  • 方法论和应用框架:因为业务系统开发工做减小,因此没有特别关注研发的方法论和应用层的新框架。虽然作技术预研时一直在写原型和实验代码,编码量没有降低,但要警戒研究内容脱离实际以及代码质量降低的状况。
    • 方法论:无论是业务系统仍是原型开发,都是实践的机会,TDD、重构等都要不断练习领会
    • 应用框架:Spring Boot等Spring周边产品,还有最新版的SpringSide都是不错的从新学习机会
  • 业余练习项目:尽管大部分书籍阅读时都动手作了练习和读书笔记,但并无写一些对本身或别人很实用的小工具。之后仍是要多动手,写一些像《用Qt开发简单的浏览器(一)》里这样好玩又能对别人有帮助的小开源软件。

2015的总结就到这里了,2016还有更大的挑战!继续加油,珍惜每一分每一秒!

相关文章
相关标签/搜索