软件开发经典100面试题+解答.docx
《软件开发经典100面试题+解答.docx》由会员分享,可在线阅读,更多相关《软件开发经典100面试题+解答.docx(32页珍藏版)》请在冰豆网上搜索。
软件开发经典100面试题+解答
程序员需要具备的基本素质
阅读代码这个技能需要程序员能够具备读懂已经存在的代码的能力,这样的能力可以让程序员分析程序的行为,了解程序,这样才能和开发团队一起工作,继承维护或是改进现有的程序。
编写程序编写程序并不包括程序设计。
不要以为编程是一件很简单的事情,很多程序员都认为编程只需要懂得程序语言的语法,并把设计实现就可以了。
但是这离编写程序还远远不够,使用什么样的编码风格成为编写程序员最需要具备的基本技能。
能否使用非常良好的编程风格直接决写了程序员的级别。
软件设计这一能力直接决定了需要吏用什么样的代码技术达到怎么样的功能,而系统架构设计直接决定了软件的质量、性能和可维护性。
并不是所有的程序在这一方面都非常优秀,但每个程序员都需要或多或少的明白和掌握这一基本技能。
熟悉软件工程每个程序员都应该明白软件工程是什么东西,都应该知道,需求分析,设计,编码,测试,Release和维护这几个阶段。
当然,几乎所有的人都知道这些东西,但并不是每个人都很清楚这些东西。
现在很多高级程序员都会混淆“需求规格说明书FS”和“概要设计HLD”。
另外,程序员还需要知道一些软件开发的方法论,比如:
敏捷开发或瀑布模型。
使用程序库或框架一个程序员需要学会使用已有的代码,无论是标论的程序库,或是第三方的,还是自己公司内部的,都需要学会做。
比如:
C++中,需要学会使用STL,MFC,ATL,BOOST,ACE,CPPUNIT等等。
使用这些东西,可以让你的工作事半功倍。
程序调试程序调试是分析BUG和解决问题最直接的能力。
没有人能够保证程序写出来不用调试就可以运行正常,也没有人可以保证程序永远不会出BUG。
所以,熟练使用调试器是一个程序员需要具备的基本技能。
使用IDE学会使用IDE工具也会让你的工作事半功倍。
比如,VC++,Emacs,Eclipse等等,并要知道这些IDE的长处和短处。
使用版本控制一定要学会使用版本控制工具,什么叫mainline/trunk,什么叫tag,什么叫branch,怎么做patch,怎么merge代码,怎么reverse,怎么利用版本控制工具维护不同版本的软件。
这是程序员需要明白的软件配置管理中最重要的一块。
单元测试单元测试是每个程序都需要做的。
很多单元测试也是需要编码的。
一定要学会在xUnit框架下进行单元测试。
比如JUnit,NUnit,CppUnit等等。
重构代码每个程序员都需要有最基本的能力去重构目前已有的代码,使代码达到最优但却不能影响任何的已有的功能。
有一本书叫《软件的重构》,每个程序员都应该读一下。
自动化编译程序员需要使用一个脚本,其能自动化编程所有的工程和代码,这样,整个开发团队可以不停地集成代码,自动化测试,自动化部署,以及使用一些工具进行静态代码分析或是自动化测试。
需求
你能给出一些非功能性(或者质量)需求的例子么?
所谓非功能性需求,是指软件产品为满足用户业务需求而必须具有且除功能需求以外的特性。
软件产品的非功能性需求包括系统的性能、可靠性、可维护性、可扩充性和对技术和对业务的适应性等。
下面对其中的某些指标加以说明。
在这里可以看到非功能性需求涉及的范围很广,软件产品本身不是孤立存在的,还涉及到诸多外在环境的影响。
非功能性需求必须考虑软件既要可用,又要易用。
对于非功能性需求描述的困难在于很难像功能性需求那样,可以通过结构化和量化的词语来描述清楚,在描述这类需求时候我们经常采用软件性能要好,查询要在多少时间内出结果,软件健壮性要好等较模糊的描述词语。
这类描述词语都是脱离了软件的执行环境,人和相关的场景的描述,因此信息很难体现到软件架构设计和具体的实现中。
我们在架构设计中关注的安全,系统开发框架,并发和性能,异常日志等不是凭空产生出来的,而是来源于我们对非功能性需求的分析。
一个软件系统必须完整,因此不仅仅包括了可执行的程序,还包括了在线帮助,数据和用户管理,日志异常查询,自动升级等相关功能特征。
这些需求不仅仅是为了满足用户的需要,也是为了我们后续维护和监控系统的需要。
系统的可靠性,可维护性和适应性是密不可分的。
当系统出现故障和用户出现错误的操作后是否支持恢复,当用户在使用过程中遇到错误的时候是否可以立即定位问题,但业务场景和逻辑发生变化的时候系统是否支持,当网络不稳定或使用中异常中断的情况下系统是否都有相应的容错措施,这些都是需要在非功能性需求中考虑到的问题。
易用性也是我们在开发非功能性需求中必须要考虑到的问题,易用性同时还涉及到美工和UI界面,人机工程,交互式设计,心理学,用户行为模式等多方面的知识。
易用性的三原则就是易见,易学和易用或者叫为发现,易懂,效率。
易见就是各种功能操作不要藏得太深,用户很容易找到他们期望进行的各种操作;易学需要软件系统通过在线帮助,导航,向导等各种方式保证软件是可自学习的;易用的重点则在软件在熟练使用后应该可以更快的进行各项操作。
这三者相互间也存在冲突,需要平衡,而平衡的一个重点就是真正的做到以用户为中心进行设计,需要去细分场景和用户。
对于非功能性需求的描述,在描述过程中必须要强调到人,业务场景,环境等各方面的内容。
强调的目的就是要说明非功能性需求不是无限度的,任何一项非功能性需求的实现往往会付出更大的研发人力成本和硬件网络成本。
比如我们在描述一个表单的模糊查询功能的时候,如果简单的描述为所有查询都要在多少秒内完成,那么这种需求将很难得到满足,以下是一些可选的描述方式。
1.估计用户数为1万人,每天登录用户数为3000左右,网络的带宽为100M带宽。
2.在非高峰时间根据编号和名称特定条件进行搜索,可以在3秒内得到搜索结果。
3.当通过互联网接入系统的时候,期望在编号和名称搜索时最长查询时间<15秒。
有了这些场景和数据后,我们在进行架构设计的时候就可以有针对性的选择我们的开发框架和模式,数据库,软硬件环境配置已经复杂功能的具体实现方式等。
同时这些需求还可以更好的指导我们对通过性能测试等工具对这些非功能性需求进行验证。
在某个时间范围内,产品运行稳定的程度;在某些压力极端情况(断电、饱和度),产品运行稳定的程度;不正常宕机后,产品的恢复度量。
如果客户需要高性能、使用极其方便而又高度安全,你会给他什么建议?
1高性能,一般需要集群实现
2使用方便,这个需要根据用户的水平。
B/S是很容易掌握的。
3安全,最好用VPN进行访问,或者干脆专网专用。
密码管理的问题不是系统能解决的。
就算加上实时的密码锁。
4选择合适的人,并保持稳定
总之,这些要求在一些大型应用里面都是必须的,比如电信级的计费系统。
方便与高性能、高度安全是不完全统一的。
方便带来的问题是安全性的降低,或性能不能达到最合适的程度;高性能会导致复杂性;安全性会让性能不能达到最佳。
最好的方式是选择一种优先级,比如以安全性为主要的考核标准,适当安排性能和难易程度;或者以性能为主。
尽量达到三者的平衡点,在某些极端的情况可比保证性能降低,但安全有保证
你能给出一些用来描述需求的不同技术么?
它们各自适用于什么场景?
需求分类:
项目需求:
商业需求,项目管理需求,交付需求等
产品需求:
技术需求,安全需求,性能需求等
如果非要说个技术那就是观察,也叫工作跟踪,通常由观察者从外部来观察使用者的工作参与观察者,实际执行一个流程或程序,体验他们是如何实施的。
需求分析
需求分析在整个开发过程中占的工作量不大,但是产生的影响巨大(这又是一个二八原理的例子)。
既然需求分析如此重要,照理说应该安排最强的人来搞。
但实际情况往往不是如此:
很多公司负责需求分析的人并不胜任这项工作。
我经历过几个不太成功的项目,其问题的根源都和需求分析有关。
需求分析最要紧的是:
搞清楚用户到底想要什么?
如果这个问题搞错了、搞偏了,后面的步骤做得再好也是白搭(比如客户想要一个文本编辑器,结果你搞了个图形编辑器给他)。
这方面其实有很多的道道,限于篇幅就不展开了,大伙儿如果有兴趣,以后可以单独说一下。
在搞清楚“用户想要什么”之后,接着要整理出功能列表(也有叫FeatureList),并筛选出大约20%的重点功能。
这个步骤是我今天主要想介绍的,因为这个步骤和后续的各项开发密切相关。
一般来说,功能筛选的依据有如下几个:
1、用户经常用的功能(比如save、copy、cut、paste)
2、宣传的卖点(要能够超出同类软件,吸引眼球)
3、和用户利益密切相关的功能(这种功能不允许出错,比如存盘功能)
这个筛选的过程要尽早完成,而且最好是产品人员、开发人员、测试人员三方的头头一起讨论,以保证立场客观、观点全面。
筛选出重要功能点后,其他人员的工作安排要"以重点功能为纲",有所侧重。
●项目管理
如果你是个项目经理,在排项目计划时,就得尽量优先安排重点功能的开发/测试,而且要安排能力强的人员来完成。
按照我以前的做法,重点功能排计划至少得留出1/3的时间余量,以防万一(事实证明,几乎每个稍大点的项目都会出现万一)。
至于非重点功能,尽量排到后面,安排能力一般的人开发/测试。
然后,在项目进行过程中,肯定要有定期的例会。
作为项目经理,你应该主要关注重点功能的进度情况和风险情况。
一旦项目有延期的风险,就从非重点功能开始裁减(俗称砍功能)。
由于是裁减非重点功能,不至于产生致命的影响。
●设计界面
设计界面时,你得保证所有的常用功能都放在显著的位置(比如工具条);还得保证它们用起来方便(比如提供快捷键和右键菜单支持)。
对于卖点,它不一定是常用功能,它的目的是激起用户的购买欲望和使用欲望。
因此你要把它们设计得比较酷,有噱头。
对于利益相关的功能,大部分情况下都是侧重于业务逻辑实现。
如果它既不是常用功能、也不是卖点,那么界面设计方面倒不一定要额外花大力气。
其它的非重点功能,只要按照常规方法设计,不用花太大精力。
●编写代码
我发现很多开发人员有几个通病:
先做有趣或容易的功能,然后再做无聊或者繁琐的功能;对自己有兴趣的功能投入精力多,对自己没兴趣的简单应付。
以上这些都是开发的大忌。
作为一个职业的开发人员,不应该以自己的兴趣和喜好来决定开发的轻重缓急。
正确做法应该如下:
你首先得用主要精力完成上述所说的重点功能,而且要保证它们的代码质量尽可能好,尽可能方便维护(重点功能往往是经常有需求变更,经常被修改的)。
对于重点功能中的“常用功能”,要保证时间性能够好(能快速响应)。
对于"用户利益相关的功能",要保证bug尽可能少(尤其是安全性、稳定性、健壮性的bug)。
至于其它的非重点功能,只要不出明显bug,有点小缺陷无伤大雅。
●测试
如果你是个测试人员,你同样要把主要精力用于测试那些重点功能。
对于"用户利益相关的功能",多进行一些健壮性测试、稳定性、安全性等测试(比如测试保存大文件是否会出错)。
对于常用功能,主要进行易用性和性能测试(比如拷贝、粘贴是否易用)。
至于其它功能,只要进行普通的测试,保证它不出现明显和严重bug即可。
要知道Windows2000发布的时候,尚遗留上千个未修复的bug(当然都是低优先级的),微软不也照样发布。
●产品演示
有些软件开发完之后,会搞一些Demo进行宣传。
如果你是负责进行Demo的人,你肯定要把主要的Demo时间用来秀软件的卖点,这样给客户的印象最深刻,效果最好;至于非卖点的功能,都未必要提及。
几种和开发相关工作就介绍到这里,最后送给大伙一句话:
Donotworkhard,worksmart!
下面以我们的项目来介绍一个项目的开发过程:
1.首先进行用户需求调研,先弄明白用户想要什么(如果有老系统,可以先参观老系统,看有什么可以改进的,有什么可以继承的)熟悉业务。
需求调研完成后,完成开发文档《用户调研报告》,然后根据调研,列出功能列表,同时区分重点功能和非重点功能。
2.调研完成后,画界面原型让用户来确认,如何使用等讲解清楚(这个过程中,可以会产生需求的变更),同时完成《用户需求规格说明书》,同时完成此文档的评审工作。
此时,应该可以说到达了软件的一个里程碑。
3.需求评审完成后,进行数据库设计和详细设计,此时形成的文档有《数据库设计说明书》,《详细设计说明书》,同时完成文档的评审工作。
4.设计完成以后,就要进行开发工作了。
依据详细设计说明书,此时要先进行重点功能的开发,然后进行非重点功能的开发。
在此过程中开发人员进行模块的检测,确保系统的可运行。
5.开发完成后,由专门的测试人员进行单元测试、流程测试、性能测试等。
(此时还可能有第三方测试人员和用户代表的参与)。
此时会形成专门的测试文档。
6.用户测试。
首先进行用户测试的培训,然后挑选部分用户进行系统的测试,此时一般会有开发人员进行现场的技术支持,使用用户尽快的熟悉系统的使用。
7.系统上线试运行。
需求跟踪是什么意思?
什么是向前追溯,什么是向后追溯?
需求跟踪的内容
跟踪能力(联系)链(Traceability Link)使你能跟踪一个需求使用期限的全过程,即从需求源到实现的前后生存期。
跟踪能力是优秀需求规格说明书的一个特征。
跟踪能力联系链记录了单个需求之间的父层、互连、依赖的关系。
1. 需求跟踪目的
审核(Certification) 跟踪能力信息可以帮助审核确保所有需求被应用。
变更影响分析跟踪能力信息在增、删、改需求时可以确保不忽略每个受到影响的系统元素。
维护可靠的跟踪能力信息使得维护时能正确、完整地实施变更,从而提高生产率。
项目跟踪在开发中认真记录跟踪能力数据,就可以获得计划功能当前实现状态的记录。
再设计(重新建造)。
可以列出传统系统中将要替换的功能,记录它们在新系统的需求和软件组件中的位置。
重新利用跟踪信息可以帮助你在新系统中对相同的功能利用旧系统相关资源。
减小风险 使部件互连关系文档化可减少由于一名关键成员离开项目带来的风险。
测试 测试模块、需求、代码段之间的联系链可以在测试出错时指出最可能有问题的代码段。
2. 需求跟踪能力矩阵
3. 需求跟踪能力工具
4. 需求跟踪能力过程
5. 需求跟踪能力的可行性
变更需求代价:
影响分析
“变更是免费的”这种误解是造成项目范围延伸的一个原因。
在职业生涯中,绝大多数开发人员会遇到要求添加“没有代价且不影响进度的变更”的要求。
对这样奇怪的要求的正确回答是“不行”,变更只能在项目时间、预算、资源的限制内进行协商。
1. 影响分析过程
建议的变更涉及的问题核对表
基准(线)中是否已有需求与建议的变更相冲突?
是否有待解决的需求变更与已建议的变更相冲突?
不采纳变更会有什么业务或技术上的后果?
进行建议的变更会有什么样的负面效应或风险?
建议的变更是否会不利于需求实现或其他质量属性?
从技术条件和员工技能的角度看该变更是否可行?
若执行变更是否会在开发、测试和许多其他环境方面提出不合理要求?
实现或测试变更是否有额外的工具要求?
在项目计划中,建议的变更如何影响任务的执行顺序、依赖性、工作质量或进度?
评审变更是否要求原型法或别的用户提供意见?
采纳变更要求后,浪费了多少以前曾做的工作?
建议的变更是否导致产品单元成本增加?
如增加了第三方产品使用许可证的费用。
变更是否影响任何市场营销、制造、培训或用户支持计划?
变更影响的软件元素核对表
确认任何用户接口要求的变更、添加或删除。
确认报告、数据库或文件中任何要求的变更,添加或删除。
确认必须创建、修改或删除的设计部件。
确认源代码文件中任何要求的变更。
确认文件或过程中任何要求的变更。
确认必须修改或删除的已有的单元、集成或系统测试用例。
评估要求的新单元、综合和系统测试实例个数。
确认任何必须创建或修改的帮助文件、培训素材或用户文档。
确认变更影响的应用、库或硬件部件。
确认须购买的第三方软件。
确认在软件项目管理计划、质量保证计划和配置管理计划等中变更将产生的影响。
确认在修改后必须再次检查的工作产品。
2. 影响分析报告模板
追溯分为两种,向前追溯和向后追溯.
向前追溯就是,向保单起保日期之前追溯,主要体现在按照"期内索赔式"投保的产品责任险中.简单说:
就是对起保之前生产的产品,在保险期间出险了,保险公司也要赔付!
例如:
A公司在2006年生产了一批产品,然后,在民安投保了产品责任险,保险期间为2007-01-01到2007-12-31号,追溯期为1年,意思就是说:
对于2006年生产的产品在2007年出险了,保险公司也要赔付.(追溯起始时间为:
2006-01-01,追溯结束日期为:
2006-12-21号)
在追溯期,但是不在保险期间发生的案件,需要理赔!
追溯期主要是向前追溯,就是起保之前,用于产品责任险比较多!
在责任险中有追溯期的概念,下面查到的些资料可供大家理解。
产品责任险附加条款汇编:
产品责任险的承保方式有两种:
一种是以事故发生为基础,这种方式下只要产品责任事故发生在保险期限内,不论何时提出索赔,保险人均要负责赔偿,另一种是以索赔提出为基础,这种方式下不论产品责任事故是否发生在保险期限内,只要被保险人或受害人在本年度保单有效期内提出索赔,保险人就要承担赔偿责任。
上述概念是理论上的,现实承保中保险人为控制风险,对在事故发生制下提出索赔的时间和对在索赔提出制下事故发生的时间均有限制。
我国目前产品责任险的基本条款采用的是事故发生制,在赔偿处理部分规定:
被保险人的索赔期限,从损失发生之日起,不得超过两年。
如果要采用以索赔提出为基础的方式,保险人则规定追溯期,即在追溯期开始后发生的产品责任事故并在保单有效期内提出索赔,保险人才承担责任,且追溯期一般规定不超过5年。
一般情况下,保险人出具第一张以索赔提出为基础的保单时,不给追溯期。
现实承保中,采用此条款,被保险人通常可有一定宽限期,即便保单到期或注销,只要被保险人在条款中规定的发现期中提出索赔,这个索赔仍旧有效。
我国目前保险市场对产品责任险以索赔提出为基础承保的最好条件为:
追溯期5年,发现期3年。
采用以索赔提出为基础的方式,如果能把发现期争取到2年,则即使没有追溯期,也已经优于以事故发生为基础的承保方式了。
你喜欢用什么工具跟踪需求?
你怎么看待需求变化?
它是好是坏?
给出你的理由。
你怎样研究需求,发现需求?
有哪些资源可以用到?
你怎么给需求制定优先级?
有哪些技术?
在需求过程中,用户、客户、开发人员各自的职责是什么?
用户从某种意义上来讲是和客户等同的,开发人员是负责开发产品,用户和客户就是使用产品啊!
你怎么对待不完整或是令人费解的需求?
以客户为导向,和客户召开需求reviewmeeting,向客户表述自己对当前需求的理解。
如果有不完整或者理解有误的地方,客户会及时纠正。
一定要在需求明确的前提下进一步设计,不正确的理解需求会导致项目失败。
功能设计
在功能设计中有哪些隐喻?
给出几个成功的例子。
如果有些功能的执行时间很长,怎么能让用户感觉不到太长的等待?
如果用户必须要在一个很小的区域内,从一个常常的列表中选择多个条目,你会用什么控件?
有哪些方法可以保证数据项的完整?
建立系统原型有哪些技术?
原型系统是指当前系统的原始形态,不一定就是信息系统,非信息化的系统也有原型。
广义来理解,当前系统的原始形态,这里不一定就是信息系统,非信息化的系统也有原型。
狭义来理解,原型特指系统生命期开始阶段建立的,可运行的最小化系统模型。
软件开发过程就是分析系统原型,建立系统模型,再优化转换的过程。
构造原型系统的八大原则对自己的产品设计很有帮助
作为一名工程师或科学家,您或许会构想些您认为有市场价值的产品构思;然而,您或许会担心您缺乏充分开发您的构思所需的培训或技能。
不必担心!
有成功之路可循!
如果您可以演示,或者如果能给客户提供原型系统就更好了,并得到关于创新价值的真实反馈,那么您获得商业成功的可能性会大为提高。
如果您希望创建企业实现自己的产品构思,请开发原型系统并牢记下列八大原则。
1、认识到构思的廉价性——鉴于我们生活在关联的、充满互联网智慧的世界,构思已经变得廉价,而且可能会随着时间的推移变得更为低廉。
成本在于测试和验证什么是具有经济价值的。
一个优秀的原型系统常常是开始与潜在客户对话并检验构思价值的最佳方式。
2、从书面设计开始——您或许急于开始非常快速地编写代码或设计电子产品。
抑制冲动!
未实际考虑一些设计因素就进行代码编写,会导致痛苦和大量的修改。
从一个简单的书面设计开始。
对于一个用户界面或网页软件原型系统,一份书面设计可以有效且高效地快速处理其功能特性。
您可以从同事和(希望如此)客户获得关于图像、文本、按钮、图表、菜单或下拉式选项的位置的反馈。
书面设计不仅成本不高,而且比口头表达更有价值。
3、仅投入足够的工作量——清楚您的目标并坚持您的目标。
构造原型系统有两个很好的理由:
一是检验软硬件架构的可行性,二是创建一个演示版本并获得客户的反馈,便于您为自己的创新报价和赋予价值。
牢记这些目标,并小心不要沉湎于这个过程。
构造原型非常有趣,而且创新者喜欢进行修正,但是,您希望仅投入足够的时间和工作以满足这些目标。
4、期望多个选择——记住模块化设计您的原型系统。
优秀的原型系统通常是模块化的,这意味着您可以快速对其调整以满足客户不可预料的需求。
最终决定如何使用您产品的是客户,而不是您自己。
设计扩展、性能和封装的备选项,并降低成本。
5、设计以方便在最终产品中的复用——理想的状况是设计一个您可以大批量生产和分发的原型系统。
没有许多原型系统构造工具可以满足这样的要求。
典型情况下,您牺牲性能以获得设计的灵活性。
寻找能够将您的原型系统从实验室推向市场的原型系统构造工具。
6、避免过早对成本的关注——对于硬件设计,一个潜在的耗时点和陷阱是在您的原型系统设计的早期阶段纠缠于无休止的成本优化分析。
成本总是重要的,但您的目的在于使得原型系统落在可盈利设计的有效范围内。
在初始阶段,聚焦于证明创新的价值,并牢记模块化的设计原则。
虽然令人沮丧,但是您的设计或许通过很多途径都不能最终实现价值。
关注于争取您的第一批客户,然后再进行成本优化的工作。
7、反对“均值回归”——在原型系统构造过程中,倾向于开发简单的产品,而不是开发那些令人惊叹的产品。
坚持您的愿景,并确保原型系统实现了您创新的最初构想。
8、确保您可以展示您的原型系统——您的原型系统应当便于演示。
对于客户、风险资本家(VC)和潜在的从业人员,您希望强势出击并首先展示最瞩目的功能。
切勿构建渐强音!
绝大多数人群的注意力保持的时间不超过60秒。
在原型系统介绍中,无论他们是面向新的从业人员还是VC,尽可能快地进入到产品演示。
如果原型系统的演示引人瞩目,所有其它的内容会逐渐被了解。
应用程序怎样建立对用户行为的预期?
给出一些例子。
如何入手设计一组数量庞大而又复杂的特性,你能举出一些设计思路吗?
有一个列表,其中有10个元素,每个元素都有20个字段可以编辑,你怎样设计这种情况?
如果是1000个元素,每个元素有3个字段呢?
用不同的颜色对一段文本中的文字标记高亮,这种做法有什么问题?
Web环境和Windows环境各有些什么限制?
技术设计
什么是低耦合和高聚合?
封装原则又是什么意思?
低耦合是针对类与类间的依赖关系而言,类具有单一职责,低耦合度的类不依赖其它类,从而保持其独立性;高聚合针对类中各个职责的关联程度而言。
封装原则是对类的可变性而言,应遵守开放-封闭原则,对修改封闭,对添加开放。