编程范式思考问题

原文出自:http://aayy520.blog.163.com/blog/static/2318226020131087499654/

1、软件开发者的成长需要经历哪些阶段?
学会-》会学--》会用--》被用
知其所然--知所以然,人为我用到我为人用
2、要想在IT业中生存与发展,传统的学习方式是否够用?
封闭----系统完备的终极式知识
单向----师教生学的单向式传输知识
被动----师命生从的被动式接受知识
静态----只注重知识的现状,忽略知识的起源、历程和未来的趋势
3、优秀程序员应该具备哪些素质?
知识之上是思想,思想之上是精神
除了要迅速掌握知识、善于领域思想之外,还必须具备务实与研究精神、独立与合作精神、批判与自省精神

4、谁是你真正的老师?
真正的老师不是别人,正是自己
5、程序员是吃青春饭的吗?
出自那些缺乏灵感和激情的人之口
6、计算机语言这么多,到底学哪个好?
语言合适就是好

7、语言好坏的标准是什么?
评判语言的优劣,不能离开使用语言的主题和对象。好的语言就是适合编程者和解决对象的语言
8、计算机语言的发展经历哪几个阶段?
计算机语言按其发展历程分为5代,依次为:机器语言、汇编语言、高级语言、面向问题语言和人工智能语言。通常,前两代统称为低级语言,后面的统称为高级语言。
9、第4代语言和第5代语言与前3代相比,有什么不同?
第4代语言和第5代语言与前3代语言最大的不同在于:重目标轻过程、重描述轻实现。
10、什么是低级语言和高级语言?它们各自的特点与应用范围是什么?
通常,前两代统称为低级语言,后面的统称为高级语言。计算机语言从低级发展到高级,渐渐远离机器,靠近人类,以牺牲部分性能和效率为代价,换来更高的开发效率和可维护性。中低级语言更适合中小型或底层应用,高级语言更适合大型应用。
11、为什么称C语言为中级语言?
C语言兼具高级语言和低级语言的的特征

12、什么是编程范式?
编程范式是计算机编程中的基本风格和典范模式,是编程者在其所创造的虚拟世界中自觉不自觉采用的世界观和方法论。每种范式都是引导人们带着其特有的倾向和思路去分析和解决问题。OOP是一种编程范式。
Object-Oriented多翻译为面向对象,但不如对象导向贴切
13、编程范式与编程语言的关系是什么?
如果把一门编程语言比作兵器,它的语法、工具和技巧等是招法,它采用的编程范式则是心法。
抽象的编程范式须要通过具体的编程语言来体现。范式的世界观体现在语言的核心概念中,范式的方法论体现在语言的表达机制中。一种语言的语法和风格与其所支持的编程范式密切相关。

14、库和工具包与框架有何不同?
库和工具包侧重代码重用,框架侧重设计重用。库和工具包从微观上解决具体问题,为程序员带来自由的;框架是从宏观上控制软件整体的结构和流程,为程序员带来约束的。框架是通过控制反转(IoC)机制反客为主。
15、什么是设计模式、惯用法和架构?
设计模式是软件的战术思想,架构是软件的战略决策。与框架、库和工具包不同,他们不是软件产品,而是软件思想。
设计模式与惯用法都是针对常发问题的解决方案,但前者重设计,后者重实现。
16、为什么要谈编程范式,而不是框架、设计模式或架构?
架构太高,谈之过早;框架太多,无从谈起;设计模式太少,不必多谈。至于编程范式,对培养编程语言的语感至关重要,需要充分的重视和长期的积累,方能悟其精髓。

17、泛型编程有哪些优点?
泛型编程能打破静态类型语言的数据类型之间的壁垒,在不牺牲效率并确保类型安全的情况下,最大限度地提高算法的普适性。
18、STL有哪些要素?各自有什么作用?
3个要素:算法、容器、迭代器。算法是一系列可行的步骤;容器是数据的集合,是抽象化的数组;迭代器是算法与容器之间的接口,是抽象化的指针。算法串联数据,数据实化算法。
19、泛型编程的泛化对象是什么?
泛型编程不仅能泛化算法中涉及的概念(数据类型),还能泛化行为(函数、方法、运算)
20、泛型编程的核心思想是什么?
泛型编程是算法导向的,以算法为中心,逐渐将其所涉及的概念内涵模糊化、外延扩大化,并将其所涉及的运算抽象化、一般化,从而提高算法的可重用性。

21、什么是元编程?它与通常的编程有何不同?
元编程是编写、操纵程序的程序。在传统的编程中,运算是动态的,但程序本身是静态的;在元编程中,二者都是动态的。
22、元编程有何用处?它有哪些应用?
元编程能减少手工编程,突破原语言的语法限制,提升语言的抽象级别与灵活性,从而提高程序员的生产效率。
元编程有诸多应用:许多开发工具、框架引擎之类的基础软件都有自动生成源代码的功能;创造DSL以便更高效地处理专门领域的业务;自动生成重复代码,动态改变程序的语句、函数、类等等。
23、相比自编的元程序,用IDE自动生成的代码有什么缺陷?
IDE下自动生成的代码通常局限性大且可读性差,小操作可能造成的源码上的大差异,削弱了版本控制的意义。用自编的无需人机交互的元程序来生成代码,只需将元程序的数据来源版本化,简明而直观。同时由于元程序可以随时修改,因此局限性小,更加灵活。
24、语言导向式的编程有何优点?它与元编程有何关系?
语言导向式编程(LOP)通过创建一套专用语言DSL来编程。相比通用语言,DSL更简单、更抽象、更专业、更接近自然语言和声明式语言、开发效率更高,同时有助于专业程序员与业务分析员之间的合作。
语言导向式编程一般通过元编程将专用语言转化为通用语言。
25、元编程与产生式编程有何异同?
产生式编程与静态元编程都能自动生成源代码。产生式编程强调代码的生成,元编程强调生成代码的可执行性。此外,动态元编程并不生成源代码,但在能在运行期间修改程序。
26、为什么说元程序是一种最高级的程序?
元程序将程序当做数据来对待,有着其他程序所不具备的自觉性、自适应性和智能型,可以说是一种最高级的程序。

27、什么是SoC和DRY?
SoC是Separation of concerns的编写,指应将关注点分离;DRY是Don't Repeat Yourself的缩写,指应尽量减少重复代码。
28、如何有效地避免紊乱、松散、重复的代码?
抽象和分解
29、抽象分解的原则是什么?
单一化和正交化,以保障软件系统符合“高内聚低耦合”的要求
30、什么是横切关注点?
指与程序的纵向主流执行方向和横向正交的关注焦点。
31、接入点和切入点有什么区别?
接入点是附加行为---建议advise的执行点,切入点pointcut是指定的接入点join point的集合,这些接入点共享一段插入代码。切入点与建议组成了切面aspect,是模块化的横切关注点。
32、什么是编织?有哪些不同的编织方法?
编织是将附加的切面逻辑嵌入到主体应用程序之中的过程。编织分静态编织和动态编织,静态编织在编译期、后编译期或加载期嵌入代码,动态编织则在运行期间嵌入。
33、实施AOP有哪些步骤?
切面分解、切面实现和切面合成
34、为什么说AOP是OOP的一种补充?
OOP只能沿着继承树的纵向方向重用,AOP可以沿横向方向重用。
35、为什么提倡尽可能地阅读原文的书籍和资料?
语言之间的天然差别、译者的专业水准、语言功底和严谨程度及时间上的滞后决定了阅读原文书籍和资料的必要性。

36、什么是事件?有哪些不同类型的事件?
事件是程序中令人关注的信息状态上的变化。在基于事件驱动的系统中,事件包括内建事件与用户自定义事件,其中内建事件又分为底层事件和语义事件,此外,事件还有自然事件和合成事件之分。
37、什么是回调函数?什么是异步回调?它们有什么用处?
Callback指能作为参数传递的函数或代码,它允许低层模块调用高层模块,使调用者与被调用者从代码上解耦。异步callback在传入后并不立即被调用,是调用者与被调用者从时间上解耦。
38、控制反转的目的是什么?它们是如何实现的?它在框架设计中起什么作用?
控制反转一般通过callback来实现,其目的是降低模块之间的依赖性,从而降低模块的耦合度和复杂度。
39、控制反转、依赖反转原则和依赖注射的共同点是什么?
在框架设计中,控制反转增强了软件的可重用性、柔韧性和可扩展性,减少了用户的负担,简化了用户的代码。
控制反转、依赖反转原则和依赖注射是近义词,他们的主题是控制与依赖,目的是解耦,方法是反转,而实现这一切的关键是抽象接口(包括函数指针、抽象类、接口、C++中的泛型函子和C#中的委托)
40、事件驱动是编程有哪些关键步骤?
3个步骤:实现事件处理器;注册事件处理器;实现事件循环。
41、异步过程特点和作用是什么?
异步过程在主程序中以非堵塞的机制运行,即主程序不必等待该过程返回就能继续下一步。异步机制能减少随机因素造成的资源浪费,提高系统的性能和可伸缩性。
42、事件驱动是编程最重要的特征是什么?它们是如何实现的?
独立是异步的前提,耗时是异步的理由。
事件驱动式最重要的两个特征是被动型和异步性。被动型来自控制反转,异步性来自会话切换。
43、事件驱动式与观察者模式、MVC架构有何关系?
观察者模式又名发行/订阅模式,既是事件驱动式的简化,也是事件驱动式的核心思想。MVC架构是观察者模式在架构设计上的一个应用。

44、掌握编程范式对编程语感的提高有什么作用?
学习知识之表须通过记忆,掌握知识之里须通过练习,渗透知识之根须通过培养。编程范式正是知识之根。适度地容忍无知也是一种学习技巧。
不同的编程范式代表不同的解决问题的思想和方法。不同的编程语言提倡不同的编程范式,并在语法上给予支持,只有掌握范式,才能更合理、更有效地运用编程语言的语法和语义特征,并能针对不同的问题领域不同的编程风格,编写的代码才会和谐自然、富于美感。
45、为什么声明式程序一般比命令式程序更简洁?
命令式编程须要指定计算的过程,着重微观的细节;声明式编程只须指定计算的原则,着重宏观的方向。因此二者繁简有别。
46、函数式编程有哪些特征?为何简洁而不失强大?
函数式编程中,函数是程序的核心,是头等公民,一般没有或很少有副作用,同时没有显示的内存管理。
由于函数式编程中的高阶函数与基本数据类型平起平坐,故可将代码作数据用,这是程序既简洁又强大的原因之一。回调机制采用的正式函数式风格。
47、函数的无副作用性的意义何在?
无副作用的函数容易重构,调试和测试,便于并发和优化处理,并能贯彻和运用数学思维。
惰性求值是需求驱动的,可以避免不必要的等待和计算。
48、相比过程式和OOP,函数式编程的弱点是什么?
相比过程式和OOP,函数式编程思想过于数学化和抽象化,语言的表现力和运行效率略显不足。

49、衡量软件复杂度是由代码的长度决定的吗?
代码的长度不是衡量软件复杂度的唯一标准。其中的逻辑结构越复杂、越微妙、受需求变化的影响越大,软件越难控制和维护。
50、为什么逻辑式的编码一般比过程式的更简洁?
算法=逻辑+控制。逻辑式编程将算法中的控制部分大都移交给编程语言,编程人员主要关注算法的核心逻辑。这样大大减轻了程序员的负担,编码也更简洁易懂,更具可维护性和可扩展性。
有别于过程式和函数式,逻辑式没有明显的输入和输出之分。
51、逻辑式编程相比命令式编程有哪些优势和劣势?
逻辑式编程不仅适用于人工智能方面的学术领域,同样广泛适用于各种涉及知识管理、决策分析等方面的应用领域。
相对于命令式,逻辑式更简洁、更抽象、更少副作用,能提高生产效率,还能用于快速原型开发。但在运行效率、可掌控性、语言成熟度等方面有所欠缺。另外,因其思维方式独特而鲜为人用,适合基于规则而非基于状态的应用 。

常见的编程范式:

52、编程范式与设计模式有什么区别?
相比设计模式,编程范式针对的问题领域更广泛,提出的思想和方法更普适、更抽象、更系统。此外,设计模式重在设计,对语言和工具的要求不高,而编程范式需要建立一套抽象机制和方法体系,离不开语言或工具的支持。
53、编程范式的核心价值是什么?
编程范式的核心价值在于:突破原有的编程方式的某些限制,带来新思维和新方法,从而进一步解放程序员的劳动力。
54、总结前面介绍的编程范式,它们各自有哪些代表语言?核心概念和运行机制是什么?针对的问题和主要的目的是什么?实现原理是什么?常见的应用有哪些?有什么不足之处?
正文中编程范式的汇总表格既是对此前知识的总结,也是对今后编程的指导。
既要了解编程范式的长处,也要了解它们的短处。
编程范式为神,编程语言为形,应以神导形、以形传神。

55、什么是闭包?为什么被称为闭包?它有什么作用?
闭包是一种能保留当初创建时的环境变量的函数。它通常以匿名的方式存在,多用于函数式编程中,能使代码更加简洁清晰。Java中的匿名类可以看作OO化的闭包形式。
56、规则引擎有何用处?
Java平台上的Jess、Drools、JLisa、JRules和.NET平台上的MS BRE、WF Rules都是规则引擎,主要基于正向推理。它们提供了逻辑式编程环境,能有效地将业务规则从应用程序中分离出来,提高了软件的灵活性和可维护性。
57、能否设想一个生活中的场景,把介绍的九种编程范式都用上?
每种编程范式都能在生活中找到它的应用,它们本来就是人类思维方式的投影。

58、什么是迭代学习法?
所谓迭代学习法,是指在具体知识与抽象理论之间进行增量式的循环学习。
59、一个合格的程序员需要学习和掌握不同领域的许多知识,如何能胜任愉快?
一个合格的程序员不应只局限某一层的应用开发。
要想工作胜任愉快,才能、兴趣、方法和努力缺一不可。一套好的方法可以激发才能、兴趣和努力。

60、动态语言与动态类型语言是一回事吗?
尽管动态语言大多数是动态类型语言,但二者并不是一回事。
61、数据类型有哪两个要素?其意义何在?
数据类型包含两个要素:允许取值的集合和允许参与的运算。
数据类型既有针对机器的物理意义,又有针对人的逻辑意义,提高了代码的安全性和抽象性。
62、什么是动态类型和静态类型?它们的区别是什么?各有什么优缺点?
动态类型的类型检查发生在运行期间,静态类型的类型检查发生在编译期间(运行之前)。
动态类型的变量不需要显式声明,静态类型的变量需要通过显式声明或类型推断。
63、什么是鸭子类型(duck typing)?它有什么优缺点?
鸭子类型是动态类型的一种风格,允许非继承性多态,即一个对象的类型可以由其接口集合来确定,不需要通过显式继承。它有利于代码重用,但也可能造成误用和滥用。
动态类型语言的优点:代码简明灵活、易于重用,适合泛型编程和快速原型开发。
静态类型语言的优点:运行之前的类型检查增强了代码的可靠性,使编译器有可能进行优化处理从而提高运行效率,节省了运行期的类型检查所占用的时间和空间,同时类型声明有辅助文档的功效。
静态类型检查实行“疑罪从有”的有罪推定制,动态类型检查实行“疑罪从无”的无罪推定制。取舍的原则是:Static Typing Where Possible, Dynamic Typing When Needed。即尽可能守规则,必要时求变通。

64、什么是强类型与弱类型?什么是类型安全的?
类型的动静以类型的绑定时间来划分,类型的强弱以类型的约束强度来划分,它们之间没有必然联系。弱类型语言允许类型的隐性转化,被认为是类型不安全的;而强类型语言则一般不允许这种转化,被认为是类型安全的。

65、脚本与程序的区别是什么?
程序是为终端用户服务的,脚本是为程序员服务的。
66、脚本语言有什么特点?为什么适合作粘合语言?
脚本语言一般是解释型语言,不需要通过“编写-编译-链接-运行”的循环圈,便利快捷,加之简洁宽松的语法、面向字符的特性以及较强的文本处理能力,尤其适合作为粘合语言,多用于系统管理和集成。
67、动态语言有什么特点?它与脚本语言究竟有什么分别?
动态语言能在程序运行期间改变数据结构、函数定义、对象行为或指令流程等,相比静态语言在结构和功能上的更具动态性。
动态语言重在优化人工时间而非机器时间,因此相比静态语言,其开发效率较高,但运行效率较低
脚本语言与动态语言尽管并不完全重合,但更多地还是提法上的区别。前者强调作为命令行工具和粘合工具的语言用途,后者强调动态的语言特征。当脚本语言不再局限于粘合语言,从专用语言发展为通用语言,并且胜任复杂的应用开发的时候,动态语言的提法显然更加合理。
68、动态语言也能用于大型应用开发吗?
动态语言的以下特点决定了它在大型应用开发中的价值:代码量较少,从一定程度减轻了维护难度;不少提供了字节码编译或JIT编译,弥补了运行效率上的不足;一些模块的结构和功能上的变化不会导致相关模块的重新编译和连接;具有灵活、适应力强和开发周期短的特点,能快速响应客户需求的变化,并且适合快速原型开发。
69、动态语言会最终取代静态语言吗?
静态语言安全稳定、性能优越、成熟普及,并且逐渐开始吸纳动态语言的一些优点,这些都决定了它不可能被后者完全替代。 

70、为什么那么多人对某些编程语言都有浓厚的宗教情结?
凡事因了解而喜爱,因无知而憎恶。
破除语言的宗教情结,保持自我批判的勇气和精神。
71、存在至高无上的语言吗?
过分拔高一种语言与抹煞语言之间的差别是两种极端观点,皆不可取。
72、“语言不过是工具,其实都差不多”。这种论调正确吗?
每种语言都有其特到之处和不足之处,与其抱怨争执,不如扬长避短。
73、IDE、框架、设计工具等比语言更重要吗?
编程语言是程序员的立身之本。切不可本末倒置,忽视语言的学习,却热衷于挖掘IDE、框架、设计工具等的新功能。
74、语言是低级的代名词,设计是高级的代名词吗?
语言不等于低级,设计也不等于高级。
75、架构师就不关心语言了吗?
架构师同样关心语言,并且需要对语言有更深更广的认识。 

76、为什么C++不支持自动垃圾回收?
C++对C语言的兼容是其成功的一个重要因素,但同时也继承了C的一些缺陷。
C++设计者没有直接支持自动垃圾回收,是担心它造成过大的时空开销,同时会削弱底层开发能力。
77、在C++中如何解决内存释放问题?
除了手工释放内存外,C++提倡运用RAII原则解决包括内存在内的资源管理问题。
“RAII 是Resource Acquisition Is Initialization的缩写,直译为‘资源获取即初始化’。”冒号解释,“其实更准确的叫法应该是RRIF(Resource Release Is Finalization),即‘资源释放即终结化’[4]。其思想是:将资源的取放与某一对象的生命周期绑定,初始化对象时获取资源,终结化对象时释放资源。用户代码不再直接管理资源,只需控制相应的对象即可。这样代码得以简化,资源的有效性也得以保障,并且还是异常安全的(exception- safe)[5]。” 
78、系统语言有哪些特点?
优化机器的时间而不是人的时间,优化机器的记忆而不是人的记忆;假设编译器是愚蠢的而程序员是聪明的,因此赋予程序员更多的权利、义务与责任
79、在不引入OOP的前提下,C语言可以借鉴C++的哪些特征?
 C可以借鉴C++的 命名空间、重载、异常处理和STL等非OOP的特征。
80、D语言比C++有哪些改进?
D语言提供了可控制的垃圾回收器,支持线程同步、动态数组、嵌套函数和契约式设计,并废除了头文件和前置声明(forward declaration)。
81、在电脑性能日益提升的今天,还有必要在乎程序的性能和效率吗?
在程序性能与生产效率之间,系统语言更看重前者,它们在赋予程序员更多的权利的同时,也带给程序员更多的负担。
程序的性能和效率永远是重要的。一方面,用户对软件性能的期望越来越高;另一方面,有时硬件性能与软件需求并不匹配:有些应用(如人工智能、大型计算)对程序的性能和效率要求极高,有些系统(如嵌入式系统)的资源十分有限。 


闭包应用场景:
1、保护函数内的变量安全。以最开始的例子为例,函数a中i只有函数b才能访问,而无法通过其他途径访问到,因此保护了i的安全性。
2、在内存中维持一个变量。依然如前例,由于闭包,函数a中i的一直存在于内存中,因此每次执行c(),都会给i自加1。
82.在C++的基础上,Java 与C#作了哪些改进?
相比C++,Java与C#更加安全(限用指针、数组边界检查、类型安全、资源管理等)、简单(自动垃圾回收、废除多继承和头文件等)、中性(编译成机器无关的字节码,运行于虚拟机)、OO(无全局变量和函数等)、丰富(支持反射和并发编程、更完备的API等)、标准(注释性文档、更好的Unicode支持等)。
83.Java与C#在设计理念上有何不同?
Java的目的是让一种语言在多种平台上运行,而C# (.NET)的目的是让多种语言在一种平台上运行。Java重在语言,让语言向平台扩散;C#重在平台,让平台来凝聚语言。
84.Java 与C#是如何互相借鉴的?
在Java1.5的增强特征中,有不少C#的影子。如增强版的for循环;可变长参数(varargs);自动装箱(autoboxing);类型安全的枚举(typesafe enum)等等。此外,支持元数据的的注释(annotation)与C#的特性(attribute)大同小异,C#从Delphi中引入的属性(property)也出现在Java 7的提案中。
85.Java与C#为什么擅长企业应用开发?它们能作系统开发语言吗?
虽然系统开发并非Java与C#的禁区,它们更多地还是用于企业级应用开发。丰富的资源、强大的整合能力和巨头公司的鼎力支持是它们得天独厚的优势。编程语言的发展是技术和商业合力推动的结果。

86、Visual Basic和Delphi有何共同点和不同点?
Visual Basic和Delphi均擅长可视化快速应用开发,易学易上手,常用于前台的桌面应用。
Delphi相对VB的优势在于:可视化框架更优秀;运行效率更高;不限于Windows;支持指针。
VB相对Delphi的优势在于:学习曲线更短;便于扩展开发包括MS Office在内的应用程序;与.NET平台更融合(主要指VB.NET);有大公司(微软)的支持。
87、相比其他的富客户端技术,JavaScript的前景如何?
以JavaScript为核心的DHTML和AJAX技术,相比其他的富客户端技术有其明显的优势:标准、普及、成熟、毋需插件、对搜索引擎友好。
88、JavaScript是一门严肃的语言吗?
作为弱类型的动态语言,JavaScript有它的一些问题:基于原型的对象式令人陌生;API相对贫乏;浏览器标准不够统一;IDE和调试工具不够理想;多由不够专业的程序员编写等等。但它本身是一门功能齐全、强大而优美的语言,只要严肃地对待它,它就是一门严肃的语言。
89、前台编程、后台编程与系统编程,哪个最难?
前台编程涉及面专,更关注界面设计;后台编程涉及面广,更关注业务逻辑;底层编程涉及面深,更关注系统资源。它们只是侧重点有所不同,并无真正的难易之别、高下之分。
90、Perl、Python、Ruby和PHP各自有何特点?
Perl凝练晦涩,Python优雅明晰,Ruby精巧灵动,PHP简明单纯
Perl精练、复杂、强大、灵活、自由、隐晦、表现力强,但规范性、可读性、一致性、整洁性和可维护性较差。
Python优雅规范、简洁明晰、易学易用、类库丰富,但效率稍差,有些人不喜欢它对空白符敏感的特性。
Ruby语法精巧、高度灵活,兼具Perl的表现力和Python的可读性,尤其注重程序员的感受,但其性能和线程模型尚有待改进。
PHP简单、专一、实用、流行,在但相比其他三种语言,在语法和功能上稍有欠缺。
91、为什么动态语言多作为轻量级的解决方案?
比起Java平台和.NET平台,动态语言轻便灵活、开发效率高,但整合凝聚力还不够,在运行效率、类型安全、可用资源、开发工具、技术支持以及影响力等方面也有一定差距,故通常作为轻量级的解决方案。
92、LAMP为什么受欢迎?
LAMP是由Linux、Apache、MySQL和包括PHP、Perl、Python或Ruby在内的脚本语言组成的网络开发平台,具有开放灵活、开发迅速、部署方便、高可配置、安全可靠、成本低廉等优点。
93、Ruby on Rails为什么会流行?
RoR是一种轻量级套餐式的web应用解决方案,是由好的设计(MVC架构和CoC、DRY原则)加上好的语言(Ruby)在好的时机(web2.0和敏捷开发风行之际)打造出的好的框架。
94、编程语言的发展趋势是什么?
静态语言与动态语言从语言特征到运行环境都在逐渐融合。
程序员应该与程序语言一样,既要有自己的专长,又要向通用化和全能化发展。
编程语言惯例用法、哲学理念和编程范式形成了语言的编程风格。

95、什么是抽象?它在软件开发中有什么作用?
抽象是去粗取精以化繁为简、由表及里以异中求同,是对问题作减法和除法。
抽象既有角度之分,也有程度之别。
编程范式的风格差异和编程语言的级别高低,都取决于各自提供的抽象机制。
软件设计者利用抽象来完成从现实世界到虚拟世界的多对一映射。
96、软件开发的分析阶段、设计阶段和实现阶段各自的主要任务和抽象方法是什么?
在软件开发过程中,分析阶段的主要任务是在问题领域和业务需求的基础上制定功能规范;设计阶段的主要任务是在分析的基础上制定实现规范;实现阶段则在设计的基础上完成软件编码。
97、什么是参数抽象和规范抽象?它们各有什么好处?
抽象贯穿软件开发的核心过程;分析阶段多采用性质导向式抽象;设计阶段则采用模型导向式抽象;实现阶段多采用参数抽象和规范抽象;
性质导向式抽象侧重于描述系统性质,因而是定性的,抽象程度较高;模型导向式侧重于建造数学模型,因而是定量的,抽象程度较低。
参数抽象增强了软件模块的普适性和重用性。
规范抽象在使用者与实现者之间建立了一种契约,使代码的功能与实现相分离。它一方面规范了实现者的义务,另一方面又保障了使用者的权利。规范可以用通俗的自然语言在文档中注释,也可以用精确的形式规范语言来表达。
规范抽象的好处:文档性--程序员不必阅读代码即可正确使用;局部性---对某一抽象的实现代码的阅读或改写不会涉及其他抽象的实现;可变性---修改实现代码不会影响其他代码。
98、什么是契约式编程?它与防御性编程有什么关系?
契约式涉及通过编程语言的内建支持或引入形式规范语言,对规范抽象的语义契约实施保障,以增强软件的规范性和可靠性。一些语言支持断言,对契约式设计的部分支持。
先验条件是客户方的承诺,后验条件是服务方的承诺。
防御性编程的缺陷:重复检查先验条件、增加程序员的负担和困惑、职责不清晰。
防御性编程一般处理难以防止或预测的异常(多由于终端客户的误用或硬件问题),采用“先兵后礼”的策略,重在保证软件的健壮性;契约式编程一般处理不应发生的异常(多由于程序员的错误),采用“先礼后兵”的策略,重在保证软件的正确性。二者互补共生,为软件的可靠性提供保障。
在契约式设计中,实现中包含设计----在语言层面上保证接口设计的规范性;在模型驱动架构中,设计中包含实现--模型语言UML可以作为高级的编程语言来使用。
99、软件设计与软件实现之间的差别是什么?
把握抽象的级别比区分设计与实现更重要。抽象程度越高,越接近设计,越远离实现,相应的语言也越高级。
抽象本身并不能解决问题,但却是解决问题的必经之路。通过抽象能简化和分解问题,使之更容易理解和控制,相应的解法也更具稳定性、普适性、重用性和可维护性。
100、编程中常用到哪几类抽象?它们各有什么特点和作用?

101、抽象数据类型与数据结构的关系是什么?
数据结构与抽象数据类型同为数据与运算的有机集合体,常可看做同一事物的两个方面。前者强调具体实现,多从实现者和维护者的角度来考虑;后者强调抽象接口,多从设计者和使用者的角度来考虑。
102、抽象数据类型与具体数据类型的区别是什么?
具体数据类型一般只是被动地作为数据储存或打包的工具,很少行为特征,与实现细节紧密相关。
103、数据抽象分别给使用者和开发者带来什么好处?
数据抽象依赖于规范,包括所有的接口规范和数据类型的整体规范
带来的好处:接口与实现的分离,有利于开发时间的分配和开发人员的分离。
对接口编程,而不是对实现编程
104、OOA、OOD、OOP各有何侧重?
OOA阶段以对象而不是过程为中心,OOD以接口而不是实现为中心,OOP以数据而不是算法为中心。
105、OOP的核心和起源是什么?
抽象尤其是数据抽象是OOP的核心和起源,是封装、继承和多态的基础。

106、封装与信息隐藏是一回事吗?
信息隐藏是一种原则,而封装是实现这种原则的一种方式
107、封装的意义何在?
广义的封装是把一些数据和方法捆绑在一起,从而引入了一种被称为类的模块,并使函数(方法)的调用更简洁、更符合认知模式。
狭义的封装从语法上强化了抽象,即用户不仅可以从高层接口来对待一类对象,而且不用关心也无权访问底层实现。
108、如何有效地实现信息隐藏?
信息隐藏的关键是掩盖实现细节,包括内部数据结构和算法逻辑。但知易行难,常见的错误有:将可变的内部对象引用作为返回值;将可变的对象引用直接赋值给内部对象;没有进行必要的深拷贝;接口方法的参数或返回值类型不够抽象;在方法命名上透露实现策略等等。
109、访问控制真是牢不可破的吗?
访问控制不仅是一种语法限制,也是一种语义规范,明确地将接口与实现分离开来。
访问控制不是牢不可破的,C++可以通过指针、JAVA和C#可以通过反射来绕过访问限制。
110、值对象与引用对象的区别是什么?
值对象重在值而非同一性,引用对象重在同一性而非值,如果值对象是可变的,往往要利用值拷贝来防止因同一性而导致的意外同步变化。
从宏观上看,知识是延伸想通、大道合一的;从微观上看,知识又是至精至微、各具奥妙的。
抽象与封装是OOP的关键所在

许多编程设计思想包括OOP的思想都是以提高应变力为主题的,能保证代码永远不变的软件有更好的归宿:要么退化为硬件,要么进化为人件。软件要想有高度的可重用性,必须以高度的应变性为前提。

111、编程究竟难在何处?
逻辑的复杂性和需求的变化性
软件质量的一个重要因素生意适应变化的能力,这也是许多编程设计思想针对的主题
112、信息隐藏的目的是为了保证软件安全吗?
信息隐藏屏蔽了一个模块中非本质、容易变化的部分,从而保证内部修改不会波及客户。它的目的是提高软件的应变性和灵活性,而不是安全性。
113、软件的变化主要来自哪些方面?
软件变化主要来自于两个方面:一个以改善软件质量为目的的内在结构性变化;一个是以满足客户需要为目的的外在功能性变化。
114、桥梁模式有什么好处?
信息隐藏能将接口与实现从逻辑上分离,桥梁模式则进一步将二者从物理上分离,从而使代码具有更强的应变能力。在C++中,桥梁模式(也称Pimpl惯用法)还能减少各类之间在编译器的依赖性,从而节省编译链接时间。
115、什么开闭原则?它有何重要意义?
开闭原则(OCP)指软件实体(类、模块、函数等)应对扩展开放、对修改封闭。开闭原则是编程设计(包括OOD)的一个重要准则,对提高软件应变能力尤具有指导意义。遵循这一原则的关键在于合理地引入抽象,特别是抽象接口。
软件重用性是建立在应变性的基础上的。

116、选择访问修饰符的基本原则是什么?
使类和成员的可访问性极小化
117、为什么域成员一般都采用private修饰符?
除具体数据类型和private内部类的域成员和静态常量域外,域一般都应该用private来修饰。
原则上,在设计好一个类的接口后,将接口公开,其他的都隐藏。有些抽象类会提供一些protected接口供子类服务。少数用于包内部的接口用包级控制(Java中默认的package、C#中的internal)
118、嵌套类有何好处?
嵌套类提供了新的类结构层次化的方式。若使用得当,有利于结构的紧凑清晰和信息隐藏。
119、C++中的friend修饰符对封装是一种破坏吗?
C++中一个类与其友类或友函数是联合关系而非主客关系。合理地使用friend修饰符,不仅不会破坏封装,相反能加强封装。
120、访问控制的本质是什么?它有哪些作用?
访问控制划分了抽象的边界,从语义上将抽象层次化,从语法上保护主客双方的代码不受彼此影响
访问控制是对静态关联代码的控制,划分了代码修改的边界。
访问控制使得类的接口层次化、职责层次化、服务层次化、客户层次化。
121、什么是客户意识?它为什么容易被忽视?
重视培养客户意识和责任感,不可轻诺寡信
不要为追求重用而轻易扩大接口范围。

122、一个类提供的服务应满足哪些条件?
一个类提供的服务要有可靠性、稳定性、纯粹性和完备性。
123、享受类的服务时应注意些什么?
应遵守规则、遵循规范
124、如果在阅读文档之后仍对一个类的用法存在疑问,应如何处理?
使用类时应以规范文档为依据,不能以源代码为依据。前者代表抽象接口,后者代表具体实现。如果文档不够明确,应尽可能地与作者通过不断改进的提交文档来交流。
125、访问控制能完全保证封装吗?
访问控制只能维护语法上的封装和信息隐藏,而语义上的封装只能靠规范来维护。对程序员来讲,前者是一种知识,后者是一种素质。
126、如何构建既可靠又灵活的系统?
如果对象个体都能保证服务的信誉和品质、能遵守服务的规则和规范,就能构建出既可靠又灵活的系统整体。

127、继承有哪几种方式?
从子类到超类的泛化,是一种概念抽象的过程;从超类到子类的特化,是一种概念细化的过程。两种过程在设计中往往是交替采用的。
泛化是一种概念关系,继承是一种语言机制。
继承有3类:只继承实现(如C++中非公开继承);只继承接口(如JAVA和C#中继承interface);既继承实现又继承接口(如JAVA和C#继承class)。后两种分别又被称为接口继承和实现继承。
继承主要是一种规范的技巧,而不是一种实现的技巧。
128、实现继承与接口继承有何区别?
实现继承消费可重用的旧代码,接口继承生产可重用的新代码。后者更符合OOP“自底向上”的设计理念。
设计类时要有历史责任感---履行所有超类型所承诺的职责,要有主人翁精神----多考虑如何为其他类提供服务。
129、什么是里氏代换原则?它与开闭原则有何内在联系?
子类型具有可代换性。
类型A的子类型B应该满足下面的条件:将程序中类型A的对象置换为类型B的对象,不会影响程序的合理性和正确性。这是里氏代换原则。
里氏代换原则让规范抽象从单个类型扩展到类型族。
接口继承在遵循里氏代换原则的前提下,通过接口重用达成规范重用,保证了多态抽象,进而维护了开闭原则,让客户代码不用修改就能得到扩展。
由于实现继承在继承实现的同时也继承了接口,故也应遵循里氏代换原则。这既是一种义务,也是一种权益。
语法与语义应尽可能地契合,以减少代码中的逻辑隐患。
130、is-a关系与继承关系是等价的吗?
is-a或is-a-kind-of是判断继承关系的必要条件,而非充分条件。
继承关系用behaves-like-a或is-substitutable-for来表述更准确。
131、继承只是为了代码重用吗?
继承的主要作用:通过实现继承完成代码重用;通过接口继承完成代码被重用;建立概念的分类体系。
132、类与类型、子类与子类型有何区别?
类型的概念取决于它的行为规范,而非其命名所引发的认知。
概念抽象只是手段,规范抽象才是依据。
子类型应该保持或强化超类型的规范。
子类型不能强化超类型的先验条件,不能弱化超类型的后验条件和类不变量。
类偏重语法,强调实现方式;类型偏重语义,强调行为方式。类是实现,类型是接口。
133、为什么说多态抽象是数据抽象的推广?
两种分离类的接口与实现的方式:在语义上通过数据抽象得到接口,在语法上通过封装隐藏实现;在语义上通过多态抽象得到接口,在语法上通过集成隐藏实现。这两对“接口/实现”构成了OOP的主体特征,其中后一对的抽象层次更高。编程应优先针对高层的抽象接口。

你可能感兴趣的:(其他)