1. 快速看完整部教材,列出你仍然不懂的5到10个问题,发布在你的我的博客上。git
2.1.2 “单元测试必须由最熟悉代码的人(程序的做者)来写
程序员
并不认同这里这个“必须”。在我自身实习的经验中,通常都会采用开发和测试分离的模式,即你们在构思设计的时候约定好公共的接口模式,而后并行开始开发和测试程序的构建,你们公共的部分就是统一的接口,测试人员不须要知道内部的实现细节,并且根据接口来构造一系列的强覆盖逻辑,保证接口对正常功能和异常功能都能正确处理。这样作一提升了效率,二是测试不会被开发的设计思路所束缚,彻底从一个外部的角度来思考,这样设计测试样例通常会更全面。
不过写到此处想到另外一个问题:彻底不了解内部细节,那可能会出现覆盖不到接口内部分逻辑的状况,有可能有隐藏的分支并无覆盖到,留下了隐患。还有就是接口内部一些可能产生的反作用也不能及时发现,这的确也是存在的问题。github
10.3 规格说明书shell
关于规格说明书我有一个一直以来的疑问,就是规格说明书-注释-代码之间的联系和配合,严格来讲,他们之间有不少重复的内容,好的代码风格自己就有必定的说明做用,注释是程序员最好的助手,文档又是真正开发不可或缺的一部分,如何构建一种最合适的模式,使得每一个层次都有合理的功能而有不冗余呢。数据库
16.1.5 迷思之五: 要成为领域的专家,才能创新浏览器
在目前的环境下,仅仅成为领域的专家,彷佛并不太足够了。在各行各业都高度专业化的今天,各个行业领域之间的壁垒也愈来愈重,不少领域的专家每每会不知不觉地局限于本身的领域,因此说,领域专家只是一个创新的必要条件。那么在如今的环境下,交叉学科彷佛正在成为新兴的创新爆发点,借鉴其余学科的思路的观点,结合本领域的知识,将会产生更多的可能。深度学习中的不少优秀设计即是来源于神经科学,好比神经元的基本模型,还有生物学,好比借鉴人的视网膜细胞来组织新的卷积层,结合大脑的计算模式来构建新的高度并行化的神经网络芯片。安全
2.请问 “软件” 和 “软件工程” 这些词汇是如何出现的 - 什么时候、何地、何人?服务器
软件: 这个词是在1958年,由John Tukey在其论文"The Teaching of Concrete Mathematics"中提出的网络
Tukey's 1958 paper "The Teaching of Concrete Mathematics"[10] contained the earliest known usage of the term "software"
多线程
软件工程: 这个词是在1969 年(阿波罗 11 号期间),由Margaret Hamiltion提出的
Q:你是在这段期间发明了“软件工程”一词吗?
A:软件在这个计划的初期还被看成初初学步的孩子通常对待,彻底不像其余工程学科;例如像硬件工程那样的受到重视,并且在你们的眼光中他就像是艺术、魔术通常,而不是一门科学。
我一直以来坚信这项发明流着艺术与科学的血液,虽然当时不多人是这么想。所以,我致力于为软件以及那些发明者争取应有的正统性与尊重,因此我开始使用“软件工程”这样的字眼来将之与硬件还有其余工程学类作出区别。
3.你们知道了软件和软件工程的起源,请问软件工程发展的过程当中有什么你以为有趣的冷知识和故事?
- 丰田的一万多个全局变量的故事。28万行代码中有1万多个全局变量,简直就是bug培养基。
其中还有人专门作过测试。
软件设计的基本要求是模块尽可能简单化,由于这样能够一来更易于阅读二来更易于维护,但丰田的工程师显然没有遵循这原则。Barr使用一种工具自动根据代码的可能分支数量评估函数的复杂度,结果是丰田的软件中至少有67条函数复杂度超过50,意味着运行这个函数可能出现超过50种不一样的执行结果,属于“非可测”级别。由于为了测试这50个不一样的结果,必须准备至少50条不一样的测试用例以及相应的文档,在生产环境中是根本不现实的。而在这67条函数中还有12条复杂度超过100,达到“非可维护”级别,意味着一旦发现缺陷(Bug)也没法修复,由于实在太复杂,修复缺陷的过程当中会产生新的缺陷。其中最复杂的一条函数有超过1300行代码,146个可能执行路径——正好用于根据各传感器数值计算节气门开关角度。
4.上网调查一下目前流行的源程序版本管理软件和项目管理软件都有哪些, 各有什么优缺点?
下表是2018年源代码托管软件的用户数和项目数,出自https://en.wikipedia.org/wiki/Comparison_of_source-code-hosting_facilities#Popularity

从中能够看到通常最熟悉的git(github,gitlab)仍是占据了最主要的部分,下面是几大主流软件的优缺点对比。
Git
优势:
- 免费且开源。
- Git支持分支功能(branch)。若是开发一个新的产品功能,能够创建一个分支,对这个分支的进行修改,而不至于会影响到主支上的代码。或者是fork。
- 可拿Git作备份系统,或者同步多台机器的文档,很方便。
- 支持离线工做,有本地仓库和远程仓库。本地提交能够稍后提交到服务器上,不用和集中的代码管理服务器交互。 只有最终完成的版本才须要向一个中心的集中的代码管理服务器提交。
- Git 提交都是原子的,且是整个项目范围的。
- Git 中的每一个工做树都包含一个具备完整项目历史的仓库,还原和版本回退很是方便。
- P.S. 推广一下本身写的git简易教程 https://github.com/OO-guide-2019/git-guide
缺点:
- 学习成本大。由浅入深的过分很漫长,须要大量时间的投入。(有合适的教程其实很快)
- Git版本库须要频繁的手动维护。
SVN
优势:
- 对目录的组织的管理更加方便。SVN不光对文件作版本跟踪,也会对目录作版本跟踪。所以能够根据项目的须要,对目录结构随时进行修改,能够把现有的目录移动到新的地方。
- 保证提交操做的完整性。SVN对提交操做的处理方式相似数据库的事务处理,要么所有成功,要么所有无效,保证了原子性。
- SVN容许一个文件有任意多的可命名属性,功能十分彻底。
缺点:
- 不能离线工做。全部的版本信息都放在服务器上。若是脱离了服务器,开发者基本上能够说是没法工做的。
- 提交、更新、浏览历史的速度慢。耗费CPU资源。
- 代码不能及时提交。强迫使用者即时处理冲突,而后才能提交。
- 不能恢复到历史版本。SVN记录了单个文件的历史版本,但没有记录全局版本,不能恢复到上次的状态。这一点是很致命的。
Microsoft TFS
优势:
- 任务版上能将需求、项目进度尽收眼底,集成了项目管理、版本控制、BUG 跟踪。
- 能有效实现 SCRUM,能与 VS 无缝接合。
缺点:
- 搭建、维护tfs比较复杂,硬件要求也比较高。
- 整个系统是用 asp 实现的,用浏览器访问较慢。
Mercurial
优势:
- 学习门槛较低。总体上看,hg须要掌握的命令要比git少不少。
- 能够一键彻底恢复到某一个历史版本。
- 封装好。相比git,hg不多暴露一些实现内的细节。
- 照顾 svn 的迁移用户。hg 的不少命令是迁移自 svn 命令的,习惯 svn 命令的团队,几乎能够零成本的切换到 hg。
- hg的版本库不须要维护。
缺点:
- 分支管理不灵活。Mercurial的branch管理和Git相比不是很方便。不适合大型团队使用。
5.关于版本控制软件的我的理解
目的:版本控制软件的目的主要是两点,版本记录控制,团队协做
从使用者角度来看,一款好的版本控制软件须要知足以下的需求:
- 简单易学易上手,这一点须要创建在软件自己指令的设计,与操做系统shell命令的结合,详细但又不啰嗦的教程,以及面向真正开发需求的实践练习。就拿git来讲,不少入门者以为痛苦的一个重要因素就是其对基本shell命令本就不太熟悉,对于命令行式开发和运维相关熟练度远远不够,而同时目前的教程更像是一部工具说明书,即以各个命令自己为基本单元,而不是git工做的整个流程,因此就会带来一种割裂感,此外,没有真正意义上的对于整个git协同开发的练习,单单看教程记忆天然不能熟练掌握(因此也就有那么多人吐槽git学起来难)
- 支持强大的版本控制操做,对我的来讲,主要的需求有两点,一是不一样版本路线的开发,即多个branch的开发,每一个branch负责一种设计思路,二是可以方便的回退到某个版本,换句话说就是强大的存档读档功能,而对团队来讲,协做就是最重要的点,以git为例,在团队开发时以fork为主,每一个人的修改要想整合进来必须通过pull request,这样的机制就使得每一个人能够各司其职,减小了形成冲突的可能性。就算是在一个分支中出现了merge时的冲突,git也提供了良好的冲突处理机制,更有git rebase这种高级操做,使得处理起来很是方便。
- 支持网页查看,对于阅读源代码和配置文件,不必定须要笨重地每次都clone到本地仓库一份,像github和gitlab提供的网页界面阅读代码,使得这个过程变的很是轻便。
- 对于大文件的管理,在开发大型项目的时候,咱们可能会生成一些几十甚至几百MB级别以上的文件,那么像基本的github就不支持这样的大文件传输,但有的时候咱们确实须要将其托管在远程仓库进行管理,这时,像git-lfs这样的工具即可以提供很是温馨的体验(强烈推荐)
从版本控制软件设计者来看,其须要考虑的因素以下:
- 对功能的封装,解耦合(抱歉我是git吹),考虑一个项目内,可能有正在编辑的文件,可能有已经编辑好的文件,可能有远程服务器上的文件,若是一视同仁,其实会很是混乱,可是像git这样的设计,工做区,暂存区,本地仓库,远程仓库,将复杂的事情解耦成为几个不一样的阶段,就很是清楚。
- 面向安全的封装,对于内部的具体实现,是否暴露给用户,这一点须要考虑,暴露给用户的话能够支持更多的开发者,可是也带来了必定程度上的安全风险
- CPU等本地硬件资源的消耗和传输速度保证,好比你们均可以发现,git clone/pull/push都是使用多线程来操做的,如何利用好本地硬件资源且不带来过分的负担,也须要认真考虑
- 本地和服务器的关系,通常来讲咱们但愿本地能够直接工做,断网时也能够本地版本控制,另外一方面,服务器上也能够进行修改,不依赖本地。不过如今网络传输基本不会出现什么问题。
- 图形化界面,多是由于基本使用命令行的缘故,因此git的GUI十分丑陋。。。
- 数据的分析和统计,在github和gitlab有不少对于项目开发状况的可视化数据统计,这对于一个团队的开发也是很棒的信息。