• 《构建之法》1~3章学习记录


    《构建之法》邹欣pdf:https://pan.baidu.com/s/1Z7cTtVBqxbVcU3vsyynysQ 提取码:dusr

    章1.概论

    软件=程序+软件工程

    写程序练习数据结构/算法,用新的语言尝试以下“hello world”->用JavaScrip、ASP.NET、Ruby写写网站->钻研新技术,应用新技术在软件行业创新->银行软件系统,互联网搜索行业,淘宝、Windows操作系统

    软件工程是什么

    软件工程是把系统的、有序的、可量化的方法应用到软件的开发、运营和维护上 的过程

    软件的特殊性

    软件的各种形式:

    • 系统软件:操作系统、设备驱动程序、工具软件等
    • 应用软件:用户使用它们来完成工作,从管理核电厂到写文章,或者是通信、 游、浏览网页、播放视频等
    • 恶意软件:软件病毒等软件

    软件开发过程中有什么特别的难题?

    • 复杂性(Complexity):软件的各个模块之间有各种显性或隐性的依赖关系,随着系统的成长和 模块的增多,这些关系的数量往往以几何级数的速度增长
    • 不可见性(Invisibility):工程师是“看”不到自己的源代码如 何具体地在用户的机器上被执行的。商用软件出现了错误,工程师可以看到程序 在出错的一瞬间留下的一些痕迹(错误代号、大致的目标代码位置、错误信 息),但是几乎无法完整重现到底程序出现了什么问题
    • 易变性(Changeability):正确地修改软件是一件很困难的事情。
    • 服从性(Conformity):软件总是要运行在硬件上面,它要服从系统中其他组成部分的 要求,它还要服从用户的要求、行业系统的要求
    • 非连续性(Discontinuity):有时输入上很小的变化,会引起输出上极大的变化

    软件的这些本质特性让“做一个好软件”变得很难,同时也让软件工程有它独特的挑战和魅力

    软件工程与计算机科学的关系

    工程:创造性地运用科学原理,设计和实现建筑、机器、装置或生产过程;或者是在实践中使用一个或多个上述实体;或者是实现这些实体的过

    托尼·霍尔(Tony Hoare)比较计算机科学和软件工程不同的侧重点

    计算机科学 软件工程
    发现和研究长期的、客观的真理 短期的实际结果(具体的软件会过时)
    理想化的 对各种因素的折衷
    确定性,完美,通用性 对不确定性和风险的管理,足够好,具体的应用
    各个学科独立深入研究,做出成果 关注和应用各个相关学科的知识,解决问题
    理论的统一 百花齐放的实践方法
    强调原创性 最好的、成熟的实践方法
    形式化,追求简明的公示 在实践中建立起来的灵感和直觉
    正确性 可靠性

    软件工程的目标--创造“足够好”的软件

    好软件--没有缺陷(Bug) | 软件工程--把软件中的Bug都消灭掉的过程

    • 用户满意度:用户使用时发现了很多Bug,影响了用户使用软件的效率。

    • 可靠性:某个软件经常会崩溃,某个操作系统会时不时死机。

    • 软件流程的质量:软件团队和开发流程的问题太多,导致团队成员无法互相协 作,按时交付软件。这也可以说是软件团队的Bug。

    • 可维护性:某个软件太难维护了,按下葫芦起了瓢,修复了一个问题,另一个问 题又出来了。也没有足够的文档,维护人员表示需要更多的资金和时间来维护这 个软件

    章2.个人技术和流程

    单元测试

    • 如何能让自己负 责的模块功能定义尽量明确,模块内部的改变不会影响其他模块,而且模块的质 量能得到稳定的、量化的保证?单元测试就是一个很有效的解决方案。

    • 因为可将程序的功能分为可作为单个单元 测试的独立可测试行为,所以它叫做单元测试

    • 只要你编写了一个函数或其他应用程序代码块,就可以创建单元测试用于验证对应于输入数据的标准、边界和不正确情况的代码的行为,而且用于检查代码所做的任何显式或隐式假设

    VSTS (Visual Studio Team System) 写单元测试

    简单例子

    新建一个控制台程序ConsoleApp2,在Program.cs添加如下类:

    public class CheckingAccount
        {
            public double m_balance;
            string name;
    
           public CheckingAccount(string name,double balance)
            {
                this.name = name;
                m_balance = balance;
            }
    
            public void Withdraw(double amount)
            {
                if (m_balance >= amount)
                {
                    m_balance -= amount;
                }
                else
                {
                    throw new ArgumentException(nameof(amount), "Withdrawal exceeds balance!");
                }
            }
        }
    

    右击Withdraw方法点击创建单元测试

    创建单元测试

    在生成的CheckingAccountTests.cs中添加测试方法

    		[TestMethod()]
            public void Withdraw_ValidAmount_ChangesBalance()
            {
                double currentBalance = 10.0;
                double withdrawal = 1.0;
                double expected = 9.0;
                var account = new CheckingAccount("hhq", currentBalance);
    
                account.Withdraw(withdrawal);
    
                Assert.AreEqual(expected, account.m_balance);
            }
    

    image-20200209233637945

    打开测试资源管理器,选择相应方法进行测试

    打开测试资源管理器

    更多内容

    Visual Studio文档单元测试https://docs.microsoft.com/zh-cn/visualstudio/test/getting-started-with-unit-testing?view=vs-2019

    好的单元测试的标准

    单元测试应该准确、快速地保证程序基本模块的正确性,单元测试应该在最基本的功能/参 数上验证程序的正确性。单元测试应该测试程序中最基本的单元—如在 C++/C#/Java中的类,在此基础上,可以测试一些系统中最基本的功能点(这些 功能点由几个基本类组成)

    回归测试

    在单元测试的基础上,我们就能够建立关于这一模块的回归测试(Regression Test)

    在软件项目中,如果一个模块或功能以前是正常工作 的,但是在一个新的构建中出了问题,那么这个模块就出现了一个“退步”(Regression),从正常工作的稳定状态退化到不正常工作的不稳定状态。在 一个模块的功能逐步完成的同时,与此功能有关的测试用例也同样在完善中。一 旦有关的测试用例通过,我们就得到了此模块的功能基准线(Baseline),一个模块的所有单元测试就是这个模块最初的Baseline,一个 模块的所有单元测试就是这个模块最初的Baseline。工程师们应该在新版本上运行所有 已通过的测试用例,以验证有没有“退化”情况发生,这个过程就是一 个“Regression Test”。

    效能分析工具

    个人开发流程

    PSP(Personal Software Process)

    PSP有如下特点

    • 不局限于某一种软件技术(如编程语言),而是着眼于软件开发的流程,这 样,开发不同应用的软件工程师可以互相比较。
    • 不依赖于考试,而主要靠工程师自己收集数据,然后分析,提高
    • 在小型、初创的团队中,很难找到高质量的项目需求,这意味着给程序员的输 入质量不高。在这种情况下,程序员的输出(程序/软件)往往质量也不高, 然而这并不能全部由程序员负责
    • PSP依赖于数据
    • 需要工程师输入数据,记录工程师的各项活动,这本身就需要不小的时间代价
    • 如果数据不准确或有遗失,怎么办?让工程师编造一些?
    • 如果一些数据不利于工程师本人(例如:花很多时间修改缺陷),我们怎么能 保证工程师愿意如实地记录这些数据呢?
    • PSP的目的是记录工程师如何实现需求的效率,而不是记录顾客对产品的满意度

    软件工程师的任务清单

    PSP2.1
    计划
    • 估计这个任务需要多少时间
    开发
    • 分析需求
    • 生成设计文档
    • 设计复审(和同事审核设计文档)
    • 代码规范(为目前的开发制定合适的规范)
    • 具体设计
    • 具体编码
    • 代码复审
    • 测试(包括自测,修改代码,提交修改)
    记录用时 测试报告 计算工作量 事后总结 提出过程改进计划

    章3.软件工程师的成长

    个人能力的衡量与发展

    软件系统的绝大部分模块都是由个人开发或维护的。在 软件工程的术语中,我们把这些单个的成员叫做Individ-ual Contributor(IC)。 IC在团队中的流程是怎么样的呢?以开发人员为例,流程如下:

    • 通过交流、实验、快速原型等方法,理解问题、需求或任务
    • 提出多种解决办法并估计工作量
    • 其中包括寻找以前的解决方案,因为很多工作是重复性的
    • 与相关角色交流解决问题的提案,决定一个可行的方案
    • 执行,把想法变成实际中能工作的代码,同时验证方案的可行性和其他特性 (例如程序的效能等)
    • 和团队的其他角色合作,在测试环境中测试实现方案,修复缺陷(Bug)。如 果此方案有严重的问题,那么就考虑其他方案
    • 在解决方案发布出去之后,对结果负责每个人的工作质量直接影响最终软件的 质量

    什么样的数据能说明一个软件工程师的技术和能力呢?衡量能力有哪 些参数?没有量化的指标,就谈不上衡量和比较。我们还是看看搬砖的伙计们, 关于工作量,他们:

    • 有多少块砖?
    • 要搬多远?他们也有简单的指标衡量工作质量。
    • 多快搬完?
    • 搬的过程中损坏了多少块砖?

    初级软件工程师如何成长?

    • 积累软件开发相关的知识,提升技术技能(如对具体技术的掌握,动手能 力)。例如:对Java、C/C++、C#的掌握,诊断/提高效能的技术,对设备驱动程序(Device Driver)、内核调试器(Kernel Debugger)的掌握;对于某一开发平台的掌握
    • 积累问题领域的知识和经验(例如:对医疗或金融行业的了解)。第一点和第二点都可以在很多简历上都可以看到,也可以比较容易地检测出来。随着经验的 增长,一个工程师可以掌握更广泛、更深入的技术和问题领域的知识。
    • 对通用的软件设计思想和软件工程思想的理解。这一方面就比较虚,什么是好的软件设计思想?什么是好的软件工程思想?一个工程师开了博客,转发了很多别人的文章,这算有思想么?另一个工程师坚持做任何设计都要画UML图,这算有思想么?
    • 提升职业技能(区别于技术技能)。职业技能包括:自我管理的能力,表达和交流的能力,与人合作的能力,按质按量完成任务的执行力,这些能力在IT行业和其他行业都很重要
    • 实际成果。绝大部分软件工程师的工作成果都是可以公开的,你参与的产品用 户评价如何,市场占有率如何,对用户有多大价值?你在其中起了什么作用?

    软件工程师的职业发展

    就软件工程师这个职业而言,有很多证明 个人能力的办法和模型,下面简单介绍几种

    职业发展----考级之路

    在中国,软件工程师的职业资格考试有:

    • 计算机等级考试和全国计算机技术与软件专业技术资格考试

    此类考级的好处:国家认证,有一定的权威性和通用性;任何人都可以参与

    局限性:以答题/评分为主要考试形式,没有面对面的口试;考试中每个人单独行动,不能考量团队合作能力;要考虑到通用性和稳定性,考题内容相对滞后于工业界的发展,部分内容相当滞后

    很多公司也提供了针对自己产品的职业认证项目,如:

    • 微软公司有微软认证专家(Microsoft Certi-fied Professional,MCP)
    • 甲骨文公司有Oracle认证项目(Oracle Certi-fication Program,OCP)

    国内也有机构和学校探索各种能力和认证考试服务,如:

    职业成长----Steve McConnell

    一个软件工程师需要具备一定的知识和能力:

    知识:迈克康奈尔把相关的软件知识分为十大知识领域

    能力:一个工程师对这些知识的掌握分为如下四个阶段

    • 入门(Introductory);

    • 熟练(Competency);

    • 带头人(Leadership);

    • 大师(Mastery)

    迈克康奈 尔把工程师分为8个级别(8—15),一个工程师要从一个级别升到另一个级别, 需要在各方面达到一定的要求。例如,要达到12级,工程师必须在三个知识领域 达到“带头人”水平。例如要到达“工程管理(知识领域)的熟练(能力)”水平,工 程师必须要做到以下几点:

    • 阅读:4—6个经典文献的深入分析和阅读
    • 工作经验:要参与并完成6个具体的项目
    • 课程:要参加3个专门的课程有些级别

    职业成长----大公司版本

    微软公司的软件工程师职业等级:

    等级 要求
    SDE(初级软件开发工程师) 入门。在学校里学到了一些技能
    SEE II(中级软件开发工程师) 独立。可以写别人交给你的任何东西,不明白时知道去问谁
    Senior SDE(高级软件开发工程师) 小组领导。影响着3~12名工程师,或者是它们的行政领导;或者是它们的技术带头人
    Principal SDE(首席软件开发工程师) 团队领导。影响着10人以上的一个大团队,成为影响团队成败的关键人物
    更高的职位有:
    Partner SDE
    Distinguished Engineer
    Technical Fellow
    影响力扩大到整个机构,甚至工业界

    职业成长----自我评估

    并不是每个软件工程师都有强烈的愿望或机遇去做最先进、最创新、最有风险的项目。绝大部分软件工程师都不是技术天才,但即使是一般的工程师,做一般的信息系统,就是业界说的“CRUD”(Cre-ate/Retrieve/Update/Delete,增删改查)数据库系统,也需要一些核心技术和许多扩展的知识:

    基本需求 基本技术 扩展技术 进一步的扩展技术
    把数据放到数据库中满足增删改查的需求 数据库技术(关系数据库的基本原理和操作) 大容量的数据库操作、并行、备份等技术 关系数据库模型,数据挖掘,商业智能
    有网页满足一般用户的查询需求 网页服务技术(ASP.NET、PHP等),数据绑定及控件 用户界面的设计,对不同浏览器的支持 用户心理,用户交互的原则在不同设备和不同场景下的应用
    能不断实现新的功能 编程语言和开发工具(Java、C#、Python) 程序的效能分析,软件的重用,面向对象的理论等 能改进软件工具,或构建新的语言提高解决问题的效率
    软件团队能按时高质量完成任务 每日构建,版本管理,单元测试,项目管理 需求分析,敏捷开发等高级软件工程的技术 软件团队的绩效评估,团队的发展
    要有一定的安全性 数据安全、网站的安全 计算机网络与数据通讯,操作系统的知识,数据加密解密 密码学,各种病毒工作原理
    能满足业务的需求 对业务领域有基本的了解 进一步了解业务领域知识 对业务领域有深入了解,能洞察行业发展的趋势

    很少有人能在学校里掌握这么多知识后才毕业找工作,随后把技术运用在实践中。工程师应该在实际工作中不断学习和不断成长,根据自己的情况选择在哪个方面追求“专和精”,在哪几个方面达到“知道就好”的水平

    技能的反面

    巴克斯顿说技能的反面是“Problem Solving”—“解决问题“

    一个例子:

    一个IT专业的大学生来面试,简历上写“技 能:精通Visual Studio C#编程”。于是面试官请他用Visual Studio IDE写一段程 序。一个“不精通”的面试者的编程过程实际上就是一个“解决问题”的过程。例如:
    嗯,怎么开始一个C#的命令行程序呢? 定义数组是怎么弄的?是“int [] arr”还是“int arr[]”,还是ArrayList, 还是Array。哦,我平时都是上网查的。哦,我不知道还有MSDN网站。 嗯,为什么编译没过呢,哦,这里少一个分号。 嗯,怎么设断点?怎么定义命令行参数?额,
    我要查一查……你发现他把时间都花在“解决(低层次)问题”上了,你想考察的“算法技能”、“C#程序设计技能”都无暇顾及。注意,这是在他认为非常精通的编程工具和编程语言中出现这样的问题。你要这样的员工么?那怎么提高技能呢?答案很简单,通过不断的练习,把那些低层次的问题都解决了,变成不用经过大脑的自动操作,然后才有时间和脑力来解决较高层次的问题

  • 相关阅读:
    Qt 打印机支持模块
    手动启动jenkins
    Ubuntu下安装Apache2, php5 mysql
    Ubuntu 使用apt-get时提示错误:无法获得锁 /var/lib/dpkg/lock
    scp 在不同机器上传文件
    python 正则表达式 贪婪模式的简介和匹配时的几种模式
    python指定pypi的源地址 镜像地址
    python三元运算符
    python导入上级目录中的模块
    linux下使用vim替换文件中的^M换行符
  • 原文地址:https://www.cnblogs.com/hhhqqq/p/12287911.html
Copyright © 2020-2023  润新知