1. 进程与线程的关系,图解

进程简单理解就是我们平常使用的程序,进程拥有自己独立的内存空间地址,拥有一个以上的线程。

线程可以理解为轻量级的进程,是程序执行的最小单元。在某个进程启动后,会默认产生一个主线程,主线程可以创建多个子线程,因此线程是存在进程内的,位于一个进程内的线程可以共享部分资源,故线程间的切换比进程少得多。

多线程可以并行、并发执行(如互联网开发中高并发编程技术),可以共享数据和资源,线程间采用多种线程通信方式进行通信。

相关链接:https://baijiahao.baidu.com/s?id=1630348661230501723&wfr=spider&for=pc

2. 线程的基本概念、线程的基本状态及状态之间的关系

基本概念:线程,即轻量级进程(LWP:Light Weight Process),是程序执行流的最小单元。一个线程是进程的一个顺序执行流。同类的多个线程共享一块内存空间和一组系统资源,线程本身有一个供程序执行时的堆栈。线程在切换时负荷小,因此,线程也被称为轻负荷进程。一个进程中可以包含多个线程。

在一个进程内部,要同时干多件事情,就需要同时运行多个子任务,我们把进程内的这些子任务叫做线程。

多线程就是为了同步完成多项任务(在单个程序中同时运行多个线程完成不同的任务和工作),不是为了提高运行效率,而是为了提高资源使用效率来提高系统的效率。

基本状态:就绪、阻塞和运行三种基本状态。

就绪状态,指线程具备运行的所有条件,逻辑上可以运行,在等待处理机;

运行状态,指线程占有处理机正在运行;

阻塞状态,指线程在等待一个事件(如信号量),逻辑上不可执行。

状态之间的关系参考:线程的基本概念、线程的基本状态及状态之间的关系

3. https://blog.csdn.net/morewindows/article/details/7392749

4. 多态性可以简单地概括为“一个接口,多种方法”,程序在运行时才决定调用的函数,它是面向对象编程领域的核心概念。多态(polymorphisn),字面意思多种形状。

C++多态性是通过虚函数来实现的,虚函数允许子类重新定义成员函数,而子类重新定义父类的做法称为覆盖(override),或者称为重写。(这里我觉得要补充,重写的话可以有两种,直接重写成员函数和重写虚函数,只有重写了虚函数的才能算作是体现了C++多态性)而重载则是允许有多个同名的函数,而这些函数的参数列表不同,允许参数个数不同,参数类型不同,或者两者都不同。编译器会根据这些函数的不同列表,将同名的函数的名称做修饰,从而生成一些不同名称的预处理函数,来实现同名函数调用时的重载问题。但这并没有体现多态性。

那么多态的作用是什么呢,封装可以使得代码模块化,继承可以扩展已存在的代码,他们的目的都是为了代码重用。而多态的目的则是为了接口重用。也就是说,不论传递过来的究竟是那个类的对象,函数都能够通过同一个接口调用到适应各自对象的实现方法。

之前学的Direct2D以及Direct3D都是通过接口调用来实现多种方法。

实现多态有两个条件:  一是虚函数重写

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

重写 :子类的函数覆盖父类的函数,子类重新定义父类的虚函数(针对虚函数而言)

常用于继承关系中
特点:
(1)父类和子类函数名相同
(2)父类和子类的参数以及返回值值相同
(3)父类的函数中必须含有virtual关键字。

重载:函数名相同,参数不同。与继承没有直接关联
特点:
(1)相同的作用域 (都在类中,或者类外)
(2)函数名相同
(3)参数不同
(4)virtual关键字可有可无
(5)返回值可以不同

隐藏:子类的函数屏蔽了父类的同名函数。只有是同名函数,没有virtual,不管参数列表是否形同。
           父类的函数都会被隐藏。

(1)不在同一个作用域(分别位于子类和父类)
(2)函数名相同
(3)返回值可以不同
(4)参数可以不同,此时,不论有无 virtual 关键字,基类的函数将被隐藏
     (与重载有区别)
(5)参数相同,但是基类函数没有 virtual关键字。此时,

基类的函数被隐藏(注意与重写的区别)

相关链接:从一个面试题来谈C++的多态性

C++ 多态详解及常见面试题

5. TCP三次握手,四次挥手

TCP/IP协议详解

三次握手:(SYN:同步标志    ACK:确认标志    FIN:结束标志)

(1)第一次握手:建立连接时,客户端发送SYN包(SYN=i)到服务器,并进入到SYN-SEND状态,等待服务器确认

(2)第二次握手:服务器收到SYN包,必须确认客户的SYN(ack=i+1),同时自己也发送一个SYN包(SYN=k),即SYN+ACK包,此时服务器进入SYN-RECV状态

(3)第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认报ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手,客户端与服务器开始传送数据。

四次挥手:

(1)第一次挥手:Client发送一个FIN,用来关闭Client到Server的数据传送,Client进入FIN_WAIT_1状态。

(2)第二次挥手:Server收到FIN后,发送一个ACK给Client,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号),Server进入CLOSE_WAIT状态。

(3)第三次挥手:Server发送一个FIN,用来关闭Server到Client的数据传送,Server进入LAST_ACK状态。

(4)第四次挥手:Client收到FIN后,Client进入TIME_WAIT状态,接着发送一个ACK给Server,Server收到并确认后,Server进入CLOSED状态,完成四次挥手。

6. GDI vs Direct2D

  • 硬件加速 (硬件越新,加速越快,Direct2D全部都是硬件加速,而GDI和GDI+基本不靠硬件加速)

GDI将其资源(尤其是位图)保留在系统内存中,窗口内容的存储在视频内存表面。GDI使用CPU将大部分渲染执行到光圈存储器,当GDI需要更新窗口内容,也就是需要更新      视频内存时,除非资源已经在光圈存储器段中或者可以直接表示该操作,否则必须通过(bus)总线来完成,最后将结果发送回窗口表面。

而Direct2D就直接在显示适配器上的视频内存中维护其资源,然后将结果呈现在GPU上,然后发送到窗口表面。GDI也有部分api是在GPU上加速的,比如BitBlts,AlphaBlend,TransparentBlt和StretchBlt等。

  • Direct2D完全在用户模式下运行。这有助于防止由于内核中的代码缺陷而导致系统崩溃。但是,GDI在内核模式下的会话空间中具有大部分功能,而在用户模式下则具有API界面。
  • Direct2D的渲染调用都是到GPU的独立命令流。每个Direct2D工厂代表一个不同的Direct3D设备。GDI对系统上的所有应用程序使用一个命令流。GDI的方法可能导致GPU和CPU渲染上下文开销的累积。

7. TCP协议-如何保证传输可靠性

  • 校验和
  • 序列号
  • 确认应答
  • 超时重传
  • 连接管理
  • 流量控制
  • 拥塞控制

8. 虚拟内存(为什么要有虚拟内存)(好文章)

物理内存是有限的,多个进程要运行的时候,很显然内存不够分配。并且操作指令都是直接访问物理内存的,那么我这个进程就可以修改其他进程的数据,这是不合理的。

所以我们需要虚拟内存,进程运行时都会得到4G(32位)的虚拟内存,进程得到的这4G虚拟内存是一个连续的地址空间(这也只是进程认为),而实际上,它通常是被分隔成多个物理内存碎片,还有一部分存储在外部磁盘存储器上,在需要时进行数据交换。

进程开始要访问一个地址,它可能会经历下面的过程:(如果面试官问的特别仔细)

  • 进程访问地址空间上的某一个地址,都需要把地址翻译为实际物理内存地址
  • 所有进程共享这整一块物理内存,每个进程只把自己目前需要的虚拟地址空间映射到物理内存上
  • 进程需要知道哪些地址空间上的数据在物理内存上,哪些不在(可能这部分存储在磁盘上),还有在物理内存上的哪里,这就需要通过页表来记录
  • 页表的每一个表项分两部分,第一部分记录此页是否在物理内存上,第二部分记录物理内存页的地址(如果在的话)
  • 当进程访问某个虚拟地址的时候,就会先去看页表,如果发现对应的数据不在物理内存上,就会发生缺页异常
  • 缺页异常的处理过程,操作系统立即阻塞该进程,并将硬盘里对应的页换入内存,然后使该进程就绪,如果内存已经满了,没有空地方了,那就找一个页覆盖,至于具体覆盖的哪个页,就需要看操作系统的页面置换算法是怎么设计的了。

9. 纯虚函数只能被继承,无法被实例化。纯虚函数用来定义没有意义的实现,用于抽象类中需要交给派生类具体实现的方法。

因为虚函数都是采用的虚函数列表来进行的,如果是纯虚函数的话,该表指向一个不存在的函数,所以实例化被禁止。简单来说,就是 如果基类中含有纯虚函数,都不能实例化,在继承了该基类中的派生类中,如果不对该函数进行改写,也不能实例化。

小知识:纯虚函数还有利于检查基类的虚函数是否定义,比如有些时候我们使用虚函数光声明,但是没有定义的话,编译器就会报错。 使用了纯虚函数就不会报错了。

virtual void show() = 0; //纯虚函数

10. 虚函数列表的一些知识

一个类存在虚函数,那么编译器就会为这个类生成一个虚表,在虚表里存放的是这个类所有虚函数的地址。当生成类对象的时候,编译器会自动的将类对象的前四个字节设置为虚表的地址,而这四个字节就可以看作是一个指向虚表的指针。虚表里依次存放的是虚函数的地址,每个虚函数的地址占4个字节。

11. 广度优先搜索和深度优先搜索

这类概念经常在遍历文件或者遍历文件夹上用到。

12. 为什么需要内存对齐?

  • 某些处理器只能存取对齐的数据,存取非对齐的数据可能会引发异常;
  • 某些处理不能保证在存取非对齐数据的时候的操作是原子操作;
  • 相比于存取对齐的数据,存取非对齐数据需要额外花费更多的时钟周期;
  • 有些处理器虽然支持非对齐数据访问,但是会引发对齐陷阱;
  • 某些处理只支持简单数据指令非对齐存取,不支持复杂数据指令非对齐存取。

总结起来就是两个大的原因:提升效率和避免出错。

13. C++中的static关键字

静态全局变量有以下特点:

  • 该变量在全局数据区分配内存;
  • 未经初始化的静态全局变量会被程序自动初始化为0(自动变量的值是随机的,除非它被显式初始化);
  • 静态全局变量在声明它的整个文件都是可见的,而在文件之外是不可见的; 

静态局部变量有以下特点:
    (1)该变量在全局数据区分配内存;
    (2)静态局部变量在程序执行到该对象的声明处时被首次初始化,即以后的函数调用不再进行初始化;
    (3)静态局部变量一般在声明处初始化,如果没有显式初始化,会被程序自动初始化为0;
    (4)它始终驻留在全局数据区,直到程序运行结束。但其作用域为局部作用域,当定义它的函数或语句块结束时,其作用域随之结束;

关于静态成员函数,可以总结为以下几点:

  • 出现在类体外的函数定义不能指定关键字static;
  • 静态成员之间可以相互访问,包括静态成员函数访问静态数据成员和访问静态成员函数;
  • 非静态成员函数可以任意地访问静态成员函数和静态数据成员;
  • 静态成员函数不能访问非静态成员函数和非静态数据成员;
  • 由于没有this指针的额外开销,因此静态成员函数与类的全局函数相比速度上会有少许的增长;
  • 调用静态成员函数,可以用成员访问操作符(.)和(->)为一个类的对象或指向类对象的指针调用静态成员函数,也可以直接使用如下格式:

<类名>::<静态成员函数名>(<参数表>)
           调用类的静态成员函数。

网络上收集的C++常见面试题的更多相关文章

  1. iOS常见面试题汇总

    iOS常见面试题汇总 1. 什么是 ARC? (ARC 是为了解决什么问题而诞生的?) ARC 是 Automatic Reference Counting 的缩写, 即自动引用计数. 这是苹果在 i ...

  2. JDBC常见面试题

    以下我是归纳的JDBC知识点图: 图上的知识点都可以在我其他的文章内找到相应内容. JDBC常见面试题 JDBC操作数据库的步骤 ? JDBC操作数据库的步骤 ? 注册数据库驱动. 建立数据库连接. ...

  3. 整理的最全 python常见面试题(基本必考)

    整理的最全 python常见面试题(基本必考) python 2018-05-17 作者 大蛇王 1.大数据的文件读取 ① 利用生成器generator ②迭代器进行迭代遍历:for line in ...

  4. java常见面试题及答案

    java常见面试题及答案 来源 https://blog.csdn.net/hsk256/article/details/49052293 来源 https://blog.csdn.net/hsk25 ...

  5. HTTP、TCP、IP协议常见面试题

    前言:在看面试题之前,先了解一下基本定义. HTTP.TCP.IP协议基本定义 HTTP: (HyperText Transport Protocol)是超文本传输协议的缩写,它用于传送WWW方式的数 ...

  6. python爬虫常见面试题(二)

    前言 之所以在这里写下python爬虫常见面试题及解答,一是用作笔记,方便日后回忆:二是给自己一个和大家交流的机会,互相学习.进步,希望不正之处大家能给予指正:三是我也是互联网寒潮下岗的那批人之一,为 ...

  7. 整理的最全 python常见面试题

      整理的最全 python常见面试题(基本必考)① ②③④⑤⑥⑦⑧⑨⑩ 1.大数据的文件读取: ① 利用生成器generator: ②迭代器进行迭代遍历:for line in file; 2.迭代 ...

  8. 【javascript常见面试题】常见前端面试题及答案

    转自:http://www.cnblogs.com/syfwhu/p/4434132.html 前言 本文是在GitHub上看到一个大牛总结的前端常见面试题,很多问题问的都很好,很经典.很有代表性.上 ...

  9. 夯实Java基础系列16:一文读懂Java IO流和常见面试题

    本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutorial 喜欢的话麻烦点下 ...

  10. 【搞定 Java 并发面试】面试最常问的 Java 并发进阶常见面试题总结!

    本文为 SnailClimb 的原创,目前已经收录自我开源的 JavaGuide 中(61.5 k Star![Java学习+面试指南] 一份涵盖大部分Java程序员所需要掌握的核心知识.觉得内容不错 ...

随机推荐

  1. [转帖]TiDB 中的各种超时

    https://docs.pingcap.com/zh/tidb/stable/dev-guide-timeouts-in-tidb 本章将介绍 TiDB 中的各种超时,为排查错误提供依据. GC 超 ...

  2. [转帖]kafka指定topic设置消息留存时间

    背景 单个主题消息量庞大,需要指定这个主题的消息留存时间缩小点 执行命令 ./bin/kafka-configs.sh --bootstrap-server node1:9092 --entity-t ...

  3. [转帖]MioIO读/写性能测试

    https://www.jianshu.com/p/a0a84f91b16f   image.png COSBench是Intel团队基于java开发,是一个测试云对象存储系统的分布式基准测试工具,全 ...

  4. [转帖]一个Linux 内核 bug 导致的 TCP连接卡死

    https://plantegg.github.io/2022/10/10/Linux%20BUG%E5%86%85%E6%A0%B8%E5%AF%BC%E8%87%B4%E7%9A%84%20TCP ...

  5. 获取特定端口java进程的路径的shell脚本

    获取特定端口java进程的路径的shell脚本 ll /proc/`lsof -i:5200 |grep ^java |awk '{print $2}' |uniq` |grep cwd |cut - ...

  6. Stream流处理快速上手最佳实践

    一 引言 JAVA1.8得益于Lambda所带来的函数式编程,引入了一个全新的Stream流概念Stream流式思想类似于工厂车间的"生产流水线",Stream流不是一种数据结构, ...

  7. element-ui表格展开行每次只能展开一行

    element-ui表格展开行每次只能展开一行 <template> <el-table :data="tableData" :expand-row-keys=& ...

  8. Vue 中keep-alive组件将会被缓存

    动态包裹哈 <keep-alive> <component :is="comName"></component> </keep-alive ...

  9. 动态添加input,然后获取所有的input框中的值

    今天遇见一个问题. 点击按钮,动态添加input框(可以添加多个) 然后搜集用户在input中输入的值. 我刚刚在纠结,给input框中注入事件. 但是这样会很麻烦. 经过同事的指点. 我直接去拿v- ...

  10. TienChin 代码格式化-项目结构大改造

    代码格式化 博主下载项目之后发现,整体的代码格式化风格,与 C 那种语言很相似,说明这个作者之前就是从事这块的导致风格有点类似,我们来格式化一下,当然这不是必要的,我是没习惯这种写法所以这里我写一下我 ...