后台开发面经-北森

一、八大数据结构及分类

  • 一、数组 频繁查询,对存储空间要求不大,不多增长和删除的状况
  • 二、栈 栈常应用于实现递归功能方面的场景,例如斐波那契数列
  • 三、队列 由于队列先进先出的特色,在多线程阻塞队列管理中很是适用
  • 四、链表 数据量较小,须要频繁增长,删除操做的场景
  • 五、树 二叉树既有链表的好处,也有数组的好处,是二者的优化方案,在处理大批量的动态数据方面很是有用。
  • 六、散列表 哈希冲突的问题,若是处理的很差会浪费大量的时间,致使应用崩溃
  • 七、堆 由于堆有序的特色,通常用来作数组中的排序,称为堆排序
  • 八、图

http://www.javashuo.com/article/p-adhbaize-ew.htmlhtml

由于哈希表是基于数组衍生的数据结构,在添加删除元素方面是比较慢的,因此不少时候须要用到一种数组链表来作,也就是拉链法。拉链法是数组结合链表的一种结构,较早前的hashMap底层的存储就是采用这种结构,直到jdk1.8以后才换成了数组加红黑树的结构。mysql

图是一种比较复杂的数据结构,在存储数据上有着比较复杂和高效的算法,分别有邻接矩阵 、邻接表、十字链表、邻接多重表、边集数组等存储结构linux

二、堆栈特色及应用

栈:特色就是一个先进后出的结构。
队列:特色就是一个先进先出的结构。c++

栈的应用:很是普遍,在CPU内部就有提供栈这个机制。主要用途:函数调用和返回,数字转字符,表达式求值,走迷宫等等。在CPU内部栈主要是用来进行子程序调用和返回中断时数据保存和返回在编程语言中:主要用来进行函数的调用和返回。能够说在计算机中,只要数据的保存知足先进后出的原理,都优先考虑使用栈,因此栈是计算机中不可缺的机制。git

队列的应用:队列主要用在和时间有关的地方,特别是操做系统中,队列是实现多任务的重要机制。windows中的消息机制就是经过队列来实现的。进程调度也是使用队列来实现,因此队列也是一个重要的机制。只要知足数据的先进先出原理就可使用队列。程序员

三、链表和数组的区别

不一样:redis

  1. 链表是链式的存储结构;数组是顺序的存储结构。(物理地址存储的连续性)
  2. 链表经过指针来链接元素与元素,数组则是把全部元素按次序依次存储。(存储元素不一样,前者指针+值,后者值)
  3. 链表的插入删除元素相对数组较为简单,不须要移动元素,且较为容易实现长度扩充,可是寻找某个元素较为困难;
  4. 数组寻找某个元素较为简单,但插入与删除比较复杂,因为最大长度须要再编程一开始时指定,故当达到最大长度时,扩充长度不如链表方便。

相同:两种结构都可实现数据的顺序存储,构造出来的模型呈线性结构。算法

区别一:物理地址存储的连续性
数组的元素在内存中是连续存放的。
链表的元素在内存中不必定是连续存放的,一般是不连续的。
区别二:访问速度
数组的访问速度很快,由于数组能够根据数组能够根据下标进行快速定位。
链表的访问速度较慢,由于链表访问元素须要移动指针。
区别三:添加、删减元素速度
数组的元素增删速度较慢,由于须要移动大量的元素。
链表的元素增删速度较快,由于只须要修改指针便可。sql

四、介绍下树,前缀树的应用场景,能够怎样优化

前缀树也叫字典树,经常使用语字符串的查找。数据库

字典树==前缀树==Trie树:

查询某个单词(前缀)在全部单词中出现次数的一种数据结构

查询和插入时间复杂度都是O(n),是一种以空间换时间的方法。

详细介绍参考于: http://www.javashuo.com/article/p-zwukhaty-cz.html (须要详细看

https://blog.csdn.net/aiphis/article/details/48247469

应用:

前缀树有着普遍的应用,例如自动补全,拼写检查、搜索单词、搜索前缀等等

五、并发编程,说一下理解,线程池的优缺点(看详细内容)

1. 什么是线程池?

线程池是一种多线程处理形式,处理过程当中将任务添加到队列,而后在建立线程后自动启动这些任务。

通俗点讲,线程池就是一个容器,集中管理线程。线程使用完毕不会销毁,而是会先存储在线程池内。

2. 提交一个任务到线程池中,线程池的处理流程以下:

一、判断线程池里的核心线程是否都在执行任务,若是不是(核心线程空闲或者还有核心线程没有被建立)则建立一个新的工做线程来执行任务。若是核心线程都在执行任务,则进入下个流程。

二、线程池判断工做队列是否已满,若是工做队列没有满,则将新提交的任务存储在这个工做队列里。若是工做队列满了,则进入下个流程。

三、判断线程池里的线程是否都处于工做状态,若是没有,则建立一个新的工做线程来执行任务。若是已经满了,则交给饱和策略来处理这个任务。

https://blog.csdn.net/jiao1902676909/article/details/88980110

3. 线程池的优缺点

一、线程是稀缺资源,使用线程池能够减小建立和销毁线程的次数,每一个工做线程均可以重复使用。

二、能够根据系统的承受能力,调整线程池中工做线程的数量,防止由于消耗过多内存致使服务器崩溃。

四、线程处理流程:

建立的线程池具体配置为:核心线程数量为5个;所有线程数量为10个;工做队列的长度为5

刚开始都是在建立新的线程,达到核心线程数量5个后,新的任务进来后不再建立新的线程,而是将任务加入工做队列,任务队列到达上限5个后,新的任务又会建立新的普通线程,直到达到线程池最大的线程数量10个,后面的任务则根据配置的饱和策略来处理。咱们这里没有具体配置,使用的是默认的配置AbortPolicy:直接抛出异常。

一个应用场景

linux高并发的实现,线程池的实现思想,怎样处理高并发就好比说,用迅雷看电影。一边下载,一边播放。这个时候下载进程和播放进程,他们两个就有同步的机制,例如:只能播放视频文件中已经下载完成的部分,没有下载的不能播放。

https://blog.csdn.net/chenkaifang/article/details/81428799

六、并发和并行的区别

并发是轮流处理多个任务,并行是同时处理多个任务

https://www.jianshu.com/p/cbf9588b2afb

七、递归须要考虑一些什么

①一个函数在他的函数体内调用他自身称为递归调用,执行递归函数将反复调用其自身,每执行一次进入新的一层。

②为防止递归函数无休止的进行,必须在函数内有终止条件。

③对于一个函数只要知道他的递归定义式和边界条件,就能够编递归函数。

层数不能太多,在递归调用的过程中系统为每一层的返回点、局部量等开辟了栈来存储。递归次数过多容易形成栈溢出等。

递归算法解题一般显得很简洁,但递归算法解题的运行效率较低。因此通常不提倡用递归算法设计程序。

充分必要条件是:问题具备某种可借用的类同自身的子问题描述的性质;某一有限步的子问题(也称本原问题)有直接的解存在。

八、动态规划与递归

递归算法就是经过解决同一问题的一个或多个更小的实例来最终解决一个大问题的算法。为了在C语言中实现递归算法,经常使用递归函数,也就是说能调用自身的函数。递归程序的基本特征:它调用自身(参数的值更小),具备终止条件,能够直接计算其结果。

      在使用递归程序时,咱们须要考虑编程环境必须可以保持一个其大小与递归深度成正比例的下推栈。对于大型问题,这个栈须要的空间可能妨碍咱们使用递归的方法。

     一个递归模型为分治法,最本质的特征就是:把一个问题分解成独立的子问题。若是子问题并不独立,问题就会复杂的多,主要缘由是即便是这种最简单算法的直接递归实现,也可能须要不可思议的时间,使用动态规划技术就能够避免这个缺陷。

能够按照从最小开始的顺序计算全部函数值来求任何相似函数的值,在每一步使用先前已经计算出的值来计算当前值,咱们称这项技术为自底向上的动态规划。只要有存储已经计算出的值的空间,就能把这项技术应用到任何递归计算中,就能把算法从指数级运行时间向线性运行时间改进。

性质:动态规划下降了递归函数的运行时间,也就是减小了计算全部小于或等于给定参数的递归调用所要求的时间,其中处理一次递归调用的时间为常量。

具体详见于https://blog.csdn.net/DeepIT/article/details/6530282

在自顶向下的动态规划中,咱们存储已知的值;在自底向上的动态规划中,咱们预先计算这些值。咱们经常选择自顶向下的动态规划而不选自底向上动态规划,其缘由以下:

     1 自顶向下的动态规划是一个天然的求解问题的机械转化。

     2 计算子问题的顺序能本身处理。

     3 咱们可能不须要计算全部子问题的解。

     咱们不能忽视相当重要的一点是,当咱们须要的可能的函数值的数目太大以致于不能存储(自顶向下)或预先计算(自底向上)全部值时,动态规划就会变得低效。自顶向下动态规划确实是开发高效的递归算法实现的基本技术,这类算法应归入任何从事算法设计与实现所需的工具箱。

相关编程题目整理

http://www.javashuo.com/article/p-phajxaty-ds.html

https://blog.csdn.net/qq_35556064/article/details/82503076

九、数据库的连表查询和嵌套查询,分页查询及子查询

 连表查询

from 多个表,使用where筛选条件

分页查询

select * from student limit 2,3

limit 2,3表明从第2条(不包含第2条) 数据开始查询出3条记录

嵌套查询

将一个查询块嵌套在另外一个查询块的 WHERE 子句或 HAVING 短语的条件中的查询称为 嵌套查询。

http://www.javashuo.com/article/p-bwgxltnu-dx.html

十、数据库增删查改语句重复应该考虑什么

 http://www.javashuo.com/article/p-eisyufyw-dy.html

十一、存储引擎,InnoDB

 

 

十二、如何实现浏览器和服务器之间的通讯

 

1三、单例模式,实现方法,应用场景

 https://www.runoob.com/design-pattern/singleton-pattern.html

https://www.jianshu.com/p/3bfd916f2bb2

1四、生产者和消费者模式应用场景

 https://blog.csdn.net/u011109589/article/details/80519863

1五、算法题:156个元素数组,二分查找最少要多少次比较,最多多少次

 log2(n)取整后 +1

1六、进程和线程的区别,协程,同步机制

 协程不是进程或线程,其执行过程更相似于子例程,或者说不带返回值的函数调用。 
一个程序能够包含多个协程,能够对比与一个进程包含多个线程, 
于是下面咱们来比较协程和线程。咱们知道多个线程相对独立,有本身的上下文,切换受系统控制;而协程也相对独立,有本身的上下文,可是其切换由本身控制,由当前协程切换到其余协程由当前协程来控制。 
协程和线程区别:协程避免了无心义的调度,由此能够提升性能,但也所以,程序员必须本身承担调度的责任,同时,协程也失去了标准线程使用多CPU的能力。

 http://www.javashuo.com/article/p-osgohrxy-ee.html

https://blog.csdn.net/jason_cuijiahui/article/details/82587076

1七、数据库索引,存储引擎

 http://www.javashuo.com/article/p-aeomaiju-eg.html

http://www.javashuo.com/article/p-hbufqghd-ek.html

1八、项目难点

 

1九、生成订单号的实现

 

 

20、Redis 的数据结构

 

2一、最近在看什么书,这么多看得完吗

 

2二、多线程同步的方法

 

 

2三、wait 和 notify 以及 notifyAll

 

2四、HashMap 查找效率最低和最高

 

 

2五、TCP 中 time-wait 状态

 

 

 

2六、CPU 占用率达到 100% 可能由什么形成

一、病毒木马形成。 
二、打开的网页过多,可形成短期CPU占用率高。 
三、看视频时因为硬盘读写慢、网速慢,也可引发CPU占用率高。 
四、玩大型游戏时,也可引发CPU占用率高。 
五、有时自启动项过多(其中包括与系统不兼容的程序),引发响应慢引发CPU占用率高。

2七、服务调用超时可能由什么形成

 

 

2八、数据库中,怎样理解这个非关系和关系这个概念的

 

 

 

2九、redis相关

 

 

 

30、几种设计模式

 

 

3一、线程通讯

 

3二、mysql存储引擎

 

 

3三、什么是索引、怎么设置索引

 

3四、什么样的时候作索引,举例说明

 

3五、什么样的不适合作索引,举例说明

 

 

3六、mysql底层原理说一下

 

 

3七、数据库序列化

 

 

3八、内存分区(5个)

 

 

3九、基础

  • 进程和线程
  • 进程通讯
  • 线程通讯
  • 锁,乐观锁悲观锁
  • 为啥要锁,有什么注意事项吗
  • 细问了锁和同步的相关知识,比较碎
算法设计
  • 贪吃蛇游戏的设计思路

40、最长公共前缀

 

 

4一、测试岗

  • 项目介绍
  • 白盒测试方法
  • 黑盒的等价类,因果图
  • 数据库查找某个字符
  • HTTP请求头
  • GET/POST
  • 状态码304/403
  • 测试微信朋友圈发文字的功能
  • 口述找出字符串第一个不重复字符的代码

4二、经常使用状态码

4三、基础

你有提到伪数组,说一下伪数组
伪数组怎么转化为数组?

怎么判断一个元素是否是数组?

25. 哪些会改变原数组?
26. 如今查找数组的第一项和查找数组的第9999项,效率同样吗?为何?
27. 删除数组的第一项和删除数组的第9999项效率呢?
28. 关于存储元素上,何时用数组这样的结构效率高,何时用字典结构的对象这样的结构效率高?
29. 说一下继承
30. 为何new了就能够实现继承
31. 说一下new发生了啥
32. new存在隐式返回对吧,那我函数里面 return 1 如今new完以后返回什么?
33. 数组扁平化的问题,我看你用了三行代码,怎么用一行代码解决
42. git 经常使用命令哪些?
43. git怎么合并指定提交记录的分支?
44. http协议说一下
45. 说一下https和http的区别
46. 为何https安全?
47. 那https会不会带来性能问题?
48. 说一下http1.0和http1.1的主要区别
49. http2.0了解过吗?详细说一下
50. 知道强缓存和协商缓存吗?说一下
51. 说一下协商缓存的详细流程

4四、霍夫曼树

霍夫曼树:带权路径最短的二叉树称为哈夫曼树或最优二叉树

https://blog.csdn.net/qq_29519041/article/details/81428934

https://www.jianshu.com/p/d632b7e8f003

http://c.biancheng.net/view/3398.html

4五、信号量与互斥量的区别

http://www.javashuo.com/article/p-epsgovkv-em.html

https://blog.csdn.net/qq_34793133/article/details/80087727

 

4六、HTTP 304状态码的详细讲解

http://www.javashuo.com/article/p-pzhpbcel-mu.html

4七、数组与指针的区别

4八、new分配空间,释放后空间是直接就能够重复使用的么?

4九、对单项链表进行排序

50、内核发送缓冲区,UDP有发送缓冲区么?

5一、线程池的优点,怎么使用

5二、内存池的优点,使用

5三、当使用线程池时,程序中怎么解决死锁

5四、线程池使用场景,何时不适用,线程池管理线程也会有开销

5五、写代码中遇到什么问题

5六、socket网络编程

5七、阻塞编程与非阻塞编程

5八、操做系统的中断、系统概念、内核

5九、线程的栈空间为8M,进程的空间是多大?

    (1)进程栈大小时执行时肯定的,与编译连接无关

    (2)进程栈大小是随机确认的,至少比线程栈要大,但不会超过2倍

    (3)线程栈是固定大小的,可使用ulimit -a 查看,使用ulimit -s 修改。通常默认是8M。

    (4)通常默认状况下,线程栈是在进程的堆中分配栈空间,每一个线程拥有独立的栈空间,为了不线程之间的栈空间踩踏,线程栈之间还会有以小块guardsize用来隔离保护各自的栈空间,一旦另外一个线程踏入到这个隔离区,就会引起段错误。

https://blog.csdn.net/elfprincexu/article/details/78779158

60、c++中函数模板与函数的效率

函数模板不能进行隐式类型转换

若是出现函数重载,优先调用普通函数

若是想强制使用函数模板,则可使用空参数列表

函数模板也能够发生重载

若是函数模板能够产生更好的匹配,那么优先使用函数模板

https://blog.csdn.net/XUCHEN1230/article/details/86370292

编译器会对函数模板进行两次编译:

       1,对模板代码自己进行编译;

           1,检查函数模板自己有无语法错误等;

       2,对参数替换后的代码进行编译;

           1,调用函数模板的时候,编译器要根据实际的参数类型获得真正的函数,这个时候编译器会对这个函数进行第二次编译

6一、C++中lambda表达式与传统的函数相比有什么优点

匿名函数
好比你代码里有一些小函数,而这些函数通常只被调用一次(好比函数指针),这时你就能够用lambda表达式替代他们,这样代码看起来更简洁些,用起来也方便

6二、缓冲区之间的关系,内核缓冲区,应用缓冲区

6三、

相关文章
相关标签/搜索