常见的面试题(1)

目录

1.malloc和new的区别?

2.滑动窗口最大值

3.面向对象语言的特点

4.static的用法 

5.list和vector区别

6.迭代器失效问题

7.多态

8.引用和指针的区别?

9. 深拷贝浅拷贝区别

10.GET和POST的区别

11.手撕冒泡排序

12.手撕快排

13.使用sizeof计算一个空类为什么大小是1?

14.c++内存布局,和每个区存储的数据类型

15.Linux常用命令,怎样查看CPU和内存使用情况


1.malloc和new的区别?

  • C++允许重载new/delete操作符,特别的,布局new的就不需要为对象分配内存,而是指定了一个地址作为内存起始区域,new在这段内存上为对象调用构造函数完成初始化工作,并返回此地址。而malloc不允许重载的。
  • new分配内存成功后返回一个对象的指针,而malloc返回的是一个void*,需要通过强转成特定类型的指针。
  • new关键字申请内存时无需指定大小(这个由编译器计算对象的大小),而malloc需要指定大小;对于申请失败时,new会抛异常(bac_alloc异常),而malloc返回null。
  • 这里new还可以通过调用malloc实现自身,而malloc不可以调用new。
  • new分配内存在自由存储区(可以是堆,也可以是其他),malloc在堆上申请内存。

2.滑动窗口最大值

class Solution {
public:
    vector<int> maxSlidingWindow(vector<int>& nums, int k) {
       vector<int>  ans;
       int n = nums.size();
        if(n==0)
        {
            return ans;
        }
        priority_queue<pair<int, int>> q;
        for (int i = 0; i < k; ++i) {
            q.emplace(nums[i], i);
        }
         ans = {q.top().first};
        for (int i = k; i < n; ++i) {
            q.emplace(nums[i], i);
            while (q.top().second <= i - k) {
                q.pop();
            }
            ans.push_back(q.top().first);
        }
        return ans;
    }
};

3.面向对象语言的特点

  • 将客观事物看做具有属性和行为的对象
  • 通过抽象找出同一类对象的共同属性和行为,形成类.
  • 通过类的继承与多态实现代码重用

4.static的用法 

首先static有两种作用限定作用域和保持变量内容持久化

全局静态变量
static <T> a;
生命周期:整个程序运行期间。作用域:在声明文件之外是不可见的
局部静态变量
在局部变量前加上static作用域仍为局部作用域,当定义它的函数或者语句块结束的时候,作用域结束。但是当局部静态变量离开作用域后,并没有销毁,而是仍然驻留在内存当中,只不过我们不能再对它进行访问,直到该函数再次被调用,并且值不变;
静态函数
在函数返回值之前加上static,表示该函数只能在本文件中被调用

 类的静态成员
 类中只有一份,类的所有实例都共享
类的静态成员函数
实现的时候也不需要static的修饰,因为static是声明性关键字;类的静态函数是该类的范畴内的全局函数,不能访问类的私有成员,只能访问类的静态成员,不需要类的实例即可调用;实际上,他就是增加了类的访问权限的全局函数;

5.list和vector区别

list底层是双向链表,并且内存不连续,因此具有高效的数据插入和删除,但是其因为只能通过指针访问数据,所以存取数据时间复杂度是O(N);

vector底层是数组,实现顺序存储,内存连续,数据存取是O(1),但是在插入和删除时,会造成内存块的拷贝,所以时间复杂度为O(N);

二者都重载了++,vector还重载了+、+=、<、[]等操作符,而list没有

6.迭代器失效问题

list删除会导致当前位置迭代器失效,但是前后的不影响,只需要在下一次使用迭代器之前给其赋值就可以

vector的删除跟list差不多

7.多态

多态就是不同对象对同一行为会有不同的状态。(就比如,买票时儿童和成人,一个半票,一个全票)

实现多态有两个条件: 一是虚函数重写,重写就是用来设置不同状态的

           二是对象调用虚函数时必须是指针或者引用

1.inline函数可以是虚函数吗?

       不能,因为inline函数没有地址,无法放到虚函数表中

2.静态成员可以是虚函数吗?

 不能, 因为静态成员函数没有this指针, 因为有this指针才能访问到虚表指针,有虚表指针才能找到虚表从而调用实际应该调用的函数。

3.构造函数可以是虚函数吗?/虚函数指针在什么时候生成的的?

不能,因为对象中的虚表指针是在构造函数初始化列表阶段才初始化的

4.析构函数可以是虚函数吗?什么场景下析构函数是虚函数?

可以,并且最好把基类的析构函数定义成虚函数当父类指针指向子类对象时,如果析构函数不是虚函数,析构就只会释放父类对象,造成内存泄漏       

5.对象访问普通函数快还是虚函数更快?

首先如果是普通对象,是一样快的,如果是指针对象或者是引用对象,则调用的普通函数快,因为普通对象在编译时就确定地址了,虚函数构成多态,运行时调用虚函数需要到虚函数表中去查找 

8.引用和指针的区别?

  • 引用必须被初始化,但是不分配存储空间。指针不需要初始化,在初始化的时候需要分配存储空间。
  • 引用初始化后不能被改变,指针可以改变所指的对象。
  • 不存在指向空值的引用,但是存在指向空值的指针。
  • 指针使用时需要*解引用,而引用不需要

9. 深拷贝浅拷贝区别

假设B去复制A,这时候改变A的值,如果B改变,那就是浅拷贝,本质上浅拷贝只是增加了一个指针指向A,。

而如果B没有改变,那就是深拷贝,增加了一个指针指向一块新的空间,这种深拷贝可以避免浅拷贝带来的释放同一个地址空间带来的错误

10.GET和POST的区别

  1. get请求一般是去取获取数据(其实也可以提交,但常见的是获取数据);post请求一般是去提交数据。
  2. get因为参数会放在url中,所以隐私性,安全性较差,请求的数据长度是有限制的,不同的浏览器和服务器不同,一般限制在 2~8K 之间,更加常见的是 1k 以内;
  3. post请求是没有的长度限制,请求数据是放在body中;
  4. get请求刷新服务器或者回退没有影响,post请求回退时会重新提交数据请求。
  5. get请求可以被缓存,post请求不会被缓存。
  6. get请求会被保存在浏览器历史记录当中,post不会。get请求可以被收藏为书签,因为参数就是url中,但post不能。它的参数不在url中。
  7. get请求只能进行url编码(appliacation-x-www-form-urlencoded),post请求支持多种(multipart/form-data等)。
  8. …GET 和 POST都是http请求方式, 底层都是 TCP/IP协议;通常GET 产生一个 TCP 数据包;POST 产生两个 TCP 数据包(但firefox是发送一个数据包),对于 GET 方式的请求,浏览器会把 http header 和 data 一并发送出去,服务器响应 200(返回数据)表示成功;
  9. 而对于 POST,浏览器先发送 header,服务器响应 100, 浏览器再继续发送 data,服务器响应 200 (返回数据)。

11.手撕冒泡排序

void BubblingSort(int ar[],int size)
{
	bool flag = false;

	for (int i = 0; i < size; ++i)
	{
		for (int j = 1; j < size - i; ++j)
		{
			if (ar[j] < ar[j - 1])
			{
				swap(ar[j], ar[j - 1]);
				flag = true;
			}
		}
		if (!flag)
		{
			return;
		}
	}
}

12.手撕快排

int _quicksort(int ar[], int left, int right)
{
	int temp = ar[left];
	while (left < right)
	{
		while (left < right && ar[right]>=temp)
		{
			right--;
		}
		ar[left] = ar[right];
		while (left < right && ar[left] <= temp)
		{
			left++;
		}
		ar[right] = ar[left];
	}
	ar[left] = temp;
	return left;
}
void quicksort(int ar[], int left, int right)
{
	int index = 0;
	if (left < right)
	{
		index = _quicksort(ar, left, right);
		quicksort(ar, left,index);
		quicksort(ar, index + 1, right);
	}
}

13.使用sizeof计算一个空类为什么大小是1?

因为空的类或结构体同样可以被实例化,如果定义对空的类或者结构体取sizeof()的值为0,那么该空的类或结构体实例化出很多实例时,在内存地址上就不能区分该类实例化出的实例,所以,为了实现每个实例在内存中都有一个独一无二的地址,编译器往往会给一个空类隐含的加一个字节,这样空类在实例化后在内存得到了独一无二的地址,所以空类所占的内存大小是1个字节。

14.c++内存布局,和每个区存储的数据类型

堆区:由程序猿手动申请,手动释放,若不手动释放,程序结束后由系统回收,生命周期是整个程序运行期间。使用malloc或者new进行堆的申请,堆的总大小为机器的虚拟内存的大小。

栈区:由系统进行内存的管理。主要存放函数的参数以及局部变量。在函数完成执行,系统自行释放栈区内存,不需要用户管理。整个程序的栈区的大小可以在编译器中由用户自行设定,VS中默认的栈区大小为1M,可通过VS手动更改栈的大小。64bits的Linux默认栈大小为10MB,可通过ulimit -s临时修改。

内存映射段:存放动态库,静态库和一些映射信息以及有依赖的东西

数据段:存的是全局变量或者静态变量。

代码段:二进制代码和只读常量。

15.Linux常用命令,怎样查看CPU和内存使用情况

mkdir vim rm -rf g++ -std=c++11 -l -L./ -lpthread touch 

ls -lh cd cd .. stat等等

top vmstat

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值