首页 > 其他分享 >面试八股(持续更新)

面试八股(持续更新)

时间:2023-05-26 21:11:59浏览次数:45  
标签:八股 函数 对象 更新 面试 C++ 静态 ptr 指针

C++

1. C++从源文件到可执行文件的步骤

​ (1) 预处理:处理所有的预编译指令,生成.i文件。

​ (2) 编译:经过词法分析、语法分析、语义分析和优化后生成汇编语言。生成.s文件

​ (3) 汇编:将编译阶段生成的汇编文件转化成机器码,生成可重定位目标文件。生成.o文件

​ (4) 链接:将多个目标文件及所需要的库链接成最终的可执行目标文件。生成.out文件

2. C++多态

1)多态的方式有几种

(1)静态多态(重载,模板)

是在编译的时候,就确定调用函数的类型。

(2)动态多态(覆盖,虚函数实现)

运行的时候,才确定调用的是哪个函数,动态绑定。运行基类指针指向派生类的对象,并调用派生类的函数。

2)多态是什么

允许将子类类型的指针赋值给父类类型的指针。多态在C++中都是通过虚函数实现的

虚函数实现原理:虚函数表和虚函数指针。

纯虚函数: virtual int fun() = 0;

3)虚函数表和虚指针

虚表是一个指针数组,其中存储了类中所有虚函数的地址。每个类都有一个虚表,其中存储了该类的所有虚函数的地址。当一个类被继承时,子类会继承父类的虚表,并在其后面添加自己的虚函数地址。这样,当子类对象调用父类的虚函数时,会通过父类对象的虚指针找到父类的虚表,然后调用相应的函数。而当子类对象调用自己的虚函数时,会通过子类对象的虚指针找到子类的虚表,然后调用相应的函数。

img

3. C++访问权限控制符

public 公有成员 基类、派生类、友元、外部都可以访问

protected 保护成员 基类、派生类、友元可以访问

private 私有成员 基类、友元可以访问

对于继承来说:

1、public 方式继承

派生类能访问基类的public, protected成员,继承过来权限不变,派生类对象只能访问基类public成员。

2、protected方式继承

派生类可以访问基类的public, protected,继承过来都变成了protected,派生类对象啥都不能访问。

3、private方式继承

派生类可以访问基类的public, protected成员,继承过来之后变成自己私有的。 派生类的对象啥都不能访问。

4. C++11的新特性

  • 自动类型推导(auto);
  • 智能指针(std::unique_ptr、std::shared_ptr、std::weak_ptr);
  • lambda表达式;
  • 右值引用(&&);
  • constexpr关键字;
  • 变长参数模板(Variadic Templates);
  • 新的整数类型long long int;
  • std::function和std::bind等封装使函数调用更加方便。
  • nullptr空指针

5. 智能指针

1)为什么要用智能指针

从较浅的层面看,智能指针是利用了一种叫做RAII(资源获取即初始化)的技术对普通的指针进行封装,

这使得智能指针实质是一个对象,行为表现的却像一个指针

作用当然很明显,防止忘记调用delete,当然还有另一个作用,

也指出来了,就是异常安全。在一段进行了try/catch的代码段里面,即使你写入了delete,也有可能因为发生异常,程序进入catch块,从而忘记释放内存,这些都可以通过智能指针解决。

但是智能指针还有一重更加深刻的含义,就是把 所说的value语义转化为reference语义

C++和Java有一处最大的区别在于语义不同,在Java里面下列代码:

Animal a = new Animal();

Animal b = a;

你当然知道,这里其实只生成了一个对象,a和b仅仅是把持对象的引用而已。但在C++中不是这样,

Animal a;

Animal b;

这里确实就是生成了两个对象。

在编写OOP程序时,value语义带来太多的困扰,例如TCP连接中我封装一个accept函数接收请求,那么应该是这样的:

Socket accept();

这就带来一个问题,采用对象做返回值,这里面有一个对象的复制的过程,但是Socket因为某些原因,我让他继承了boost::noncopyable,总之就是Socket失去了复制和赋值的能力,那么该怎么办?

我们首先想到指针,在accept内部new生成一个对象,然后返回指针。但是问题更多,这个对象何时析构? 过早析构,程序发生错误,不进行析构,又造成了内存泄露。

这里的解决方案就是智能指针,而且是引用计数型的智能指针。

typedef boost::shared<Socket> SocketPtr;

SocketPtr accept();

这样外部就可以用智能指针去接收,那么何时析构?当然是引用计数为0,也就是我不再需要这个Socket的时候析构。

这样,我们利用了SockerPtr,实现了跟Java类似的Reference语义。

还有一个例子,Java中往容器中放对象,实际放入的是引用,不是真正的对象,而C++在vector中push_back采用的是值拷贝,如果想实现Java中的引用语义,就应该使用智能指针,可以参考《C++标准库程序》(侯捷/孟岩 译)的第五章讲容器的部分,有一节叫做“用Value语义实现Reference语义”

2)shared_ptr的循环引用问题

虽然智能指针会减少内存泄漏的可能性,但是如果使用智能指针的方式不对,一样会造成内存泄漏。比较典型的情况是循环引用问题,比如这段代码

class B; // 前置声明
class A {
public:
shared_ptr<B> ptr;
};

class B {
public:
shared_ptr<A> ptr;
};

int main()
{
while(true) {
shared_ptr<A> pa(new A());
shared_ptr<B> pb(new B());
pa -> ptr = pb;
pb -> ptr = pa;
}
return 0;
}

这个程序中智能指针的引用情况如下图在这里插入图片描述

上图中,class A和class B的对象各自被两个智能指针管理,也就是A object和B object引用计数都为2,为什么是2?

分析class A对象的引用情况,该对象被main函数中的pa和class B对象中的ptr管理,因此A object引用计数是2,B object同理。

在这种情况下,在main函数中一个while循环结束的时候,pa和pb的析构函数被调用,但是class A对象和class B对象仍然被一个智能指针管理,A object和B object引用计数变成1,于是这两个对象的内存无法被释放,造成内存泄漏,如下图所示

在这里插入图片描述

解决方法
解决方法很简单,把class A或者class B中的shared_ptr改成weak_ptr即可,由于weak_ptr不会增加shared_ptr的引用计数,所以A object和B object中有一个的引用计数为1,在pa和pb析构时,会正确地释放掉内存

3)weak_ptr的lock()

​ lock()函数通过expired()来判断是否对象是否存在,如果expired()返回true,说明该对象已经被析构,此时只会返回一个空的shared_pte;如果expired()返回false,说明此对象shared_pte的引用次数大于0,此时会返回一个指向该对象的shared_ptr

6. C++中的static关键字

1)static关键字

(1)局部变量

静态局部变量使用static修饰符定义,即使在声明时未赋初值,编译器也会把它初始化为0。且静态局部变量存储于进程的全局数据区,即使函数返回,它的值也会保持不变。

(2)全局变量

普通全局变量对整个工程可见,其他文件可以使用extern外部声明后直接使用。也就是说其他文件不能再定义一个与其相同名字的变量了(否则编译器会认为它们是同一个变量)。

静态全局变量仅对当前文件可见,其他文件不可访问,其他文件可以定义与其同名的变量,两者互不影响。

在定义不需要与其他文件共享的全局变量时,加上static关键字能够有效地降低程序模块之间的耦合,避免不同文件同名变量的冲突,且不会误使用。

(3)函数

函数的使用方式与全局变量类似,在函数的返回类型前加上static,就是静态函数。其特性如下:

  • 静态函数只能在声明它的文件中可见,其他文件不能引用该函数
  • 不同的文件可以使用相同名字的静态函数,互不影响

非静态函数可以在另一个文件中直接引用,甚至不必使用extern声明

(4)静态成员变量

静态成员变量不能在类中定义,在定义时分配存储空间

同全局变量相比,使用静态数据成员有两个优势:

  • 静态数据成员没有进入程序的全局名字空间,因此不存在与程序中其它全局名字冲突的可能性
  • 可以实现信息隐藏。静态数据成员可以是private成员,而全局变量不能

(5)静态成员函数

与静态数据成员类似,静态成员函数属于整个类,而不是某一个对象,其特性如下:

静态成员函数没有this指针,它无法访问属于类对象的非静态数据成员,也无法访问非静态成员函数,它只能调用其余的静态成员函数
出现在类体外的函数定义不能指定关键字static
非静态成员函数可以任意地访问静态成员函数和静态数据成员

2)静态变量的初始化顺序问题

如果静态变量在同一个编译单元,则他们的初始化顺序取决于他们声明的顺序

但是如果静态变量在不同的编译单元,则会出现初始化顺序问题

(59条消息) Effective C++笔记(3)—条款4分析_NearXDU的博客-CSDN博客

Linux

1. malloc中的brk和mmap

(60条消息) Linux内存分配小结--malloc、brk、mmap_mmap申请的内存和堆内存有什么区别_gfgdsg的博客-CSDN博客

标签:八股,函数,对象,更新,面试,C++,静态,ptr,指针
From: https://www.cnblogs.com/lihaoxiang/p/17435810.html

相关文章

  • hvv蓝初面试常见漏洞问题(上)
    1.SQL注入漏洞成因:可控变量变量会带入数据库查询变量不存在过滤或者变量过滤不严格注入流程判断是否有注入点orderby判断字段数量unionselect报错查看注入点使用函数查看数据库相关信息注入分类:注入类型:报错、联合、盲注(布尔,时间)、堆叠注入提交方式:get,post,co......
  • 关于EF Core 更新速度随时间越来越慢的解决办法
    #关于EFCore更新速度随时间越来越慢的解决办法##背景最近在做一些数据分析时,遇到了一个问题,当我把计算结果更新到数据库时,一开始速度会很快,但随着时间的推移,更新速度会越来越慢。本篇博客就来说明这种现象的原因和解决办法。我使用的是`.NET7`和`EFCore7`.##事例......
  • 招行面试
    自我介绍mysql的隔离级别、锁机制说一下分布式锁的实现方式有哪些?深拷贝和浅拷贝的区别、什么时候一样?消息队列的顺序性是否存在问题?死锁的理解说一下?怎么避免?最近一个相关目里你负责的模块说一下?设计模式在项目中有用过哪些?面向对象的六大原则开闭原则、单一职责。讨论......
  • INFINI Labs 产品更新 | Console 新增数据比对、新增数据看板表格组件及支持下钻功能
    INFINILabs产品更新啦~,本次产品版本更新包括Gatewayv1.14.0、Consolev1.2.0、Easysearchv1.1.1等,其中Console在上一版基础上做了很多优化改进以及新增了一些特性,如新增数据比对校验功能、数据看板模块新增了表格组件、图表组件支持下钻功能等。欢迎下载体验。INFINIGat......
  • 基于Quartz的可视化UI操作组件GZY.Quartz.MUI更新说明(附:在ABP中集成GZY.Quartz.MUI
    前言时隔2年.(PS:其实陆陆续续在优化,不过没发博客)...本组件又迎来了新的更新...很久没更新博客了.生了娃,换了工作单位,太忙了..实在抱歉NETCore基于Quartz的UI可视化操作组件GZY.Quartz.MUI简介GitHub开源地址:l2999019/GZY.Quartz.MUI:基于Quartz的轻量级,注入化的U......
  • HCL华三模拟器BGP配置更新源
    peerconnect-interface命令用来指定与对等体/对等体组创建BGP会话时建立TCP连接使用的源接口,即采用指定源接口的IP地址/IPv6地址与对等体/对等体组建立TCP连接。本命令的作用与peersource-address命令的作用类似:peersource-address命令直接指定建立TCP连接的源地址;本命令通过......
  • 常见场景问题、面试问题,解决思路指南
    如何避免订单或表单重复提交?这个用术语来讲,是保证用户操作的幂等性。有以下思路:前端对按钮点击事件做好处理,避免短时间内可以点击两次,且都能成功调用后端服务接口。比如对按钮设置状态,在后端接口正常响应前再次点击无效或禁用按钮。后端接口执行逻辑前,先查询,判断之前未做相关......
  • 面试中被问到CAS机制该怎么回答
    一个小例子说说什么是线程安全并发是Java编程的基础,在我们日常的工作中,很多时候都会跟并发打交道,当然,这也是面试考察的重点。在并发编程中,被提起最多的概念是线程安全,下面我们先来看一段代码,看看运行后会发生什么:publicclassTest{privatestaticintinc=0;public......
  • 面试官问你:知道什么是ABA问题吗?
    大家好啊,我是你们的老朋友青戈,我又来分享干货啦......
  • kubenetes 面试题汇总1
    什么是Kubernetes?答:Kubernetes是一个开源的容器编排平台,用于自动化部署、扩展和管理容器化应用程序。它提供了一种简单而有效的方式来管理大规模的容器化应用程序,并且可以在不同的基础设施上运行,包括公共云、私有云和混合云。Kubernetes中的Pod是什么?它有什么作用?答:Pod是Kubernetes......