1.你怎么学习的C++

2.这个问题忘了是啥了 反正是内存分配相关的我懵了没回答上(题目都没咋听明白)

3.堆和栈的区别

  • 堆栈空间分配不同。栈由操作系统自动分配释放 ,存放函数的参数值,局部变量的值等,栈有着很高的效率;堆一般由程序员分配释放,堆的效率比栈要低的多。
  • 堆栈缓存方式不同。栈使用的是一级缓存, 它们通常都是被调用时处于存储空间中,调用完毕立即释放;堆则是存放在二级缓存中,速度要慢些。
  • 空间大小: 栈的空间大小并不大,一般最多为2M,超过之后会报Overflow错误。堆的空间非常大,理论上可以接近3G。(针对32位程序来说,可以看到内存分布,1G用于内核空间,用户空间中栈、BSS、data又要占一部分,所以堆理论上可以接近3G,实际上在2G-3G之间)。
  • 能否产生碎片: 栈的操作与数据结构中的栈用法是类似的。‘后进先出’的原则,以至于不可能有一个空的内存块从栈被弹出。因为在它弹出之前,在它上面的后进栈的数据已经被弹出。它是严格按照栈的规则来执行。但是堆是通过new/malloc随机申请的空间,频繁的调用它们,则会产生大量的内存碎片。这是不可避免地。

4.32位整型在大小端的区别

小端模式:的有效字节存储在的存储器地址。常用的X86结构是小端模式。

大端模式:的有效字节存储在的存储器地址。KEIL C51则为大端模式。

5.int char 的大小

int 4字节,char 1字节

6.struct vs class

  • struct 一般用于描述一个数据结构集合,而 class 是对一个对象数据的封装;

  • struct 中默认的访问控制权限是 public 的,而 class 中默认的访问控制权限是 private 的,例如:

struct A{
    int iNum;    // 默认访问控制权限是 public
}
class B{
    int iNum;    // 默认访问控制权限是 private
}
  • 在继承关系中,struct 默认是公有继承,而 class 是私有继承;

  • class 关键字可以用于定义模板参数,就像 typename,而 struct 不能用于定义模板参数,例如:

template<typename T, typename Y>    // 可以把typename 换成 class 
int Func(const T& t, const Y& y) { 
    //TODO 
}

7.静态成员变量特点

在c++中,static关键字可以用于定义类中的静态成员变量:使用静态数据成员,它既可以被当成全局变量那样去存储,但又被隐藏在类的内部。类中的static静态数据成员拥有一块单独的存储区,而不管创建了多少个该类的对象。所有这些对象的静态数据成员都共享这一块静态存储空间。

8.什么是虚函数和纯虚函数

函数前面修饰类型为virtual的为虚函数

包含纯虚函数的类称为抽象类(Abstract Class)。之所以说它抽象,是因为它无法实例化,也就是无法创建对象。原因很明显,纯虚函数没有函数体,不是完整的函数,无法调用,也无法为其分配内存空间。

抽象类通常是作为基类,让派生类去实现纯虚函数。派生类必须实现纯虚函数才能被实例化。

9.数组 vs 链表

  • 数组内存连续、有序;链表内存可以不连续
  • 数组可以直接访问下标,访问时间复杂度O(1);链表需要通过下一级指针层层递进访问,访问时间复杂度O(n)
  • 数组插入或删除元素时需要移动后面的元素,时间复杂度O(n);而链表插入或删除元素时,时间复杂度O(1)
  • 频繁访问元素的场景用数组;频繁插入或删除的场景用链表
  1. 单向队列用什么实现

可以用链表,也可以用数组

  1. 线程如何同步数据?

线程同步主要包括四种方式:

  • 互斥量pthread_mutex_
  • 读写锁pthread_rwlock_
  • 条件变量pthread_cond_
  • 信号量sem_

12.多线程问题

13.指针 vs 引用

(1)指针是实体,占用内存空间;引用是别名,与变量共享内存空间。

(2)指针不用初始化或初始化为NULL;引用定义时必须初始化。

(3)指针中途可以修改指向;引用不可以。

(4)指针可以为NULL;引用不能为空。

(5)sizeof(指针)计算的是指针本身的大小;而sizeof(引用)计算的是它引用的对象的大小。

(6)如果返回的是动态分配的内存或对象,必须使用指针,使用引用会产生内存泄漏。

(7)指针使用时需要解引用;引用使用时不需要解引用‘*’。

(8)有二级指针;没有二级引用。

  1. 单例类如何创建

单例实现原理是,将能够创建对象的函数都设置为private,通过静态成员返回一个实例。

有两种方式,一个是懒汉式,一个是饿汉式。懒汉式需要考虑加锁。

实现代码如下:

#include <iostream>
#include <pthread.h>
using namespace std;

class singleInstance{
public:
	static singleInstance* GetsingleInstance(){
		if (instance == NULL){
			pthread_mutex_lock(&mutex);//mlock.lock();
			if (instance == NULL){
				instance = new singleInstance();
			}
			pthread_mutex_unlock(&mutex);//mlock.unlock();
		}
		return instance;
	};
	~singleInstance(){};
	static pthread_mutex_t mutex;//mutex mlock; 加锁互斥
private:// 涉及创建对象的函数都设置为private
	singleInstance(){};
	singleInstance(const singleInstance& other){};
	singleInstance& operator=(const singleInstance& other){ return *this; };
	static singleInstance* instance;
};

//懒汉式,静态变量需要定义
singleInstance* singleInstance::instance = nullptr;
pthread_mutex_t singleInstance::mutex;

int main(){
	// 因为没有办法创建对象,就得采用静态成员函数的方法返回静态成员变量
	singleInstance *s = singleInstance::GetsingleInstance();
	//singleInstance *s1 = new singleInstance(); // 报错
    cout << "Hello World";
    delete s;  // 防止内存泄露
    return 0;
}

下面是饿汉式:

#include <iostream>
#include <pthread.h>
using namespace std;

class singleInstance{
public:
	static singleInstance* GetsingleInstance(){ // 饿汉式,直接创建一个对象,不需要加锁
		static singleInstance instance;
		return &instance;
	};
	~singleInstance(){};
private:// 涉及创建对象的函数都设置为private
	singleInstance(){};
	singleInstance(const singleInstance& other){};
	singleInstance& operator=(const singleInstance& other){ return *this; };
};

int main(){
	// 因为没有办法创建对象,就得采用静态成员函数的方法返回
	singleInstance *s = singleInstance::GetsingleInstance();
	//singleInstance *s1 = new singleInstance(); // 报错
    cout << "Hello World";
    return 0;
}

15.类中默认函数有几个

类的6个默认的成员函数包括: 构造函数、析构函数、拷贝构造函数、赋值运算符重载函数、取地址操作符重载、const 修饰的取地址操作符重载。

16.对公司了解多少?