先临三维C++ 一面凉经之解答
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)
- 频繁访问元素的场景用数组;频繁插入或删除的场景用链表
- 单向队列用什么实现
可以用链表,也可以用数组
- 线程如何同步数据?
线程同步主要包括四种方式:
- 互斥量pthread_mutex_
- 读写锁pthread_rwlock_
- 条件变量pthread_cond_
- 信号量sem_
12.多线程问题
略
13.指针 vs 引用
(1)指针是实体,占用内存空间;引用是别名,与变量共享内存空间。
(2)指针不用初始化或初始化为NULL;引用定义时必须初始化。
(3)指针中途可以修改指向;引用不可以。
(4)指针可以为NULL;引用不能为空。
(5)sizeof(指针)计算的是指针本身的大小;而sizeof(引用)计算的是它引用的对象的大小。
(6)如果返回的是动态分配的内存或对象,必须使用指针,使用引用会产生内存泄漏。
(7)指针使用时需要解引用;引用使用时不需要解引用‘*’。
(8)有二级指针;没有二级引用。
- 单例类如何创建
单例实现原理是,将能够创建对象的函数都设置为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.对公司了解多少?
略
以上答案均来自本人专栏:机器学习面试题汇总与解析(蒋豆芽面试题总结)
欢迎大家围观:https://blog.nowcoder.net/jiangwenbo
#C++#