Skip to content

Latest commit

 

History

History
executable file
·
586 lines (336 loc) · 13.7 KB

编程语言.md

File metadata and controls

executable file
·
586 lines (336 loc) · 13.7 KB

[TOC]

编程语言

一、C/C++

C 与 C++ 的区别(面向对象的特点)

  • TODO

C++ 与 Python的区别

  • TODO

判断struct的字节数

一般使用sizeof判断struct所占的字节数,那么计算规则是什么呢?

关键词:

1.变量的起始地址和变量自身的字节数

2.以最大变量字节数进行字节对齐(倍数关系)。

注:这里介绍的原则都是在没有#pragma pack宏的情况下

先举个例子:

struct A
{
    char a[5];
    int b;
    short int c;
}struct A;

在上例中,要计算 sizeof(a) 是多少?

有两个原则: 1)各成员变量存放的起始地址相对于结构的起始地址的偏移量必须为该变量的类型所占用的字节数的倍数 即当 A中的a占用了5个字节后,b需要占用四个字节,此时如果b直接放在a后,则b的起始地址是5,不是sizeof(int)的整数倍,所以 需要在a后面补充3个空字节,使得b的起始地址为8. 当放完b后,总空间为5+3+4 = 12. 接着放c,此时为 12 + 2 = 14.

2)为了确保结构的大小为结构的字节边界数(即该结构中占用最大空间的类型所占用的字节数)的倍数, 所以在为最后一个成员变量申请空间后,还会根据需要自动填充空缺的字节。 这是说A中占用最大空间的类型,就是int型了,占用了4个字节,那么规定A占用的空间必须是4的整数倍。本来计算出来占用的空间为14, 不是4的整数倍,因此需要在最后补充2个字节。最终导致A占用的空间为16个字节。

再举个例子:

struct B
{
    char *d;
    short int e;
    long long f;
    char c[1];
}b;
 
void test2() {
	printf("%d\n", sizeof(b));
}

对于此题,需要注意的一点是:windows系统对long long是按照8字节进行对齐的,但是Linux系统对long long则是按照4字节对齐的。

因此: d占用4字节(因为d是指针)

e占用2字节

f占用8字节,但是其起始地址为为6,不是4的整数倍(对于Linux系统),或不是8的整数倍(对于Windows系统),因此对e之后进行字节补齐,在这里不管对于Linux还是Windows都是补充2个字节,因此 f 的起始地址是8,占用8个字节。

对于c,它占用了1个字节,起始地址是16,也是1的整数倍。 

最后,在c之后需要对整个B结构体占用的空间进行补齐,目前占用空间是16+1 = 17个字节。

对于Linux,按4字节补齐(long long 是按4字节补齐的),因此补充了3位空字节,最后占用空间是 17 + 3 = 20字节。

对于Windows系统,是按8字节补齐的,因此就补充了7个字节,最后占用的空间是24字节。

参考资料

static 作用

什么是static?

static 是C++中很常用的修饰符,它被用来控制变量的存储方式和可见性。

为什么要引入static?

函数内部定义的变量,在程序执行到它的定义处时,编译器为它在栈上分配空间,大家知道,函数在栈上分配的空间在此函数执行结束时会释放掉,这样就产生了一个问题: 如果想将函数中此变量的值保存至下一次调用时,如何实现? 最容易想到的方法是定义一个全局的变量,但定义为一个全局变量有许多缺点,最明显的缺点是破坏了此变量的访问范围(使得在此函数中定义的变量,不仅仅受此函数控制)。

static的作用

第一个作用是限定作用域(隐藏);第二个作用是保持变量内容持久化;

  • 函数体内static变量的作用范围为该函数体,不同于auto变量,该变量的内存只被分配一次,因此其值在下次调用时仍维持上次的值。

举个例子

#include<iostream>

using namespace std;

int main(){

    for(int i=0; i<10; ++i){
	    int a = 0;
		static int b = 0;
		cout<<"a: "<< a++ <<endl;
		cout<<"b(static): " << b++ <<endl;
	}
	return 0;
}

输出结果:

a: 0
b(static): 0
a: 0
b(static): 1
a: 0
b(static): 2
a: 0
b(static): 3
a: 0
b(static): 4
a: 0
b(static): 5
a: 0
b(static): 6
a: 0
b(static): 7
a: 0
b(static): 8
a: 0
b(static): 9
  • 在模块内的static全局变量可以被模块内所有函数访问,但不能被模块外其他函数访问

  • 在模型内的static函数只可被这一模块内的其他函数调用,这个函数的使用范围被限制在声明它的模块内。

  • 在类中的static成员变量属于整个类所有,对类的所有对象只有一份复制。即类的所有对象访问的static成员变量是同一个,而不是对象专属的。

  • 在类中的static成员函数属于整个类所有,这个函数不接收this指针,因而只能访问类的static成员变量。同类的static成员变量性质一样,类的对象访问的static成员函数是同一个,不是对象专属的。

参考

Const 作用

  • TODO

extern "C"的作用

  • TODO

多态

  • TODO

如何实现多态?

  • TODO

虚函数

  • TODO

虚函数怎么实现的?

  • TODO

析构函数

  • TODO

虚析构函数的作用

  • TODO

virtual函数能不能用在构造函数中?

  • TODO

继承

  • TODO

多线程的同步问题

  • TODO

左值和右值

  • TODO

C++的设计模式

  • 工厂模式
  • 策略模式
  • 适配器模式
  • 单例模式
  • 原型模式
  • 模板模式
  • 建造者模式
  • 外观模型
  • 组合模式
  • 代理模式
  • 享元模式
  • 桥接模式
  • 装饰模式
  • 备忘录模式
  • 中介者模式
  • 职责链模式
  • 观察者模式

参考资料

动态内存管理

  • TODO

智能指针

  • TODO

long long转成string

  • TODO

NULL和nullstr的区别

  • TODO

new/delete和 malloc/free的区别

  • TODO

delete和delete []区别

  • TODO

C++虚函数的实现机制

  • TODO

C++基类的析构函数为什么建议是虚函数?

防止内存泄漏

  • TODO

STL中的 vector 和 list 的区别

  • TODO

STL中的 vector 和 map 的底层结构

  • TODO

map 和 unorder_map 区别

  • TODO

实现atoi,即将"1234"转化成1234(int类型)

  • TODO

实现atof,即将"1.234"转换成1.234(float类型)

  • TODO

结构体和联合体的区别

结构体:把不同类型的数据组合成一个整体-------自定义数据类型,结构体变量所占内存长度是各成员占的内存长度的总和。

联合体:使几个不同类型的变量共占一段内存(相互覆盖),共同体变量所占内存长度是各最长的成员占的内存长度。

Structure 与 Union主要有以下区别:

1.struct和union都是由多个不同的数据类型成员组成, 但在任何同一时刻, union中只存放了一个被选中的成员, 而struct的所有成员都存在。在struct中,各成员都占有自己的内存空间,它们是同时存在的。一个struct变量的总长度等于所有成员长度之和。在Union中,所有成员不能同时占用它的内存空间,它们不能同时存在。Union变量的长度等于最长的成员的长度。

2.对于union的不同成员赋值, 将会对其它成员重写, 原来成员的值就不存在了, 而对于struct的不同成员赋值是互不影响的。

3.联合体的各个成员共用内存,并应该同时只能有一个成员得到这块内存的使用权(即对内存的读写),而结构体各个成员各自拥有内存,各自使用互不干涉。所以,某种意义上来说,联合体比结构体节约内存。

举个例子:

typedef struct
{
int i;
int j;
}A;
typedef union
{
int i;
double j;
}U;

sizeof(A)的值是8,sizeof(U)的值也是8(不是12)。

为什么sizeof(U)不是12呢?因为union中各成员共用内存,i和j的内存是同一块。而且整体内存大小以最大内存的成员的划分。即U的内存大小是double的大小,为8了。

sizeof(A)大小为8,因为struct中i和j各自得到了一块内存,每人4个字节,加起来就是8了。 了解了联合体共用内存的概念,也就是明白了为何每次只能对其一个成员赋值了,因为如果对另一个赋值,会覆盖了上一个成员的值。

举个例子:

例如:书包;可以放置书本、笔盒、记事本等物。

联合体,仅能放入一样东西的包(限制),其尺寸,是可放物品中,最大一件的体积。

结构体,是能放入所有物品的包,所以其尺寸,可同时容纳多样物品。

联合体,同时间只能有一个成员在内。或是说,可以用不同型态,去看同一组数据。

结构体,可以包含多个成员在一起,成员都能个别操作。

引用和指针

  • TODO

C++ operator new 和 new operator

  • TODO

怎么理解C++面向对象?跟Python面向对象有什么区别?

  • TODO

C++多态特性,父类和子类的区别

  • TODO

虚函数有哪些作用?多态的虚函数(父类和子类)返回值类型可以不一样吗?什么情况下,返回值类型不一样?

  • TODO

C++四种强制类型转换有哪些?每种特性是什么?有什么区别?

  • TODO

map 实现原理

  • TODO

set 实现原理

  • TODO

STL中的sort函数实现

  • TODO

std::vector描述一下,如何动态扩展,如何shink内存

  • TODO

unorder容器与ordered容器的区别

  • TODO

说一下智能指针,shared_ptr与unique_ptr

  • TODO

普通指针如何实现一块内存只能有一个指针指向这种功能

  • TODO

C++ RTTI 是什么?

  • TODO

C++是如何实现多态的?

  • TODO

vector的iterator什么时候失效?

  • TODO

写CmakeLists.txt,写gcc指令

  • TODO

函数局部变量存在哪里?new出来的变量在哪里?

  • TODO

堆区和栈区什么区别?

  • TODO

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

  • TODO

什么是内存泄漏?怎么产生的?如何检测?

  • TODO

extern关键字的底层机制是怎么实现的?

  • TODO

静态绑定和动态绑定是怎么实现的?

  • TODO

虚函数表跟对象还是跟类绑定?

  • TODO

返回函数中的静态变量的地址会发生什么?

  • TODO

全局static变量和非static的有什么区别?

STL 的 map 如何实现的?

  • TODO

unordered_map怎么实现的?画一下底层的数据结构

  • TODO

sorted_set 怎么实现?

  • TODO

    • volatile关键字

.h里面定义函数,会在什么阶段错误?

  • TODO

为什么.h里面一般只放函数声明?为什么这么设计?

  • TODO

内联函数 inline 作用

TODO

析构函数 virtual 作用

  • TODO

static和const区别?

const和define的区别?

struct和class的区别?

sizeof和strlen的区别?

32位,64位系统中,各种常用内置数据类型占用的字节数?

virtual, inline, decltype,volatile,static, const关键字的作用?使用场景?

C++中函数指针的作用?由那些属性唯一决定一个函数指针?

C++中如何唯一确定一个重载函数?重载函数默认初始化方式?

C++多态的实现机制?虚函数表的内部实现机制?

C++中重载,覆盖,隐藏的区别?

深拷贝与浅拷贝的区别?

派生类中构造函数,析构函数调用顺序?

C++类中数据成员初始化顺序?

结构体内存对齐问题?结构体/类大小的计算?

static_cast, dynamic_cast, const_cast, reinpreter_cast的区别?

shared_ptr, unique_ptr, weak_ptr的区别?auto_ptr与shared_ptr的区别?weak_ptr主要是为了解决什么问题的?shared_ptr的内部实现?

new/delete和malloc/free的区别?

strcat,strcpy,strncpy,memset,memcpy的内部实现?

new operator, operator new, placement new的区别?

单例模式?懒汉式?饿汉式?

C++中有哪些容器(序列容器,关联容器)?vetor与list的区别?set与unordered_set的区别?

vector.size() 和 vector.capicity() 区别

  • TODO

计算 vector.push_back() 的平均复杂度

  • TODO

怎么设计一个内存池,要考虑哪些方面?

  • TODO

lambda 捕获对象的实现

  • TODO

参考资料

二、Python

Python中可变和不可变对象是什么意思?

  • TODO

tuple、list 和 dict 的区别

  • TODO

iterables、generator 和 yield的区别

  • TODO

Python 的装饰器

  • TODO

Python 的迭代器

  • TODO

使用迭代器遍历和非迭代器遍历区别?

  • TODO

Python 的生成器

  • TODO

Python的全局锁

  • TODO

Python 字典采用的是什么数据结构?

答:使用的是key-value匹配的哈希结构

Python 的 append 和 extend 有什么区别?

  • TODO

Python 的浅拷贝和深拷贝

  • TODO

Python的内存回收机制

  • TODO

可变对象和不可变对象

  • TODO