零碎知识点

C++

  1、逗号表达式是将括号中所有表达式的值算出来,但是只使用最后一个表达式的值。
  2、构造函数是可以私有化的,但一般不会这样做,因为私有化的构造函数不能被new到,并且类不能通过该私有构造函数初始化(可以调用静态方法初始化)。
  3、一个类中可以有任意个构造函数(可以函数重载),但只能有一个析构函数。无论何时,只要类的对象被创建,就会执行构造函数。
  4、类的静态数据成员只能在类内声明,类外定义和初始化。因为静态成员属于整个类,而不属于某个对象,如果在类内初始化,会导致每个对象都包含该静态成员,这是矛盾的。const的静态成员可以在类内初始化,是因为它既然是const的,那后面的程序就不会再去试图初始化了。
  5、当用#include“file.h”时,先搜索当前工作目录,如果没有,再去搜索标准库,库没有再搜索资源库;当用#include<file.h>时,编译器先从标准库开始搜索,如果没再搜索资源库目录,若还未找到则搜索当前工作目录。
  6、字符数组的复制要用strcpy()函数,不能直接用赋值操作符赋值。不能将数组的内容拷贝给其他数组作为初始值,也不能用数组为其他数组赋值。
  7、数组名就是数组首元素的地址,在用scanf函数输入的时候,不用加&。
  8、定义数组时可以对第一维的长度不指定,但第二维的长度不能省去。
  9、C++运算符是有优先级的,一般是算术运算符>关系运算符>逻辑运算符>条件运算符,所以运算符顺序是!(一元算术运算符)> !=(关系运算符)> &&(逻辑运算符)> ?:(条件运算符)
  10、内存对齐的3大规则:
  (1)对于结构体的各个成员,第一个成员的偏移量是0,排列在后面的成员其当前偏移量必须是当前成员类型的整数倍。
  (2)结构体内所有数据成员各自内存对齐后,结构体本身还要进行一次内存对齐,保证整个结构体占用内存大小是结构体内最大数据成员的最小整数倍。
  (3)如程序中有#pragma pack(n)预编译指令,则所有成员对齐以n字节为准(即偏移量是n的整数倍),不再考虑当前类型以及最大结构体内类型。
  11、✳是scanf函数中的一种修饰符,表示忽略该输入项,使用方法为:放在%与格式d(或者s,c等)之间,如:scanf(“%x%✳d%o”,&x,&y); 并且,scanf不能指明浮点数的精度。
  12、子类实现父类虚函数叫重写,不叫重载。父类有纯虚函数,子类可以不实现,此时子类仍是抽象类。
  13、继承类构造函数中,成员初始化列表同时出现对虚基类和非虚基类构造函数的调用时,虚基类的构造函数先于非虚基类的构造函数执行。
  14、C语言中&&是一种双目运算符,表示与运算,而当左边所给表达式或变量为0时,不再计算右侧,整个表达式为零。
  15、C语言中有数字三种表示:十进制、八进制(0开头)、十六进制(0x开头)。
  16、内联函数是指用inline关键字修饰的函数。在类内定义的函数被默认成内联函数。内联函数从源代码层看,有函数的结构,而在编译后,却不具备函数的性质。内联函数不是在调用时发生控制转移,而是在编译时将函数体嵌入在每一个调用处。编译时,类似宏替换,使用函数体替换调用处的函数名。一般在代码中用inline修饰,但是能否形成内联函数,需要看编译器对该函数定义的具体处理。
  17、结构化程序由三种基本结构组成,三种基本结构组成的算法只能完成符合结构化的任务。
  18、字符数组整体输入输出只是库函数里面用循环来完成一个一个元素的输入输出的,宏观上看上去就成了整体输入输出了。本质上说,与整型数组单个元素输入输出并没有区别,差别在于整型数组并不知道什么位置终止,需要人为地控制输入输出终止的条件,字符数组则很简单,输出默认’\0’终止,输入则默认空白字符或者换行。
  19、read是UNIX或类UNIX系统中的系统函数,而fread才是C库里面的库函数。
  20、在类定义时,无法使用构造函数,因而无法完成对象的初始化,类还没有定义完,不能初始化对象。只有在定义类对象时才会调用构造函数。
  21、一般成员变量需要在类内进行初始化。静态成员变量必须在类外初始化,int型静态成员常量在类中初始化。
  22、由于类的构造次序是由基类到派生类,所以在构造函数中调用虚函数,这个虚函数不会呈现出多态;相反,类的析构是从派生类到基类,当调用继承层次中某一层次的类的析构函数时往往意味着其派生类部分已经析构掉,所以也不会呈现出多态。(effeetive c++ 条款9)。
  23、虚函数可以声明为inline,因为加上inline只是我们对编译器的一种建议,是否为inline还得看编译器的选择。相反,内联函数不能为虚函数,因为函数的内联属性是在编译器确定的,是静态行为,而虚函数的性质是在运行期确定的,是动态行为,二者是矛盾的,所以要想作为内联函数,就不要将它写成虚函数。
  24、在C中使用malloc时不需要强制类型转换,因为在C中从void※到其他类型的指针是自动隐式转换的;在C++中使用malloc时必须要强制类型转换,否则会报错,因为C++是不支持void※类型隐式转换为其他类型的,但在c++中一般用new而不用malloc。malloc有一个参数。
  25、宏定义不做语法检查。预处理是在编译之前的处理,而编译的工作之一便是语法检查,所以预处理不做语法检查。
  26、C++中引入友元函数,是为在该类中提供一个对外(除了他自己意外)访问的窗口;这个友元函数不属于该类的成员函数,他是定义在类外的普通函数,只是在类中声明该函数可以直接访问类中的private或者protected成员。
  27、使用友元函数注意的要点:
    1)类中通过使用关键字friend来修饰友元函数,但该函数并不是类的成员函数,其声明可以放在类的私有部分,也可放在共有部分。友元函数的定义在类体外实现,不需要加类限定。
    2)一个类中的成员函数可以是另外一个类的友元函数,而且一个函数可以是多个类友元函数。
    3)友元函数可以访问类中的私有成员和其他数据,但是访问不可直接使用数据成员,需要通过对对象进行引用。
    4)友元函数在调用上同一般函数一样,不必通过对对象进行引用。
  28、程序占用三种类型的内存:静态内存、栈内存、堆内存;
  静态内存:用来保存局部static对象、类static数据成员以及定义在任何函数之外的变量。
  栈内存:用来保存定义在函数内的非static对象。
  堆内存:在程序运行时分配。
  分配在静态内存或栈内存中的对象由编译器自动创建和销毁。对于栈对象,仅在其定义的程序块运行时才存在;static对象在使用之前分配,在程序结束时销毁。动态对象的生存周期由程序(用户)来控制。
  29、数组指针和指针数组的区别:
  指针数组:首先它是一个数组,数组的元素都是指针,数组占多少个字节由数组本身的大小决定,每一个元素都是一个指针,在32 位系统下任何类型的指针永远是占4 个字节。它是“储存指针的数组”的简称。
  数组指针:首先它是一个指针,它指向一个数组。在32位系统下任何类型的指针永远是占4个字节,至于它指向的数组占多少字节,不知道,具体要看数组大小。它是“指向数组的指针”的简称。
  30、C语言中实数常数的科学表示法规定格式为:“实数e整数”或“实数E整数”,其中幂是整数,不能写成实数。e(或E)前后的实数和整数都不能省略掉。C语言规定。0开头的是八进制数,0x(0x)开头的是十六进制数。而八进制数数字是0~7,出现8是错误的。实数的小数点前后的数字都可以不写。
  31、逗号表达式的求解过程是:先求解表达式1,再求解表达式2。整个逗号表达式的值是表达式2的值。例如逗号表达式a=3+5,a+4,对此表达式的求解,赋值运算符的优先级别高于逗号运算符,因此应先求解a=3+5,经计算和赋值后得到a的值为8,然后求解a+4,得12,整个逗号表达式的值为12(a仍为8)。
  32、文件指针指向的是一块内存区域,这块区域存储着打开的文件的相关信息,包括文件读取指针当前位置、文件读取缓冲区大小等信息,并不是指向文件的。fscanf是从文件中格式化读取,fprintf是向文件中格式化写入。
  33、类的方法后面加了const后,该方法的实现中不能修改类的成员。
  34、文件读写操作的几种模式:
    r代表read的简写,+代表可读可写,w代表write,b代表bit二进制位,t代表text。

    r 打开只读文件,该文件必须存在。
    r+ 打开可读可写的文件,该文件必须存在(这里的写文件是指将之前的文件覆盖。
    rt 打开只读文本文件,该文本必须存在。
    rt+ 读写打开一个文本文件,允许读和写,该文件必须存在(这里的写文件是指将之前的文件覆盖。
    rb 只读打开一个二进制文件,该文件必须存在。
    rb+ 读写打开一个二进制文件,允许读和写,该文件必须存在(这里的写文件是指将之前的文件覆盖。

    w 打开只写文件,若文件存在,则文件长度清零,即文件内容会消失,若文件不存在则建立该文件。
    w+ 打开可读写文件,若文件存在,则文件长度清零,即文件内容会消失,若文件不存在则建立该文件(这里的读文件,同样需要使用rewind()函数)。
    wt 打开只写文本文件,若文件存在,则文件长度清零,即文件内容会消失,若文件不存在则建立该文件。
    wt+ 打开可读写文本文件,若文件存在,则文件长度清零,即文件内容会消失,若文件不存在则建立该文件。
    wb 打开只写二进制文件,若文件存在,则文件长度清零,即文件内容会消失,若文件不存在则建立该文件。
    wb+ 打开可读写二进制文件,若文件存在,则文件长度清零,即文件内容会消失,若文件不存在则建立该文件。

    a 以附加的方式打开只写文件,若文件不存在,则建立文件,存在则在文件尾部添加数据,即追加内容。
    a+ 以附加的方式打开可读写文件,不存在则建立文件,存在则写入数据到文件尾(这里的读文件,同样需要使用rewind()函数,但是写文件不需要rewind()函数,a是追加)。
    at 文本数据的追加,不存在则创建,只能写。
    at+ 读写打开一个文本文件,允许读或在文本末追加数据(这里的读文件,同样需要使用rewind()函数,但是写文件不需要rewind()函数,a是追加)。
    ab 二进制数据的追加,不存在则创建,只能写。
    ab+ 读写打开一个二进制文件,不存在则创建,允许读或在文本末追加数据(这里的读文件,同样需要使用rewind()函数,但是写文件不需要rewind()函数,a是追加)。
  35、静态局部变量和全局变量的区别:静态局部变量虽然和全局变量都存放在全局数据区,延长了生命周期,但是作用域不同!静态局部变量仍然是个局部变量,只对函数内可见。
  36、栈空间上面的局部变量默认初始化为随机值。全局整形变量和静态static整形变量默认初始值为0。
  37、c++中包含纯虚函数的类称为抽象类,由于抽象类中包含了没有定义的纯虚函数,所以不能定义抽象类的对象。
  38、抽象类只能用作其他类的基类,不能定义抽象类的对象。抽象类不能用于参数类型、函数返回值或显示转换的类型。抽象类可以定义抽象类的指针和引用,此指针可以指向它的派生类,进而实现多态性。
  39、逻辑运算符的优先级:! > && > ||。!运算符比许多C++运算符具有更高的优先级。因此,为了避免错误,应始终将其操作数括在括号中,除非打算将其应用于没有其他操作符的变量或简单表达式。
  40、运算符优先级:!> 算术运算符 > 关系运算符 > (&& ||)> 条件运算符> 赋值运算符 > 逗号运算符。
  41、实型常量又称实数或浮点数。在C语言中可以用两种形式表示一个实型常量。
  小数形式:小数形式是由数字和小数点组成的一种实数表示形式,例如0.123、.123、123.、0.0等都是合法的实型常量。注意:小数形式表示的实型常量必须要有小数点。
  指数形式:这种形式类似数学中的指数形式。在数学中,一个可以用幂的形式来表示,如2.3026可以表示为0.23026×10^1 2.3026×10^0 23.026×10^-1等形式。在C语言中,则以“e”或“E”后跟一个整数来表示以“10”为底数的幂数。2.3026可以表示为0.23026E1、2.3026e0、23.026e-1。C语言语法规定,字母e或E之前必须要有数字,且e或E后面的指数必须为整数。如e3、5e3.6、.e、e等都是非法的指数形式。注意:在字母e或E的前后以及数字之间不得插入空格。
  42、程序运行的过程中,其值不能被改变的量称为常量。常量有不同类型,其中12、0、-5为整型常量。’a’’b’为字符常量。而4.6、-8.7则为实型常量。一个实型常量可以赋给一个 float 型、double 型或 long double变量。根据变量的类型截取实型常量中相应的有效位数字。
  43、用基类的指针指向不同的派生类的对象时,基类指针调用其虚成员函数,则会调用其真正指向对象的成员函数,而不是基类中定义的成员函数(只要派生类改写了该成员函数)。若不是虚函数,则不管基类指针指向的哪个派生类对象,调用时都会调用基类中定义的那个函数。
  44、virtual函数是动态绑定,而缺省参数值却是静态绑定。意思是你可能会在“调用一个定义于派生类内的virtual函数”的同时,却使用基类为它所指定的缺省参数值。结论:绝不重新定义继承而来的缺省参数值!(可参考《Effective C++》条款37)
例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class A
{
public:
virtual void func(int val = 1)
{ std::cout<<"A->"<<val <<std::endl;}
virtual void test()
{ func();}
};
class B : public A
{
public:
void func(int val=0)
{std::cout<<"B->"<<val <<std::endl;}
};
int main(int argc ,char* argv[])
{
B*p = new B;
p->test();
return 0;
}

p->test()执行过程理解:
(1) 由于B类中没有覆盖(重写)基类中的虚函数test(),因此会调用基类A中的test();
(2) A中test()函数中继续调用虚函数 fun(),因为虚函数执行动态绑定,p此时的动态类型(即目前所指对象的类型)为B✳,因此此时调用虚函数fun()时,执行的是B类中的fun();所以先输出“B->”;
(3) 缺省参数值是静态绑定,即此时val的值使用的是基类A中的缺省参数值,其值在编译阶段已经绑定,值为1,所以输出“1”;
最终输出“B->1”。所以记住上述结论:绝不重新定义继承而来的缺省参数值!
  45、char✳ strcpy(char ✳dest,char ✳src);将从src开始包含’\0’的字符串拷贝到以dest开始的位置,进行覆盖char✳ strcat(char ✳dest,char ✳src);将src开始的字符串添加到dest字符串的末尾(覆盖dest的\0”)两者都返回指向dest的指针。
  46、所谓的左值,说通俗一点就是可以被修改和引用的值,左值可以取地址。与之相对的就是右值。在使用时,左值可以作为右值,但右值不能作为左值。例如a++操作通过临时量返回其值,该值是一个常量,因此不能被修改(不是左值),而++a就是一个左值,可以修改。a++通过一个临时量temp返回其中值,该值是一个常量,并不是用户定义的那种可以引用,寻址的变量,不能对其进行修改或者赋值操作,只能将其用来赋值给其他左值。
  47、cin>> 该操作符是根据后面变量的类型读取数据。输入结束条件:遇到Enter、Space、Tab键。对结束符的处理:丢弃缓冲区中使得输入结束的结束符(Enter、Space、Tab)
  48、const只对它左边的东西起作用,唯一的例外就是const本身就是最左边的修饰符,那么它才会对右边的东西起作用。
  49、模板的实参是用来实例化类类型参数(typename)的,因此实参必须为有已确定内存空间大小的数据类型(指针、用户自定义类···);也不能为抽象类,可为具体类(抽象类的限制)。不是任意的数据类型。

网络

  1、斜杠记法标识子网掩码,/20的意思就是掩码中有20个1,用十进制表示,就是255.255.240.0 二进制中255有8个1,240是1111 0000有4个1,一共20个1。/24即255.255.255.0。
  2、HTTP状态码中400代表请求报文语法有误,服务器无法识别。
  3、https使用的是非对称加密,举例子就是A生成一个公钥A,发送给B。B收到后对称生成一个秘钥B并用A加密,发送给A。最后A接收到后用私钥得到秘钥B,之后A与B之间就可以利用秘钥B进行加密通信了,并不用每次做一次非对称加密。

java

  1、通常情况,JVM中使用类加载器的优先级是:根类加载器(bootstrap class loader)扩展类加载器(extensions class loader)系统类加载器(system class loader)用户类加载器(user class loader)。
  2、Java8的Stream中的中间操作方法:
  (1)过滤:filter()
  (2)截断流:limit()
  (3)跳过元素:skip(n)
  (4)筛选:distinct()
  (5)映射:map() flatMap()
  (6)排序:sorted()

数据库

  1、数据库中某一个字段的值并不唯一,但是需要创建索引加速查询速度,应该选择的索引类型为普通索引。即普通索引允许被索引列有重复值。
  2、

数据结构和算法

  1、采用插入方式构建一颗大小为n的红黑树的时间复杂度是:O(n*log(n))。
  2、