目录

81、 vector越界访问下标,map越界访问下标?vector删除元素时会不会释放空间?

82、 map[]与find的区别?

83、 STL中list与queue之间的区别

84、 STL中的allocator,deallocator

85、 STL中hash_map扩容发生什么?

86、 map如何创建?

87、 vector的增加删除都是怎么做的?为什么是1.5倍?

88、 C++ sort排序算法底层

89、 函数指针?

90、 C与C++的联系与区别

91、 C++中NULL和nullptr的区别

92、 C/C++内存分配

93、 c/c++的内存分配模型,详细说一下栈、堆、静态存储区?

94、 野指针是什么?如何检测内存泄漏?

95、 悬空指针和野指针有什么区别?

96、 内存泄漏

97、 内存溢出定位

98、 什么是内存对齐

99、 为什么内存对齐

100、 内存对齐规则


81、 vector越界访问下标,map越界访问下标?vector删除元素时会不会释放空间?

1.通过下标访问vector中的元素时不会做边界检查,即便下标越界。也就是说,下标与first迭代器相加的结果超过了finish迭代器的位置,程序也不会报错,而是返回这个地址中存储的值。如果想在访问vector中的元素时首先进行边界检查,可以使用vector中的at函数。通过使用at函数不但可以通过下标访问vector中的元素,而且在at函数内部会对下标进行边界检查。
2.map的下标运算符[]的作用是:将key作为下标去执行查找,并返回相应的值;如果不存在这个key,就将一个具有该key和value的某人值插入这个map。
3.erase()函数,只能删除内容,不能改变容量大小; erase成员函数,它删除了itVect迭代器指向的元素,并且返回要被删除的itVect之后的迭代器,迭代器相当于一个智能指针;clear()函数,只能清空内容,不能改变容量大小;如果要想在删除内容的同时释放内存,那么你可以选择deque容器。

82、 map[]与find的区别?

1.map的下标运算符[]的作用是:将关键码作为下标去执行查找,并返回对应的值;如果不存在这个关键码,就将一个具有该关键码和值类型的默认值的项插入这个map。
2.map的find函数:用关键码执行查找,找到了返回该位置的迭代器;如果不存在这个关键码,就返回尾迭代器。

83、 STL中list与queue之间的区别

1.list不再能够像vector一样以普通指针作为迭代器,因为其节点不保证在存储空间中连续存在;
2.list插入操作和结合才做都不会造成原有的list迭代器失效;
3.list不仅是一个双向链表,而且还是一个环状双向链表,所以它只需要一个指针;
4.list不像vector那样有可能在空间不足时做重新配置、数据移动的操作,所以插入前的所有迭代器在插入操作之后都仍然有效;
5.deque是一种双向开口的连续线性空间,所谓双向开口,意思是可以在头尾两端分别做元素的插入和删除操作;可以在头尾两端分别做元素的插入和删除操作;
6.deque和vector最大的差异,一在于deque允许常数时间内对起头端进行元素的插入或移除操作,二在于deque没有所谓容量概念,因为它是动态地以分段连续空间组合而成,随时可以增加一段新的空间并链接起来,deque没有所谓的空间保留功能。

84、 STL中的allocator,deallocator

1.第一级配置器直接使用malloc()、free()和relloc(),第二级配置器视情况采用不同的策略:当配置区块超过128bytes时,视之为足够大,便调用第一级配置器;当配置器区块小于128bytes时,为了降低额外负担,使用复杂的内存池整理方式,而不再用一级配置器;
2.第二级配置器主动将任何小额区块的内存需求量上调至8的倍数,并维护16个free-list,各自管理大小为8~128bytes的小额区块;
3.空间配置函数allocate(),首先判断区块大小,大于128就直接调用第一级配置器,小于128时就检查对应的free-list。如果free-list之内有可用区块,就直接拿来用,如果没有可用区块,就将区块大小调整至8的倍数,然后调用refill(),为free-list重新分配空间;
4.空间释放函数deallocate(),该函数首先判断区块大小,大于128bytes时,直接调用一级配置器,小于128bytes就找到对应的free-list然后释放内存。

85、 STL中hash_map扩容发生什么?

1.hash table表格内的元素称为桶(bucket),而由桶所链接的元素称为节点(node),其中存入桶元素的容器为stl本身很重要的一种序列式容器——vector容器。之所以选择vector为存放桶元素的基础容器,主要是因为vector容器本身具有动态扩容能力,无需人工干预。
2.向前操作:首先尝试从目前所指的节点出发,前进一个位置(节点),由于节点被安置于list内,所以利用节点的next指针即可轻易完成前进操作,如果目前正巧是list的尾端,就跳至下一个bucket身上,那正是指向下一个list的头部节点。

86、 map如何创建?

1.vector 底层数据结构为数组 ,支持快速随机访问
2.list底层数据结构为双向链表,支持快速增删
3.deque底层数据结构为一个中央控制器和多个缓冲区,详细见STL源码剖析P146,支持首尾(中间不能)快速增删,也支持随机访问
deque是一个双端队列(double-ended queue),也是在堆中保存内容的。它的保存形式如下:
[堆1] --> [堆2] -->[堆3] --> ...
每个堆保存好几个元素,然后堆和堆之间有指针指向,看起来像是list和vector的结合品.
4.stack 底层一般用list或deque实现,封闭头部即可,不用vector的原因应该是容量大小有限制,扩容耗时
5.queue 底层一般用list或deque实现,封闭头部即可,不用vector的原因应该是容量大小有限制,扩容耗时(stack和queue其实是适配器,而不叫容器,因为是对容器的再封装)
6.priority_queue 的底层数据结构一般为vector为底层容器,堆heap为处理规则来管理底层容器实现
7.set 底层数据结构为红黑树,有序,不重复
8.multiset 底层数据结构为红黑树,有序,可重复
9.map底层数据结构为红黑树,有序,不重复
10.multimap 底层数据结构为红黑树,有序,可重复
11.hash_set 底层数据结构为hash表,无序,不重复
12.hash_multiset 底层数据结构为hash表,无序,可重复
13.hash_map 底层数据结构为hash表,无序,不重复
14.hash_multimap 底层数据结构为hash表,无序,可重复

87、 vector的增加删除都是怎么做的?为什么是1.5倍?

1.新增元素:vector通过一个连续的数组存放元素,如果集合已满,在新增数据的时候,就要分配一块更大的内存,将原来的数据复制过来,释放之前的内存,在插入新增的元素;
2.对vector的任何操作,一旦引起空间重新配置,指向原vector的所有迭代器就都失效了;
3.初始时刻vector的capacity为0,塞入第一个元素后capacity增加为1;
4.不同的编译器实现的扩容方式不一样,VS2015中以1.5倍扩容,GCC以2倍扩容。
对比可以发现采用采用成倍方式扩容,可以保证常数的时间复杂度,而增加指定大小的容量只能达到O(n)的时间复杂度,因此,使用成倍的方式扩容。
扩容倍数
考虑可能产生的堆空间浪费,成倍增长倍数不能太大,使用较为广泛的扩容方式有两种,以2二倍的方式扩容,或者以1.5倍的方式扩容。
1.以2倍的方式扩容,导致下一次申请的内存必然大于之前分配内存的总和,导致之前分配的内存不能再被使用,所以最好倍增长因子设置为(1,2)之间;
2.向量容器vector的成员函数pop_back()可以删除最后一个元素;
3.而函数erase()可以删除由一个iterator指出的元素,也可以删除一个指定范围的元素。
4.还可以采用通用算法remove()来删除vector容器中的元素.
5.不同的是:采用remove一般情况下不会改变容器的大小,而pop_back()与erase()等成员函数会改变容器的大小。

88、 C++ sort排序算法底层

sort作为一个内置的排序方法,可以被vector等直接调用。
对于STL中的sort()算法:
1.当数据量大时,将会采用Quick Sort(快排),分段递归进行排序。
2.一旦分段后的数据量小于某个阈值,为了避免快排的递归带来过大的额外的开销,sort()算法就自动改为Insertion Sort(插入排序)。
3.如果递归的层次过深,还会改用Heap Sort(堆排序)。
简单来说,sort并非只是普通的快速排序,除了对普通的快排进行优化,它还结合了插入排序和堆排序。根据不同的数量级以及不同的情况,能够自动选择合适的排序算法。

89、 函数指针?

1.什么是函数指针?
函数指针指向的是特殊的数据类型,函数的类型是由其返回的数据类型和其参数列表共同决定的,而函数的名称则不是其类型的一部分。
一个具体函数的名字,如果后面不跟调用符号(即括号),则该名字就是该函数的指针(注意:大部分情况下,可以这么认为,但这种说法并不很严格)。
2.函数指针的声明方法
int (*pf)(const int&, const int&); (1)
上面的pf就是一个函数指针,指向所有返回类型为int,并带有两个const int&参数的函数。注意*pf两边的括号是必须的,否则上面的定义就变成了:
int*pf(const int&, const int&); (2)
而这声明了一个函数pf,其返回类型为int *, 带有两个const int&参数。
3.为什么有函数指针
○1函数与数据项相似,函数也有地址(函数名就是指针)。我们希望在同一个函数中通过使用相同的形参在不同的时间使用产生不同的效果。
○2一个函数名就是一个指针,它指向函数的代码。一个函数地址是该函数的进入点,也就是调用函数的地址。函数的调用可以通过函数名,也可以通过指向函数的指针来调用。函数指针还允许将函数作为变元传递给其他函数;
○3两种方法赋值:
指针名 = 函数名;指针名 = &函数名

90、 C与C++的联系与区别

一、C++与C的联系:
1、C++是在C语言的基础上开发的一种面向对象编程语言,应用广泛。C++支持多种编程范式 --面向对象编程、泛型编程和过程化编程。 其编程领域众广,常用于系统开发,引擎开发等应用领域,是最受广大程序员受用的最强大编程语言之一,支持类:类、封装、重载等特性!
2、C++在C的基础上增添类,C是一个结构化语言,它的重点在于算法和数据结构。C程序的设计首要考虑的是如何通过一个过程,对输入(或环境条件)进行运算处理得到输出(或实现过程(事务)控制),而对于C++,首要考虑的是如何构造一个对象模型,让这个模型能够契合与之对应的问题域,这样就可以通过获取对象的状态信息得到输出或实现过程(事务)控制。
二、C++与C的区别
1、C是面向过程的语言,而C++是面向对象的语言,那么什么是面向对象?
面向对象:面向对象是一种对现实世界的理解和抽象的方法、思想,通过将需求要素转化为对象进行问题处理的一种思想。
2、C和C++动态管理内存的方法不一样,C是使用malloc、free函数,而C++不仅有malloc/free,还有new/delete关键字。那malloc/free和new/delete差别?
malloc/free和new/delete差别:
①malloc/free是C和C++语言的标准库函数,需要头文件包含,new/delete是C++的运算符,关键字,需要编译器支持。它们都可用于申请动态内存和释放内存。
②由于malloc/free是库函数不是运算符,不在编译器范围之内,不能够把执行构造函数和析构函数的任务强加入malloc/free。因此C++需要一个能完成动态内存分配和初始化工作的运算符new,一个能完成清理与释放内存工作的运算符delete。
③new可以认为是malloc加构造函数的执行。new出来的指针是直接带类型信息的。而malloc返回的都是void指针。
④malloc是从堆上开辟空间,而new是从自由存储区开辟(自由存储区是从C++抽象出来的概念,不仅可以是堆,还可以是静态存储区)。
⑤malloc对开辟的空间大小有严格指定,而new只需要对象名。
⑥malloc开辟的内存如果太小,想要换一块大一点的,可以调用relloc实现,但是new没有直观的方法来改变。
3、C中的struct和C++的类,C++的类是C中没有的,C中的struct可以在C++中等同类来使用,struct和类的差别是,struct的成员默认访问修饰符是public,而类默认是private。
4、C++支持重载,而C不支持重载,C++支持重载在于C++名字的修饰符与C不同,例如在C++中函数 int f(int) 经过名字修饰之后变为_f_int,而C是_f,所以C++才会支持不同的参数调用不同的函数。
5、C++中有引用,而C没有。那指针和引用有什么差别?
指针和引用的区别:
①指针有自己的一块空间,而引用只是一个别名。
②使用sizeof查看一个指针大小为4(32位),而引用的大小是被引用对象的大小。
③指针可以是NULL,而引用必须被初始化且必须是对一个以初始化对象的引用。
④作为参数传递时,指针需要被解引用才可以对对象进行操作,而直接对引用的修改都会改变引用所指向的对象。
⑤指针在使用中可以指向其它对象,但是引用只能是一个对象的引用,不能被修改。
⑥指针可以有多级指针(**p),而引用只有一级。
⑦指针和引用使用++运算符的意义不一样。
6、C++全部变量的默认连接属性是外连接,而C是内连接。
7、C中用const修饰的变量不可以用在定义数组时的大小,但是C++用const修饰的变量可以。(如果不进行&,解引用的操作的话,是存放在符号表的,不开辟内存)
8、C++有很多特有的输入输出流。

91、 C++中NULL和nullptr的区别

1.在C语言中,NULL通常被定义为:
#define NULL ((void *)0)
所以说NULL实际上是一个空指针。
2.C++是强类型语言,void*是不能隐式转换成其他类型的指针的,所以实际上编译器提供的头文件做了相应的处理:
#ifdef __cplusplus
#define NULL 0
#else
#define NULL ((void *)0)
#endif
可见,在C++中,NULL实际上是0。
3.C++中的nullptr
就是空指针常量,C++11之前并没有所谓的“空指针类型”,C++11设计了nullptr_t,它唯一接受的值就是nullptr,专门代表空指针。

92、 C/C++内存分配

1、静态存储区分配
内存分配在程序编译之前完成,且在程序的整个运行期间都存在,例如全局变量、静态变量等。
2、栈上分配
在函数执行时,函数内的局部变量的存储单元在栈上创建,函数执行结束时这些存储单元自动释放。
3、堆上分配
堆分配(又称动态内存分配)。程序在运行时用malloc或者new申请内存,程序员自己用free或者delete释放,动态内存的生存期由我们自己决定。

93、 c/c++的内存分配模型,详细说一下栈、堆、静态存储区?

1、栈区(stack),由编译器自动分配释放,存放函数的参数值,局部变量的值等其操作方式类似于数据结构中的栈。
2、堆区(heap),一般由程序员分配释放,若程序员不释放,程序结束时可能由OS(操作系统)回收。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表。
3、全局区(静态区)(static),全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。程序结束后由系统释放。
4、常量存储区,常量字符串就是放在这里的。程序结束后由系统释放。
5、程序代码区,存放函数体的二进制代码。

94、 野指针是什么?如何检测内存泄漏?

1.野指针:指向内存被释放的内存或者没有访问权限的内存的指针。
2.“野指针”的成因主要有3种:
○1指针变量没有被初始化。任何指针变量刚被创建时不会自动成为NULL指针,它的缺省值是随机的,它会乱指一气。所以,指针变量在创建的同时应当被初始化,要么将指针设置为NULL,要么让它指向合法的内存。例如char *p = NULL;char *str = new char(100);
○2指针p被free或者delete之后,没有置为NULL;
○3指针操作超越了变量的作用范围。
3.如何避免野指针:
○1对指针进行初始化
①将指针初始化为NULL。
char *p = NULL;
②用malloc分配内存
char * p = (char * )malloc(sizeof(char));
③用已有合法的可访问的内存地址对指针初始化
char num[ 30] = {0};
char *p = num;
○2指针用完后释放内存,将指针赋NULL。
delete(p);
p = NULL;

95、 悬空指针和野指针有什么区别?

1.野指针:野指针指,访问一个已删除或访问受限的内存区域的指针,野指针不能判断是否为NULL来避免。指针没有初始化,释放后没有置空,越界
2.悬空指针:一个指针的指向对象已被删除,那么就成了悬空指针。野指针是那些未初始化的指针。

96、 内存泄漏

1.内存泄漏
内存泄漏是指由于疏忽或错误造成了程序未能释放掉不再使用的内存的情况。内存泄漏并非指内存在物理上消失,而是应用程序分配某块内存后,由于设计错误,失去了对该段内存的控制;或者申请了⼀块内存空间,使⽤完毕后没有释放掉,或者由程序申请的⼀块内存,且没有任何⼀个指针指向它,那么这块内存就泄漏了。⼀般表现⽅式是程序运⾏时间越⻓,占⽤内存越多,最终⽤尽全部内存,整个系统崩溃。
2.内存泄漏的后果
只发生一次小的内存泄漏可能不被注意,但泄漏大量内存的程序将会出现各种征兆:性能下降到内存逐渐用完,导致另一个程序失败,而使用户无从查找问题的真正根源。
3.内存泄漏类型
(1)堆内存泄漏 (Heap leak)。对内存指的是程序运行中根据需要分配通过malloc,realloc new等从堆中分配的一块内存,再是完成后必须通过调用对应的 free或者delete 删掉。如果程序的设计的错误导致这部分内存没有被释放,那么此后这块内存将不会被使用,就会产生Heap Leak.
(2)系统资源泄露(Resource Leak)。主要指程序使用系统分配的资源比如 Bitmap,handle ,SOCKET等没有使用相应的函数释放掉,导致系统资源的浪费,严重可导致系统效能降低,系统运行不稳定。
4.如何排除
使用工具软件BoundsChecker,BoundsChecker是一个运行时错误检测工具,它主要定位程序运行时期发生的各种错误;
调试运行DEBUG版程序,运用以下技术:CRT(C run-time libraries)、运行时函数调用堆栈、内存泄漏时提示的内存分配序号(集成开发环境OUTPUT窗口),综合分析内存泄漏的原因,排除内存泄漏。
5.解决方法
智能指针。
6.检查、定位内存泄漏
1.window上检查方法:在main函数最后面一行,加上一句_CrtDumpMemoryLeaks()。调试程序,自然关闭程序让其退出,查看输出:
输出这样的格式{453}normal block at 0x02432CA8,868 bytes long
被{}包围的453就是我们需要的内存泄漏定位值,868 bytes long就是说这个地方有868比特内存没有释放。
定位代码位置
在main函数第一行加上_CrtSetBreakAlloc(453);意思就是在申请453这块内存的位置中断。然后调试程序,程序中断了,查看调用堆栈。加上头文件#include <crtdbg.h>
2.linux:⾸先可以通过观察猜测是否可能发⽣内存泄漏,Linux中使⽤ swap 命令观察还有多少可⽤的交换空间,在⼀两分钟内键⼊该命令三到四次,看看可⽤的交换区是否在减少。
3.还可以使⽤其他⼀些 /usr/bin/stat ⼯具如 netstat、 vmstat 等。如发现波段有内存被分配且从不释放,⼀个可能的解释就是有个进程出现了内存泄漏。
3.⽤于内存调试,内存泄漏检测以及性能分析的软件开发⼯具 valgrind 这样的⼯具来进⾏内存泄漏的检测。

97、 内存溢出定位

如果是Windows,考虑下Visual Leak Detector,这个对泄露点信息定位相当不错;如果是Linux,考虑下Valgrind,检测内存使用以及线程方面的Bug功能非常强大

98、 什么是内存对齐

现在计算机内存空间都是按照byte字节划分的,理论上讲对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定类型变量的时候经常在特定的内存地址上访问,这就需要各种数据类型按照一定的规则在空间上排列,而不是一个接一个的排放,这就是内存对齐。

99、 为什么内存对齐

1.平台原因(移植原因)
2.不是所有的硬件平台都能访问任意地址上的任意数据的;
3.某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异
4.性能原因:
○1数据结构(尤其是栈)应该尽可能地在自然边界上对齐。
○2原因在于,为了访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要一次访问。

100、 内存对齐规则

在不用#pagrama pack()包裹的情况下,结构体或联合体按照编译器默认的对齐方式有以下三个对其原则:
1.数据成员对齐原则:结构(struct或union)的数据成员,第一个数据成员存放在offset为0的地方,以后每个数据成员存储的起始位置都要从其占用内存大小的整数倍开始。
2.结构体作为成员的原则:如果一个结构中有某些结构体成员,则结构的成员要从其内部最大元素大小的整数倍地址开始存储。(struct a里有struct b,b里有char,int,double等元素,那b应该从8的整数倍开始,当然了,如果struct b在结构体a开始位置,则直接考虑其大小)
3.结构(或联合)的整体对齐原则:在数据成员各自对齐后,结构(或联合)本身也要进行对齐,即以结构体内部占用内存空间最大的数据类型进行对齐。(等同于sizeof该结构体的结果必须是其内部最大成员占用内存的整数倍)。
示例1:

struct mystruct
{
char a;//偏移量为0;a占用一个字节
double b;//下一个可用地址偏移量为1,不是sizeof(double)=8的整数倍,需要补7个字节
int c;//下一个可用地址偏移量为1+7+8=16,是sizeof(int)=4的整数倍,满足Int的对齐方式
}//所有成员变量都分配了空间,空间大小=1+7+8+4=20,不是最大空间类型double的整数倍,所以需要填充4个字节以满足结构体大小为sizeof(double)=8的整数倍
sizeof(mystruct)=24;

示例2:

struct B {
int a;
char b;
int c;
};
struct A {
char x1;
B b;
short x2;
float x3;
char x4;
}aa;
//#pragma pack()
int main() {
printf("%d\n", sizeof(struct A));
//printf("%x,%x,%x\n", aa.a, *(&aa.b + 1), aa.c);
//printf("%p,%p,%p\n", &aa.a, &aa.b, &aa.c);
return 0;
}

添加了#pragma pack(n)后规则就变成了下面这样:
1、 偏移量要是n和当前变量大小中较小值的整数倍
2、 整体大小要是n和最大变量大小中较小值的整数倍
3、 n值必须为1,2,4,8…,为其他值时就按照默认的分配规则

二十万字C/C++、嵌入式软开面试题全集宝典五相关推荐

  1. 二十万字C/C++、嵌入式软开面试题全集宝典七

    目录 121. 怎样判断两个浮点数是否相等? 122. 宏定义一个取两个数中较大值的功能 123. define.const.typedef.inline使用方法? 124. printf实现原理? ...

  2. 二十万字C/C++、嵌入式软开面试题全集宝典十一

    目录 1. 红黑树的性质 2. 红黑树的插入与旋转 3. 红黑树与平衡二叉树 4. 二叉平衡树.红黑树.B树.B+树的区别与联系 5. hello world 程序开始到打印到屏幕上的全过程? 1. ...

  3. 二十万字C/C++、嵌入式软开面试题全集宝典八

    目录 141. 迭代器++it,it++哪个好,为什么 142. C++如何处理多个异常的? 143. 模板和实现可不可以不写在一个文件里面?为什么? 144. 在成员函数中调用delete this ...

  4. 二十万字C/C++、嵌入式软开面试题全集宝典四

    目录 1. 虚函数的代价? 2. 用C语言实现C++的继承 3. 继承机制中对象之间如何转换?指针和引用之间如何转换? 4. C++四种类型转换 5. 为什么要用static_cast转换而不用c语言 ...

  5. 二十万字C/C++、嵌入式软开面试题全集宝典三

    目录 1. 构造函数析构函数可否抛出异常 2. 类如何实现只能静态分配和只能动态分配 3. 如果想将某个类用作基类,为什么该类必须定义而非声明? 4. 什么情况会自动生成默认构造函数? 5. 构造函数 ...

  6. 二十万字C/C++、嵌入式软开面试题全集宝典二

    目录 1.静态绑定和动态绑定的介绍 2.C语言struct和C++struct区别 3.虚函数可以声明为inline吗? 4.介绍 C++ 所有的构造函数 5. 什么情况下会调用拷贝构造函数 6. 为 ...

  7. 二十万字C/C++、嵌入式软开面试题全集宝典十

    目录 1. 编码实现某一变量某位清0或置1 2. 分别写出BOOL,int,float,指针类型的变量a 与"零"的比较语句. 3. 局部变量全局变量的问题? 4. 数组和指针的区 ...

  8. 二十万字C/C++、嵌入式软开面试题全集宝典九

    目录 161. 空类 162. 空类会默认添加哪些东西?怎么写? 163. 标准库是什么? 164. const char* 与string之间的关系,传递参数问题? 165. char * 与cha ...

  9. 二十万字C/C++、嵌入式软开面试题全集宝典六

    目录 101. 字节对齐有什么作用? 102. C语言中#pragma用法 103. new和malloc的区别? 104. malloc/calloc/realloc三者之间的区别? 105. de ...

最新文章

  1. Devexpress Xtraform 资源文件 汉化
  2. php和python哪个做第二语言-php之后如何选择第二语言?
  3. 征战蓝桥 —— 2013年第四届 —— C/C++A组第7题——错误票据
  4. java动态代理--代理接口无实现类
  5. flex平均分布换行后自动对齐
  6. 基于 Token 的身份验证:JSON Web Token
  7. JAVA比较两个List集合的方法
  8. AC自动机(python)
  9. 在教学中利用计算机软件,计算机软件技术教学方法研究
  10. 【Unity3D插件】DoTween插件(二)
  11. Oracleji数据库、实例、用户、表空间、表之间的关系
  12. ioi 赛制_杨骏昭IOI2019参赛总结
  13. AD转换精度提高方法
  14. Java 五子棋(一)绘制棋盘、棋子
  15. OSG/OSGEarth一万一千字学习实践完整总结(强烈推荐!!!)
  16. SpringBoot:异步 定时 邮件任务
  17. DSO(1)——DSO论文详细解读
  18. 【已解决】Paragon NTFS for mac彻底删除
  19. 工作小笔记——对MLE和MAP的简单理解
  20. 旅行app(游记、攻略、私人定制) | 顺便游旅行H5移动端实例

热门文章

  1. 关于linkedin的network的观察和自己的职业道路的追求
  2. 学到了关于服务器磁盘阵列
  3. UNITY编辑器模式下static变量的坑
  4. 网页渲染的颜色竟然和设定值的不同!Chrome 61+色差解决办法
  5. Java 位运算- 十进制数值转十六进制(内存中的数据)
  6. 一份技术简历是如何搞定BAT的面试官?
  7. unity3d 数学的数学基础和辅助类
  8. 存储控制器_SDRAM详解
  9. 如何设置Reporting Services链接到网页URL的参数?
  10. nyoj 10 skiing(DAG上的最长路,备忘录方法)