【9】C++岗位求职面试八股文系列文章(语言基础)

第一篇:语言基础

第二篇:设计模式

第三篇:数据库

第四篇:计算机网络

第五篇:操作系统

第六篇:LInux

第七篇:数据结构

第八篇:智力题

[161]请问拷贝构造函数的参数是什么传递方式,为什么

拷贝构造函数的参数必须使用引用传递 Class(const Class & c_class),如果拷贝构造函数中的参数不是一个引用,即形如Class(const Class c_class),那么就相当于采用了传值的方式(pass-by-value),而传值的方式会调用该类的拷贝构造函数,从而造成无穷递归地调用拷贝构造函数。因此拷贝构造函数的参数必须是一个引用。

[162]什么情况下会调用拷贝构造函数

• 用类的一个实例化对象去初始化另一个对象的时候• 普通函数的参数是类的对象时(非引用传递)• 函数的返回值是函数体内局部对象的类的对象时 ,此时虽然发生(Named return Value优化)NRV优化,但是由于返回方式是值传递,所以会在返回值的地方调用拷贝构造函数。,而Windows + VS2019在值返回的情况下发生拷贝构造函数,引用返回方式则不发生拷贝构造函数。

情况1比较好理解

情况2的实现过程是,调用函数时先根据传入的实参产生临时对象,再用拷贝构造去初始化这个临时对象,在函数中与形参对应,函数调用结束后析构临时对象

情况3在执行return时,理论的执行过程是:产生临时对象,调用拷贝构造函数把返回对象拷贝给临时对象,函数执行完先析构局部变量,再析构临时对象

[163]C++的异常处理的方法

在程序执行过程中,由于程序员的疏忽或是系统资源紧张等因素都有可能导致异常,任何程序都无法保证绝对的稳定,常见的异常有:• 数组下标越界• 除法计算时除数为0• 动态分配空间时空间不足(1)try、throw和catch关键字

C++中的异常处理机制主要使用try、throw和catch三个关键字

C++ 引入了异常处理机制。其基本思想是:函数 A 在执行过程中发现异常时可以不加处理,而只是“拋出一个异常”给 A 的调用者,假定为函数 B。拋出异常而不加处理会导致函数 A 立即中止,在这种情况下,函数 B 可以选择捕获 A 拋出的异常进行处理,也可以选择置之不理。如果置之不理,这个异常就会被拋给 B 的调用者,以此类推。如果一层层的函数都不处理异常,异常最终会被拋给最外层的 main 函数。main 函数应该处理异常。如果main函数也不处理异常,那么程序就会立即异常地中止。

[164]C++标准异常类

C++ 标准库中有一些类代表异常,这些类都是从 exception 类派生而来的。常用的几个异常类如图 1 所示。

bad_typeid类型异常, 通常用typeid操作符,作用于一个NULL指针时,而该指针是带有虚函数的类,这时抛出bad_typeid异常bad_cast转换异常(在使用dynamic_cast()进行从多态基类对象(或引用)到派生类对象(或引用)的强制类型转化时,如果类型是不安全的,则会抛出异常)、bad_alloc分配内存异常(在使用new运算符进行动态内存分配时,如果没有足够的空间可分配,则会引发此类异常)bad_exception: 函数异常,通常是函数运行错误,抛出的异常out_of_range 越界异常(数组字符串等下标越界,抛出访问越界异常)runtime_error运行异常(从基类(exception)中派生,报告运行时错误,只有在程序运行时,这类错误才会被检测到)

都是 exception 类的派生类。C++ 程序在碰到某些异常时,即使程序中没有写 throw 语句,也会自动拋出上述异常类的对象。

处理就是try throw catch finally

[165]Java线程锁

乐观锁悲观锁、公平锁与非公平锁独占锁和共享锁重量级所 轻量级锁读写锁、自旋锁、可重入锁(递归锁) 在JAVA环境下 ReentrantLock 和 synchronized 都是可重入锁

java 实现多态有三个必要条件:继承、᯿重写、向上转型。

[166]java接口和抽象类的区别

抽象类和接口的区别

1 接口和抽象类都不能被实例化,它们都位于继承树的顶端,用于被其他类实现和继承。2 接口和抽象类都可以包含抽象方法,实现接口或继承抽象类的普通子类都必须实现这些抽象方法。

二 接口和抽象类的区别

接口:

拥有一些方法并且想让他们中的一些有默认实现,那么使用抽象类吧。实现多重继承,那么你必须使用接口添加链接描述

Java四种访问权限:java有四种访问权限, 其中三种有访问权限修饰符,分别为private,public和protected,还有一种不带任何修饰符default

同类private同包default不同包子类protected

[167]栈溢出和内存溢出

栈溢出是指不断的调用方法,不断的压栈,最终超出了栈允许的栈深度,就会发生栈溢出,比如递归操作没有终止,死循环

每一个用户请求,都会产生一个线程来处理这个请求,每一个线程对应着一个栈,栈会分配内存,此时如果请求过多,这时候内存不够了,就会发生栈内存溢出

栈溢出最终导致内存溢出内存比作是一个大箱子,栈是一个小箱子,栈溢出是指小箱子装不下了;而栈内存溢出是大箱子在也装不下小箱子了

[168]java中==和eqauls()的区别

==地址相等Equals()地址相等,string重写后值相等

如果两个对象根据equal()⽅法⽐较相等,那么 调⽤这两个对象中任意⼀个对象的hashCode()⽅法必须产⽣相同的哈希值。

[169]Object 中哪些⽅法

equals(), toString(), getClass(),wait(),clone(),notify(),notifyAll(),

[170]final有哪些⽤法

[171]值传递、指针传递、引用传递的区别和效率

值传递:有一个形参向函数所属的栈拷贝数据的过程,如果值传递的对象是类对象 或是大的结构体对象,将耗费一定的时间和空间。(传值)

指针传递:同样有一个形参向函数所属的栈拷贝数据的过程,但拷贝的数据是一个固定为4字节的地址。(传值,传递的是地址值)

引用传递:同样有上述的数据拷贝过程,但其是针对地址的,相当于为该数据所在的地址起了一个别名。(传地址)

效率上讲,指针传递和引用传递比值传递效率高。一般主张使用引用传递,代码逻辑上更加紧凑、清晰

[172]静态变量什么时候初始化

  1. 初始化只有一次,但是可以多次赋值,在主程序之前,编译器已经为其分配好了内存。
  2. 静态局部变量和全局变量一样,数据都存放在全局区域,所以在主程序之前,编译器已经为其分配好了内存,但在C和C++中静态局部变量的初始化节点又有点不太一样。在C中,初始化发生在代码执行之前,编译阶段分配好内存之后,就会进行初始化,所以我们看到在C语言中无法使用变量对静态局部变量进行初始化,在程序运行结束,变量所处的全局内存会被全部回收。编译阶段
  3. 而在C++中,初始化时在执行相关代码时才会进行初始化,主要是由于C++引入对象后,要进行初始化必须执行相应构造函数和析构函数,在构造函数或析构函数中经常会需要进行某些程序中需要进行的特定操作,并非简单地分配内存。所以C++标准定为全局或静态对象是有首次用到时才会进行构造,并通过atexit()来管理。在程序结束,按照构造顺序反方向进行逐个析构。所以在C++中是可以使用变量对静态局部变量进行初始化的。运行阶段

[173]说说类方法和数据的权限有哪几种

C++通过 public、protected、private 三个关键字来控制成员变量和成员函数的访问权限,它们分别表示公有的、受保护的、私有的,被称为成员访问限定符。类继承中, public.protected,private可以访问父类的public,protected子类对象只有public继承时候,可以访问父类的public

[174]如何理解抽象类?

抽象类的定义如下:纯虚函数是在基类中声明的虚函数,它在基类中没有定义,但要求任何派生类都要定义自己的实现方法。在基类中实现纯虚函数的方法是在函数原型后加“=0”,有纯虚函数的类就叫做抽象类。抽象类有如下几个特点:1)抽象类只能用作其他类的基类,不能建立抽象类对象。2)抽象类不能用作参数类型、函数返回类型或显式转换的类型。3)可以定义指向抽象类的指针和引用,此指针可以指向它的派生类,进而实现多态性。

[175]什么是多态?除了虚函数,还有什么方式能实现多态?

多态是面向对象的重要特性之一,它是一种行为的封装,就是不同对象对同一行为会有不同的状态。多态是以封装和继承为基础的。在C++中多态分为静态多态(早绑定)和动态多态(晚绑定)两种,其中动态多态是通过虚函数实现,静态多态通过函数重载实现,

[176]简述一下虚析构函数,什么作用

1.虚析构函数,是将基类的析构函数声明为virtual

2.虚析构函数的主要作用是防止内存泄露。定义一个基类的指针p,在delete p时,如果基类的析构函数是虚函数,这时只会看p所赋值的对象,如果p赋值的对象是派生类的对象,就会调用派生类的析构函数(毫无疑问,在这之前也会先调用基类的构造函数,在调用派生类的构造函数,然后调用派生类的析构函数,基类的析构函数,所谓先构造的后释放);如果p赋值的对象是基类的对象,就会调用基类的析构函数,这样就不会造成内存泄露。如果基类的析构函数不是虚函数,在delete p时,调用析构函数时,只会看指针的数据类型,而不会去看赋值的对象,这样就会造成内存泄露。

[177]说说什么是虚基类,可否被实例化(区分抽象类)

在被继承的类前面加上virtual关键字,这时被继承的类称为虚基类

虚继承的类可以被实例化

[178]简述一下拷贝赋值和移动赋值

拷贝赋值是通过拷贝构造函数来赋值,在创建对象时,使用同一类中之前创建的对象来初始化新创建的对象。移动赋值是通过移动构造函数来赋值,二者的主要区别在于

1)拷贝构造函数的形参是一个左值引用,而移动构造函数的形参是一个右值引用;2)拷贝构造函数完成的是整个对象或变量的拷贝,而移动构造函数是生成一个指针指向源对象或变量的地址,接管源对象的内存,相对于大量数据的拷贝节省时间和内存空间。

[179]仿函数了解吗?有什么作用

仿函数(functor)又称为函数对象(function object)是一个能行使函数功能的类。仿函数的语法几乎和我们普通的函数调用一样,不过作为仿函数的类,都必须重载operator()运算符,

[180] C++ 中哪些函数不能被声明为虚函数?5个(编译阶段、无意义/语法不支持)

普通函数(非成员函数),静态成员函数,内联成员函数,构造函数,友元函数。inline, static, constructor虚函数一定是放在类内的成员函数中的

为什么C++不支持普通函数为虚函数?普通函数(非成员函数)只能被overload,不能被override,声明为虚函数也没有什么意思,因此编译器会在编译时绑定函数。,所以语法不支持

为什么C++不支持构造函数为虚函数?构造函数用来创建一个新的对象,而虚函数的运行是建立在对象的基础上,在构造函数执行时,对象尚未形成,所以不能将构造函数定义为虚函数

为什么C++不支持内联成员函数为虚函数?其实很简单,那内联函数就是为了在代码中直接展开,减少函数调用花费的代价,虚函数是为了在继承后对象能够准确的执行自己的动作,这是不可能统一的。(再说了,inline函数在编译时被展开,虚函数在运行时才能动态的绑定函数)内联函数是在编译时期展开,而虚函数的特性是运行时才动态联编,所以两者矛盾,不能定义内联函数为虚函数

为什么C++不支持静态成员函数为虚函数?这也很简单,静态成员函数对于每个类来说只有一份代码,所有的对象都共享这一份代码,他也没有要动态绑定的必要性。static函数在编译时被展开,虚函数在运行时才能动态的绑定函数)静态成员函数属于一个类而非某一对象,没有this指针,它无法进行对象的判别

为什么C++不支持友元函数为虚函数?因为C++不支持友元函数的继承,对于没有继承特性的函数没有虚函数的说法。

[续]C++岗位求职面试八股文第十篇

更多关于算法题解、软件开发面经、机器学习算法面经、各企业面试问题记录,关注Fintech砖,持续更新中。https://www.nowcoder.com/users/873777317

企业面试记录专栏https://www.nowcoder.com/creation/manager/columnDetail/0YBWnm

机器学习面经专栏https://www.nowcoder.com/creation/manager/columnDetail/j8nNy0

软件开发面经专栏https://www.nowcoder.com/creation/manager/columnDetail/0aXKaM

更多校园招聘常见面试问题(开发、算法、编程题目)参见CSDN博客:http://t.csdn.cn/V4qbH

欢迎关注、收藏、点赞后进行问题咨询及秋招建议!

#晒一晒我的offer##我的实习求职记录##软件开发薪资爆料##实习,投递多份简历没人回复怎么办##互联网没坑了,还能去哪里?#
软件开发八股面经 文章被收录于专栏

包含C++、操作系统、数据库、计算机组成、计算机网络、设计模式、操作系统、牛客网服务器项目、综合智力题等

全部评论
感谢分享,加油牛友!😁
点赞 回复 分享
发布于 2024-04-23 19:15 山东

相关推荐

不愿透露姓名的神秘牛友
07-23 14:18
点赞 评论 收藏
分享
06-23 11:43
门头沟学院 Java
allin校招的烤冷...:我靠,今天中午我也是这个hr隔一个星期发消息给我。问的问题还是一模一样的😅
点赞 评论 收藏
分享
评论
2
18
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务