面试的书籍主要是参考《王道程序员求职宝典》这本书来复习的,这本书列出了很多零散的知识点,还是蛮值得一看的。
标准库提供的字符串处理函数:
1. strlen(s)
2. strcmp(s1,s2)
3. strcat(s1,s2)
4. strcpy(s1,s2)
5. strncat(s1,s2,n)
6. strncpy(s1,s2,n)
传递给这些标准库例程的指针必须具有非零值,并且指向以NULL结束的字符数组,其中的一些标准库函数会修改传递给它的字符串。这些函数将假定它们所修改的字符串具有足够大的空间接收本函数新生成的字符,程序员必须确保目标字符串必须足够大。
void * memcpy(void * desc,const void * str,size_t n)
从源src指向的目标地址的起始位置开始拷贝n个字节到目标desc所指向的内存地址的起始位置中,函数返回指向desc的指针。
strcpy和memcpy的区别:
1. 复制的内容不同,strcpy只能用于复制字符串,memcpy可以复制任意内容。
2. 复制的方法不同,strcpy不需要指定长度,它遇到被复制字符的串结束符’\0’才结束,memcpy根据第3个参数来决定。
3. 用途不同,复制字符串时用strcpy,复制其他类型时用memcpy。
void * memset(void * s,int ch,size_t n)
将s中前n个字节用ch替换并返回s。
字符串转换为整数需要考虑的三个问题:
1. +-号问题
2. 字符是否有效的问题
3. 整数是否溢出的问题
在一个字符串中找到第一个只出现一次的字符:
1. 使用一个hash表(记录下每个字符出现的次数)
2. 两次遍历
判断一个字符串中所有字符是否相同:
- hash表
- 为了节省空间,可以使用bitmap
- 作位运算(异或)
自定义str 的函数时需要特别注意三点:
- 断言asssert,判断输入指针是否为NULL
- 返回值(char*),为了支持链式调用
- const修饰(输入参数要加,输出参数不能加)
char数组移除字符就是要将整个数组移动,使用两个指针。
printf函数数据类型大小大于占位符时会出现问题如:
printf(“%d”,long long)
“%d”只会寻址四个字节,但是long long 类型的数据会有8个字节入栈。
printf打印long long时需要特别注意。
enum 枚举类型名
{
枚举常量1[=整型常量] ,
枚举常量2,
...
}[变量名列表];
花括号内的内容成为枚举表,其中的每一项称为枚举变量。
sizeof是单目运算符,它的计算发生在编译时刻。
sizeof可以对一个函数调用求值,其结果是函数返回类型的大小,函数不会被调用,注意是函数调用,不是函数。
C99标准规定,函数,不能确定类型的表达式以及位域成员不能被计算sizeof值。
#pragma pack(n)
枚举只是定义了一个常量集合,里面没有元素。枚举类型是当做int类型存储,故而枚举类型的sizeof为4。
sizeof求字符数组时千万不要忘记最后的’\0’。
异或运算符有一个性质:两个相同的数异或结果为0,0与任意数异或的结果为该数。
异或和按位或的应用:
1. 交换两个数
2. 不用算术运算符实现加法
3. 求平均值
移位运算符优先级比算术运算符低,所以要特别注意加上括号。
在C++中,有符号数与无符号数转换时,内存中的内容并没有改变。只是对内容中相同的数据解释不通而已。
- 整型提升
bool,char,unsigned char,signed char,short,signed short都会提示为int。 - 运算时的转换
int(signed int)->unsigned int->long->unsigned long->float->double->long double
new和delete是C++中的运算符:
1. 首先调用operator new的标准库函数
2. 调用构造函数
malloc和new的异同点:
相同点:
都可以用于申请动态内存和释放内存。
不同点:
1. malloc与free是C/C++语言的标准库函数,new/delete是C++中的运算符。
2. new自动计算需要分配的空间,而malloc需要手工计算字节数。
3. new是类型安全的,malloc不是。
4. new调用operator new 分配足够的空间,并调用相关对象的构造函数,而malloc不能调用构造函数。
5. malloc/free需要库文件支持,new/delete则不需要。
局部变量和全局变量重名时会覆盖掉全局变量,若要使用全局变量需要使用::或extern。
使用malloc需要注意3点:
1. 强制类型转换
2. 非空判断
3. free释放掉内存
inline说明对于编译器来说只是一个建议,编译器可以选择忽略。
在C++程序中调用被C编译器编译后的函数,需要加上extern “C”,C++运营是一种面向对象的编程语言,为了支持重载机制,在编译生成的汇编码中,要对函数的名字进行一些处理,比如加上函数的返回值类型等信息。而在C语言中只是简单的函数名字而已,不会加入其它信息。也就是说,C和C++语言对产生的函数的名字的处理是不一样的。这样在链接阶段若是按照C++的函数命名规则去查找C编译器编译的函数,就会出现链接错误。
没有默认构造函数的类类型成员,以及const类型的成员变量和引用类型的成员变量,都必须在构造函数初始化列表中进行初始化。
有一种特别常见的情况需要类定义自己的复制控制成员:类具有指针成员。
成员函数的隐藏:
1. 两个函数参数相同,但基类函数不是虚函数。
2. 两个函数参数不同,无论基类函数是否是虚函数。
定义类型转换函数,需要注意一下几点:
1. 转换函数必须是成员函数,不能是友元函数。
2. 转换函数不能指向返回类型,但是再函数体内必须用return语句以传值方式返回一个目标类型的变量。
3. 转换函数不能有参数。
基于引用计数的垃圾回收机制:
基于跟踪处理的垃圾回收机制:
- 标记-清除
- 标记-整理
- 标记-拷贝
reinterpret_cast:显示强制转换,用()实现。
const_cast:转换表达式的const性质。
static_cast:编译器隐式执行的任何类型转换都可由static_cast显示完成,仅当类型之间可由隐式转换时(除类层次之间的下行转换以外),static_cast的转换才是合法的。
dynamic_cast:必须是指针,类的引用或者void *,dynamic_cast设计运行时类型检查,dynamic_\cast主要用于类层次间的上行和下行转换。
海量数据处理,top k问题的通用解决方法:
1. 分治 –>使用hash进行映射
2. 堆排序
3. 快排中的分割思想
4. 位图bitmap
必须要root权限才能打开的端口为小于1024的端口。
应用不支持一般意义的赋值运算,因此没有引用类型的容器。
容易元素类型必须满足以下两个约束:
1. 元素类型必须支持赋值运算
2. 元素类型对象必须可以复制
源代码删除是删除死代码,死代码是指永远不会被执行到的代码。
单例模式:
1. 静态成员变量(指针)
2. 静态局部变量 返回引用,注意拷贝,赋值要为private。
3. 静态局部变量,返回指针
4. 考虑线程安全,异常安全,使用双重锁,静态成员变量(指针)