技术岗面试常见问题(更新中)

这篇总结会不断更新,内容大致包括几方面:数据库,C/C++,HTML,操作系统,计算机网络
文中题目转载汇集自各论坛大佬的总结和详解

目录

# 数据库

1.事务四大特性

原子性、一致性、隔离性、持久性;并称ACID
原子性:事务包含的所有操作要么全部成功,要么全部失败回滚
一致性:事务开始前和结束后,数据库的完整性约束没有被破坏
隔离性:多个用户并发访问数据库,数据库为每个用户开启的事务,不能被其他事务操作干扰
持久性:事务一旦提交,对于数据库的数据改变是永久的

2.事务并发带来的问题

脏读: A读取了B的更新,B回滚了,A读取到的就是脏数据
不可重复读: A多次读取同一数据,B在A多次读取的时候,进行了更新并提交,导致A多次读取时,先后两次读到结果不一致
幻读: 解决了不重复读,保证同一事务里,查询到的数据都是开始的状态(即一致性)

3.事务的隔离级别

事务隔离级别脏读不可重复读幻读注释
读未提交修改数据单位提交,本事务会脏读
不可重复读同2
可重复读同样的SELECT操作读到结果一致,但会有幻读
串行化最高级别的隔离,无异常,循序执行

读未提交: 一个事务读取到了另一个事务尚未提交的内容记录;一个事务在访问数据,并进行了修改,但是修改还没提交到数据库,另一个访问这个数据的事务读到了这个未提交的内容,这就造成了脏读。
不可重复读: 只能读到已经提交的数据
可重复读: 同一事务中先后执行同一个查询语句的时候,得到结果相同
串行读: 事务执行时不允许别的事务并发,完全串行化,读写相互阻塞。

4.常见系统的默认隔离级别

MySQL:repeatable-read
Oracle:READ_COMMITED(已读提交)
SQL server:READ_COMMITED
隔离级别越高,越能保证数据完整性和一致性,但是并发性能也会下降

5.聚集索引和非聚集索引

根本区别: 是否保证数据库表中记录的物理存储顺序和索引顺序相同,聚集索引能提高多行检索速度,非聚集对于单行检测较快

6.Mysql数据库索引

普通索引、唯一索引、主键索引、组合索引
Mysql数据库索引类型

7.数据库三范式

第一范式:是对属性的原子性约束,要求字段具有原子性,不可再分解(关系型数据库都满足1NF)
第二范式:满足第一范式前提下,确保数据库表中,一个表只能保存一种数据,不能多种数据保存在一张表中;确保表中每一列都和主键相关,不能只某部分相关
第三范式:第二范式前提下,确保每列都和主键列直接向相关,不是间接相关
详细见链接

8.主键、外键、索引的区别

在这里插入图片描述

9.数据库的锁

数据库系统角度:排他锁、共享锁、更新锁
程序员角度:乐观锁、悲观锁
悲观锁: 每次取数据都认为别人会修改,所以每一次拿数据都上锁,避免别人此时拿数据
悲观锁按性质又分为共享锁、排他锁、更新锁

  1. 共享锁:Share Lock,也叫读锁,用于所有只读数据操作,非独占,允许多个并发事务读取锁定的资源
  2. 排他锁:Exclusive Lock,也叫写锁,用于写操作,一个事务对对象加了X锁,其他事务就不能加任何锁
  3. 更新锁:Update Lock,在修改操作初始化阶段,用来锁定可能要被修改的资源,避免使用共享锁造成死锁
    悲观锁按作用划分为行锁、表锁
  4. 行锁作用范围是行
  5. 表锁作用范围是整个表

乐观锁: 每次取数据都认为别人不会修改,不上锁,在更新时判断期间是否有人更新数据
实现方式:版本号(version)、时间戳(timestamp)、待更新字段

10.sql注入,以及如何避免

sql注入是一种注入攻击,执行恶意的sql语句,通过任意sql代码插入数据库进行查询,使攻击者可以完全控制Web应用程序后面的数据库服务器,绕过应用安全措施,绕过网页或者web的身份验证和授权,获取数据库所有内容,也可以修改和删除内容。
防止方式:
(1)不使用动态的Sql:避免用户的输入直接放入语句之中
(2)不将敏感数据保留在纯文本之中
(3)限制数据库权限和特权
(4)定期测试与数据库交互的web应用程序
(5)设置防火墙

# C/C++

1.C/C++区别

C是结构化语言,面向过程,基于算法和数据结构
C++是面向对象,基于类、对象和继承

2.sizeof,strlen,length,size区别:(高频)

sizeof和strlen:获取数组,字符串长度,sizeof是运算符,strlen是函数;
sizeof可以用类型做参数,参数可以是任何类型;strlen只能用char*做参数,必须以"\0"结尾;
sizeof是申请空间的大小,strlen是具体内容的大小
c/c++中sizeof()、strlen()、length()、size()详解和区别

3.malloc和new

malloc是库函数,new是运算符,都可以动态申请和释放内存
内置类型数据两者没什么区别,malloc申请内存要制定字节数,不初始化;new申请时默认初始化,也可以指定初始化
类类型的对象,malloc满足不了要求,对象创建会执行构造函数,消除时要析构函数。malloc是库函数,不能执行构造函数和构造函数,所以这时候就需要new来完成。

4.一个C源程序从开始运行到结束的完整过程(四个过程)

预处理:处理条件编译指令,引入头文件,宏替换,去除注释,生成.i文件。
编译:将预处理后的内容转换成汇编语言代码,生成.s文件
汇编:汇编变为二进制机器代码,生成.o的文件
链接:连接目标代码,生成可执行程序

5.指针和引用的区别(高频)

指针是一个新变量,它存储的是另一个变量的地址,可以通过访问这个地址来修改变量
引用还是变量本身,只是一个别名,对引用操作,就是对变量操作。
指针可以多级,但是引用不行
指针可以为空,引用不行,而且引用的时候需要初始化
指针初始化之后可以变,引用初始化后不能

6.链表和数组的区别(高频)

1. 存储位置上: 数组逻辑相邻的元素在物理上也要相邻,链表不一定
2. 存储空间上: 相同规模的数据,数组存储需要空间比链表需要的小,因为链表还需要存放前后的空间
3. 查找上: 链表不能随机访问,数组可以
4. 删除和插入: 数组需要进行元素的移动,链表元素不动,指针改变即可

7.C++类中默认函数

1. 构造函数:
在每次创造类的新对象时执行;名称与类名称完全相同,不返回任何类型,也不会返回void;可用于为成员变量设置初始值;
当然如果需要,构造函数也可以带参数,在创建对象时就给对象赋初始值。
2. 拷贝构造函数:
是构造函数的重载
创建对象时,使用同一类之中之前创建的对象来初始化新创建的对象
复制对象,将其作为参数传给函数
复制对象,从函数返回它
3. 析构函数:
析构函数在每次删除创建的对象时执行,名称与类名称完全相同,只是前面加了一个~,不返回任何值,不带有任何参数,有助于跳出程序之前释放资源
4. 友元函数:
友元可以是一个函数也可以是一个类,友元类的所有成员都是友元
声明时要前加关键字friend
友元函数不属于类成员,但是可以访问该类的私有成员,相当于是被”视为“类的一个成员

8.C++之中调用C的函数,extern “C”

1.在函数名前与C连用:目的是告诉编译器在编译这个函数的时候,要按照C的规则去翻译而不是C++;由于C++支持函数重载,C不支持,混合编程时会使得函数名称发生变化,而非本意
2.在头文件之中:作用是声明全局变量或函数作用范围,是一个关键字;是声明而不是定义,声明的函数和变量可以在此模块或其他模块之中使用。

9.虚函数,纯虚函数(高频)

虚函数是允许被其他子类重新定义的成员函数,实现了多态性(将接口和实现分离);virtual关键字
普通函数不能是虚函数,这个函数必须是某一个类的成员函数
静态成员函数,内联函数,构造函数都不能是虚函数

虚函数表,每一项是一个虚函数地址,每一个对象包含一个虚指针,指向虚函数表
纯虚函数是虚函数一种,是指被标明不具体实现的虚函数,没有函数体,定义时候函数名后加“=0”

10.面向对象技术的基本概念,基本特征

基本概念:类、对象、继承
基本特征:封装、继承、多态
封装:就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息隐藏
继承:是指这样一种能力,它可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展
多态:允许将基类类型指针或引用 ,指向派生类型对象,可通过虚函数机制实现,可以实现接口重用,可以说:一个接口,多个方法

11.内存泄漏,野指针

内存泄漏:是指程序动态分配了内存,但是却没有进行释放,在整个程序之中始终占用那个内存 (多态中存在的问题)
处理方法:检测内存泄漏的关键是要能截获住对分配内存和释放内存的函数的调用。截获住这两个函数,我们就能跟踪每一 块内存的生命周期,比如,每当成功的分配一块内存后,就把它的指针加入一个全局的list中;每当释放一块内存,再把它的指针从list中删除。这样,当程序结束的时候,list中剩余的指针就是指向那些没有被释放的内存
野指针:成因有两种:
(1)指针变量没有初始化,因为指针变量没有初始化时不会自动赋值为空,所以指针创建时,要么初始化赋值,要么指向合法内存
(2)指针被释放时没有置空
规避方法:
(1)初始化指针的时候将其置为nullptr,之后对其操作。
(2)释放指针的时候将其置为nullptr。

12.内存溢出、内存越界

内存溢出:需要的内存超出了新系统所能给的,满足不了,产生溢出
内存越界:申请一块内存,在使用时超出了申请的范围,造成了越界

13.重载和重写,隐藏

重载:函数名相同,但是参数列的内容不同,不关心函数返回类型
重写:也叫覆盖,继承和派生时出现,在派生类之中重新定义函数,函数名1参数类型和数量与基类一致,但是函数体不同。必须要virtual修饰
隐藏:也是继承派生时出现,是指派生类的函数屏蔽了基类的函数,只要时派生类中函数名与基类相同,基类的函数都会隐藏。

14.main函数执行前会执行什么,执行main之后还能执行代码吗

全局对象的构造函数会在main函数执行之前执行
可以用_onexit注册函数,他在main之后执行

15.内联函数(inline)和#define的区别

内联函数在编译器生成的代码之中是不存在的,所以也没有普通函数调用时的压栈跳转等额外开销;
是一种对于编译器的请求,所以是有可能被拒绝的;
由编译器处理,直接将编译后的函数体插入调用位置

#define是宏代码片段,由预处理器处理,进行文本替换,没有编译过程

16.STL(标准模板库)容器

容器:序列式容器、适配器容器、关联式容器
序列式:向量vector、列表list
适配器:栈stack、队列queue、优先队列
关联式:集合set、多重集合multiset、映射map、多重映射multimap、智能指针auto_ptr

用过哪些STL容器?
stack:
创建:stack< int >s;入栈:push();出栈:pop();栈顶:top();非空判断:empty()
vector:
一个能够存放任意类型的动态数组,能够增加和压缩数据;
需要头文件#include < vector >;
属于std命名域,需要命名限定:using namespace std;
常用成员函数: 判断容器是否为空:c.empty()、在尾部加入一个数据:c.push_back()、删除最后一个数据c.pop_back()、元素交换:swap()
STL面试常考问题

17.红黑树(未完)

RB树的统计性能要好于一般的AVL树,具有更高的插入效率,但相应查找效率要低一点;
是关联容器的内部结构,map(),set()底层实现全是用RB树
可以在O(logn)内查找插入和删除

什么是红黑树?

节点都是红色或黑色,根节点为黑色,叶节点为黑色,红色节点的子节点是黑色
满足黑色完美平衡:任意一个节点到每个叶子节点的路径都包含着数量相同的黑节点
红黑树的自平衡需要三种操作:

  1. 左旋:以某节点P为旋转轴点,其右节点V变为父节点,V的左子节点R变为P的右子节点,其他不变
    左旋图示(转自后面本题后链接)
  2. 右旋:与左旋类似此处只附图
    在这里插入图片描述
  3. 变色:根据颜色规则变色
    可以看到旋转的操作是局部的,只影响旋转节点和他的左子树(右旋),或右子树(左旋)
红黑树的查找

查找不会破坏平衡,所以和AVL树查找无异:从根节点开始,大于节点则找右子树,小于则找左子树,直到找到或节点为空,结束,时间复杂度为O(logN)

红黑树插入

第一步和查找类似,直到找到相应位置;之后如果相应位置节点大小相等,刷新节点数据,如果节点位置为空,插入,插入节点颜色应为红色,如果为黑,则不满足黑色平衡,会有自平衡
在这之中共有8种插入场景
在这里插入图片描述

转载–详细请看——30张图带你彻底理解红黑树

18.递归和迭代的区别

  1. 递归:简单来说,递归就是自己调用自己,实现自身循环,直到有返回,才会逐层返回;利用的是栈的机制,代码简单易读,但可能造成堆栈溢出,所用时间开销大
  2. 迭代:迭代是通过变量原值推出新值代替自己,函数中某段代码中循环,开销相对小,代码会复杂

19.排序算法相关

排序算法复杂度与稳定性

#计算机网络

1.TCP三次握手,四次挥手,为什么挥手会多一次(高频)

2.HTTP和HTTPS区别是什么

https协议需要申请证书,免费较少,需要一定费用;
http是超文本传输协议,信息时明文传输,https是具有安全性的加密传输协议;
两者链接方式不同,端口也不同,http为80,https为443;
http连接简单,无状态,https协议是由SSL/TLS加上http构建的可加密,可身份认证的网络协议,是安全的,运用的是共享密钥加密和公开密钥加密并用的混合加密机制

状态码:

常用:
200 OK(请求成功)
301域名永久性转移
302暂时性转移
304所请求资源未修改
401没有权限,需要进行身份认证
403资源不可用,拒绝访问
404链接指向的网页不存在,URL失效

1xx请求处理中
2xx成功处理
3xx重定向,需要附加进一步操作
4xx客户端错误
5xx服务器错误

HTTP1.0:get,head,post ,默认短链接, 建立连接,发送请求,回送请求,关闭链接
HTTP1.1: option,delete,connect 持续(长)链接—>keep-alive字段,流水线处理;新增状态码100,表示Continue

3.TCP/UDP区别(高频)

TCP的优点是:可靠、稳定。它体现在TCP在传递数据之前,会有三次握手来建立连接;在数据传递时,采用校验和、序列号、确认应答、超时重发、流量控制、拥塞控制;还采用了滑动窗口、延迟应答和捎带应答等机制
拥塞控制: 慢开始、拥塞避免、快重传、快恢复。
60字节保报文头,固定部分20字节

TCP的缺点:运行速度慢,效率低
握手:SYN; SYN,ACK; ACK
挥手:FIN,seq; ACK,seq,ack ; FIN,ACK; ACK
UDP的优点:运行速度较快,比TCP安全;
UDP的缺点:不可靠,不稳定

TCP面向字节流,UDP面向报文;
TCP只支持点对点通信,UDP支持一对一,一对多,多对一,多对多;

TCP.UDP对应的应用层协议

TCP:FTP、Telnet、SMTP、POP3、HTTP
UDP:DNS、SNMP、TFTP

4.输入URL,显示页面的过程(高频)

(1)浏览器查找域名IP地址,DNS获取域名对应的IP,搜索自身DNS缓存,操作系统DNS缓存,本地Host文件,向本地DNS服务器查询。如果找不到,进行地址映射,域名解析,进行迭代查询或递归查询。

本地域名服务器——>根域名服务器——>顶级域名服务器——>权限域名服务器

(2)获取到地址后,请求简历链接,三次握手;链接建立后,浏览器向web发送HTTP请求,并等待应答
(3)服务器处理请求,包括查看参数,cookies,最后生成响应
(4)收到应答,浏览器显示HTML内容
(5)页面渲染处理
**用到的协议:**TCP,IP,OSPF(路由选择),ARP(地址转换),HTTP

5.TCP之中CLOSE_WAIT和TIME_WAIT,分别是做什么用的?分别在哪一个端存在?

CLOSE_WAIT在服务器端,TIME_WAIT在客户端
C_W: 对方主动关闭连接或者网络异常导致连接中断,这时我方的状态会变成CLOSE_WAIT 此时我方要调用close()来使得连接正确关闭
T_W: 我方主动调用close()断开连接,收到对方确认后状态变为TIME_WAIT,缺省为240秒。TCP协议规定TIME_WAIT状态会一直持续2MSL(即两倍的分段最大生存期),以此来确保旧的连接状态不会对新连接产生影响。

此外还有一些较简单的OSI,TCP/IP模型的问题,不赘述

6.ICMP协议

是internet控制报文协议,处于IP层;ping命令就基于这个协议

#OS

1.操作系统调度

进程调度

FCFS,优先级调度,时间片轮转,多级反馈队列,短作业优先、高响应比优先

页面调度

最佳页面置换、LRU、NRU(也叫clock)、FIFO、改进clock

2.进程和线程(高频)

线程、进程是什么:

进程是正在运行的程序,是线程的集合。
线程是进程中的一个执行路径。
多线程就是为了提高程序的效率。

线程和进程的区别:
  1. 一个线程只能属于一个进程,而一个进程可以有多个线程,至少一个
  2. 进程是资源分配的最小单位,线程系统调度的最小单元
  3. 进程有自己的独立地址空间,线程没有
  4. 线程进程通信方式不同,线程通信比较方便,同进程下线程共享数据
  5. 进程之间不会互相影响,但是线程会影响其他线程
进程通信方式、线程通信方式
进程:
  1. 管道(pipe):只支持亲缘关系进程使用
  2. 有名管道:允许无亲缘关系进程
  3. 信号量机制(semaphore)
  4. 消息队列
  5. 共享内存
  6. socket套接字 :地址+端口号
  7. 信号机制(signal)
线程:
  1. 互斥锁、读写锁
  2. 信号量机制(semaphore)
  3. 信号机制(signal)

3.linux系统从通电到开机经历了什么过程(高频)

在这里插入图片描述

4.死锁

死锁是什么

所谓死锁,是指多个进程在运行过程中因争夺资源而造成的一种僵局,当进程处于这种僵持状态时,若无外力作用,它们都将无法再向前推进。

产生原因

进程竞争资源、进程间推进顺序非法

必要条件

互斥条件、请求和保持条件、不剥夺条件、环路等待条件

处理方法

死锁预防、死锁避免、死锁检测、死锁接触

5.内存池、进程池、线程池

池化:提前保存大量资源,备不时之需,和重复使用

线程/进程池: 线程池的原理很简单,类似于操作系统中的缓冲区的概念,它的流程如下:先启动若干数量的线程,并让这些线程都处于睡眠状态,当需要开辟一个线程去做具体的工作时,就会唤醒线程池中的某一个睡眠线程,让它去做具体工作,当工作完成后,线程又处于睡眠状态,而不是将线程销毁。

内存池: 内存池是指程序预先从操作系统申请一块足够大内存,此后,当程序中需要申请内存的时候,不是直接向操作系统申请,而是直接从内存池中获取

# HTML

# 测试等相关

1.软件测试类型

黑盒测试:系统测试
白盒测试:单元测试
近似灰盒测试:集成测试

  • 4
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值