Java教程

程序员进阶攻略笔记01-10

本文主要是介绍程序员进阶攻略笔记01-10,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

有人有天赋,有人凭兴趣,有人看前景。
在人生的不同阶段里,我都喜欢做“复盘”,一方面审视过去的自己,另外一方面思索未来的方向。
选择开发语言:对一门语言掌握到通透之后,再学习其他语言才可能触类旁通。
开发平台,它包括一种编程语言、附带的平台生态及相关的技术。
    与语言平台关联的还有其技术生态以及各种技术框架的繁荣程度。
算法【动态】
数据结构【静态】
    数组 Array
    链表 Linked List
    队列 Queues
    堆栈 Stacks
    散列 Hashes
    集合 Sets
    树 Trees
    图 Graphs
    
数据存储系统有下面三类:
    SQL 关系型数据库(如:MySQL、Oracle)
    NoSQL 非关系型数据库(如:HBase、MongoDB)
    Cache 缓存(如:Redis、Memcached)
    
用好各类数据存储,那么按了解的深度需要依次知道如下几点:
    如何用?在什么场景下,用什么数据存储的什么特性?
    它们是如何工作的?
    如何优化你的使用方式?
    它们的量化指标,并能够进行量化分析?
测试思维:
    测试驱动开发(TDD)
工程规范
    代码结构
    代码风格
    
    目标:更清晰、易读的代码,一致性的风格
开发流程
    了解敏捷开发方法论
    了解团队演进形成的开发流程规范【先了解,再优化】
    
源码管理
    CVS -> SVN -> Git[至少要了解 Git,并用好它]
    
    对源码进行管理的最基本诉求有以下三点:
        并行:以支持多特性,多人的并行开发
        协作:以协调多人对同一份代码的编写
        版本:以支持不同历史的代码版本切换

做优秀的程序员,首先要有优秀的笔记本【利剑】
    职场的第一个台阶就是形成独立性:独立承担职责的能力。
    你问出什么样的问题,就可以看出你对这个问题做出了怎样的探索与思考,以及让你困惑的矛盾点在哪里。有些人就喜欢不假思索地问些 Google 都能够轻易回答的问题,形成路径依赖,虽然最终搞定了问题,但换得的评价却不会高,特别要省之戒之。
    遇到问题:先想一想,找到问题方向->查资料->写出来(一方面是梳理,一方面是让帮你解决问题的人,了解你的思路。)->询问(要点在于,态度谦卑,要节约对方时间)->总结问题和自己的思考(方便复盘和共享问题库) 

架构与实现:
    把一种想法、一个需求变成代码,这叫 “实现”
        中间有一个过程称为设计,设计中有个特别的阶段叫 “架构”:软件系统的结构与行为设计。
        实现就是围绕这种已定义的宏观结构去开发程序的过程。
        
    架构是一种结构设计,但它同时可能存在于不同的维度和层次上:
        高维度:指系统、子系统或服务之间的切分与交互结构。
        中维度:指系统、服务内部模块的切分与交互结构。
        低维度:指模块组成的代码结构、数据结构、库表结构等。
    架构师的共同点包括下面4个方面:
        确定边界:划定问题域、系统域的边界。
        切分协作:切分系统和服务,目的是建立分工与协作,并行以获得效率。
        连接交互:在切分的各部分之间建立连接交互的原则和机制。
        组装整合:把切分的各部分按预期定义的规则和方法组装整合为一体,完成系统目标。

    架构师的交付成果是一整套决策流,文档仅仅是交付载体
        选型评估;程序设计;执行效率;稳定健壮;维护运维;集成部署。
            选择一些合适的库或框架,再从中找到需要的API。
            确定了合适的选型后,需要从逻辑、控制与数据这三个方面进一步考虑程序设计:
                逻辑,即功能的业务逻辑,反映了真实业务场景流程与分支,包含大量业务领域知识。
                控制,即考虑业务逻辑的执行策略,哪些可以并行执行,哪些可以异步执行,哪些地方又必须同步等待结果并串行执行?
                数据,包括数据结构、数据状态变化和存取方式。
            开始编码实现时,你进一步要考虑代码的执行效率,需要运行多长时间?要求的最大等待响应时间能否满足?并发吞吐能力如何?运行的稳定性和各种边界条件、异常处理是否考虑到了?上线后,出现 Bug,相关的监控、日志能否帮助快速定位?是否有动态线上配置和变更能力,可以快速修复一些问题?新上线版本时,你的程序是否考虑了兼容老版本的问题等?

            最后你开发的代码是以什么形态交付?如果是提供一个程序库,则需要考虑相关的依赖复杂度和使用便利性,以及未来的升级管理。如果是提供服务,就需要考虑服务调用的管理、服务使用的统计监控,以及相关的 SLA 服务保障承诺
        熵:系统的混乱程度====架构的核心关注点“熵”,实现的核心关注点“简”
            一开始清晰整洁的架构与实现随着需求的变化而不断变得浑浊、混乱。也即系统的“熵”在不断增高。
            软件系统的“熵”有个临界值,当达到并超过临界值后,软件系统必须重写或对系统做架构升级。
        断裂带:    
            架构与实现之间存在的一条鸿沟,这是它们之间的断裂带。
            架构师如何准确地传递架构决策?而开发实施的效果又如何能与架构决策保持一致?
                定期对系统的状态做快照【定期去检视系统的状态】,而非去把握每一次大大小小的变化
                在做快照的过程中我会发现很多的细节,也许和我当初想的完全不一样
                在我发现和掌握的所有细节中,我需要做一个判断,哪些细节上的问题会是战略性的,而我有限的时间和注意力,必须放在这样的战略性细节上。
                其他大量的实现细节也许和我想的不同,但只要没有越出顶层宏观结构定义的边界即可。
                
                关注与把控边界,并确认领地中的战略要地:架构与实现的鸿沟上选择合适的地方建设桥梁,建设桥梁的地方必是战略要地。
    总结:架构是关注系统结构与行为的决策流,而实现是围绕架构的程序开发过程;架构核心关注系统的“熵”,而实现则顺应“简”;架构注重把控系统的边界与 “要塞”,而实现则去建立 “领地”;所有架构的可实现性都是等效的,但实现的成本、效率绝不会相同。
模式与框架
    框架和模式的共同点在于,它们都提供了一种问题的重用解决方案。其中,框架是代码复用,模式是设计复用。
    
    设计模式【联系武功的内功】
        每个模式都描述了一个在我们的环境中不断出现的问题,然后描述了该问题的解决方案的核心,通过这种方式,我们可以无数次地重用那些已有的成功的解决方案,无须再重复相同的工作。
    框架:
        框架就像是给程序员定制的开发脚手架。一个框架是一个可复用的设计组件,它统一定义了高层设计和接口,使得从框架构建应用程序变得非常容易。因此,框架可以算是打开“快速开发”与“代码复用”这两扇门的钥匙。
        框架会用只是第一步,原理一定要明白,不懂就要去看文档和代码,框架搞透了,设计模式的应用自然就明了了。框架的实现中大量应用了设计模式
多维与视图==机械设计的三视图引申
    UML(Unified Modeling Language): 统一建模语言,一种涵盖软件设计开发所有阶段的模型化与可视化支持的建模语言。
    1、组成视图===理清系统功能。
        组成视图,表达了系统由哪些子系统、服务、组件部分构成。
            按功能划分,用于了解系统结构与分工
            功能单一化:每个模块负责且只负责一个功能
            功能正交化:每个功能由且仅有一个模块提供
    2、交互视图==用以分析服务间依赖,看看是否拆分错。
        交互视图,表达了系统或服务与外部系统或服务的协作关系,也即:依赖与被依赖。
            如果我们把目光聚焦在一个服务上,以其为中心的表达方式,就体现了该服务的依赖协作关系。
    3、部署视图===用以关注服务,中间件,使用端之间的网络传输,确定IO瓶颈
        部署视图,表达系统的部署结构与环境。
        
    4、流程视图
        流程视图,表达系统内部实现的功能和控制逻辑流程【UML 的序列图】。
        重点在于要把逻辑表达清楚。
        逻辑流程一般分两种:业务与控制。
            有些系统业务逻辑很复杂,而有些系统业务逻辑不复杂但请求并发很高,导致对性能、安全与稳定的要求高,所以控制逻辑就复杂了
    5、状态视图
        状态视图,表达系统内部管理了哪些状态以及状态的变迁转移路径。
代码与分类
    按代码的作用,大概都可以分为如下三类:
        功能
        控制
        运维
    1、功能
        功能代码,是实现需求的业务逻辑代码,反映真实业务场景,包含大量领域知识。
            把功能代码写好,最难的不是编码本身,而是搞清楚功能背后的需求并得到正确的理解(用户的心理诉求有可能表达错了,也有可能被理解错)。
            程序员需要对被要求开发的功能进行更深入的思考,努力去理解业务及其背后用户的真实需求,才是写好功能代码的基本能力。
            当功能实现了并非已经完成了开发,这仅仅是第一步。
    2、控制:功能代码满足了服务的功能需求,而控制代码则保障了服务的稳定可靠。
        控制代码,是控制业务功能逻辑代码执行的代码,即业务逻辑的执行策略。
        通用控制型代码由各种开源框架来提供,比如微服务架构模式下关注的控制领域,包括:通信、负载、限流、隔离、熔断、异步、并行、重试、降级。
        “服务网格(Service Mesh)” 架构模式:将控制和功能分离做到了极致,控制和功能代码甚至运行在了不同的进程中。
        
    3、运维
        运维代码,就是方便程序检测、诊断和运行时处理的代码。它们的存在,才让系统具备了真正工业级的可运维性。
        检测诊断代码的终极目标:让程序系统完成运行时的自检诊断。这是完美的理想状态,却很难在现实中完全做到。
            退而求其次,至少在系统异常时可以具备主动运行状态汇报能力,由开发和运维人员来完成诊断分析,这也是我们常见的各类系统或终端软件提供的机制。
        最常见的检测诊断性代码:日志
        运维类代码的另一种类,是方便在运行时,对系统行为进行改变的代码。通常这一类代码提供方便运维操作的 API 服务,甚至还会有专门针对运维提供的服务和应用,例如:备份与恢复数据、实时流量调度等。
        
    功能代码易变化,控制代码固复杂,运维代码偏繁琐
    优雅就是边界与距离
    
    
粗放与精益:编程的两种思路与方式 
    写得粗放,写得多
    写得精益,写得好
    
    不要盲目追求理想上的 “好与精益” ,而要通过“多与粗放”完成,通过做得多,不断尝试,快速迭代 ,最后取得到更好的结果【反馈与迭代改进在发挥关键作用】。
        核心在“迭代”,迭代的好处就是试错和反馈。
            试错,是快速找到自己根本没有意识到的错误,看一遍和做一遍差距太大
            反馈,你会在做不停做中得到反馈,并迭代 
    编程,其实一开始哪有什么完美,只有不断变得更好。
    好不是完美,好是一个过程,一个不断精益化的过程。
炫技与克制
    要真正提高代码水平,需要多读代码。就像写作,写得再多,不多读书,思维和认知水平其实是很难提高的。
        我读源码的方式是,发现这个框架实现了某个能力,我自己想不出怎么做,就会去看看别人怎么实现的。带着问题去读,可能有针对性一些
    好代码中有一种味道和品质:克制。
    炫技:炫技是指,为了展示自己的水平,人为的推高自己代码的复杂度和理解难度。(损人不利己) 
        技术人就容易倾向性地关注项目或工程中的技术含量与难点,项目中的炫技,未必能加分,还有可能导致减分,比如其维护与理解成本变高了。
        除了增加不必要的复杂性外,炫技的代码,也可能更容易出 Bug。
        见猎心喜,手上拿个锤子看到哪里都是钉子。
        炫技是因为你想表达得不一样,就像平常说话,你要故意说得引经据典去彰显自己有文化,但其实效果不一定佳,因为我们更需要的是平实、易懂的表达。炫技是因为你想表达得不一样,就像平常说话,你要故意说得引经据典去彰显自己有文化,但其实效果不一定佳,因为我们更需要的是平实、易懂的表达。
    克制:克制俗称低调有内涵。为了程序的稳定,以及可读性,人为的降低代码的复杂度和理解难度(损己利人) 
        对于新技术,即使从我知道、我了解到我熟悉、我深谙,这时也还需要克制,要等待合适的时机。
        新技术的应用,也需要等待一个合适的出击时刻,也许是应用在新的服务上,也许是下一次架构升级。
        不克制的一种形态是容易做出臆想的、通用化的假设,而且我们还会给这种假设安一个非常正当的理由:扩展性。
            扩展性很重要,但扩展性也应当来自真实的需求,而非假设将来的某天可能需要扩展,因为扩展性的反面就是带来设计抽象的复杂性以及代码量的增加。
            
        克制的编程方式:
            克制的编码,是每次写完代码,需要去反思和提炼它,代码应当是直观的,可读的,高效的。
            克制的代码,是即使站在远远的地方去看屏幕上的代码,甚至看不清代码的具体内容时,也能感受到它的结构是干净整齐的,而非 “意大利面条” 似的混乱无序。
            克制的重构,是每次看到 “坏” 代码不是立刻就动手去改,而是先标记圈定它,然后通读代码,掌握全局,重新设计,最后再等待一个合适的时机,来一气呵成地完成重构。
            
    不炫技、不追新,且恰到好处地满足需要,是一种平实、清晰、易懂的表达。
    面对新技术,基本态度希望是积极拥抱,但在实际工作中要有克制【业务要稳定,技术可以渐变,不要突变】。 
    

这篇关于程序员进阶攻略笔记01-10的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!