高效研发实战训练营笔记Ⅰ

250 阅读10分钟

        科技探索的每一次进步,不只拓展着人类认知的疆界,也为经济社会发展带来了强大的动力,几次重大的科技革命带来机械化、电气化、自动化、信息化等多次产业革命,世界发展面貌和格局之深刻改变。
        DUT ~ 计算机科学与技术 ~ 殷祺云

internet.jpg

一、设计方法与实践介绍

(1)软件设计原则
        软件设计是为了使软件在长期范围内能够容易的进行变化
①高内聚
        内聚指的是一个软件内部间元素相关联的程度,高内聚追求的是紧密相关联的元素要放在一起。
②低耦合
        低耦合指的是单位之间尽可能少的关联与依赖。
        在高内聚低耦合之上有很多其他的原则:

image.png

(2)clean code
        我们写的代码应该能够在尽可能短的时间内被别人读懂,且代码排版整洁、逻辑清晰、扩展性好;命名规则需要做到自注释,使用有意义的循环迭代遍历,避免拼音缩写;同时,好的注释也是必不可少的,其中注释中包含版权信息、设计意图以及警示信息。
        在进行函数的书写时,要注意每个函数只做一件事且每个函数都是单一职责的,函数可以做如下分类。
  • 骨架函数:业务逻辑和算法在高层次上的抽象描述
  • 步骤函数:业务逻辑和算法的一些实现细节
        编码细节:
  1. 使用自然的比较顺序
  2. 简化逻辑层次,避免多层嵌套
  3. 在写三元表达式时不要出现复杂逻辑以及过长条件
  4. 控制变量作用域
(3)单元测试
        单元测试是最底层的测试,可以更早的发现问题,更容易集成以及有着更安全的代码修改,写好单元测试可以降低产品开发的成本。我们通常将单元测试视为文档工作。在之后对项目进行修改时,只需要查看单元测试即可。
        单元测试可实现自检,判断测试是否成功,不需要人为判定。同时,不能单独为测试创建特别的逻辑,更不能破坏原有代码的逻辑。
(4)重构
  1. 业务导向
  2. 小步快跑(主干、分支)
  3. 演进式设计
  4. 正交设计原则(分变化方向)
(5)配置化架构
        配置化架构是在领域建模的基础上表述业务,以配置组织架构元素,如数据、服务、组件等。
应用配置化架构
  1. 业务配置化改造
  2. 提高配置的开发效率
  3. 降低配置的维护成本

二、高效研发流程脚本

(1)用户故事地图

image.png

制作步骤:
  1. 一步一步写出你的故事
  2. 组织情节
  3. 探索替代故事
  4. 提取故事地图的主干
  5. 切分出能帮你达成特定目标的任务
(2)制定发布计划
制定计划:
  1. Big Story进行细化讨论
  2. 按照价值和重要程度进行版本规划
  3. 确定每个版本的期望达成目标
  4. 确定每个版本的内容
  5. 团队达成共识
(3)从发布计划到迭代计划
        在集中发布模式中,一次发布包含多次迭代;在迭代发布模式中,一次发布等于一次迭代。
对用户故事的拆分
        对用户故事的拆分要做到拆分出的故事尽量小,但是要适当,而并不是越小越好,避免出现一个迭代内无法完成的故事。
用户故事的优先级
        在原本的迭代计划基础上,会插入更高优先级的需求,替换低优先级的需求,把低优先等级的需求放入下一次的迭代中。
用户故事估算
        对用户故事工作量进行估算,根据团队的均值能力进行估算。
迭代计划制定
(4)从迭代计划到迭代的落地执行

三、研发工具链介绍

(1)iCafe需求管理
        iCafe 是一个专业、好用的互联网研发管理工具,内嵌产品规划、开发计划、执行跟踪、回顾分析、持续改进等众多互联网研发优秀实践,让研发管理轻松高效, 为企业提供基于敏捷开发方法的高效的任务协同工具。
(2)iCode
        iCode是一个代码管理工具。
        基于工作流。基于主干的工作流,整个团队维护一条主干分支,发布后恢复到一条主干的简明模式。基于分支的工作流,基于主干最新的代码,分支完成相应功能的开发、测试和发布,分支发布前,先同步主干的更新,上线后将分支合并回主干。
(3)iPipe
        iPipe是一个交付平台。可以让开发、测试与运维人员在这个工具中直观的看到产品的状态与质量情况。

image.png

四、持续交付方法与实践

(1)软件交付流程

image.png

(2)持续交付
        持续交付可以让代码快速安全的部署到生产环境中,自动化过程,提供了一套更为完善的解决传统软件开发流程的方案。可以有效缩短提交代码和部署上线的时间,可以自动快速的提供反馈与修复缺陷,持续交付课让软件在整个生命周期内都处于可部署的状态,简化部署步骤。
(3)敏捷开发与Devops

image.png

(4)持续交付的基础
        持续集成和持续部署是持续交付的基础。持续集成包括代码编译,近代检查与单元测试任务。运用虚拟机技术与容器技术可实现快速将项目进行部署。
(5)持续部署
        应用容器技术进行持续部署。

image.png

        部署层次有效分明。

image.png

        有效解决了第三方依赖库重构问题,将所有需要的内容全部打包进行复制与部署。其中,包括蓝绿部署(通过域名解析方式切换版本)与金丝雀部署(少量用户发现问题,出现问题即即使处理并重新发布)。
(6)流程控制

image.png

五、代码的艺术

(1)黑盒与白盒机制

image.png

(2)系统设计注意要点
        首先,系统架构定义了系统的结构、行为与更多的视图,要素包括系统要完成的功能、系统如何组成以及功能在这些组成部分之间如何划分。其次,包括资源的限制,有计算的限制,存储的限制以及IO/网络的限制。需求是系统设计决策的来源,且清楚接口的重要性,接口主要包括模块对外的函数接口、平台对外的API、系统见通信的协议以及系统间存在依赖的数据。

六、Mini-spider实践

(1)多线程编程
        正确案例(将添加和判断写进一个函数):
class UrlTable(object):
    def init (self):
        self.lock=threading.Lock() 
        self.table=()
        
        def add(self, url):
        "add url to table" 
        ret_val ='OK'
        self.lock.acquire() 
        if url in self.table:
            ret val ='ERROR' 
        else:
            selftable[url]=True 
         self.lock.release() 
        return ret_val

        错误案例(分别编写添加和判断函数):

class UrlTable(object):
    def init (self):
        self.lock=threading.Lock() 
        self.table=()
    def add(self,url):
        self.lock.acquire()
        self.table[url]=True 
        self.lock.release()
        
    def is_in_table(self, url):
        self.lock.acquire()
        ret_val=url in self.table 
        self.lock.release() 
        return ret_val

        同时,模块划分和逻辑的复杂程度无关,即使是逻辑简单的代码,如果没有做好模块划分,也会变得难于维护。

(2)程序优雅推出
- task_down()机制
- join()机制
(3)爬虫主逻辑代码
  1. 从队列中拿到任务
  2. 读取内容
  3. 存储数据
  4. 检查数据深度
  5. 如果数据深度不足,继续解析,并且放到队列中
  6. 结束任务
def zun(self):
    while self.active:
        # get url and depth from input queue
        url, depth=self.input queue.get()
        
       # read data from given url 
       data=webpage get(url) 
       if data is None:
            self.input queuetask done()
            continue
            
        # save data to file
        url filesave(self.output directory,ur1,data)
        
        # check depth
        if depth<selfmax depth:
            # get new urls from data
        new urls =html parseurl extract(data)
        
        # add new url to input queue 
        for new url in new urls:
            if selfurl table.add(newurl)=='OK':
                self.input queue put((new url,depth+1))
        # task done
        self.input queue.task done()

七、代码检查规则背景和总体介绍

(1)代码检查场景&工具

image.png

(2)代码检查覆盖范围
  1. 编码规范(较快)
  2. 代码缺陷(较慢)
  3. 开源框架引用安全检查
  4. 可维护性
(3)规则等级处理
  1. Error
  2. Warning
  3. Advice

八、python语言案例详解

(1)代码风格规范
  1. 每行字符<=120字
  2. 函数长度<=120行
  3. 不能用分号做结尾
  4. 一行只能写一条语句
  5. 尽量避免冗余的括号
  6. 禁止使用Tab,统一使用4个空格进行缩进
  7. 类或全局函数隔两个空行,类方法隔一个空行
  8. 括号内不加空格,参数列表左括号前无空格,都好分号冒号前无空格,后一个空格
  9. 二元运算符前后各一个空格
  10. 参数默认值等号前后无空格
  11. 文件声明中注释中应有版权声明、功能用途介绍、修改人及联系方式
  12. docstring必须用三个双引号,对外接口必须使用docstring
  13. docstring必须包括功能简介,参数和返回值,如果可能抛出异常,必须特别注明
(2)代码引用规范
  1. 在导入库后再调用类或函数
  2. 每行只导入一个库,按标准库、第三方库、应用程序自有库的顺序导入
(3)代码定义规范
  1. 局部变量全小写字母,全局变量卸载文件头部,常量使用全大写字母
  2. 函数返回值小于等于三个
  3. 在导入库后再调用类或函数
  4. 类使用首字母大写的驼峰命名法
  5. _protected成员 __private成员
  6. 如果一个类无基类,必须继承自ovject类
(4)异常处理规范
  1. 禁止使用双参数形式或字符串形式的语法抛出异常
  2. 自定义异常名称为Error
  3. 除非重新抛出异常,禁止使用except语句捕获所有异常
  4. 使用as语法,不能使用逗号语法
(5)python惯例
  1. 让模块既可以被导入又可以被执行
  2. in运算符使用
  3. 不适用临时变量交换两个值
  4. 用序列构建字符串

九、个人感悟

        如果人生就像编程,那么指针能寻找到绝对地址,心情就能带我们去到想要去的地方;如果人生就像编程,输入总是能得到相应输出,那真心换来的一定也是真心;如果人生就像编程,我就是那个简单的程序员,用键盘敲出想要的生活。加油,未来的工程师!

image.png