好好学习,天天向上

问题大部分来自现有帖子的汇总,参考见文末

一、

文章目录

1、自我介绍~

2、你对腾讯云存储有什么认识?

一种云计算的服务,提供了可扩展的、安全的云存储服务,帮助用户存储和管理各种类型的数据,包括图片、音频、文档之类的。用户可以通过腾讯云存储来实现数据的备份、归档、共享和分发等功能。同时,据我所知,腾讯云存储还提供了丰富的API和SDK,可以方便用户在自己的应用程序中集成云存储服务,实现数据的快速上传、下载和管理。

3、介绍一下红黑树?查询效率?时间复杂度?

红黑树是一种自平衡的二叉搜索树,它的查询效率非常高,时间复杂度为O(log n)
它的平衡性是通过以下规则来维护的:
1、每个节点要么是红色,要么是黑色
2、根节点是黑色
3、每个叶子节点(NIL节点,空节点)是黑色的
4、如果一个节点是红色的,则它的两个子节点都是黑色的
5、对于每个节点,从该节点到其所有后代叶子节点的简单路径上,均包含相同数目的黑色节点
这些规则保证了红黑树的高度不会超过logn,因此查询效率为O(log n)
红黑树原理和算法可参考
一文带你彻底读懂红黑树(附详细图解)

4、进程和线程的区别是什么?

都是操作系统中的执行单位,有以下几点区别:
①、资源占用:进程是系统资源分配的基本单位,每个进程都有独立的地址空间、数据栈、文件描述符等系统资源,而线程则是进程中的执行单元,它们共享进程的资源。
②、调度:进程是操作系统进行资源分配和调度的基本单位,而线程是调度的基本单位。线程的调度比进程的调度更加轻量级,因为线程共享进程的资源,所以线程的创建、销毁和切换的开销比进程小得多。
③、通信:进程之间通信需要使用进程间通信机制,如管道、消息队列、共享内存等,而线程之间通信可以直接读写共享变量,因为它们共享进程的地址空间。
④、安全性:由于线程共享进程的资源,所以线程之间的数据共享和通信比较容易出现问题,需要使用同步机制来保证线程之间的安全性。而进程之间的数据隔离比较明显,不需要过多的同步机制。

同步机制

【如何使用同步机制来保证线程之间的安全性?】
【同步机制是一种用于协调多个线程之间访问共享资源的技术,其目的是保证线程之间的安全性,常见的同步机制如下:】
【①、互斥锁:保证同一时间只有一个线程可以访问共享资源,当一个线程获得了互斥锁,其他线程就必须等待该线程释放锁后才能访问共享资源】
【②、信号量:一种计数器,用于控制多个线程对共享资源的访问,当一个线程访问共享资源时,它会将信号量减一,当信号量为零时,其他线程就必须等待该线程释放资源后才能访问】
【③、条件变量:一种用于线程之间通信的机制,它可以让一个线程等待另一个线程的通知。当一个线程需要等待某个条件满足时,它会调用条件变量的等待函数,该函数会将该线程挂起,直到另一个线程发出通知后才会唤醒该线程】

**

5、项目中使用过Git分支吗?介绍一下?**

git分支介绍
主分支:Master Branch 项目的主要分支,包含稳定的代码,在主分支上进行的更改应该经过严格的测试和审核。
开发分支:用于开发新功能和修复错误的分支。
功能分支:开发分支中创建的,用于开发新功能。
修复分支:用于修复紧急错误的分支。

6、如何解决哈希冲突?*

哈希冲突是指不同的键值对在哈希表中被映射到同一个槽位上,这会导致数据的丢失或错误。
①、链地址法:将哈希表中每个槽位看作一个链表的头结点,当发生哈希冲突时,将新的键值对插入到对应槽位的链表中。
②、开放地址法:通过一定的算法找到哈希表中的下一个空槽位,将键值对插入到该槽位中。
③、再哈希法:当发生哈希冲突时,使用另一个哈希函数重新计算键的哈希值,直到找到一个空槽位为止。
④、建立公共溢出区:将键值对插入到一个公共的溢出区中,可以避免链地址法中链表过长的问题。

7、什么原因导致I/O阻塞?*

①、数据量过大:读取或写入的数据量过大时,IO操作需要花费更多的时间,从而导致阻塞。
②、网络延迟
③、硬件故障:例如磁盘故障、网络设备故障
④、程序设计问题:例如在单线程程序中进行了大量IO操作,或者在IO操作中使用了不合适的缓冲区大小等
⑤、并发竞争:当多个线程同时进行IO操作时,可能会出现并发竞争的情况,从而导致IO操作阻塞。

8、造成死锁的原因?怎么解决?

死锁是指两个或多个进程在执行过程中,因争夺资源而造成的一种互相等待的现象。
原因:
①、系统资源不足,导致进程无法获取所需资源
②、进程运行顺序不当,导致资源竞争
③、资源分配不当,导致资源浪费和竞争

解决:
①、预防死锁:通过合理地分配资源,避免进程发生死锁。例如,采用银行家算法等资源分配算法,避免进程竞争同一资源。
【银行家算法的核心是:只有当系统能够满足所有进程的资源需求时,才会分配资源】
银行家算法(初学者,简单易懂)
【操作系统】几种常用调度算法
那些主宰操作系统的经典算法,你都知道了?
【常见的资源分配算法有哪些?】
【最佳适应算法(在可用资源中找到最小的能够满足需求的资源)、最坏适应算法、首次适应算法、循环首次适应算法、最小剩余算法、最大剩余算法、等比例算法、随机分配算法】
②、避免死锁:通过动态地分配资源,避免进程发生死锁。例如,采用资源分配图等方法,预测进程请求资源地情况,避免进程发生死锁。
③检测死锁:死锁检测算法?
④、解决死锁:通过剥夺进程资源、撤销进程等方式。例如采用资源剥夺算法,剥夺某些进程的资源,使其他进程可以继续执行。

冒泡,插入之类

的:「干货」编程语言十大经典算法,你知道几个?

9、C++的新特性?有哪些?举例几个展开说说 使用时候的注意事项之类的?

C++11:auto关键字,让编译器自动推断变量的类型;
lambda表达式,方便的定义匿名函数,例如:auto f = [] (int x) {return x*x}
智能指针:std::unique_ptr、std::weak_ptr、std::weak_ptr,帮助管理动态分配内存
右值引入和移动语义

C++14:二进制字面量,可以使用0b前缀来表示二进制数,例如:int x = 0b1010

C++17:结构化绑定,可以方便地从结构体中提取成员变量
if语句中定义变量并初始化

C++20:概念(concepts),可以约束模板参数的类型

**10、线程池创建的方式有哪些?

ThreadPoolExecuter的参数有哪些?**
问题是来自JAVA岗的
针对C++:
①、可使用std::thread创建线程池中的线程,使用std::async创建异步任务,将任务提交到线程池中执行;
②、使用boost库中的线程池类boost::threadpool,可以方便地创建线程池并提交任务。
③、使用第三方库,例如,Poco库中提供了一个线程池类Poco::ThreadPool,可以方便地创建线程池并提交任务。
④、自己实现:可以手动创建线程池,使用条件变量和互斥锁来实现任务队列和线程池的同步,这种方式需要自己实现线程池的管理和任务调度,比较复杂,但可灵活地控制线程池的行为。

11、ArrayList和LinkedList的区别在哪?
都是Java中的集合类~

12、HashMap和TreeMap的区别?都是java中的Map接口的实现类。

哈希和Map表区别?

哈希表是一种通过哈希函数将键映射到索引的数据结构,哈希函数将键转换为一个索引,该索引指向哈希表中的一个桶。每个桶都包含一个或多个键值对。哈希表的优点是可以快速查找、插入和删除键值对,时间复杂度O(1)。但是,哈希表的缺点:需要处理哈希冲突,即两个或多个键被映射到同一个索引的情况。
Map表,是一种将键值映射到值得数据结构。Map表中得每个元素都包含一个键和一个值。优点:可以快速查找、插入和删除元素,时间复杂度为O(log n),缺点:相对于哈希表来说它的效率较低。
因此,哈希表适用于需要快速查找、插入和删除键值对的场景,而map表适用于需要将键映射到值得场景。

13、假设有一个10W的数据请求,你会有什么方法来实现这些数据的增删改查?

①、数据库索引优化:对于需要频繁查询的字段,可以创建索引,以提高查询效率。
②、数据库分表分库:将数据按照一定规则分散到多个表或多个数据库中,以减少单个表或单个数据库的数据量,提高查询效率。
③、缓存技术:使用缓存技术,将热点数据缓存到内存中,以减少数据库的查询次数。
④、异步处理:对于一些非实时性的数据操作,可以使用异步处理方式,将数据操作放到消息队列中,以减少对数据库的直接操作,提高系统的并发能力。
⑤、分布式系统:对于数据量较大的系统,可以采用分布式系统架构,将数据分散到多个节点上,以提高系统的可扩展性和容错性。

14、介绍一下联合索引?

联合索引是指在一个表中创建多个列的索引,以提高查询效率。它可以将多个列的值组合在一起,形成一个索引键,从而加快查询速度。
举个例子,假设有一个学生表,包含学生的姓名、年龄和性别等信息。如果我们需要根据姓名和年龄来查询学生信息,那么可以创建一个联合素引,将姓名和年龄作为素引键。这样,当我们执行查询语句时,数据库引擎就可以直接使用这个联合素引,快速定位符合条件的记录,而不需要扫描整个表。
需要注意的是,联合素引的创建顺序也很重要。如果我们特姓名和年龄的顺序颠倒,那么查询时就无法使用这个索引,因为索引键的顺序与查询条件不匹配。因此,在创建联合索引时,需要根据实际查询需求来确定索引键的顺序。

以(a,b,c)为例,在什么情况下,单查b也能够命中联合索引?
如果查询条件包含了索引的左侧列a,那么单独查询b也能够命中联合索引。

15、你用过哪些数据库?MySQL数据库的存储引擎了解过哪些?这些存储引擎的特点是什么?

①、InnoDB: 支持事务处理,支持行级锁定,支持外键约束,适合于高并发的OLTP应用。
②、MyISAM:不支持事务处理,支持表级锁定,适合于读密集型应用,如数据仓库。
③、Memory:将数据存储在内存中,适合于临时表和缓存表。
④、Archive:适合于存储大量历史数据,支持高压缩比,但不支持索引和更新操作。
⑤、CSV:将数据以CSV格式存储在文件中,适合于导入和导出数据。
⑥、Blackhole:将写入的数据丢奔,适合于测试和日志记录。
⑦、NDB Cluster:支持分布式存储和高可用性,适合于大规模的分布式应用。

16、MySQL默认是什么存储引擎,为啥用这个?

InnoDB是MySQL默认的存储引擎,支持事务处理和行级锁定,适合于高并发的OLTP应用;
MyISAM适合于读密集型应用,但不支持事务处理;
Memory适合于临时表和缓存表,但数据存储在内存中,容易丢失;
Archive适合于存储大量历史数据,但不支持索引和更新操作;
CSV适合于导入和导出数据;Blackhole适合于沉试和日志记录;
NDB Cluster 适合于大规模的分布式应用。

17、InnoDB为啥索引的数据结果要用B+树?提高数据库的查询效率和性能

是因为B+树具有以下优点:
1.高效的查找:B+树的查找效率非常高,因为它的每个节点都可以存储多个关键宇,可以减少磁盘1/0次数,提高查找效率。
2. 有序性:B+树的所有叶子节点都按照关键字大小顺序排
列,因此可以支持范围查找和排序操作。
3. 支持高效的插入和删除:B+树的插入和删除操作只需要
对少量节点进行修改,因此效率非常高。
4. 支持高效的范围查找:B+树的所有叶子节点都按照关键字大小顺序排列,因此可以支持高效的范围查找操作。
5. 支持高效的顺序访问:B+树的所有叶子节点都按照关键字大小顺序排列,因此可以支持高效的顺序访问。

18、(InnoDB)为啥不用Hash索引?Hash索引查找的时候不是更快吗?

InnoDB 不使用哈希素引的主要原因是哈希索引不支持范围查询和排序操作。在哈希素引中,数据是根据哈希函数计算出的哈希值进行存储和查找的,因此只能进行等值查询,无法迸行范围查询和排序操作。而在实际的数据库应用中,范围查询和排序操作是非常常见的,因此InnoDB 选择使用 B+树索引来支持这些操作。
此外,哈希索引还存在一些其他的问题,例如哈希冲突、哈希函数的选择和调整等问题,这些问题都需要额外的处理和优化。相比之下,B+树索引更加稳定和可靠,能够更好地适应各种查询场景和数据分布情况。因此,InnoDB 选择使用 B+树索引来支持数据的存储和查询操作。

19、网络编程了解过吗?说说如何创建一个Socket连接?

网络编程是指使用计算机网络进行通信的编程技术。在网络编程中,我们通常使用套接宇(socket)来进行网络通信。

创建一个socket连接的步骤如下:
1、导入socket模块:在Python中,我们需要先导入socket模块才能使用socket相关的函数和方法。
2. 创建socket对象:使用socket模块中的socket() 函数创建一个socket对象。该函数需要传入两个参数,第一个参数是地址族 (AF INET表示
1Pv4地址族),第二个参数是套接字类型 (SOCK_STREAM 表示TCP协议)
3、 连接服务器:使用socket对象的connect0方法连接服务器。该方法需要传入一个元组,元组的第一个元素是服务器的1P地址,第二个元素是服务器的端口号。

20、C++的基本数据结构了解过吗?

C++常用数据结构

21、写过多进程和多线程不?都在什么情况下用过?遇到什么困难不?

多进程和多线程都是实现多任务的方式,但它们的实现方式不同。
多进程是指在操作系统中同时运行多个进程,每个进程都有自己的独立内存空间和系统资源,它们之间相互独立,互不千扰。多进程可以通过进程间通信(IPC)来实现数据共享和协作。
多线程是指在同一个进程中同时运行多个线程,每个线程共享进程的内存空间和系统资源,它们之间可以直接访问共享的数据和变量。多线程可以通过锁机制来实现数据同步和协作。
相比之下,多线程的开销更小,切换速度更快,但是多线程的并发控制和数据同步需要开发者自己处理,容易出现死锁和竞争等问题。而多进程之间相互独立,不会出现线程间的竞争和死锁问题。

多进程和多线程都是用来提高程序并发性和效率的技术,但是它们适用的场景和存在的问题有所不同。
多进程适用于需要同时处理多个独立任务的场景,每个进程都有白己的独立内存空间,可以避免不同进程之间的数据竞争和互相千扰。多进程的优点是稳定性高,一个进程崩溃不会影响其他进程的运行,同时可以利用多核CPU提高程序的并发性和效率。但是多进程的缺点是进程问通信比较麻烦,需要使用IPC(进程间通信)机制,而且每个进程都需要独立的系统资源,比如内存、文件句柄等,会占用较多的系统资源。
多线程适用于需要同时处理多个相似任务的场景,多个线程共享同一个进程的内存空问,可以方便地共享数据和通信。
多线程的优点是轻量级,线程的创建和销毁比进程快,可以更好地利用系统资源,同时线程之间的切换也比进程快。但是多线程的缺点是稳定性差,一个线程崩溃可能会导致整个进程崩溃,同时线程之间的数据竞争和互相千扰也需要特别注意。

可能出现的问题:
1、 数据竞争和互相干扰:多个进稈或线程同时访问共享数据时,需要使用锁或其他同步机制来避免数据竞争和互相干扰。
2.、死锁:多个进程或线程之间的互相等待,导致程序无法继续执行,需要特别注意避免死锁的情况。
3、资源占用:多进程或多线程会占用较多的系统资源,需要合理分配和管理系统资源,避免资源耗尽导致程序崩溃。
4、调试和排错:多进程或多线程的程序调试和排错比较困难,需要使用专门的工具和技术来辅助调试和排错。

22、你觉得对你最难的是哪块?C++方面

1.指针和内存管理:C++中的指针和内存管理是其最基本的特性之一,但也是最容易出错的部分。需要理解指针的概念、指针的运算、指针的类型转换、动态内存分配和释放等。
2. 类和对象:Ct+是一种面向对象的语言,需要掌握类和对象的概念、构造函数和析构函数、成员函数和成员变量、继承和多态等。
3.模板和泛型编程:C++中的模板是一种强大的泛型编程工具,但也是比较难理解和使用的。需要掌握模板的语法、模板的实例化、模板的特化、模板的偏特化等。
4. 异常处理:C++中的异常处理机制可以让程序在出现错误时进行优雅的处理,但也需要掌握异常的概念、异常的抛出和捕获、异常的层次结构等。

23、有没有Linux下的编程经验?常用命令了解哪些?

pwd, cd , ls , unzip , zip -r, cat, mkdir, vim, cp, mv, find -name, sudo, chmod, kill, ping,
Linux 常用命令有哪些

24、Linux中的epoll和select这些多路复用了解过吗?【什么是多路复用?】

多路复用是指在计算机网络中,将多个数据流合并成一个数据流进行传输的技术。它可以通过在传输层上对数据进行分组和复用,使得多个应用程序可以共享同一个物理链路,从而提高网络的利用率。
在Linux中,两者都是用于实现I/O多路复用的机制,作用:让一个进程可以同时监控多个文件描述符,当其中任意一个文件描述符有数据可读或者可写时,进程就可以进行相应的操作。
epoll是Linux内核提供的一种高效的I/O多路复用技术,可同时监控大量的文件描述符,并且可以避免select的一些缺点,如文件描述符数量的限制和效率问题,epoll使用了驱动的方式,当文件描述符上有事件发生时,内核会通知应用程序。
select是Linux内核提供的一种高效的I/O多路复用技术,可同时监控大量的文件描述符,并且可以指定超时时间。当其中任意一个文件描述符有数据可读或者可写时,select会返回相应的文件描述符,从而让应用程序进行相应的操作。缺点:文件描述符数量的限制和效率问题。

25、说说五层网络模型吧?对应的协议?

计算机网络模型(TCP五层模型)
将网络通信分为五个层次,每个层次都有自己的功能和对应的协议。
①、物理层:负责传输比特流,即0和1的电信号;对应的协议有:IEEE 802.3以太网,RS-232串口, V.35同步串口
②、数据链路层:负责将比特流组装成帧,进行差错检测和纠正(PPP点对点协议,HDLC高级数据链路控制协议,MAC媒体访问控制协议)
③、网络层:负责将帧转换为数据包,并进行路由器选择和拥塞控制(IP网际协议,ICMP Internet控制报文协议,ARP地址解析协议)
④、传输层:提供端到端的可靠数据传输(TCP传输控制协议,UDP用户数据报协议)
⑤、应用层:提供各种应用程序的接口和协议(HTTP超文本传输协议,FTP文本传输协议,SMTP简单邮件传输协议)

26、抓过网络包吗?

网络包:计算机网络中传输的基本单位,它是一段二进制数据,包含了源地址、目的地址、协议类型、数据长度、数据内容等信息。在网络通信中,数据被分割成一个个的网络包,通过网络传输到目的地,然后再被组装成完整的数据。网络包的传输是通过网络协议来实现的,不同的网络协议有不同的网络包格式和传输规则。

27、如果要设计一个快速插入和查找的数据结构,你会用什么结构?Hash冲突的解决方法?

哈希。
将数据通过哈希函数映射到一个固定的位置,然后在该位置上进行插入和查找操作。时复O(1)
看第六题

28、有一个容量为N的数据,里面存放了N个数,每个数的取值范围是1~N,有没有什么快速办法判断是否有重复元素,哪个元素重复了?空间复杂度要求是O(1)

抽屉原理,因为数据的取值范围是1~N,而数据的个数也是N,所以必然存在至少一个数重复出现。
遍历数据,将每个数作为下标,将对应下标的数据取相反数,如果某个数已经是负数了,说明这个数之前已经出现过,即为重复元素。

int findDuplication(vector<int>&nums) {
	int n = nums.size();
	for (int i = 0; i < n; i++) {
		int index = abs(nums[i]) - 1if (num[index] < 0) {
			return abs(nums[i]);
		}
		nums[index] = -nums[index];
	}
	return -1;
}

抽屉原理(鸽笼原理)一种计数原理,指:如果有n个物体放入m个抽屉中,其中n>m,那么至少有一个抽屉中必须放置不少于两个物体。

29、求二叉树深度的算法呢?说说看?时间和空间尽可能的小

①、递归实现,可能会栈溢出
时间复杂度O(n),空间复杂度O(h),n为二叉树的节点,h为二叉树的高度

int maxDepth(TreeNode* root) {
	if (root == nullptr) {
		return 0;
	}
	int leftDepth = maxDepth(root -> left);
	int rightDepth = maxDepth(root -> right);
	return max(leftDepth, rightDepth) + 1;
}

②、迭代实现,可避免栈溢出
使用栈来模拟递归过程,时间复杂度O(n),空间复杂度O(h),n为二叉树的节点,h为二叉树的高度

int maxDepth(TreeNode* root) {
	if (root == nullptr) {
		return 0;
	}
	stack < pair < TreeNode*, int >> s;
	s.push (make_pair(root, 1));
	int maxDepth = 0;
	while (!s.empty()) {
		auto node = s.top().first;
		auto depth = s.stop().second;
		s.pop();
		maxDepth = max (maxDepth, depth);
		if (node -> left != nullptr)
		{
			s.push(make_pair(node->left, depth + 1));
		}
		if (node -> right != nullptr) {
			s.push(make_pair(node->right, depth + 1));
		}
	}
	return maxDepth;
}

30、设计模式了解过吗?

单例模式,工厂模式,观察者模式,适配器模式,策略模式等等。

**31、UML类图理解的怎么样?画个类图吗?

**
用于描述系统中类、接口、对象及它们时间关系的图形化表示方法。
UML类图详解

32、云计算的知识了解吗?容器用过吗?大数据套件?ELK了解过吗?看过开源架构系统的代码

基于互联网的计算方式,通过将计算资源、存储资源和应用程序等服务通过网络提供给用户,是用户可以随时随地访问这些资源和服务。
容器:vector、list、map等
注意:初始化、元素访问、内存管理(vector扩容时会导致内存重新分配)、性能、线程安全;
大数据套件:一组用于处理大规模数据的软件工具集合。通常包括数据存储、数据处理、数据分析和数据可视化等功能。目的:帮助用户更轻松地处理和分析大数据,常见套件:Hadoop、Spark、Hive、Pig、Storm等。
ELK:开源的日志管理平台,由三个开源项目组成:Elasticsearch、Logstash、Kibana。
Elasticsearch是一个分布式搜索和分析引擎,Logstash是一个数据收集、处理和转发的工具,Kibana是一个数据可视化和分析平台。
ELK可以帮助用户收集、存储、搜索、分析和可视化各种类型的日志数据,从而帮助用户更好地理解和优化他们地应用程序和系统。

33、发布订阅模式的优点是什么?缺点是什么?如果让你来实现类似的MQTT的功能,你需要考虑哪些方面?

优点:
①、松耦合:发布者和订阅者之间没有直接的依赖关系,发布者只需要发布消息,订阅者只需要订阅感兴趣的消息即可。
②、可扩展性:发布者和订阅者可以动态地加入或退出系统,系统的扩展性更好
③、灵活性:可根据需要自由地订阅或发布消息,不需要事先知道对方的存在。
④、实时性:及时收到消息
缺点:
①、可靠性:无法保证所有订阅者都能收到消息,可能会出现消息丢失的情况。
②、复杂性:发布订阅模式需要引入中间件来实现消息的传递和管理,增加了系统的复杂性。
考虑:
①、协议设计:需要设计一种可靠的协议来实现消息的传递和管理、包括消息格式、消息传输方式、消息确认机制等。
②、安全性:考虑消息的安全性,包括消息的加密、身份验证、访问控制等
③、性能优化:消息的传输速度、系统的吞吐量、系统的可扩展性等
④、可靠性:消息的可靠性、系统的容错性、系统的恢复能力
⑤、兼容性:与其他系统的集成、与不同平台的兼容性等

34、TCP粘包拆包实现原理?如果让你来实现,你会怎么设计?

TCP粘包和拆包是由于TCP协议的特性所导致的。TCP是一个面向流的协议,它并不知道应用层数据的具体边界,因此在传输过程中可能会将多个应用层数据包合并成一个TCP数据包,也可能将一个应用层数据包拆分成多个TCP数据包,这就是TCP粘包和拆包的问题。

35、为什么用数据库连接池?如果数据库支持的最大的连接数满了,怎么操作?(高可用)如果让你来设计一个数据库连接池,你会考虑什么因素?为什么?

一种数据库连接管理技术,它可以在应用程序启动时创建一定数量的数据库连接,并将这些连接保存在一个池中。当应用程序需要访问数据库时,它可以从连接池中获取一个可用的连接使用完毕后再将连接返回给连接池,以便其他应用程序可以继续使用。

①、增加数据库支持的最大连接数:可以通过修改数据库配置文件或者调整数据库参数来增加数据库支持的最大连接数;
②、优化数据库连接:可以通过优化数据库连接的方式来减少连接数,例如使用连接池技术、减少连接超时时间等;
③、关闭空闲连接,通过设置数据库连接的最大空闲时间来关闭空闲连接,释放连接资源;
④、优化数据库查询:通过优化数据库查询语句、索引等方式来减少数据库连接数;

考虑:
连接池大小:连接池大小需要根据系统的负载和数据库的性能来确定,如果太小会导致系统无法处理所有的请求,太大会浪费资源;
连接超时:避免连接长时间占用资源而无法释放;
连接回收:定期回收空闲连接

36、介绍一下Ioc、DI、AOP原理?

IOC:控制反转,一种设计模式,将对象的创建、依赖关系的管理和对象的生命周期的控制从应用程序代码中转移到了容器中,从而实现了应用程序代码与框架的解耦。
DI:依赖注入,是IOC的一种实现方式,它通过将对象的依赖关系注入到对象中,来实现对象之间的解耦。依赖注入可以通过构造函数、属性或者方法来实现。
AOP:面向切面编程,是一种编程思想,它通过将横切关注点(如日志、事务、安全等)从业务逻辑中分离出来,以便用于重用和维护。AOP的实现方式主要有动态代理和字节码增强两种。

37、分布式存储了解过吗?分布式?

分布式存储是指将数据分散存储在多个计算机节点上,而不是集中存储在单个计算机上,每个节点都可以独立地访问和处理存储在其中地数据,这种方式可以提高数据的可靠性和可扩展性;
分布式存储是分布式系统的一部分,分布式系统是由多个计算机节点组成的系统,这些节点通过网络连接在一起,共同协作完成一些任务。分布式系统的好处是可以提高系统的可靠性、可扩展性和性能,因为任务可以分配到多个节点上并行处理,同时节点之间可以相互协作。

38、一个进程的栈大小是多少知道吗?打开文件的上限是多少?

一个进程的栈的大小是由操作系统内核在编译时指定的,通常在LINUX系统中默认为8MB,但可以通过ulimit命令进行修改;
打开文件的上限也是由操作系统的内核在编译时指定的,LINUX默认1024,可以通过ulimit命令进行修改,但是修改这些限制可能会影响系统的稳定性和安全性。

39、你觉得你最擅长做什么业务?

40、讲项目的难点?

41、redis的数据一致性问题(说了很长时间先删除后更新和先更新后删除)

内存数据库;
①、网络问题:如果Redis节点之间的网络连接出现问题,可能会导致数据同步失败;
②、客户端问题:如果客户端在写入数据时发生错误,可能会导致数据不一致
③、Redis节点故障:如果主节点发生故障,从节点可能会成为新的主节点,但在此过程中会丢失一些数据
避免:
①、使用Redis复制功能,将数据从主节点复制到从节点
②、持久化功能:将数据写入磁盘
③、事务功能:将多个操作打包成一个原子操作
④、监控功能:监控节点状态

42、知道哪些流量控制算法?

流量控制算法总结

43、深度学习常见算法?卷积神经网络流程?激活函数是干嘛的?sigmiod?

常见深度学习算法总结
激活函数是用来加入非线性因素的,提高神经网络对模型的表达能力,解决线性模型所不能解决的问题。
神经网络激活函数的作用是什么
Sigmoid 函数

44、负载均衡算法?

负载均衡算法是一种将网络流量分配到多个服务器上的技术。它可以帮助服务器集群更好地处理大量的请求,提高系统的可用性和性能。
负载均衡算法的核心思想是将请求分配到不同的服务器上,以避免某个服务器过载而导致系统崩溃。常见的负载均衡算法包括轮询、随机、最少连接等。其中,轮询算法是最简单的一种,它将请求依次分配给每个服务器,直到所有服务器都被分配了一次,然后再从头开始。随机算法则是将请求随机分配给服务器,而最少连接算法则是将请求分配给当前连接数最少的服务器。不同的负载均衡算法适用于不同的场景,需要根据实际情况进行选择。
图解 负载均衡算法及分类

45、hashmap红黑树性质?

第二题

46、haspmap为什么要用红黑树(泊松分布?)
haspmap java中的概念
在哈希表中,每个键值对都会被映射到一个桶中,如果哈希函数的设计良好,那么每个桶
中的键值对数量应该是均匀的。但是,由于哈希函数的限制,不同的键值对可能会被映射到同一个桶中,这就导致桶中的键值对数量不均衡,从而影响哈希表的性能。
为了解决这个问题,Java中的HashMap使用了链表来解决冲突。但是,当链表过长时,查找效率会变得很低。因此,当链表长度超过一定國值时,Java中的HashMap会将链表转换为红黑树,以提高查找效率。

47、高并发环境下,如何保存程序数据保存到Redis的线程安全问题?

1、使用Redis的事务机制:
Redis支持事务机制,可以将多个命令打包成一个事务,然后一次性执行。在执行事务期间,Redis会锁定相关的键,确保其他客户端无法修改这些键。因此,使用Redis事务可以保证线程安全。
2、使用Redis的乐观锁机制:
Redis 支持乐观锁机制,即在执行命令之前,先获取键的版本号,然后执行命令时检查版本号是否匹配。如果匹配,则执行命令;否则,返回错误。这种方式可以避免多个客户端同时修改同一个键的问题。
3、 使用Redis的分布式锁机制:
Redis支持分布式锁机制,可以使用SETNX命令来获取锁。如果获取成功,则可以执行命令;否则,等待一段时间后重试。这种方式可以避免多个客户端同时修改同一个键的问题。

48、讲一下sychronized(从jvm指令层面开始讲,然后又讲了hotspot团队在jdk中对sychronized的优化,继续讲了偏向锁,轻量级锁,重量级锁以及偏向锁升级到轻量级锁,从轻量级锁升级到重量级锁的详细过程,后续讲了自旋锁,自适应自旋锁和锁粗化,锁消除)
49、sychornized为什么是重量级锁,从操作系统层面讲
50、sychronized的作用,然后在聊天框出了七八道场景题(幸亏很简单)
48-50貌似全是和JAVA有关的,先跳过~
51、从轻量级锁到重量级锁中,底层是如何判断抢夺锁的线程变化的?

52、volatile关键字

C/C++中volatile关键字的作用
volatile关键字理解

53、手撕设计模式(是简单地单例模式,双重检验锁模式,面试官没有难为人)
54、这个单例模式会有什么问题(答:会被序列化和反射破坏)
55、反射如何破坏,如何防止
56、volatile在单例模式的作用以及作用在哪里
56、对象是如何生成的(5个步骤,期间讲了分配内存的指针碰撞和空闲列表)
57、对象的内存布局

58、volatile具体影响的是对象生成的过程中的哪个步骤,防止指令重排序对单例模式的影响,哪个步骤?

设计模式之单例模式(指令重排,DCL)

59、jvm

60、计网(http, https)?http2的优势?

HTTP:无状态,即服务器不会记住之前的请求和响应,使用明文传输;
HTTPS:在HTTP的基础上加入了SSL/TLS协议进行的加密传输协议。
HTTP/2 通过让所有数据流共用同一个连接,可以更有效地使用 TCP 连接,让高带宽也能真正的服务于 HTTP 的性能提升。
这种单连接多资源的方式,减少服务端的链接压力,内存占用更少,连接吞吐量更大;而且由于 TCP 连接的减少而使网络拥塞状况得以改善,同时慢启动时间的减少,使拥塞和丢包恢复速度更快

61、linux(top指令中字段的含义,里面的iowait过高是什么原因?怎么处理?给我整蒙了)

磁盘故障或者磁盘读写速度过慢,系统中有大量的进程在进行I/O操作,导致磁盘繁忙;
检测磁盘是否正常工作;优化输入输出操作,优化系统中的进程;

62、手写单例模式,各种情况,怎么保证线程安全?

C++实现单例模式,保证线程安全

63、手写单例的过程中提到了synchronized和volatile,顺便问了这两个的实现原理
64、HashMap的底层实现,它为什么是线程不安全的(数组+链表+红黑树,为什么不安全不知道?
65、知道哪些线程安全的集合类型?
66、ConcurrentHashMap的实现原理
67、HashTable的底层原理

68、MySQL索引结构,为什么用B+树

1、磁盘10次数少:B+树的叶子节点都是按照顺序存储的,因此在进行范围查询时,可以通过顺序遍历叶子节点来获取数据,减少了磁盘10次数,提高了查询效率。
2.支持范围查询:B+树的叶子节点都是按照顺序存储的,因此可以很方便地支持范围查询。
3.支持高效的插入和删除操作:B+树的叶子节点都是链表结构,因此可以很方便地进行
插入和删除操作,而且不会破坏树的结构。
4. 支持多级索引:B+树可以很方便地支持多级索引,因此可以很好地支持复杂的查询操作

69、场景题:sql查询很慢怎么排查(先检查sql语句,看看是否命中索引,是否符合最左前缀原则,用explain查看sql的执行情况)

1.确认是否存在索引问题:检查查询语句中是否使用了索引,是否存在索引失效、索引
覆盖等问题。
2. 检查 SQL 语句本身:检查SQL 语句是否存在语法错误、逻辑错误等问题。
3.检查数据库性能:检查数据库的 CPU 使用率、内存使用率、磁盘1/0 等性能指标,确认是否存在性能瓶颈。
4.检查数据库连接数:检查数据库连接数是否过多,是否存在连接池问题。
5.检查数据库表结构:检查数据库表结构是否合理,是否存在冗余字段、重复数据等问题

70、说说最左前缀原则
从最左边为起点开始连续匹配,遇到范围查询(<、>、between、like(某些like))会停止匹配。
71、MySQL的主从复制过程
72、解决Mysql主从同步数据一致性的问题
62-72参考:原帖子

73、线程有哪些状态?Flutter线程机制,单线程多线程
74、开源项目?
大创那个往过引,项目是干啥的?你在里面负责啥?遇到什么棘手问题?如何解决?
75、HashMap原理

76、C++对象生命周期?

1. 对于全局对象,程序一开始,其构造函数就先被执行(比程序进入点更早);程序即将结束前其析构函数将被执行。
2. 对于局部对象,当对象诞生时,其构造函数被执行;当程序流程将离开该对象的声明周期时,其析构函数被执行。
3. 对于静态(static)对象,当对象诞生时其构造函数被执行;当程序将结束时其析构函数才被执行,但比全局对象的析构函数早一步执行。
4. 对于以new方式产生出来的局部对象,当对象诞生时其构造函数被执行,析构函数则在对象被delete时执行。

77、重构做了哪些工作?

重构是指在不改变软件外部行为的前提下,对软件内部结构进行调整和优化的过程。具体
来说,重构做了以下工作:
1、优化代码结构:将代码中的重复部分提取出来,形成函数或类,使代码结构更加清晰、易于维护。
2、简化代码逻辑:通过优化代码逻辑,减少代码中的嵌套和条件分支,使代码更加简洁、易于理解。
3、提高代码可读性:通过重构,特代码中的变量名、函数名等命名规范化,使代码更加理解和阅读。

78、内存泄漏?举例场景?

内存泄漏是指程序在运行过程中,申请的内存空间没有被正确释放,导致这些内存空间无法再被程序使用,最终导致程序运行变慢或崩溃。
以下是一些可能导致内存泄漏的场景:

  1. 频繁的动态内存分配和释放:如果程序中频繁地使用动态内存分配函数(如malloc、new等),但没有及时释放这些内存,就会导致内存泄漏。
  2. 循环引用:如果程序中存在循环引用的情况,即两个或多个对象相互引用,但没有及时
    释放这些对象,就会导致内存泄漏。
  3. 文件操作:如果程序中频繁地打开文件,但没有及时关闭
  4. 大量的全局变量:未及时释放

79、堆和栈的主要区别

堆与栈实际上是操作系统对进程占用的内存空间的两种管理方式,主要有如下几种区别:
(1)管理方式不同。栈由操作系统自动分配释放,无需我们手动控制;堆的申请和释放工作由程序员控制,容易产生内存泄漏;
(2)空间大小不同。每个进程拥有的栈大小要远远小于堆大小。理论上,进程可申请的堆大小为虚拟内存大小,进程栈的大小 64bits 的 Windows 默认 1MB,64bits 的 Linux 默认 10MB;
(3)生长方向不同。堆的生长方向向上,内存地址由低到高;栈的生长方向向下,内存地址由高到低。
(4)分配方式不同。堆都是动态分配的,没有静态分配的堆。栈有 2 种分配方式:静态分配和动态分配。静态分配是由操作系统完成的,比如局部变量的分配。动态分配由alloca()函数分配,但是栈的动态分配和堆是不同的,它的动态分配是由操作系统进行释放,无需我们手工实现。
一文读懂堆与栈的区别

80、了解的常见的数据结构
已有

81、编译型语言(java,c++)和解释性语言(js)的区别?

编译型语言在程序执行之前,有一个单独的编译过程,将程序翻译成机器语言,以后执行这个程序的时候,就不用再进行翻译了。
解释型语言,是在运行的时候将程序翻译成机器语言,所以运行速度相对于编译型语言要慢

82、C和C++的不同?

C语言是面对过程的,而C++是面对对象的。C和C++都有结构的概念,但是在C语言中结构只有成员变量,没有成员方法,而在C++结构中,它可以有自己的成员变量以及成员方法。
C语言中结构的成员是默认是公共的,而在C++中没有加限定符则默认是私有的。
C++中有bool类型,而C语言可没有bool类型,均为数值类型
const关键字要注意一点不同就是C++的类函数,类函数声明时可以用const,表示这个函数没有改变类中的任何属性。例如:void
func()const; ,而C语言中则不可以。

83、类加载过程(加载,验证)jvm那边的

84、TCP和UDP

两种常见的网络传输协议。
TCP:面向连接的协议,提供可靠的数据传输,确保数据的完整性和顺序性。在传输数据之前,需要先建立连接,然后进行数据传输,传输完成后再断开连接。适用于需要可靠传输的应用,如文件传输、电子邮件等。
UDP:无连接的协议,它不保证数据传输的可靠性和顺序性。在传输数据之前不需要建立连接,直接将数据发送出去。适用于需要快速传输的应用,如实时视频、音频等。
总之,TCP适用于需要可靠传输的应用,而UDP适应于需要快速传输的应用。
TCP和UDP详解

85、TCP的安全保证(三次握手和其他什么)

TCP(传输控制协议)
①、数据完整性保证:TCP使用校验和来检测数据在传输过程中是否被篡改或损坏,确保数据的完整性。
②、数据机密保证:TCP本身并不提供数据加密功能,但可以与其他安全协议(如TLS/SSL)结合使用,通过加密传输数据来保证数据的机密性。
③、连接安全性保证:TCP使用三次握手建立连接,确保连接的安全性。TCP还支持使用TCP SYN cookies来防止SYM洪泛攻击。
④、可靠性保证:TCP使用确认和重传机制来保证数据的可靠传输,确保数据不会丢失或重复传输。
综述,通过检验和、三次握手、确认和重传机制等技术来保证数据的完整性、连接的安全性和可靠性。同时,TCP还可以与其他安全协议结合使用,来提供数据的机密性保证。

86、红黑树(特点)(不会)
已有。

87、MySql的数据结构

①、数据库:一个容器,用于存储表、视图、存储过程、函数等对象。
②、表:由行和列组成的二维数据结构,用于存储数据。每个表都有一个唯一的名称,以及一组定义了表中每个列的数据类型、长度、约束等信息的列定义。
③、列:是表中的一个字段,用于存储特定类型的数据。每个列都有一个唯一的名称,以及一个数据类型、长度、约束等信息。
④、表中的一个记录,包含了一组列值。每个行都有一个唯一的标识符,称为行标识符或行ID。
⑤、索引:用于加速数据的查找和排序,索引可以基于一个或多个列创建,可以是唯一或非唯一。
⑥、视图:一种虚拟表,基于一个或多个表的查询结果构建的。试图可以像表一样使用,但实际上它只是一个查询结果集。

88、where,having,groupby的执行顺序(不会)

在SQL中,GROUP BY的执行顺序通常是在FROM和WHEPE之后,SELECT之前。具体来说,查询语句的执行顺序如下:
①、FROM:从指定的表中获取数据
②、where:对数据进行筛选、只保留符合条件的行
③、group by:按照指定的列对数据进行分组
④、HAVING 对分组后的数据进行筛选,只保留符合条件的组
⑤、SELECT 选择需要的列、并进行计算和聚合操作
⑥、ORDER BY 按照指定列对结果进行排序
注:如果在SELECT语句中使用了聚合函数(如SUM、AVG、COUNT等),那么GROUP BY语句是必须的。否则,查询结果将会出现错误。

89、进程和线程的区别

已有

90、进程之间的通讯方式

①、管道:一种半双工的通信方式,只能在具有亲缘关系的进程(一般指父子进程)之间使用。
②、命名管道:命名管道也是一种半双工的通信方式,但可以在不具有亲缘关系的进程之间使用。
③、信号:异步通信方式,用于通知进程发生了某个事件
④、消息队列:消息的传递机制,可以在不同进程之间传递消息
⑤、共享内存:让多个进程同一块物理内存
⑥、套接字(Socket):套接字是一种通用的进程间通信方式,可以在不同主机之间进行通信。
⑦、信号量:一种用于控制多个进程同步的机制,控制多个进程对共享资源的访问。

91、进程通信方式–消息队列的拓展(不会)

实现不同进程之间的异步通信。
①、消息队列类型:分为系统消息队列和posix消息队列,系统消息队列是Linux系统提供的一种消息队列,而posix是由posix标准定义的一种消息队列。posix消息队列具有更好的可移植性和更高的性能。
②、优先级:以便高优先级的消息先被处理。
③、持久化:即使系统崩溃或重启,消息队列中的消息也不会丢失
④、安全性:只能由特定用户或组访问
...

92、socket编程

一种网络编程,用于计算机网络上进行进程间通信或进程与计算机网络之间的通信。实现客户端和服务器之间的通信,也可用于实现点对点的通信。在socket编程中,通信的两端都有一个socket,一个socket是指一个网络通信的端点,它包含了IP地址和端口号,通过socket编程可以实现不同计算机之间的通信,也可实现同一计算机内不同进程之间的通信。

93、队列和栈

区别在于数据的存储和访问方式
队列:先进先出,类似于排队,用于实现缓存、消息队列等场景
栈:后进后出,用于实现函数调用、表达式求值等场景
两者都可以使用数组或链表来存储数据。但是,队列通常需要维护头和队列尾的指针,而栈只需要维护栈顶指针即可。

94、插入排序有内存消耗吗

插入排序是一种原地排序,内存消耗非常小。但是,插入排序的时间复杂度为O(n^2),在处理大规模数据时可能会出现性能瓶颈。

95、快速排序原理和复杂度(加强)

基于分治的思想;
选一个基准,将数组中小于等于基准的元素放到基准左边,大于基准放到右边,对基准左右两边的子数组分别递归地进行快速排序。
O(nlogn),优化措施:随机选择基准、三数取中等避免最坏情况。

96、Spring了解多少(IOC,AOP)
java开源框架

20.点击一个链接它的过程(第二遍问 比较高频)
21.续20,IP找对应的服务器和SpringMVC有什么联系(不会)

22.死锁是咋样
23.避免死锁的方法(忘了)
已有

24.linux常用命令
已有

25.java基本类型有哪些?String算基本类型吗?

*97、基本类型做参数和非基本类型做参数有什么区别

基本数据类型和引用数据类型作为方法参数传递的区别

98、堆放哪些变量?栈存放什么?

堆:动态分配的内存,用于存储程序运行时需要的数据,如,动态分配的对象、数组等。堆的大小不固定,可以根据需要动态调整,在堆中分配内存需要手动申请和释放,否则会导致内存泄漏。
栈:存储程序执行期间的临时变量、函数参数、返回地址等。
栈的大小是固定的,由操作系统预先分配,当一个函数被调用时,它的参数和局部变量会被压入栈中,当函数返回时,这些数据会被弹出栈。

99、动态数组和动态链表–查找用什么,删除用什么?

都可使用线性查找和二分查找进行查找操作。
但是,动态链表相比动态数组更适合进行删除操作,因为删除一个元素只需要修改前后节点的指针,不需要移动其他元素。而动态数组删除一个元素需要将后面的元素都向前移动,效率较低。

100、七层或者五层网络结构?

上头有个五层的,25题
五层是将会话层和表示层合并到应用层中。

操作系统:

101、进程 线程的区别与联系 进程线程共享的资源

已有

102、程序运行的虚拟内存划分

代码段、数据段(存放程序中已初始化的全局变量和静态变量)、BSS段(存放未初始化的全局变量和静态变量,通常被初始化为0)、堆、栈、共享库区(存放程序依赖的共享库)、内核区(存放操作系统内核的代码和数据,只有内核访问)

103、临界区

指在多线程编程中,多个线程访问共享资源的代码段。在临界区,每个线程都有可能修改共享资源的值,保证线程安全,避免数据竞争。
解决方法:互斥锁、信号量、条件变量等同步机制来保证临界区的代码只能被一个线程执行,从而避免多个线程同时修改共享资源的情况。

104、锁(普通锁和读写锁的区别)

普锁(互斥锁),即同时刻只有一个线程持有该锁,其他线程需要等待该锁被释放后才能获取该锁。普通锁适用于对共享资源的互斥访问,可以防止多个线程同时修改同一份数据。
读写锁:允许多个线程同时读取共享资源,但只允许一个线程写入共享资源,提高并发读取效率,从而提高系统的吞吐量。

105、 new开辟的位置

堆上动态分配,new运算符返回一个指针新分配的内存空间的指针。

C++:

106、智能指针(区别,作用)

之前是四个,但是C++11之后一个被弃用掉了,现在是3个
unique_ptr:只能一个指针指向同一块内存,不能进行复制和赋值,但可进行移动操作,当unique_ptr被销毁时,它所指向的内存也会被自动释放;

shared_ptr,多个指针指向同一块内存,使用引用计数来管理内存的释放

weak_ptr,解决shared循环引用的问题,可以指向shared所指向的内存,但不会增加引用计数,也不会影响内存的释放。
C++里面四种智能指针的使用及区别

107、 面向对象的含义

面向对象是一种编程范式,它将程序中的数据和操作数据的方法组合成一个对象,通过对象之间的交互来完成程序的功能。面向对象的编程思想强调
将程序中的数据和操作数据的方法封装在一起,形成一个独立的实体,这个实体可以被其他对象调用和使用,从而实现程序的功能。面向对象的编程思想具有封装、继承和多态等
特性,可以提高程序的可维护性、可扩展性和可重用性。

108、STL

模板库
STL中的容器包括vector、list、 deque、 set、map等,算法包括排序、查找、合并
等,迭代器则是一种通用的访问容器元素的方式。STL的设计思想是将数据结构和算法分离,使得程序员可以更加专注于算法的实现,而不必关心数据结构的细节。

109、new和malloc

new/delete是C++关键字,需要编译器支持。

    malloc/free是库函数,需要头文件支持。

    new操作符申请内存分配时无须指定内存块的大小,编译器会根据类型信息自行计算。

    而malloc则需要显式地指出所需内存的尺寸。

    new操作符内存分配成功时,返回的是对象类型的指针,类型严格与对象匹配,无须进行类型转换,故new是符合类型安全性的操作符。

    而malloc内存分配成功则是返回void * ,需要通过强制类型转换将void*指针转换成我们需要的类型。

    new内存分配失败时,会抛出bac_alloc异常。

    malloc分配内存失败时返回NULL。

    C++允许重载new/delete操作符,

    而malloc不允许重载。

    new操作符从自由存储区(free store)上为对象动态分配内存空间,

    而malloc函数从堆上动态分配内存。

    自由存储区是C++基于new操作符的一个抽象概念,凡是通过new操作符进行内存申请,该内存即为自由存储区。而堆是操作系统中的术语,是操作系统所维护的一块特殊内存,用于程序的内存动态分配,C语言使用malloc从堆上分配内存,使用free释放已分配的对应内存。自由存储区不等于堆,如上所述,布局new就可以不位于堆中。

new和malloc

数据库:

110、 数据库的基本操作

数据库基本操作有:1、库的基本操作,创建数据库,查看数据库全部信息,修改数据库编码集,移除数据库;2、表的基本操作,创建表,查看表信息,修改字段属性,移除表;3、字段的基本操作,添加字段。
数据库基本操作

111、引擎

数据库引擎有哪些?

112、 B树和B+树的区别

B树和B+树都是一种多路搜索树,它们的主要区别在于,
1.数据存储方式:B树的每个节点都存储数据,而B+树的非叶子节点只存储索引信息,数据都存储在叶子节点中。
2. 叶子节点指针:B树的叶子节点之间没有指针相连,而
B+树的叶子节点之间通过指针相连,形成一个有序链表。
3. 范围查询效率:由于B+树的叶子节点之问有指针相连,因此范围查询时只需要遍历叶子
节点即可,而B树需要遍历整棵树。
4. 磁盘读写次数:B+树的非叶子节点只存储索引信息,因此每个节点可以存储更多的索引
信息,减少了磁盘读写次数,提高了查询效率。
综上所述,B+树相对于B树来说,具有更高的查询效率和更少的磁盘读写次数,适合用于
存储大量数据的场景。

113、为什么范围查找效率高

范围查找效率高是因为它利用了数据的有序性。在有序数据中,我们可以使用二分查找等
算法快速定位到目标数据所在的位置,然后再在目标数据所在的区间内进行查找。这样可以大大减少查找的时间复杂度,提高查找效率。
另外,范围查找还可以利用索引结构,例如B树、B+树等,将数据按照一定的规则组织起来,使得查找时可以快速定位到目标数据所在的位置,从而进一步提高查找效率。

114、 事务四种隔离级别(脏读,不可重复读 ,幻读)

读未提交(Read Uncommitted)、读已提交(Read Committed)、可重复读(Repeatable Read)和串行化(Serializable)

  1. 读未提交 (ReadUncommitted):一个事务可以读取另一个未提交事务的数据,可能会出现脏读、不可重复读和幻读的问题。
  2. 读己提交 (ReadCommitted):一个事务只能读取另一个已提交事务的数据,可以避免脏读问题,但是不可重复读和幻读问题仍然可能出现。
    3.可重复读 (RepeatableRead):一个事务在执行期间多次读取同一数据时,能够保证数据的一致性,避免了脏读和不可重复读问题,但是仍然可能出现幻读问题。
  3. 串行化 (Serializable):最高的隔离级别,强制事务串行执行,避免了所有并发问题,但会影响系统的并发性能。
    事务的四种隔离级别与脏读、幻读、不可重复读

115、 事务的特征

  1. 原子性 (Atomicity):事务是一个不可分割的操作序列,要么全部执行成功,要么全部
    失败回滚,不允许部分成功部分失败。
  2. 一致性 (Consistency):事务执行前后,数据库的状态必须保持一致,即满足所有的约束条件和完整性规则。
    3.隔离性 (lsolation):多个事务并发执行时,每个事务的操作应该与其他事务的操作相互隔离,互不干扰。
  3. 持久性 (Durability):事务一旦提交,其结果就应该永久保存在数据库中,即使系统
    崩溃也不会丢失。

数据结构:(问的比较细)

116、顺序表的两种实现在内存上的区别

顺序表是一种线性表,它的元素在内存中是连续存储的。顺序表的两种实现方式是静态实现和动态实现。
静态实现是指在程序运行前就确定了顺序表的大小,即在编译时就分配了一段连续的内存
空间来存储顺序表。这种实现方式的优点是访问元素的时间复杂度为O(1),因为元素在内存中是连续存储的,可以通过下标直接访问。但是缺点是顺序表的大小是固定的,不能动态扩展或缩小,浪费内存空间。
动态实现是指在程序运行时根据需要动态地分配内存空间来存储顺序表。这种实现方式的
优点是可以动态地扩展或缩小顺序表的大小,节省内存空间。但是缺点是访问元素的时间复杂度为O(n),因为元素在内存中不一定是连续存储的,需要通过指针来访问元素,效率较低。
因此,选择顺序表的实现方式应该根据实际情况来决定。如果顺序表的大小是固定的,可以洗择静态实现;如果顺序表的大小不确定或需要动态扩展或缩小,可以选择动态实现。

117、链表的删除

118、二叉树:红黑树,平衡二叉树(问的比较细,时间复杂度,特征)

二叉排序树、平衡二叉树、红黑树、B树、B+树

119、各种树成为链表的情况
120、 链表的时间复杂度
链表的复杂度分析

计算机网络:

121、三次握手

次握手的目的:
同步连接双方的序列号和确认号;
交换TCP窗口大小信息。
看图理解TCP的三次握手和四次挥手

122、 HTTP和HTTPS
已有

123、滑动窗口

TCP 就是通过滑动窗口、拥塞窗口这两个简单的窗口实现了流量控制和拥塞控制。
滑动窗口由接收端控制,向发送端通告,这样就可以保证发送端发出的包数量上限是明确的,也就不会存在淹没接收端导致来不及处理的情况。
拥塞窗口由发送端控制,它会根据网络中的情况动态的调整,通过慢启动、拥塞避免、拥塞发生、快速恢复四个算法,就可以很好地调整窗口的大小。和滑动窗口一起限制了发送端最大的发送范围,从而保证了拥塞在网络上不会发生。
很经典的文:滑动窗口:TCP的经典算法

124、TCP如何实现可靠传输

  1. 校验和
    TCP每一段报文都有校验和,这保证了报文不被破坏或篡改,如果收到的报文在校验过程中有差错,TCP 将丢弃这个报文段和不确认收到此报文段。
    2.序列号与确认应答
    TCP发送的每一个包都有一个序列号,这可以让接收方知道自己已经接收到了那些包,哪些包丢失了,重复的包也可以根据序号丢弃,并且根据序号将包排序,同时每一个发送的包都会返回一个确认应答消息,来确保消息被接收。
    3.重传机制
    TCP 实现可靠传输的方式之一,是通过序列号与确认应答,当发送端的数据到达接收主机时,接收端主机会返回一个确认应答消息,表示已收到消息,如果数据包丢失了,就会用重传机制解决。
    重传机制分为超时重传、快速重传、SACK、DTCP 是每发送一个数据,就需要等待对方进行ACK确认应答,这显然会极大的影响传输的速率。在发送数据的时候,最好的方式是一下将所有的数据全部发送出去,然后一起确认。于是就引入了窗口的概念,这个所谓的窗口实际上是操作系统开辟的一个缓存空间,@[TOC](发送方在等到确认应答返回之前,必须在缓冲区中保留已发送的数据。如果按期收到确认应答后,此时数据就可以从缓存区清除,同样接收方接收数据后也是放在这个缓存区中的,那么接收方缓存区还能接收多少数据,这个就是决定窗口大小的因素,如果发送方的数据超过接收方缓存区的大小,那会造成接收方数据溢出,这就会导致数据丢失。所以,通常窗口的大小是由接收方的窗口大小来决定的。发送方发送的数据大小不能超过接收方的窗口大小,否则接收方就无法正常接收到数据。
    TCP如何保证可靠性,TCP如何实现可靠性传输的

125、io复用(select和epoll的区别)

epoll跟select都能提供多路I/O复用的解决方案。在现在的Linux内核里有都能够支持,其中epoll是Linux所特有,而select则应该是POSIX所规定,一般操作系统均有实现。
两者的使用场景一般是通过一个入口能够同时监控多路I/O。一般使用的接口,
在所控制的I/O有事件到来
epoll和select在IO多路复用中的区别
详解IO多路复用机制——select、poll、epoll的原理和区别

是否对人工智能和云计算有涉猎)
手撕代码:

链表合并(简单)节点和链表数据结构+合并

实现map(只写了增删和下标运算符重载),在面试官提醒下放弃红黑树采用哈希表进行实现,用的链表的数据结构

socket的阻塞和非阻塞
select和epoll的区别
epoll的水平触发和边缘触发

126、虚函数和纯虚函数的区别

1)虚函数可以在类中声明,也可以在类的外部声明,编译器会自动将它们转换为虚函数;但是纯虚函数只能在类中声明,而不能在类的外部声明。
2)虚函数可以有实现,也可以没有实现;而纯虚函数没有实现,不可以有实现。
3)虚函数可以在子类中覆盖,也可以不被覆盖;而纯虚函数必须在子类中覆盖,否则编译器将报错。
4)虚函数可以被多态调用,也可以被静态调用;而纯虚函数只可以被多态调用,不可以被静态调用。

127、虚函数底层实现

实现原理:虚函数表+虚表指针
关键字:虚函数底层实现机制;虚函数表;虚表指针
编译器处理虚函数的方法是:为每个类对象添加一个隐藏成员,隐藏成员中保存了一个指向函数地址数组的指针,称为虚表指针(vptr),这种数组成为虚函数表(virtual function table, vtbl),即,每个类使用一个虚函数表,每个类对象用一个虚表指针。
举个例子:基类对象包含一个虚表指针,指向基类中所有虚函数的地址表。派生类对象也将包含一个虚表指针,指向派生类虚函数表。看下面两种情况:
如果派生类重写了基类的虚方法,该派生类虚函数表将保存重写的虚函数的地址,而不是基类的虚函数地址。
如果基类中的虚方法没有在派生类中重写,那么派生类将继承基类中的虚方法,而且派生类中虚函数表将保存基类中未被重写的虚函数的地址。注意,如果派生类中定义了新的虚方法,则该虚函数的地址也将被添加到派生类虚函数表中。
虚函数和纯虚函数的区别

智能指针
内存泄漏查看工具
B树和B+树的区别和应用场景
mysql的引擎(全部都问)
ssl的过程
三次握手四次挥手
*

128、udp报文最大发送大小*

理论上UDP报文最大长度是65507字节,
UDP传输报文大小详解

nagle算法
原帖子
牛客

编程题:

1、“l am a student." 翻转成”student. a am l" 要求不允许使用java内置函数

2、手写代码实现单链表的结构体,完成增删改查

3、统计一串字符串中,重叠字符出现的次数,如:AAABBBCC,输出A_3_B_3_C_2

4、求两个字符的最长公共子串

5、求矩阵的最小路径,每次只能往右或下移动,写出来后问了下思路,以及对应的模型(动态规划)

6、sql题:一个学生成绩表,字段有学生姓名、班级、成绩,求各班前十名(太久没写sql忘得差不多了。。

7、手撕:输入123456输出十二万三千四百五十六(大疆笔试题)

【反问环节】你有什么问题想问我的不?
咋这个岗位平时代码写的多吗?
1、你觉得我在本次面试中存在的问题是什么?
2、面试时间?二面啥时候来?

八股文大集合:
面试鹅厂c/c++后台开发岗,要学到什么程度才可以?
秋招结束,春招再战!(附面经)
c++工程师牛客网面经
2018年秋招面试经验总结
腾讯云智的面经

【一般是根据简历来问,】

简历里的华为鲲鹏认证需要去回顾一下,opencv,cpu 硬件方面适当了解一下,做cpu优化的这块还是要好好看一下。

1、简历里有个比赛,你在这个比赛里是做啥的?

1、时间复杂度?空间复杂度?怎么计算?

【一般听说,】

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值