1、vector和list是线程安全的吗(这是一个JAVA题)?(360实习一面)
vector
是线程安全的(准确来说是相对安全或部分安全),vector
的很多方法中使用了sychronized(同步)关键字修饰,这样在多线程并发访问vector
实例的时候,保证了某一时刻最多只能有一个线程调用vector
中被sychronized修饰的方法;list
不是线程安全的,其中的操作不是原子操作。
2、static成员函数能被继承吗?(腾讯WXG实习一面)
不能。不管类创建了多少对象,静态成员在内存空间中都只有一份拷贝,这份拷贝被所有属于这个类的对象共享。可以认为该静态成员是属于该类的,而不是属于具体某个对象的,基类和派生类共享该静态成员的内存。 static 成员是共享关系不是继承关系,故不能被继承。子类可以访问父类的 static 成员但受访问限制(如果 static 成员是 private 的就无法访问了)。
注:基类对应派生类,父类对应子类。两种说法不同,其实都是一个意思。
3、在什么情况下父类的析构函数不用被声明为虚函数?
当一个类中不含虚函数的时候,通常表示它不意图被用作一个基类,这时不需要将该类的析构函数声明为虚函数。只有一种情况我们才需要虚析构函数,就是在删除一个指向派生类对象的基类指针时。如果无端地把所有类中的析构函数都声明为虚函数,就像从未声明它们为虚函数一样,都是错误的。许多人的心得是:只有当class内含至少一个virtual函数,才为它声明virtual析构函数。
4、你平时是如何学习的?(插一个常问的非技术题)
最好不要说在B站看视频学习,或者在CSDN等博客上查资料学习。最佳的回答应该是看书,可以列举几本你看过的技术书籍。因为视频或博客上说的不一定是正确的,或者不够严谨,而经典的书籍经过若干年的再版和修订,是权威的象征,极具参考价值。我最开始也是看视频学习,后来发现视频教程质量参差不齐、节奏缓慢、往往抓不住重点,浪费了许多宝贵时间。我已经很久没看视频学习了,看书遇到疑惑的地方会上网翻翻博客,吸收大家的见解。还有一点是,书不要从第一页看到最后一页,这样看往往会让你失去耐心,只着重看你感兴趣的部分即可,也不要指望一遍就能看个明白,书都是需要反复翻阅的。
5、C++中类的成员变量和成员函数的内存分布情况?
成员函数不占用对象内存,所有函数是放在代码区的。对象大小和对象中数据成员大小是一致的,如果有虚函数的话还会有一个虚表指针。补充一点:所有的函数都放在代码区,不管是不是静态成员函数,又因为静态成员函数没有this指针,故不能访问非静态数据成员。
6、重载、重写和隐藏的区别?
- 重载是指两个函数同名,但他们的参数个数或参数类型不同,与返回值类型无关;
- 重写是指在派生类中覆盖基类中的同名虚函数,与基类的虚函数有相同的参数个数、参数类型、返回值类型;
- 隐藏是指派生类的函数屏蔽了基类中的同名函数,要求基类函数不能是虚函数。
7、push_back()和emplace_back()的区别?(百度)
在于底层实现的机制不同。push_back()向容器尾部添加元素时,首先会创建这个元素,然后再将这个元素拷贝或者移动到容器中(如果是拷贝的话,事后会自行销毁先前创建的这个元素);而 emplace_back() 在实现时,则是直接在容器尾部创建这个元素,省去了拷贝或移动元素的过程。
8、在Linux中如何把CPU打满?(字节)
//方法一
cat /dev/zero > /dev/null
//方法二:计算圆周率
echo "scale=300; a(1)*4" | bc -l //scale设置精度,scale越大计算时间越长,a(1)表示arctan(1) = 1/4 * π
//bc是linux下的计算命令,-l指定使用标准数学库
9、Linux如何删除目录下所有txt文件,目录中可能还有目录(字节)?
find ./ -name *.txt | xargs rm -rf
xargs可以将管道或标准输入(stdin)数据转换成命令行参数。
10、内存泄漏解决办法?
- 智能指针
- RAII:在构造函数中分配内存,在析构函数中释放内存。
11、为什么需要纯虚函数?
在很多情况下,类本身生成对象是不合理的,比如以动物作为基类可以派生出老虎、狮子、孔雀等子类,但将动物类本身实例化为对象是不合理的,因为动物、植物这些都是抽象的概念,所以需要为其声明纯虚函数,让它们变成不可实例化的抽象类。
12、实现一个只能在堆上创建对象的类
在C++中,类的对象建立分为两种,一种是静态建立,如
A a
;另一种是动态建立,如A* ptr = new A
。
- 静态建立是在栈中分配内存,通过直接移动栈顶指针,挪出适当的空间,然后再这片内存空间上调用构造函数形成一个栈对象,这种方法直接地调用了类的构造函数;
- 动态建立通过使用
new
运算符将对象建立在堆中,第一步执行operator new()
函数,在堆空间中搜索合适的内存块进行分配,第二步调用构造函数构造对象,初始化这片内存空间,这种方法间接地调用了类的构造函数。动态建立已经是在堆上生成对象了,而静态建立是在栈上生成对象,所以我们的目标是禁止静态建立,正确做法是将构造函数、拷贝构造函数、赋值运算符的重载函数都设置为私有,同时为了可以生成对象,还需要给出一个专门的函数用来在堆上构造对象。而且这个函数必须是静态且公有的,因为如果是非静态,那么就要通过
this
指针来调用,又因为构造函数为私有,没有构造对象也就无法产生this
指针来调用成员函数,而静态函数不需要通过this
指针来调用。
#include <iostream>
using namespace std;
class A
{
private:
A() { cout << "create" << endl; }
A(A const&) {}
A& operator=(A const&) {}
~A() { cout << "destory" << endl; }
public:
static A* getA()
{
return new A();
}
void destoryA()
{
delete this;
}
};
int main()
{
A* a = A::getA();
a->destoryA();
return 0;
}
如果反过来要实现一个只能在栈上生成对象的类,那么就把
new
和delete
重载为私有即可,代码如下:
#include <iostream>
using namespace std;
class A
{
private:
void* operator new(size_t size);
void operator delete(void* p);
};
int main()
{
A* a = new A; //这里会报错
return 0;
}
vector和list是线程安全的吗 这答案是说java吧
对对,多谢提醒。我才发现😂我改一下
cy , 加油。