MIS信息技术基础专题之一面向开发人员的计算机技术基础NAUZhu-Yihua一、如何理解计算机技术基础与信息系统开发的关系?a)理解计算机原理是开发高质量软件的基础i.受限系统上对现实世界的模拟——数字化的世界ii.现代开发语言与开发工具的发展降低了软件开发的门槛b)非规范的开发方式引入了软件缺陷,提高了开发成本…二、提高软件质量——工程化软件开发的基本原则a)什么是软件的质量?CMM(CapabilityMaturityModel能力成熟度模型):一个系统、组件或过程符合特定需求(客户/用户的要求与期望)的程度;思考:是不是运行正确的软件就是高质量的软件?质量的对立面:缺陷——BUG功能性属性正确性(精确性)软件第一质量属性健壮性(容错/恢复)航空/金融/军事可靠性(平均无故障时间——借自硬件领域)往往是不可重复的错误,难以发现。常见问题:资源与内存泄漏/数据溢出(如千年虫)非功能性属性性能时间-空间效率不等于运行速度平衡:“又要马儿跑,又要马儿不吃草”易用性:用户笨还是你笨?清晰性安全性(Security,notsafety)平衡:入侵代价获取的利益可扩展性(适应变化)兼容性(适应其他系统)可移植性(适应环境)思考:从程序员的角度来看,如何提高软件质量?郎中三兄弟(听说过这个故事么?)与提高软件质量的三个层次1、高质量的软件开发过程和规范的程序设计2、定期检查和修正错误3、对已出现的错误进行修补b)总体观念:i.有设计有实现,高处设计,低处实现思考:1、软件开发等于编程?2、编程等于用编程语言表达算法逻辑?ii.工程思想:标准与规范(过程/方法/工具)思考:1、制造业是如何提高产品质量,提高生产效率的?2、编程是艺术还是技术?软件开发人员的数量构成大致会是如何?c)程序开发中的设计高处设计:不陷于细节,从总体上考虑。能对软件整体架构进行剖析模块化与开放性思维(系统的思维方式)模块规模与拆分考虑程序流程程序设计之前的可预测性i.不要重复发明轮子——代码重用的方式与模块化思想的演进重用的好处:质量/效率/成本1.COPY&PASTE2.模块化系统的思维方式:分而治之,把复杂问题分解为简单问题。3.面向对象思考:培训班的上课问题一个讲师在上完自己的课时,通知学员如何找到参加其他课程的教室。结构化设计面向对象设计1、获得名单2、对名单中的人,循环:a.查找他的下节课b.查找下节课的地点c.查找到该地点的路径d.告知走法1、制作一张课程-走法对照表2、张贴表区别:责任的转移——学生是对自己负责有行为的主体:对象优点:如果需求发生变化,现在对参加某类培训的学员有特殊要求,两种设计方式会如何处理?4.组件ii.实验1中的问题:界面代码与功能代码混用iii.实验1中的问题:模块间的接口d)程序开发中的实现i.用户的角度:语言是算法逻辑的表达方式?表达式不等于数学公式。语言是指令的集合。思考:不使用第三个变量交换两个整型变量a,b的值解法1:a=a+b;b=a-b;a=a-b;很巧妙的算法吗?问题:该方法是否适用于浮点数?(如:a=10.3,b=7.5)ii.计算机设计者的思考角度思考:解法1是否存在BUG?1.计算机原理:数的二进制表示:字长与溢出解法2:a=a^b;b=a^b;a=a^b;2.CPU与高低位3.程序的结构与缓冲区溢出iii.操作系统设计者的思考角度例:windows的消息机制与程序运行方式典型的原生Windows程序结构与开发过程事件驱动与消息队列RAD背后——事件委托由此想到的:编程语言的比较语言与开发工具的关系IDE,Framework以及RADVisualBasic(VisualBasic)–ADO,ActiveXVisualC++(C/C++-MFC)–ODBC,ADOC++Builder(C/C++-VCL)–BDE,ADO,DBExpressDelphi(OP-VCL)–BDE,ADO,DBExpressJBuilder(Java–JDK类库)–JDBC,跨平台PowerBuilder(PowerScript-PFC)JSP/ASP/PHP开发工具间的选择与配合内部接口DLLCOM(ActiveX)组件iv.语言编译器设计者的思考角度思考:下面代码的输出结果是什么1.charstr1[]=abc;charstr2[]=abc;constcharstr3[]=abc;constcharstr4[]=abc;constchar*str5=abc;constchar*str6=abc;if(str1==str2)printf(OK1);if(str3==str4)printf(OK2);if(str5==str6)printf(OK3);请在不同的编译器下检验结果。1.C/C++:char实际上是一个整数思考:以下代码有何问题?chara=255;…//其他代码if(a==255){DoSomeThing();}2.字节对齐与结构体的空间布局思考:求sizeof(MyStruct)的结果:typedefstruct{inta;charb;charc;}MyStruct;请在不同的编译器下检验结果。3.隐式类型转换——难以发现的BUG思考:下面的C代码有何问题?intnumber=100;intunit=3;floattotal=number*11/unit;4.多线程中的高级语言单指令例:在系统级多线程程序设计中,下面哪一条C语句需要考虑同步问题?A)x=1;B)x=y;C)x=x+1;x=1;VisualC++6.0Debug模式movdwordptr[ebp-4],1BorlandC++Buildermov[ebp-0x04],1x=y;VisualC++6.0Debug模式movecx,dwordptr[ebp-0Ch]movdwordptr[ebp-8],ecxBorlandC++Buildermovedx,[ebp-0x0c]mov[ebp-0x08],edxx=x+1;VisualC++6.0Debug模式movedx,dwordptr[ebp-4]addedx,1movdwordptr[ebp-4],edxBorlandC++Builderincdwordptr[ebp-0x04]分析:高级语言中的一条语句,并不一定对应一条机器指令,在多线程程序中很可能在执行中间被挂起,在普通应用中利用CPU硬件本身的现场保护一般不会出现问题,但在操作系统的开发中就可能出现问题。例:下面的java代码在多线程应用中是否可能会发生问题?Stringstr=newstring(“美利坚合众国”);…//其他语句str=“中华人民共和国”;分析:同上。5.编译器优化v.算法、性能与编程技巧1.编写代码之前先考虑算法的适用性例:对磁盘文件中的内容(不重复的7位数字的电话号码)进行排序输出到另一个文件,可能有多少种算法?由于程序运行在受限环境下,可支配的内存约1MB-1.2M左右,要求过程在10秒左右完成(磁盘空间充足)。分析:用字符串表示号码——每个号码7个字节,1MB可存放143000个号码用整数表示号码——每个号码4个字节(32位系统),可存放250000个号码解法1:使用临时文件,每次排序250000个号码,使用快速排序等高效算法最后合并解法2:位图算法,1MB可表示为一个约有8百万个bit的字符串表示,鉴于号码不会以0开始,一般也会保留某些数字前缀,1.2MB可以容纳全部号码集合。2.工程思想与性能的平衡a)可读性:代码长短与性能不成正比思考:比较下面两段代码哪个效率更高,哪个可读性好?for(i=0;iiTotal;i++){if(condition)DoSomeThing();ElseDoOtherThing();}if(condition){for(i=0;iiTotal;i++)DoSomeThing();}Else{for(i=0;iiTotal;i++)DoOtherThing();}b)对于大型的难以维护的系统,在优化算法和升级硬件的选择上,后者是更为稳妥的方法c)不要以程序的短小或运行的效率来显示自己的水平,可读性是第一位的d)使用常用和公认的算法,除非与小组成员进行交流3.不要依赖编译器的某些特点以及未明确未定义的功能4.同样,不要依赖操作系统中某些未公开的功能5.用户需要的是体贴的功能,不是花哨的界面6.不要强迫用户——你知道什么是流氓软件吗?如何评价?启示:学习数据结构不仅要学会算法本身,还应该学会数据结构与算法的特点与适用范围。应用不是纯数学问题e)程序设计基本原则——规范与标准化命名规范•避免关键字例:在access中建立字段时起名为value,date,time,然后在应用程序中对该表进行操作.•前缀,大小写与匈牙利命名法,g_,m_,s_,公司或功能标记?•有意义,简单的名词作变量名(或形+名),动词作函数名•Min-Length&&Max-Information原则•可发音的名字•通用性,英文•避免歧义与误识别的字母,如I与l与1•直观的布尔类型,如isEmpty•常量用大写•文件名与小组成员协商制作共同的命名规范数据类型•避免浮点类型——效率与精度,int类型是最有效率的•了解语言的类型兼容性•强类型语言C++/C#/Java•弱类型语言VB/VBScript/JavaScript/PHP/Perl•有符号类型与无符号类型•显式类型转换•类型转换会不会丢失数据?操作符•熟悉优先级,加括号永远是好的习惯函数•避免参数过多•唯一出口原则?•用函数取代常用的代码段•进入时初始化,退出时清理内存与指针思考:下面的程序运行后有结果是什么?#includestdio.hvoidGetMemory(char*p){p=(char*)malloc(100);}intmain(){char*str=NULL;GetMemory(str);strcpy(str,”helloworld”);printf(str);}将GetMemory改写成下面的代码,main的调用改为str=GetMemory()后呢?char*GetMemory(void){charp[]=”helloworld”;returnp;}•malloc与free,new与delete成对使用(并非数量上的成对,而是逻辑上的)•谁分配,谁释放,否则必则在文档严格说明•指针指向的内存被释放后,应复位其值为NULL•C/C++:为字符串结束符占用的空间分配内存•对地址操作一定要小心,因为和机器和硬件相关,可能造成移植性的问题和难以检查的错误。如:高低位字节,对齐方式等性能效率•goto的合理使用•循环体内不要定义变量•常用或大尺寸的数据设为全局变量(有争议)或常量•传址与引用•延迟执行(如磁盘写缓冲区)风格与习惯•空行与空格•注释:战略性与战术性(全局与局部)/自解释•缩进•成对原则——先封两头,再写中间•代码长度与模块化100行•还是goto•不要在一行放多条语句,过长语句要分行+缩进•过于复杂的语句分解为几条•错误处理•代码重用——不断重构小结:计算机原理也是开发人员的编程基础。用计算机的方式思考用操作系统的方式思考用编译器的方式思考程序设计必须规范化编码风格编程习惯作业:1、调试以上内容中的范例2、小组为单位制定编码规范3、做一次软件企业调查,从结果中分析该企业的开发中存在的问题并提出对策