文章目录

  • 1. 多态
    • 1.1 多态的分类
    • 1.2 动态多态满足的条件及使用
    • 1.3 动态多态:虚函数
      • 1. 虚函数:
      • 2. 虚析构函数:
      • 3. 纯虚函数:
      • 4. 虚函数与纯虚函数:
      • 5.虚函数指针与虚函数表
  • 2. 空指针与野指针
    • 2.1 空指针
    • 2.2 野指针
  • 3. const那些事
    • 3.1 const修饰指针
    • 3.2 const修饰函数
    • 3.3 const修饰函数
  • 4. static那些事
  • 5. class与struct的区别
  • 6. 构造函数与析构函数
    • 6.1 构造函数
    • 6.1 析构函数
  • 7. 深拷贝与浅拷贝
  • 8. 模板
    • 8.1 小结:
    • 8.2 使用模板的注意事项
    • 8.3 普通函数与模板函数的区别
  • 9. 动态库与静态库
    • 9.1 静态库(.lib)
    • 9.2 动态库(.dll)
  • 9. 指针与引用
  • 10. 手动实现string类
  • 10. 智能指针
    • 10.1 C++98的auto_ptr
    • 10.1 C++11的智能指针
      • 1. unique_ptr的使用
      • 2. shared_ptr的使用
      • 3. weak_ptr的使用
  • 11. STL底层实现
    • 11.1 STL容器类型
    • 11.2 使用注意事项
    • 11.3 容器特性
  • 12. new和malloc的区别
    • 1. malloc、calloc、realloc、alloca
    • 2. malloc与new
  • 13. 内存泄漏、内存溢出与野指针
  • 14. 指针函数与函数指针
    • 1. 指针函数
    • 2. 函数指针
  • 14. Struct结构体大小计算
  • 15. C++的5大存储区
  • 16. 传值、传引用、传指针

1. 多态

参考:参考视频

1.1 多态的分类

  • 静态多态:函数重载运算符重载属于静态多态,复用函数名,但是形参的个数或类型不同
  • 动态多态:派生类虚函数实现运行时多态
  • 静态多态与动态多态的区别:
  1. 静态多态的函数地址早绑定,编译阶段确定函数地址
  2. 动态多态的函数地址晚绑定,运行阶段确定函数地址

1.2 动态多态满足的条件及使用

条件:

  1. 有继承关系
  2. 子类重写父类的虚函数【重写即函数返回类型,函数名,形参列表均相同】

使用:

  1. 父类的指针或引用 指向子类的对象

1.3 动态多态:虚函数

1. 虚函数:
  1. 使用virtual修饰的函数,如virtual double calcArea();
  2. 注意:1)普通函数(非成员内函数)不能是虚函数;2)静态函数(static)不能是虚函数;3)构造函数不能是虚函数;4)内联函数不能是表现多态性时的虚函数
2. 虚析构函数:
  1. 虚析构函数为了避免内存泄漏,使得在删除指向子类对象的基类指针时可以调用子类的析构函数。【在调用父类的虚析构函数时,会先调用子类的析构函数,再调用父类的析构函数,以此来防止内存泄漏】
3. 纯虚函数:
  1. 纯虚函数是一种特殊的虚函数,在基类中不能对虚函数给出有意义的实现,而把它声明为纯虚函数,它的实现留给该基类的派生类去做。如:virtual int A() = 0;
4. 虚函数与纯虚函数:
  1. 虚函数是被实现的,可以空实现,作用是为了在子类里被重写;虚函数只是个函数声明,留到子类里去实现,作用是一个借口。
  2. 在子类中,虚函数可以不被重写,但是纯虚函数必须实现后,才可以实例化子类
  3. 虚函数的类叫抽象类,不能实例化,只有被继承并实现后才可以使用。抽象类被继承后,即可以是抽象类,也可以是普通类
5.虚函数指针与虚函数表
  1. 虚函数指针:在含有虚函数类的对象中,指向虚函数表,在运行时确定。
  2. 虚函数表:在程序只读数据段,存放虚函数指针。如果派生类实现了基类的虚函数,则会类似继承基类的属性一样,继承虚函数表,同时将实现的虚函数指针替换基类的虚函数指针。

2. 空指针与野指针

2.1 空指针

空指针:指针变量指向内存编号为0的空间
用途:初始化指针变量
注意:空指针指向的内存空间不可以被访问

int * p = NULL;
count << *p << endl; // 报错,因为空指针所指向的内存不可以被访问
int a = 10;
p = &a; // 可以用来赋值

2.2 野指针

指针变量指向非法内存空间

//指针p指向内存地址编号为0x1100的空间,由于不知道地址编号为0x1100的空间的具体情况,对此空间的数据进行操作,会报错
int * p = (int *)0x1100;
count << *p << endl;    //报错

3. const那些事

  1. 常量指针:地址内的内容不可改,指针方向可以改【const int * a】
  2. 指针常量:指针的指向不可改,地址的内容可以改【int * const a】
  3. 常成员函数:不得修改类内变量,若想修改,变量前加mutable。【int fuc() const】
  4. 常对象:只能调用常函数【const A a】

3.1 const修饰指针

  1. const修饰指针 ——常量指针:指针的指向可以改,指针指向的值不可以改

const 在*前面,所以叫常量指针;*p(指针指向的值)不可以改,但是可以改指针的指向

int a = 10, b = 20;
const int * p = &a;    //const 在*前面,所以叫常量指针;*p(指针指向的值)不可以改,但是可以改指针的指向(p)
*p = 20; // 报错
p = &b; // ok
  1. const修饰常量 ——指针常量:

const 在p前面,所以叫指针常量;p(指针的指向)不可以改,但是可以改指针指向的值 (*p)

int a = 10, b = 20;
int * const p = &a;    //const 在p前面,所以叫指针常量;p(指针的指向)不可以改,但是可以改指针指向的值(*p)
*p = 20; // ok
p = &b; // 报错
  1. const即修饰指针,又修饰常量
int a = 10, b = 20;
const int * const p = &a;
*p = 20; // 报错
p = &b;  //报错

3.2 const修饰函数

  1. 常函数:
  • 成员函数后加入const后,我们称这个函数为常函数
  • 常函数内不可以修改成员的属性
  • 成员属性声明时,加入mutable后,在常函数中依然可以更改
  1. 常对象:
  • 声明对象前加入const称该对象为常对象
  • 常对象只能调用常函数
class Person {mutable int a = 10;   //若想在常函数中修改属性值,需要加上mutable;int b = 10;//常函数中this指针其实为 const int * const this 即不可以修改this的所指地址//也不可以修改this所指地址的值。void make1 () const{this->a = 20; //okthis->b = 20;   //报错this = NULL;   //报错}void make2 () {this->a = 20;   //okthis->b = 20;   //okthis = NULL;   //报错}
};const Person p;   //常对象只能调用常函数
p.make1(); //ok
p.make2(); //报错

3.3 const修饰函数

4. static那些事

  1. 修饰普通变量:修改变量的存储区域生命周期,使变量从局部变量移至静态区,生命周期至代码运行结束消亡。在 main 函数运行前就分配了空间,如果有初始值就用初始值初始化它,如果没有初始值系统用默认值初始化它。
  2. 修饰普通函数:表明函数的作用范围,尽在定义函数的文件内才能使用。在多人开发项目时,为了防止与他人命名空间里的函数重名,可以将函数定位为 static。
  3. 修饰成员变量:static修饰的成员变量,所有的对象只保存(共享)一个该变量,且不需要生成对象就可以访问该成员
  4. 修饰成员函数:static修饰的成员函数,不能访问非静态成员,且不需生成对象就可以访问

5. class与struct的区别

参考:参考视频
唯一区别在于默认的访问权限不同

struct默认权限为公共(public)
class默认权限为私有(private)

class C1
{int m_A; //默认为私有权限
}
struct C2
{int m_a; //默认为公共权限
}
int main()
{C1 c1;c1.m_A = 10; //报错,因为c1默认的m_A为私有,不可访问C2 c2;c2.m_A = 10; //ok
}

6. 构造函数与析构函数

  • 构造函数主要用来在创建对象时为对象的成员属性赋初值,一般由编译器自动调用,无须手动调用
  • 析构函数主要用在对象销毁前自动调用,执行一些清理工作

6.1 构造函数

  1. 形式:类名(){} //函数名与类名相同
  2. 构造函数没有返回值也不写void
  3. 构造函数可以有参数,因此可以发生重载
  4. 程序在调用对象时会自动调用,不用手动调用

6.1 析构函数

  1. 形式:~类名(){} //函数名与类名相同,在前面加个
  2. 构造函数没有返回值也不写void
  3. 构造函数不可以有参数,因此不可以发生重载
  4. 程序在调用对象时会自动调用,不用手动调用
  5. 用途:可以用来释放在堆中开辟出的内存

7. 深拷贝与浅拷贝

参考:参考视频
浅拷贝:简单的赋值拷贝操作【编译器所实现的拷贝都属于浅拷贝】
深拷贝:在堆中重新申请空间,进行拷贝操作
注:如果属性中有在堆区开辟的,一定要重写构造函数,进行深拷贝,解决浅拷贝可能会重复释放内存导致报错的问题

8. 模板

参考:参考视频

8.1 小结:

  • 函数模板利用关键字 template
  • 使用函数模板有两种方式:自动类型推导、显示指定类型
  • 模板的目的是为了提高复用性,将类型参数化
  • 模板不是通用的,但是可以利用具体化的模板,解决自定义类型通用化的模板【比如自定义一个Person类,比较p1 和p2,因为是自定义类没有定义比较规则,所以直接使用模板<T=Person>会报错,可以自定义一个具体化模板来解决此问题。参考】
//函数模板
template<typename T> //声明一个模板,告诉编译器后面代码中的T不要报错
void mySwap(T &a, T &b)
{T temp = a;a = b;b = temp;
}
int main()
{int a = 10, b = 20;mySwap(a, b); //调用模板方式1:自动类型推导//mySwap<int>(a, b); //调用模板方式1:显示指定类型;< >内为T所应该对应的类型
}

8.2 使用模板的注意事项

参考:参考视频

  • 自动类型推导,必须推导出一致的数据类型T,才可以使用
  • 模板必须要确定出T的数据类型,才可以使用

8.3 普通函数与模板函数的区别

  1. 普通函数可以进行隐式自动转换;【隐式自动转换:比如实际参数是char型,函数需要int型参数,就可以自动转化数据类型,将char转成int】
  2. 自动类型推导模板函数,不可以进行隐式自动转换;
  3. 显示指定类型模板函数,可以进行隐式自动转换;

9. 动态库与静态库

两者区别:

  • 静态库会包含在.exe中,不会又很多额外文件,但会导致.exe文件过大;
  • 动态库与.exe分离,因此会在.exe同级产生很多.dll文件,但同一个.dll可以被不同的.exe调用,增加了复用性。

9.1 静态库(.lib)

  1. 配置调用静态库,需要设置3个地方,参考
  2. 编写静态库:
  • 头文件:定义函数名
  • .cpp文件:函数功能具体实现
  1. 打包静态库:编译.cpp文件,在debug文件夹中会生成.lib文件。创建lib文件夹,将.lib文件放入;创建include文件,将.h文件放入,静态库大致就封装好了参考

9.2 动态库(.dll)

  1. 配置调用动态库,也需要设置3个地方,参考
  2. 编写动态库:
  • 头文件:定义函数名,额外需要设置一些宏
  • cpp文件:函数功能具体实现
  1. 打包动态库:编译.cpp文件,在debug文件夹中会生成.dll文件,借助dependcy软件处理.dll文件,使得别人可以灵活调用。参考

9. 指针与引用

参考:C++指针和引用及区别
引用是一种特殊的指针,它在用时自动解引用

  1. 指针有自己的一块空间,而引用只是一个别名(与原变量共享空间);
  2. 使用sizeof看一个指针是4,引用是被引用对象的大小
  3. 指针可以初始化为NULL, 而引用必须被初始化必须是一个已有对象的引用
  4. 作为参数传递时,指针需要被解引用才可以对对象进行操作,而直接对引用的修改都会改变引用所指向的对象;
  5. 指针在使用中可以指向其它对象,但是引用只能是一个对象的引用,不能被改变;
  6. 针可以有多级指针p),而引用只有一级**;
  7. 指针和引用使用++运算符的意义不一样;

10. 手动实现string类

  • string的底层也是 char*
    参考1
    参考2
class String
{public://构造函数String(const char* str = NULL);//析构函数~String();
private:char * m_data;
};String::String(const char* str)
{if (str == NULL) {m_data = new char[1];*m_data = '\0';}else {m_data = new char[strlen(str)+1];strcpy(m_data, str);}
}
String::~String()
{if (m_data != NULL) {delete[] m_data;m_data = NULL;}
}

10. 智能指针

参考

10.1 C++98的auto_ptr

裸指针进行封装,让程序员无需手动释放指针指向的内存区域,在auto_ptr生命周期结束时自动释放,然而,由于auto_ptr在转移指针所有权后会产生野指针,导致程序运行时crash,如下面示例代码所示:

auto_ptr<int> p1(new int(10));
auto_ptr<int> p2 = p1; //转移控制权
*p1 += 10; //crash,p1为空指针,可以用p1->get判空做保护

10.1 C++11的智能指针

  • C++11推出了智能指针unique_ptr、shared_ptr、weak_ptr
1. unique_ptr的使用

unique_ptr是auto_ptr的继承者,对于同一块内存只能有一个持有者,而unique_ptr和auto_ptr唯一区别就是unique_ptr 不允许赋值操作,也就是不能放在等号的右边(函数的参数和返回值例外),这一定程度避免了一些误操作导致指针所有权转移,然而,unique_str依然有提供所有权转移的方法move,调用move后,原unique_ptr就会失效,再用其访问裸指针也会发生和auto_ptr相似的crash,如下面示例代码,所以,即使使用了unique_ptr,也要慎重使用move方法,防止指针所有权被转移。

unique_ptr<int> up(new int(5));
//auto up2 = up; // 编译错误
auto up2 = move(up);
cout << *up << endl; //crash,up已经失效,无法访问其裸指针
2. shared_ptr的使用

shared_ptr 使用引用计数,实现对同一块内存可以有多个引用,在最后一个引用被释放时,指向的内存才释放,这也是和unique_ptr最大的区别。

3. weak_ptr的使用
  1. 使用shared_ptr过程中有可能会出现循环引用,关键原因是使用shared_ptr引用一个指针时会导致强引用计数+1,从此该指针的生命周期就会取决于该shared_ptr的生命周期,然而,有些情况我们一个类A里面只是想引用一下另外一个类B的对象,类B对象的创建不在类A,因此类A也无需管理类B对象的释放,这个时候weak_ptr就应运而生了,使用shared_ptr赋值给一个weak_ptr 不会增加强引用计数(strong_count),取而代之的是增加一个弱引用计数(weak_count),而弱引用计数不会影响到指针的生命周期,这就解开了循环引用.
  2. 弱指针允许你共享但不拥有某个对象,一旦最末一个拥有该对象的智能指针失去了所有权,任何 weak_ptr 都会自动成空(empty)

11. STL底层实现

参考:STL底层介绍

11.1 STL容器类型

  • 连续内存的容器:vector 、deque
  • 基于节点的容器:list、set、multiset、map、multimap
  • 各容器的数据模型:

vector(数组) 、list(链表)、deque(数组和链表的折中)、set(二叉树)、multiset(二叉树)、map、multimap(二叉树)

11.2 使用注意事项

  1. 需要大量添加元素时:
    vector 、deque因为是连续存储,插入中间位置时,需要拷贝大量信息,所以不适用;而list底层是链表实现,都是常数时间的插入消耗,所以list更合适
  2. 查找速度:
    序列容器:
    1)已排序的序列容器,可以使用二分查找等方法,查找速度为O(logN);
  1. 未排序的序列容器,查找速度为线性的O(n)
    对于关联容器,存储的时候存储的是一棵红黑树,查找速度为O(logN);
  1. 内存是否和C兼容:只有vector可以支持

11.3 容器特性

12. new和malloc的区别

1. malloc、calloc、realloc、alloca

  1. malloc:申请指定字节数的内存。申请到的内存中的初始值不确定
  2. calloc:为指定长度的对象,分配能容纳其指定个数的内存。申请到的内存的每一位(bit)都初始化为 0
  3. realloc:更改以前分配的内存长度(增加或减少)。当增加长度时,可能需将以前分配区的内容移到另一个足够大的区域,而新增区域内的初始值则不确定
  4. alloca:在栈上申请内存。程序在出栈的时候,会自动释放内存。但是需要注意的是,alloca 不具可移植性, 而且在没有传统堆栈的机器上很难实现。alloca 不宜使用在必须广泛移植的程序中。C99 中支持变长数组 (VLA),可以用来替代 alloca。

2. malloc与new

  1. malloc与free是C++/C语言的bai标准库函数new/delete是C++的运算符。它们都可用于申请动态内存和释放内存。
  2. 对于非内部数据类型的对象而言,光用malloc/free无法满足动态对象的要求。对象在创建的同时要自动执行构造函数,对象在消亡之前要自动执行析构函数。由于malloc/free是库函数而不是运算符,不在编译器控制权限之内,不能够把执行构造函数和析构函数的任务强加于malloc/free。
  3. 因此C++语言需要一个能完成动态内存分配和初始化工作的运算符new,以一个能完成清理与释放内存工作的运算符delete。注意new/delete不是库函数。
  4. C++程序经常要调用C函数,而C程序只能用malloc/free管理动态内存。
  5. new可以认为是malloc加构造函数的执行。new出来的指针是直接带类型信息的。而malloc返回的都是void指针

13. 内存泄漏、内存溢出与野指针

参考:C++的内存泄漏、溢出、野指针

  1. 内存泄漏:

内存泄漏是指我们在堆中申请(new/malloc)了一块内存,但是没有去手动的释放(delete/free)内存,导致指针已经消失,而指针指向的东西还在,已经不能控制这块内存。使用完这个变量之后却没有及时回收这部分内存,这时我们就说发生了内存泄露。如果发生了内存泄露又没有及时发现,随着程序运行时间的增加,程序越来越大,直到消耗完系统的所有内存,然后系统崩溃。

  1. 内存溢出:

内存溢出 out of memory,是指程序在申请内存时,没有足够的内存空间供其使用,出现out of memory;比如申请了一个integer,但给它存了long才能存下的数,那就是内存溢出。

  1. 野指针:

野指针是指向一个已删除的对象未申请访问的内存区域的指针。与空指针不同,野指针无法通过简单地判断是否为 NULL避免,而只能通过养成良好的编程习惯来尽力减少。对野指针进行操作很容易造成程序错误。
a. 指针变量未初始化
b. 野指针指针释放后之后未置空
c. 野指针指针操作超越变量作用域(不要返回指向栈内存的指针,因为栈内存在函数结束时会被释放)

14. 指针函数与函数指针

参考:函数指针和指针函数用法和区别

1. 指针函数
  1. 声明格式:类型标识符* 函数名(参数表) 如: int *fun(int x,int y);
  2. 指针函数的返回值是一个指针;
2. 函数指针
  1. 声明格式:类型标识符 (*函数名)(参数表) 如:`int (*fun)(int x, int y);
  2. 函数指针是把一个函数的地址赋值给它,再通过调用地址内的函数去运算,感觉和正常的调用函数一样
//函数赋值给函数指针的两种方法
fun = &Function;
fun = Function;
//调用函数指针的两种方法
x = (*fun)();
x = fun();

14. Struct结构体大小计算

  1. CPU周期: WIN vs qt 默认8字节对齐、Linux 32位 默认4字节对齐,64位默认8字节对齐
  2. 结构体最大成员(基本数据类型变量)
  3. 预编译指令#pragma pack(n)手动设置 n–只能填1 2 4 8 16

计算规则:

  1. 实际对齐单位:取上述3者最小的
  2. 除结构体的第一个成员外,其他所有的成员的地址相对于结构体地址(即它首个成员的地址)的偏移量必须为实际对齐单位或自身大小的整数倍(取两者中小的那个)
  3. 结构体的整体大小必须为实际对齐单位的整数倍。

15. C++的5大存储区

在C++中,内存分成5个区,他们分别是堆、栈、自由存储区、全局/静态存储区和常量存储区
1.栈,就是那些由编译器在需要的时候分配,在不需要的时候自动清除的变量的存储区。里面的变量通常是局部变量、函数参数等。
2.堆,就是那些由new分配的内存块,他们的释放编译器不去管,由我们的应用程序去控制,一般一个new就要对应一个delete。如果程序员没有释放掉,那么在程序结束后,操作系统会自动回收。
3.自由存储区,就是那些由malloc等分配的内存块,他和堆是十分相似的,不过它是用free来结束自己的生命的。
4.全局/静态存储区,全局变量和静态变量被分配到同一块内存中,在以前的C语言中,全局变量又分为初始化的和未初始化的,在C++里面没有这个区分了,他们共同占用同一块内存区。
5.常量存储区,这是一块比较特殊的存储区,他们里面存放的是常量,不允许修改(当然,你要通过非正当手段也可以修改)

16. 传值、传引用、传指针

参考:传值和传引用、传指针的区别

  1. 传指针本质上是传值的一种。传值与传指针,当发生函数调用时,需要给形参分配存储单元,形参变量是实参变量的副本(所以如果参数传递数据较大时,还将调用拷贝构造函数,比较耗时,建议传引用),对形参的改变不会影响实参,但是如果传指针时,对形参(指针)指向内容的改变还是会有作用的。
  2. 传引用的话,形参与实参是同一个对象,只是他们名字不同而已, 对行参的修改将影响实参的值。
  3. 使用指针作为函数的参数虽然也能达到与使用引用的效果,但是,在被调函数中同样要给形参分配存储单元,且需要重复使用"*指针变量名"的形式进行运算,这很容易产生错误且程序的阅读性较差

C++的基础知识【面试遇到】相关推荐

  1. mysql系列问答题_(2)MySQL运维基础知识面试问答题

    面试题001:请解释关系型数据库概念及主要特点? 面试题002:请说出关系型数据库的典型产品.特点及应用场景? 面试题003:请解释非关系型数据库概念及主要特点? 面试题004:请说出非关系型数据库的 ...

  2. 软件测试基础知识面试题目(25题英文题目)

    软件测试基础知识面试题目(25题英文题目) 1. Verification is:  a. Checking that we are building the right system b. Chec ...

  3. [C/C++基础知识] 面试再谈struct和union大小问题

    最近找工作参加了很多笔试,其中考察结构体和联合体的大小问题是经常出现的一个问题.虽然题目简单而且分值比较低,但是还是想再给大家回顾下这些C和C++的基础知识.希望文章对你有所帮助~         P ...

  4. Hadoop之Hadoop基础知识面试复习

    Hadoop之Hadoop基础知识常问面试题 列举几个hadoop生态圈的组件并做简要描述. Zookeeper:是一个开源的分布式应用程序协调服务,基于zookeeper可以实现同步服务,配置维护, ...

  5. java基础知识面试_Java 基础面试知识点

    Java 基础知识相关 Java中 == 和 equals 和 hashCode 的区别 对于关系操作符 == 若操作数的类型是基本数据类型,则该关系操作符判断的是左右两边操作数的值是否相等 若操作数 ...

  6. java总结(基础知识-面试)

    lJava发射(案例) l反射含义: lJAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息以及动态 ...

  7. Web 前端基础知识面试大全

    目录 一.HTML 1.对 HTML 语义化的理解 2.区别:src 和 href 3.DOCTYPE 的作用 4.HTML5 的新特性 5.script 标签中的 defer 和 async 6. ...

  8. 基础知识 + 面试题目 总结 索引页

    1 网络编程 同步.异步.阻塞.非阻塞  http://www.cnblogs.com/diegodu/p/3977739.html 2  TCP  http://calvin1978.blogcn. ...

  9. MySQL基础知识面试选择题40

    1.数据库系统的核心是_B_. A.数据库           B.数据库管理系统 C.数据模型       D.软件工具 2.SQL语言包括_ABCD_.(多选) A.DCL     B.DML C ...

  10. 前端中高级基础知识面试汇总

    持续更新ing- 前端基础github地址.README.md可以下载到typora中打开,会有整个大纲目录显示(github中markdown目录快捷生成方式不现实,之后可能会想办法生成贴过来,暂时 ...

最新文章

  1. JAVA8 获取叶节点_Java找出所有的根节点到叶子节点的节点值之和等于sum 的路径...
  2. Java--缓存热点数据,最近最少使用算法
  3. python pandas爬取网页成绩表格,计算各个类别学分
  4. STL源码剖析 读书笔记一 2013-5-4
  5. 博客园速度太快了,快得让人心慌……
  6. Android:SQLiteOpenHelper数据库的两套API
  7. Atitit 文档资料管理同步解决方案
  8. js面向对象练习(二):JS面向对象的思路(canvas)写躁动的小球
  9. CDATA不支持html,我应该在HTML5中使用(Should I use in HTML5?)
  10. linux date命令 下月,Linux date命令用法和使用技巧(获取今天.昨天.一分钟前等)
  11. android自定义pickerview,开源项目 好用的PickerView库了
  12. 更改Web应用地址栏显示的图标
  13. 不同IP网段连接网络打印机
  14. xiuno开发文档_$ip-XiunoPHP 4.0 开发手册
  15. StringBuilder和输入输出
  16. Cast方法oracle,oracle 中cast方法的使用
  17. 进程和线程的区别 进程间的通信方式
  18. 一款基于SpringBoot开发开源外卖系统
  19. 我的爸爸,在滴滴做自动驾驶
  20. windows桌面便笺使用小技巧

热门文章

  1. thinkphp事务处理以及无效时的解决方案(整理)
  2. Java关键字(三)——static
  3. 转载 从算法上解读自动驾驶是如何实现的?
  4. iOS小白之路...iOS中基础控件的使用
  5. SuseLinux详解(2)——网络设置静态IP 网关 DNS的方法
  6. 一个简单HTML标签marquee实现动态滚动条
  7. Java代码中换行符怎么用
  8. 重启小狼毫输入法,rime输入法重启
  9. [翻译]Adobe Flash Player 11新特性
  10. Air与java通信