【快速学习系列 - 阅读笔记 - 02】《程序员面试宝典》

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/jiangsgyx/article/details/83102858

1)C语言中的整数自动转换原则:当表达式中存在有符号类型和无符号类型时,所有的操作数都自动转换为无符号类型。

注1:在有符号与无符号数据进行混合运算时,需要特别注意该原则,否则可能得到错误的结果。

2)C++中的隐式类型转换:在混合类型的算术表达式中最宽的数据类型成为目标转换类型;用一种类型的表达式赋值给另一种类型的对象时,目标转换类型是被赋值对象的类型;把一个表达式传递给一个函数,调用表达式的类型与形式参数的类型不同时,目标转换类型是形参的类型;从一个函数返回一个表达式的类型与返回类型不同时,返回的表达式类型自动转换成函数类型。

3)算术转换的两个通用指导原则:为防止精度损失,类型总是被提升为较宽的类型;所有含有小于整型的有序类型的算术表达式,在计算之前,其类型都会被转换成整型。

4)不使用任何中间变量交换a,b的值:“a = a^b; b = a^b; a = a^b;”。

5)不用判断语句找出两个变量中的大者:“int max = ((a+b)+abs(a-b))/2;”。

6)在C++程序中调用被C编译器编译后的函数时,由于C++支持函数重载,而C不支持,所以经过C++编译后的库中的函数名会与C中的不同,通过使用C++提供的C连接交换指定符号extern “C”可以解决名字匹配的问题。

注1:在C函数与C++函数混用的程序中,需要特别注意此点。

7)头文件中的#ifndef/define/endif宏定义用于防止该文件被重复引用。

注1:建议在头文件编写时,统一使用该宏定义。

8)#include <filename.h>表示编译器将从标准库路径开始搜索该文件;#include “filename.h”表示从用户的工作路径开始搜索。

9)C++编译程序时定义了__cplusplus;C定义了__STDC__。

注1:__cplusplus为cpp预定义宏,表示当前代码按照C++进行编译;__STDC__是预定义宏,表示编译器将会按照ANSIC标准进行C代码的编译。

10)宏定义展开时容易造成二义性问题。

注1:建议宏定义中多使用小括号(),明确指出各种运算的优先级关系。

11)C语言中,const的用途包括:定义const常量(只读变量);修饰函数的参数和返回值(在C++中亦可以修饰函数的定义体),被修饰的部分均受到强制保护,可以预防意外的变动,能够提高程序的健壮性。

12)合理使用关键字const,可以使编译器很自然地保护那些不希望被改变的参数,防止其被无意的代码修改,从而减少Bug的出现。

13)const与#define的差别:const常量有数据类型,而宏定义没有,所以编译器可以对前者进行类型安全检查,而对后者只能进行字符替换,并且在替换过程中可能会出现边际效应问题;某些集成化调试工具可以对const常量进行调试;在C++中通常使用const常量,而尽量避免使用宏定义。

14)C默认const是外部链接的,而C++默认是内部链接的。

注1:内部链接是指由const修饰的只读变量,仅在定义文件内可见;若extern和const联合使用,则强制转为外部链接属性,可以在其它文件中使用。

15)当结构体内的元素的长度都小于处理器的位数时,便以结构体内最大的数据元素为对齐单位,结构体的长度一定是最长的数据元素的整数倍。

16)数据对齐是指数据所在内存地址必须是该数据长度的整数倍。

17)对于一个类而言,即便其为空类,编译器仍要给它分配一个空间,其空间大小为1个字节;多重继承的空类所占空间也是1个字节。

18)因为静态变量是存放在全局数据区的,而sizeof仅计算栈中分配的空间大小,故不会将其计算在内。

注1:在计算变量存储空间大小时,需要特别注意sizeof所计算的变量是否静态变量。

19)计算结构变量的大小就必须讨论数据对齐问题。

注1:参见15)和16)的内容。

20)sizeof的使用场合包括:与存储分配和I/O系统例程进行通信;查看某类型对象在内存中所占的单元字节;在动态分配对象时,可以让系统知道需要分配多少内存空间;便于一些类型的扩展(充);由于操作数的字节数在实现时可能出现变化,建议在涉及到操作数字节大小时使用sizeof代替常量计算;若操作数是函数中数组形参或函数类型形参,sizeof可以给出其指针的大小。

21)内联函数(inline)和宏定义(#define)的差别:内联函数和普通函数相比,可以加快程序的运行速度,因为其不需要中断调用,在编译时直接被嵌入目标代码中,减少了函数调用时的资源消耗,而宏定义只是简单替换;内联函数需要进行参数类型检查;宏定义不是函数,只是在编译前(编译预处理阶段)将程序中的相关字符串替换为宏体,内联函数是函数,但是在编译中不单独产生代码,而是将有关代码嵌入到调用处。

22)内联函数的一般应用场景为:一个函数不断被重复调用;函数只有简单几行,且不包含有for/while/switch语句。

23)指针允许直接获取和操作数据地址,实现动态存储空间分配。

24)指针和引用的差别:非空区别,指针可指向空值,引用不可;合法性区别,使用引用前不需要测试其合法性,而指针则应该总被测试,以防其为空;可修改区别,指针可以被重新赋值指向另一个不同的对象,而引用在初始化后则不能改变,其指定对象的内容可以改变;应用区别,若总是指向一个对象并且一旦指定后就不会改变指向,则可选用引用。

25)类的this指针是在实例化一个对象后产生的,并且指向对象本身,其特点有:只能在成员函数中使用;在成员函数的开始前构造,在成员函数结束后清除。

26)空指针和迷途指针的区别:当delete一个指针时,实际上仅是让编译器释放内存,但指针本身依然存在,这时它就是一个迷途指针,当使用语句“MyPtr = 0;”时,可以把迷途指针改为空指针。

27)malloc/free是C++/C语言的标准库函数,new/delete是C++的运算符,其均可用于申请和释放内存空间。

28)句柄是一个32位的整数,是一种指向指针的指针,实际上是Windows系统在内存中维护的一个对象内存物理地址列表的整数索引。

29)句柄和指针是两个截然不同的概念,Windows系统用句柄标记系统资源,隐藏系统信息;指针则标记某个物理内存地址。

30)标准模板库(STL,Standard Template Library)是一个基于模板的容器类库,包括链表、列表、队列和堆栈,其是可重用的,在不同的操作系统间是可移植的。容器是包容其他对象的对象。STL容器有两种类型:顺序(提供对其成员的顺序访问和随机访问)和关联(经过优化关键值访问它们的元素)。

31)泛型编程是一种基于发现高效算法的最抽象表示的编程方法。

32)容器部分主要由头文件<Vector>、<list>、<deque>、<set>、<map>、<stack>和<queue>组成。

33)面向对象技术的基本概念:对象、类、继承。

34)对于一个空类,编译器默认产生4个成员函数:默认构造函数、析构函数、拷贝构造函数和赋值函数。

35)class中变量默认是private,而struct中为public。

36)必须使用静态成员变量在一个类的所有实例间共享数据。

37)封装:代码模块化;继承:代码重用;多态:接口重用。

38)多态的本质就是将子类类型的指针赋值给父类类型的指针(在OP中是引用),只要这样的赋值发生,多态就产生了,因为实行了“向上映射”。

39)公有继承(public)、私有继承(private)和保护继承(protected)是常用的三种继承方式。

40)heap是堆,stack是栈。stack的空间由操作系统自动分配和释放,其空间有限;heap是很大的自由存储区。

41)strcpy函数只能够拷贝字符串;memcpy函数可以拷贝任意类型的数据。

42)黑盒测试是针对产品功能进行测试;白盒测试是针对程序逻辑进行测试。

43)C#兼具VB的快速简练、Delphi的可视化控件编程、Java的完全面向对象和C++的语法规则。

44)进程是程序的一次执行;线程可以理解为进程中执行的一段程序片段。

45)现在最常用的进程间通信方式有:信号、信号量、消息队列、共享内存。

46)存储过程是用户定义的一系列SQL语句的集合,涉及特定表或其他对象的任务,用户可以调用存储过程,而函数通常是数据库已定义的方法,它接收参数并返回某种类型的值,并且不涉及特定用户表。

47)事务是作为一个逻辑单元执行的一系列操作。

48)路由器是网络层硬件设备,主要处理IP包并用IP地址进行路由选择;交换机是链路层硬件设备,主要处理帧,通过帧的物理地址来交换信息,并选择把信息发给哪个网络。

49)交换机(Switch)和集线器(HUB)的最大不同就是能够隔离冲突域,这个过程必然要对物理地址进行选路。

注1:此处的物理地址是指MAC地址,用来表示互联网上每一个站点的标识符,采用十六进制数表示。

猜你喜欢

转载自blog.csdn.net/jiangsgyx/article/details/83102858