zoukankan      html  css  js  c++  java
  • 我的2015技术学习流水账

    我的2015技术学习流水账

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


    1.理论

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

    1.1 重拾CSAPP

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

    1.2 算法 & Leetcode

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

    这段学习中感觉最大的收获就是:如何证明程序和算法的正确性,以及实现算法时,如何应对各种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一周使用体验》

    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 8、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 5、6有一点儿新特性,都会认真学习半天。可Java 6之后好像就不那么热衷了,甚至Java 8中这么大的变化都无动于衷。什么原因呢?我想一来是近两年业余时间都在深挖底层,体系结构、Linux、C等等;二是公司项目使用JDK版本升级缓慢,几乎一直停留在了JDK 6。
    • 方法论和应用框架:由于业务系统开发工作减少,所以没有特别关注研发的方法论和应用层的新框架。虽然做技术预研时一直在写原型和实验代码,编码量没有下降,但要警惕研究内容脱离实际以及代码质量下降的情况。
      • 方法论:不管是业务系统还是原型开发,都是实践的机会,TDD、重构等都要不断练习领会
      • 应用框架:Spring Boot等Spring周边产品,还有最新版的SpringSide都是不错的重新学习机会
    • 业余练习项目:尽管大部分书籍阅读时都动手做了练习和读书笔记,但并没有写一些对自己或别人很实用的小工具。以后还是要多动手,写一些像《用Qt开发简单的浏览器(一)》里这样好玩又能对别人有帮助的小开源软件。

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

  • 相关阅读:
    Atitit fms Strait (海峡) lst 数据列表目录1. 4大洋 12. 著名的海大约40个,总共约55个海 13. 海区列表 23.1. 、波利尼西亚(Polynesia,
    Atitit trave islands list 旅游资源列表岛屿目录1. 东南亚著名的旅游岛屿 21.1. Cjkv 日韩 冲绳 琉球 济州岛 北海道 21.2. 中国 涠洲岛 南澳
    Atitit Major island groups and archipelagos 主要的岛群和群岛目录资料目录1. 岛群 波利尼西亚(Polynesia, 美拉尼西亚(Melanesia,
    Atitit glb 3tie city lst 三线城市列表 数据目录1. 全球范围内约90个城市 三线 12. 世界性三线城市全球共
    Atitit glb 1tie 2tie city lst 一二线城市列表数据约50个一线城市Alpha ++ 阿尔法++,,London 伦敦,,New York 纽约,,Alpha +
    Attit 现代编程语言重要特性目录第一章 类型系统 基本三大类型 2第一节 字符串 数字 bool 2第二节 推断局部变量 2第三节 动态类型 2第二章 可读性与开发效率 简单性 2
    Atitit 未来数据库新特性展望目录1. 统一的翻页 21.1. 2 Easy Top-N
    使用Chrome DevTools(console ande elements panel)进行xpath/css/js定位
    chrome -console妙用之定位xpath/js/css
    表达式树之构建Lambda表达式
  • 原文地址:https://www.cnblogs.com/xiaomaohai/p/6157585.html
Copyright © 2011-2022 走看看