2020-12-13:用最少数量的多线程线程数设置,每个多线程线程数设置执行for的空循环,把cpu打满了。如果在for的空循环里添加打印输

1、对linux下mysqldump备份命令的参数描述正确嘚是

2、linux中一个端口能够接受tcp链接数量的理论上限是

解释:标识一个tcp链接的是,客户端和服务器的ip加端口号尽管服务器ip地址和端口号一樣,但是客户端ip地址不一样而客户端端口号具有本地意义,理论上服务器的端口能接受的链接无上限

3、unix系统中可以用于进程间的通信

socket、共享内存、消息队列、信号量

linux进程间通信:管道、信号、消息队列、共享内存、信号量、套接字(socket)、文件锁

linux多线程线程数设置间通信:互斥量(mutex)、信号量、条件变量
windows进程间通信:管道、消息队列、共享内存、信号量(semaphore)、套接字

管道(Pipe):管道可用于具有亲缘关系进程间的通信,允许一个进程和另一个与它有共同祖先的进程之间进行通信
命名管道(named pipe):命名管道克服了管道没有名字的限制,因此除具有管道所具有的功能外,它还允许无亲缘关系进程间的通信命名管道在文件系统中有对应的文件名。命名管道通过命令mkfifo或系统调用mkfifo來创建
信号(Signal):信号是比较复杂的通信方式,用于通知接受进程有某种事件发生除了用于进程间通信外,进程还可以发送信号给进程本身;linux除了支持Unix早期信号语义函数sigal外还支持语义符合Posix.1标准的信号函数sigaction(实际上,该函数是基于BSD的BSD为了实现可靠信号机制,又能够统┅对外接口用sigaction函数重新实现了signal函数)。
消息(Message)队列:消息队列是消息的链接表包括Posix消息队列system V消息队列。有足够权限的进程可以向队列中添加消息被赋予读权限的进程则可以读走队列中的消息。消息队列克服了信号承载信息量少管道只能承载无格式字节流以及缓冲區大小受限等缺
共享内存:使得多个进程可以访问同一块内存空间,是最快的可用IPC形式是针对其他通信机制运行效率较低而设计的。往往与其它通信机制如信号量结合使用,来达到进程间的同步及互斥
内存映射(mapped memory):内存映射允许任何多个进程间通信,每一个使用该機制的进程通过把一个共享的文件映射到自己的进程地址空间来实现它
信号量(semaphore):主要作为进程间以及同一进程不同多线程线程数设置之间的同步手段。
套接口(Socket):更为一般的进程间通信机制可用于不同机器之间的进程间通信。起初是由Unix系统的BSD分支开发出来的但現在一般可以移植到其它类Unix系统上:Linux和System V的变种都支持套接字。

解释: rsync 数据镜像工具 支持的协议可以tcp、udp、而其他都是面向连接(tcp)协议一萣程度上保证可靠性

5、在linux系统中,运行一个程序程序中为初始化的全局变量会被加载到哪个内存段中

BSS(block started by symbol)用来存放程序中未初始化的全局变量和静态变量 特点:可读可写 ,在程序执行前自动清0
DATA 存放程序中已初始化的全局变量属于静态分配内存
栈(stack)堆栈,用户存放程序臨时创建的局部变量 可看作 寄存、交换临时数据的分区

6、关于系统调用的描述错误的是

系统调用中被调用的过程运行在“用户态”

解释:鼡户空间与系统空间所在的内存空间不同所以cpu的运行状态也不同,在用户空间cpu处于“用户态”在系统空间中,cpu处于“系统态”

解释:執行 git blame 会逐行显示文件并在每一行的行首显示commit号,提交者最早的提交日期

8、关于clone和fork 的区别描述正确的是

clone是fork的升级版本,不仅可以创建进程或者多线程线程数设置还可以指定创建的新的命名空间,有选择的继承父进程的内存、甚至可以将创建出来的进程变成父进程的兄弟進程等

解释:fork 复制进程创建一个新进程,不带参数clone是可选的复制父进程资源可通过参数控制复制的内容

8、关于android dvm 的进程和linux进程,应用程序的进程说法正确的是

应用程序都在自己的进程中执行都拥有一个独立的dalivk虚拟机实例,而每一个DVM都是在linux 中的一个进程所以可以认为是哃一个概念

9、unix 系统由哪几部分组成

kernel内核、shell外壳、工具及应用程序

解释:UNIX系统由内核、shell、文件系统和应用程序等4部分组成。

10、有关bash配置文件说法正确的是

.bash_profile : 每个用户都可以使用该文件输入专用于自己使用的shell信息,当用户登录时该文件仅执行一次,默认情况下

/etc/profile :此文件为系统嘚每个用户设置环境信息当用户第一次登陆时,该文件被执行

解释:/etc/bash.bashrc 对所有用户起作用~/.bashrc 多拥有者当前的home目录的用户起作用,也就是当湔用户

11、在dhcp.conf中用于向某个主机分配固定的IP地址的参数是

12、将文件file1复制为file2可以用的命令

解释:dd 作用指定大小的拷贝文件并在拷贝的同时进荇指定的转换 if 输入文件 of 输出文件

13、tcp 的握手与分手,可能出现的情形有:

解释:ACK和SYN在第二次握手的时候

14、在linux中查看ARP缓存记录的命令是

15、linux执行咾ls会引起哪些系统调用

首先,使用场景不同除了snprintf之外,其他的都是用于两个字符串之间进行比较、拷贝、拼接等操作的而snprintf最主要是,要把一个用户变量按照一个format打印到字符串中
其次,函数参数类型不同除了snprintf之外,其他的都是定长参数而snprintf是接受变长参数的。最后定义位置也不同,除了snprintf位于stdio.h之外其他的都是string.h中的。

17、在UNIX操作系统中,若用户键入的命令参数的个数为1时,执行cat$1命令:若用户键入的命令个数為2时,执行cat>>$2<$1命令,请将下面所示的shell程序的空缺部分补齐

解释:在UNIX中$$、$@、$#以及$的含义分别如下:
$$表示当前命令的进程标识数。
表示所有位置参量例如$1、$2等。
$@与$类似但当用双引号进行转义时,"$@"能够分解多个参数而"$"合并成一个参数。
$#包括位置參数的个数但是不包括命令名。

18、哪个变量用来指定一个远程x应用程序将输出放到哪个x server

解释:Linux X Window System中X是一个开放的协议规范当前版本为11,俗称X11X Window System由客户端和服务端组成,服务端X Server负责图形显示而客户端库X Client根据系统设置的DISPLAY环境变量,将图形显示请求发送给相应的X Server

20、你们公司囿三个办事处,这三个办事处的电脑在公司网络上都属于一个Windows 2000域所有的服务器都装有Windows 2000Server 系统,此网络通过帧中继连接你在名为Mon1服务器上咹装了一个第三方网络管理套件。你需要确保这个新的软件能结合并管理网络中现有的设备你该怎么做?

除了Mon1.所有的计算机都安装SNMP

解释:SNMP基于TCP/iP协议工作对网络中支持SNMP协议的设备进行管理,所有支持SNMP的设备都可以由SNMP统一管理,管理员进行统一的管理操作

关于孤儿进程和僵死进程的描述说法正确的是

孤儿进程:一个父进程退出,而它的一个或多个子进程还在运行那么哪些子进程将成为孤儿进程,该进程将被init进程(进程号为1)所收养并由init 进程对它们完成状态收集工作

僵尸进程:一个进程使用fork创建子进程,如果子进程退出而父进程并沒有调用wait或waitpid获取子进程的状态信息,那么子进程的进程描述符保存在系统中成为僵尸进程

那么保留的那段信息就不会释放,其进程号就會一直被占用但是系统所能使用的进程号是有限的,如果大量的产生僵死进程将因为没有可用的进程号而导致系统不能产生新的进程.
此即为僵尸进程的危害,应当避免

孤儿进程并不会造成伤害

解释:recv 接受对端socket数据,经过两次系统那个调用首先将内核中数据拷贝到自己嘚协议栈然后recv返回将数据从内核缓冲拷贝到用户buffer,内核从对端接收数据放在socket缓冲,然后复制到应用层的buffer所以一共两个

22、Linux系统中,已經将dhcp服务架设好客户端的网络接口eth0,可通过()命令获得服务器分配的IP

new 能自动分配空间大小 对于用户自定义的对象而言用malloc/free无法满足动態管理对象的要求 对象在创建的时候会自动调用构造函数,对象在消亡之前自动执行析构函数 由于malloc/free是库函数而不是运算符不在编译器的控制范围,不能把构 造函数和析构函数的任务强加于malloc/free 一次C++需要一个能够对对象完 成动态分配内存和初始化工作的运算符new,以及一个释放內存的运算符

26、在cpu和物理内存之间进行地址转换()将地址从虚拟(逻辑)地址空间映射到物理地址空间

解释:MMU内存管理单元,是中央處理器用来管理虚拟内存和物理内存寄存器的控制线路同时负责虚拟内存映射为物理内存

TCB多线程线程数设置控制块 PCB 进程控制块
DMA 直接内存存储,传输数据从一个地址空间到另一个地址空间

27、vsftpd 服务流量控制的参数

设置匿名登入者使用的最大传输速度单位为b/s,0表示不限制速度,默认值为0
本地用户使用的最大传输速度单位为b/s,0表示不限制速度,预设值为0

解释:fg 将后台的命令调至前台继续执行
bg 将一个在后台暂停的命囹变成继续执行
ctrl +z 将一个正在前台执行的命令放在后台,并且暂停

29、进程a读取b进程中的某个变量(非共享内存)可行的方式

b进程向消息隊列写入一个包含变量内容的消息,a进程从队列读出

解释:命名管道虽然可以通讯但是把变量的地址传递过去是没有用的,因为不同的進程的地址空间是独立的谁也不能访问谁的,只有传值才行传地址是不行的,所以错;
子进程虽然是由父进程fork()出来的但是仍然属于兩个进程,不同进程之间也是独立的子进程无权读取父进程的变量。

30、导致用户从用户态切换到内核的操作是

解释:用户态切换到内核嘚3种方式:

31、bash环境中挂起当前进程的方式

解释:ctrl+z把正在运行的程序调到后台,暂停一个前台的作业即挂起 。
ctrl+x在某些文字处理程序中这个控制字符将会剪切高亮的文本并且将它复制到剪贴板中。
ctrl+v在输入文本的时候按下之后,可以插入控制字符
ctrl+c中断,终结一个前台作业

解释:fseek库函数,其他都是调用

33、关于读屏障、写屏障、通用屏障、优化屏障说法正确的是

优化屏障用于限制编译器的指令重排
通用屏障对讀写操作都有影响
读屏障用于保障读操作有序屏障之前的读操作一定会先于屏障之后的读操作,写操作不受影响

34、在RHEL5系统中关于shell环境變量配置文件描述正确的是

用户登录系统时,bash首先执行/etc/profile配置文件和/etc/profile.d/目录下的配置文件这些配置文件对所有用户都有效

解释:/etc/priofile 为系统的每┅个用户设置环境信息,当用户第一次登陆该文件被执行,并从/etc/prifile.d 目录的配置文件中搜集shell的设置
~/.bash_profile 每个用户都可以使用该文件输入专用于自巳的shell 信息当用户登录执行,该文件仅被执行一次默认情况下,设置一些环境变量执行 ~/.bashrc
~/.bashrc 该文件包含专用于用户的bash shell 的bash 信息,当登陆时以忣每次打开新的shell 该文件被录取

35、在Linux下64位c程序请计算输出的三个sizeof分别是:

解释:64位系统,字符串大小还包括‘\0’个数位6,字符指针大小為8

36、windows平台通过栈溢()出想要利用包含stack cookie 保护的函数都有哪些方式

更改函数内部变量改变逻辑

37、为所有用户配置一个自定义注册项用最简潔的操作,才能将自定义注册项添加到一个组策略对象中

配置一个ADM模板并把模板添加到GPO

解释:1.ADM 文件是不能单独打开的
2.ADM 文件是组策略用以描述基于注册表的策略设置在注册表中的存储位置的模板文件。
3.ADM 文件还描述了管理员在“组策略对象编辑器”管理单元中看到的用户界面管理员使用组策略对象编辑器创建或修改组策略对象 (GPO)。

38、linux主机的负载相关指标

解释:sar -u 显示cpu信息-u默认选项,输出以百分比显示cpu使用情况

39、设fp已定义,执行语句fp=fopen(“file”,“w”);后,以下针对文本文件file操作叙述的选项错误的是:

可以在原有内容后追加写
写操作结束后可以从头开始读

解释:fopen(“file”,”w”)打开文件并赋值为“w”权限,即写权限因为这里不具有读权限;用“w”打开的文件只能向该文件写入。若打开的文件不存在则以指定的文件名建立该文件,若打开的文件已经存在则将该文件删去,重建一个新文件D所描述的权限应该是“w+”而非“w”,所以D錯误;

40、那些函数必须进入内核才能完成

解释:fopen是ANSIC标准中的C语言库函数在不同的系统中应该调用不同的内核api
linux中的系统函数是open,fopen是其封装函数
exit终止进程,需要内核

对进程来说其虚拟内存的大小不受物理内存的限制

多线程线程数设置有自己的栈,但没有堆普通整数的一般赋值、增量和减量语句会产生多条机器指令,操作均不具有原子性需要同步,虚拟存储器具有请求调入和置换功能所以虚拟内存的夶小不受物理内存大小的限制。

nginx进程数设置为CPU总核心数最佳 设置工作模式与连接数上限时应考虑单个进程最大连接数(最大连接数=连接数*進程数)

解释:进程数设置为CPU总核心数最佳。
B. 配置虚拟主机多个域名时,用 空格 分隔
用于进行下载等应用磁盘IO重负载应用,设置为off鉯平衡磁盘与网络I/O处理速度,降低系统的负载
D. 工作模式与连接数上限 :(最大连接数 = 连接数 * 进程数)

43、在linux编程中以下哪个TCP的套接字选项與nagle算法的开启和关闭有关

解释:为了解决大量的小报文对通信造成的影响,提高传输效率

44、哪些命令可以查看当前系统的启动时间

解释:who -b 查看当前系统的启动时间
w 查看当前系统的启动时间

top 查看当前系统的启动时间
uptime查看当前系统的启动时间

45、有关ext2和ext3 文件系统描述区别是

EXT2、EXT3:linux环境上的文件系统ext2/ext3文件系统使用索引节点来记录文件信息,作用像windows的文件分配表索引节点是一个结构,它包含了一个文件的长度、创建忣修改时间、权限、所属关系、磁盘中的位置等信息
(1)ext2和ext3的格式完全相同,只是在ext3硬盘最后面有一部分空间用来存放Journal(日志)的记录;
(2)在ext2中写资料到硬盘中时,先将资料写入缓存中当缓存写满时才会写入硬盘中;
(3)在ext3中,写资料到硬盘中时先将资料写入缓存中,鼗缓存写满时系统先通知Journal再将资料写入硬盘,完成后再通知Journal资料已完成写入工作;
(4)是否有Journal的差别:
在ext2中,系统开机时会去檢查有效位(Valid bit)如果值为1,表示系统上次有正常关机;如果为0表示上次关机未正常关机,那系统就会从头检查硬盘中的资料这样时間会很长;
在ext3中,也就是有Journal机制里系统开机时检查Journal的资料,来查看是否有错误产生这样就快了很多;

46、系统当前已经加载的所有文件系统在 ——文件中得到反映

/etc/matab 作用:记载的是现在系统已经装载的文件系统,包括操作系统建立的虚拟文件
/etc/fatab 作用:记录了计算机上硬盘分区嘚相关信息启动linux的时候,检查分区的fsck命令挂在分区的mount 命令

48、若一台计算机的内存为128MB,则交换分区的大小通常是

解释:交换分区一般是粅理分区的2倍
在小于2GB物理内存的系统中交换分区大小应该设置为内存大小的两倍;
如果内存大小多于2GB,交换分区大小应该是物理内存大尛加上2GB;

49、vsftpd 配置本地用户传输速率的参数

50、关于静态库与动态库的区别说法错误的是

加载动态库的程序运行速度相对较快

(1)代码装载速度赽,执行速度略比动态链接库快; (2)只需保证在开发者的计算机中有正确的.LIB文件在以二进制形式发布程序时不需考虑在用户的计算机上.LIB文件是否存在及版本问题,可避免DLL地狱等问题 (1)更加节省内存并减少页面交换; (2) DLL文件与EXE文件独立,只要输出接口不变(即名称、参数、返回徝类型和调用约定不变)更换DLL文件不会对EXE文件造成任何影响,因而极大地提高了可维护性和可扩展性; (3)不同编程语言编写的程序只要按照函数调用约定就可以调用同一个DLL函数; (4)适用于大规模的软件开发使开发过程独立、耦合度小,便于不同开发者和开发组织之间进行开發和测试 (1)使用静态链接生成的可执行文件体积较大,包含相同的公共代码造成浪费; (2)使用动态链接库的应用程序不是自完备的,它依賴的DLL模块也要存在如果使用载入时动态链接,程序启动时发现DLL不存在系统将终止程序并给出错误信息。而使用运行时动态链接系统鈈会终止,但由于DLL中的导出函数不可用程序会加载失败;速度比静态链接慢。当某个模块更新后如果新模块与旧的模块不兼容,那么那些需要该模块才能运行的软件统统撕掉。这在早期Windows中很常见

解释:Maxfd要监视的文件描述符的范围,一般取监视的描述符数的最大值+1

52、述是Linux下多多线程线程数设置编程常用的pthread库提供的函数名和意义说法正确的有

立即返回。 指定的多线程线程数设置必须可接合多线程线程數设置

53、使用pthread库的多多线程线程数设置程序编译时1需要加什么连接参数

54、在退出unix系统账户之后还需要继续运行某个多线程线程数设置,鈳用

55、linux两个进程可以同时打开同一个文件如下描述正确的是

两个进程分别产生两个独立的id
两个进程可以任意对文件进行写操作,操作系統并不保证写的原子性
进程可以通过系统调用对文件加锁从而实现对文件内容的保护
两个进程可以分别读取文件的不同部分而不会相互影响
一个进程对文件长度和内容的修改另外一个进程可以立即感知

解释:如果两个进程同时打开同一个文件,一个多线程线程数设置执行刪除操作只要另一个多线程线程数设置不退出,就可以继续对该文件进行操作一旦退出才会找不到该文件的索引节点而报错。

55、linux的非root鼡户在自己的目录下,不可以删除非空目录dirs的方法是

解释:/dev/null 文件的权限是666不具备执行权限,所以不能通过/dev/null 删除

解释:netd :networkdaemon缩写network守护进程,netd负责与一些涉及网络的配置操作,管理查询等相关的功能实现,例如:带宽控制流量统计,网络地址转换(NAT)个人局域网(pan),ppp链接soft-ap,共享上网(tether)配置路由表,interface配置管理
inetd 监视网络请求的守护进程根据网络请求调用相应的服务进程处理请求,为多个服务管理连接当inetd接到连接,能够确定连接所需的程序启动相应的进程,并把socket交给他

解释:fork()给子进程返回一个零值而给父进程返回一个非零值;在main这个主进程中,首先执行 fork() || fork(), 左边的fork()返回一个非零值根据||的短路原则,前面的表达式为真时后面的表达式不执行,故包含main的这个主进程创建了一个子进程由于子进程会复制父进程,而且子进程会根据其返回值继续执行就是说,在子进程中 fork() ||fork()这条语句左边表达式嘚返回值是0, 所以||右边的表达式要执行,这时在子进程中又创建了一个进程即main进程->子进程->子进程,一共创建了3个进程

向规则链增加一条規则,规则匹配的对象是IP为192.168.3.112tos等于0x10的包,使用路由表2这条规则的优先级是1500

解释:规则包含3个要素:
什么样的包,将应用本规则(所谓的SELECTOR可能是filter更能反映其作用);
符合本规则的包将对其采取什么动作(ACTION),例如用那个表;
本规则的优先级别优先级别越高的规则越先匹配(数值越小优先级别越高)。

显示passwd文件的结构

2:查看可被内核调用的函数的帮助
3:查看函数和函数库的帮助
4:查看特殊文件的帮助(主偠是/dev目录下的文件)
5:查看配置文件的帮助
7:查看其它杂项的帮助
8:查看系统管理员可用命令的帮助
man -f 【命令】–可以查看这个命令有哪些級别

59、基于linux操作系统开发的ARM应用程序源文件teast.c那么生成该程序代码的调试信息,编译时使用的GCC正确的是

60、使用什么命令把打印任务放到打茚中打印

解释:lprm 将一个工作由打印机伫列中一处
lpq 查看一个打印队列的状态及其包含的任务
lpd 一个常用的打印机管理员,或根据/etc/printcap 的内容管理夲地或远端的打印机
lpr 实用程序将一个或多个文件放入打印队列等待打印

61、哪些因素不会限制linux服务器并发连接数

解释:网卡作用是对数据嘚封装和解封

D:/var/run/utmp日志记录了正在登录本系统中的用户信息,可以用last -f命令查看

解释:B. 执行last指令时它会读取位于/var/log/wtmp的文件,并把该给文件的内嫆记录的登录系统的用户名单全部显示出来
C.wtmp是二进制文件,他们不能被诸如tail命令剪贴或合并需要使用who、w、users、last和ac来使用这两个文件包含嘚信息。

63、使用useradd创建用户和主目录相关的参数是

解释:-p 设定帐户的密码
-m 自动建立用户的主目录
-M 不要自动建立用户的主目录

64、linux查看服务程序占用的端口是

解释:netstat 命令用于显示各种网络相关信息如网络连接,路由表接口状态,连接等信息。
参数apn的作用如下:
-p 显示建立相关链接嘚程序名
-n 拒绝显示别名能显示数字的全部转化成数字。

65、有关内核多线程线程数设置和用户多线程线程数设置说法错误的是

内核进程之運行在内核态不受用户态的影响

解释:协程调度不进入内核态

66、apache目录访问控制的参数

解释:AuthName:验证窗口的名称
AuthUserFile:验证所使用的帐号密码配置攵件
Require:指定可以登录网页的用户

使用fork函数得到的子进程从父进程的继承了整个进程的地址空间,包括:进程上下文、进程堆栈、内存信息、咑开的文件描述符、信号控制设置、进程优先级、进程组号、当前工作目录、根目录、资源限制、控制终端等
子进程与父进程的区别在於:
1、父进程设置的锁,子进程不继承(因为如果是排它锁被继承的话,矛盾了)
2、各自的进程ID和父进程ID不同
3、子进程的未决告警被清除;
4、子进程的未决信号集设置为空集
多线程线程数设置是程序的多个顺序的流行动态执行
多线程线程数设置不能独立执行必须依附在應用程序中,由应用程序提供多个多线程线程数设置执行控制

多线程线程数设置是操作系统能夠进行运算调度的最小单位它被包含在进程之中,是进程中的实际运作单位程序员可以通过它进行多处理器编程,你可以使用多多线程线程数设置对运算密集型任务提速比如,如果一个多线程线程数设置完成一个任务要100毫秒那么用十个多线程线程数设置完成改任务呮需10毫秒。

122多线程线程数设置和进程有什么区别?

多线程线程数设置是进程的子集一个进程可以有很多多线程线程数设置,每条多线程线程数设置并行执行不同的任务不同的进程使用不同的内存空间,而所有的多线程线程数设置共享一片相同的内存空间每个多线程線程数设置都拥有单独的栈内存用来存储本地数据。

123如何在Java中实现多线程线程数设置?

它所修饰的变量不保留拷贝直接访问主内存中嘚。

在Java内存模型中有main memory,每个多线程线程数设置也有自己的memory (例如寄存器)为了性能,一个多线程线程数设置会在自己的memory中保持要访问的变量的副本这样就会出现同一个变 量在某个瞬间,在一个多线程线程数设置的memory中的值可能与另外一个多线程线程数设置memory中的值或者main memory中的徝不一致的情况。 一个变量声明为volatile就意味着这个变量是随时会被其他多线程线程数设置修改的,因此不能将它cache在多线程线程数设置memory中

當它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个多线程线程数设置执行该段代码

一、当两个并发多线程线程数设置访问同一个对象object中的这个synchronized(this)同步代码块时,一个时间内只能有一个多线程线程数设置得到执行另一个多线程线程数设置必须等待当前多线程线程数设置执行完这个代码块以后才能执行该代码块。

三、尤其关键的是当一个多线程线程数设置访问object的一个synchronized(this)同步代码塊时,其他多线程线程数设置对object中所有其它synchronized(this)同步代码块的访问将被阻塞

四、当一个多线程线程数设置访问object的一个synchronized(this)同步代码块时,它就获嘚了这个object的对象锁结果,其它多线程线程数设置对该object对象所有同步代码部分的访问都被暂时阻塞

五、以上规则对其它对象锁同样适用.

125,有哪些不同的多线程线程数设置生命周期

当我们在Java程序中新建一个多线程线程数设置时,它的状态是New当我们调用多线程线程数设置嘚start()方法时,状态被改变为Runnable多线程线程数设置调度器会为Runnable多线程线程数设置池中的多线程线程数设置分配CPU时间并且讲它们的状态改变为Running。其他的多线程线程数设置状态还有WaitingBlocked 和Dead。

126你对多线程线程数设置优先级的理解是什么?

每一个多线程线程数设置都是有优先级的一般來说,高优先级的多线程线程数设置在运行时会具有优先权但这依赖于多线程线程数设置调度的实现,这个实现是和操作系统相关的(OS dependent)峩们可以定义多线程线程数设置的优先级,但是这并不能保证高优先级的多线程线程数设置会在低优先级的多线程线程数设置前执行多線程线程数设置优先级是一个int变量(从1-10),1代表最低优先级10代表最高优先级。

127什么是死锁(Deadlock)?如何分析和避免死锁

死锁是指两个以上的多線程线程数设置永远阻塞的情况,这种情况产生至少需要两个以上的多线程线程数设置和两个以上的资源

分析死锁,我们需要查看Java应用程序的多线程线程数设置转储我们需要找出那些状态为BLOCKED的多线程线程数设置和他们等待的资源。每个资源都有一个唯一的id用这个id我们鈳以找出哪些多线程线程数设置已经拥有了它的对象锁。

避免嵌套锁只在需要的地方使用锁和避免无限期等待是避免死锁的通常办法。

128什么是多线程线程数设置安全?Vector是一个多线程线程数设置安全类吗

如果你的代码所在的进程中有多个多线程线程数设置在同时运行,洏这些多线程线程数设置可能会同时运行这段代码如果每次运行结果和单多线程线程数设置运行的结果是一样的,而且其他的变量的值吔和预期的是一样的就是多线程线程数设置安全的。一个多线程线程数设置安全的计数器类的同一个实例对象在被多个多线程线程数设置使用的情况下也不会出现计算失误很显然你可以将集合类分成两组,多线程线程数设置安全和非多线程线程数设置安全的Vector 是用同步方法来实现多线程线程数设置安全的, 而和它相似的ArrayList不是多线程线程数设置安全的。

129Java中如何停止一个多线程线程数设置?

Java提供了很丰富的API泹没有为停止多线程线程数设置提供APIJDK 1.0本来有一些像stop(), suspend() 和 resume()的控制方法但是由于潜在的死锁威胁因此在后续的JDK版本中他们被弃用了,之后Java API的设計者就没有提供一个兼容且多线程线程数设置安全的方法来停止一个多线程线程数设置当run() 或者 call() 方法执行完的时候多线程线程数设置会自動结束,如果要手动结束一个多线程线程数设置,你可以用volatile 布尔变量来退出run()方法的循环或者是取消任务来中断多线程线程数设置

ThreadLocal用于创建多線程线程数设置的本地变量我们知道一个对象的所有多线程线程数设置会共享它的全局变量,所以这些变量不是多线程线程数设置安全嘚我们可以使用同步技术。但是当我们不想使用同步的时候我们可以选择ThreadLocal变量。

每个多线程线程数设置都会拥有他们自己的Thread变量它們可以使用get()\set()方法去获取他们的默认值或者在多线程线程数设置内部改变他们的值。ThreadLocal实例通常是希望它们同多线程线程数设置状态关联起来昰private static属性

Thread.sleep()使当前多线程线程数设置在指定的时间处于“非运行”(Not Runnable)状态。多线程线程数设置一直持有对象的监视器比如一个多线程线程数设置当前在一个同步块或同步方法中,其它多线程线程数设置不能进入该块或方法中如果另一多线程线程数设置调用了interrupt()方法,它将喚醒那个“睡眠的”多线程线程数设置

注意:sleep()是一个静态方法。这意味着只对当前多线程线程数设置有效一个常见的错误是调用t.sleep(),(這里的t是一个不同于当前多线程线程数设置的多线程线程数设置)即便是执行t.sleep(),也是当前多线程线程数设置进入睡眠而不是t多线程线程数设置。t.suspend()是过时的方法使用suspend()导致多线程线程数设置进入停滞状态,该多线程线程数设置会一直持有对象的监视器suspend()容易引起死锁问题。

object.wait()使当前多线程线程数设置出于“不可运行”状态和sleep()不同的是wait是object的方法而不是thread。调用object.wait()时多线程线程数设置先要获取这个对象的对象锁,当前多线程线程数设置必须在锁对象保持同步把当前多线程线程数设置添加到等待队列中,随后另一多线程线程数设置可以同步同一個对象锁来调用object.notify()这样将唤醒原来等待中的多线程线程数设置,然后释放该锁基本上wait()/notify()与sleep()/interrupt()类似,只是前者需要获取对象锁

132,什么是多线程线程数设置饿死什么是活锁?

当所有多线程线程数设置阻塞或者由于需要的资源无效而不能处理,不存在非阻塞多线程线程数设置使资源可用JavaAPI中多线程线程数设置活锁可能发生在以下情形:

2,当所有多线程线程数设置卡在无限循环中

133,什么是Java Timer类如何创建一个有特定时间间隔的任务?

java.util.Timer是一个工具类可以用于安排一个多线程线程数设置在未来的某个特定时间执行。Timer类可以用安排一次性任务或者周期任务

java.util.TimerTask是一个实现了Runnable接口的抽象类,我们需要去继承这个类来创建我们自己的定时任务并使用Timer去安排它的执行

134,Java中的同步集合与并发集合有什么区别

同步集合与并发集合都为多多线程线程数设置和并发提供了合适的多线程线程数设置安全的集合,不过并发集合的可扩展性更高

在Java1.5之前程序员们只有同步集合来用且在多多线程线程数设置并发的时候会导致争用,阻碍了系统的扩展性

Java5介绍了并发集合像ConcurrentHashMap,不仅提供多线程线程数设置安全还用锁分离和 内部分区等现代技术提高了可扩展性

135,同步方法和同步块哪个是更好的选择?

同步块昰更好的选择因为它不会锁住整个对象(当然你也可以让它锁住整个对象)。同步方法会锁住整个对象哪怕这个类中有多个不相关联嘚同步块,这通常会导致他们停止执行并需要等待获得这个对象上的锁

136,什么是多线程线程数设置池 为什么要使用它?

创建多线程线程数设置要花费昂贵的资源和时间如果任务来了才创建多线程线程数设置那么响应时间会变长,而且一个进程能创建的多线程线程数设置数有限

为了避免这些问题,在程序启动的时候就创建若干多线程线程数设置来响应处理它们被称为多线程线程数设置池,里面的多線程线程数设置叫工作多线程线程数设置

从JDK1.5开始,Java API提供了Executor框架让你可以创建不同的多线程线程数设置池比如单多线程线程数设置池,烸次处理一个任务;数目固定的多线程线程数设置池或者是缓存多线程线程数设置池(一个适合很多生存期短的任务的程序的可扩展多线程线程数设置池)

这两个方法是Swing API 提供给Java开发者用来从当前多线程线程数设置而不是事件派发多线程线程数设置更新GUI组件用的。InvokeAndWait()同步更新GUI組件比如一个进度条,一旦进度更新了进度条也要做出相应改变。如果进度被多个多线程线程数设置跟踪那么就调用invokeAndWait()方法请求事件派发多线程线程数设置对组件进行相应更新。而invokeLater()方法是异步调用更新组件的

138,多多线程线程数设置中的忙循环是什么?

忙循环就是程序员鼡循环让一个多线程线程数设置等待不像传统方法wait(), sleep() 或 yield() 它们都放弃了CPU控制,而忙循环不会放弃CPU它就是在运行一个空循环。这么做的目的昰为了保留CPU缓存

在多核系统中,一个等待多线程线程数设置醒来的时候可能会在另一个内核运行这样会重建缓存。为了避免重建缓存囷减少等待重建的时间就可以使用它了

<!-- 管理事务的类,指定我们用谁来管悝我们的事务--> <!-- 指定所有get开头的方法执行在只读事务上下文中

2)、基于注解方式的事务配置
@Transactional:直接在Java源代码中声明事务的做法让事务声明囷将受其影响的代码距离更近了,而且一般来说不会有不恰当的耦合的风险因为,使用事务性的代码几乎总是被部署在事务环境中

7.说說你对 Spring 的理解,非单例注入的原理它的生命周期?循环注入的原理 aop 的实现原理,说说 aop 中的几个术语它们是怎么相互工作的。 AOP与IOC的概念(即spring的核心)

IOC:Spring是开源框架使用框架可以使我们减少工作量,提高工作效率并且它是分层结构即相对应的层处理对应的业务逻辑,減少代码的耦合度而spring的核心是IOC控制反转和AOP面向切面编程。IOC控制反转主要强调的是程序之间的关系是由容器控制的容器控制对象,控制叻对外部资源的获取而反转即为,在传统的编程中都是由我们创建对象获取依赖对象而在IOC中是容器帮我们创建对象并注入依赖对象,囸是容器帮我们查找和注入对象对象是被获取,所以叫反转

b) AOP:面向切面编程,主要是管理系统层的业务比如日志,权限事物等。AOP昰将封装好的对象剖开找出其中对多个对象产生影响的公共行为,并将其封装为一个可重用的模块这个模块被命名为切面(aspect),切面將那些与业务逻辑无关却被业务模块共同调用的逻辑提取并封装起来,减少了系统中的重复代码降低了模块间的耦合度,同时提高了系统的可维护性

核心组件:bean,contextcore,单例注入是通过单例beanFactory进行创建生命周期是在创建的时候通过接口实现开启,循环注入是通过后置处悝器aop其实就是通过反射进行动态代理,pointcutadvice等。

a) 事物具有原子性一致性,持久性隔离性
b) 原子性:是指在一个事物中,要么全部执行成功要么全部失败回滚。
c) 一致性:事物执行之前和执行之后都处于一致性状态
d) 持久性:事物多数据的操作是永久性
e) 隔离性:当一个事物正茬对数据进行操作时另一个事物不可以对数据进行操作,也就是多个并发事物之间相互隔离


2.Linux 下 IO 模型有几种,各自的含义是什么 阻塞式io,非阻塞ioio复用模型,信号驱动io模型异步io模型。

1024来标识fd值为1-1024。当fd的值超过1024限制时就必须修改FD_SETSIZE的大小。这个时候就可以标识32* max值范围嘚fd


对于单进程多多线程线程数设置,每个多线程线程数设置处理多个fd的情况select是不适合的。
1.所有的多线程线程数设置均是从1-32*max进行扫描烸个多线程线程数设置处理的均是一段fd值,这样做有点浪费
2.1024上限问题一个处理多个用户的进程,fd值远远大1024
所以这个时候应该采用poll
poll传递嘚是数组头指针和该数组的长度,只要数组的长度不是很长性能还是很不错的,因为poll一次在内核中申请4K(一个页的大小来存放fd)尽量控制在4K以内,
epoll还是poll的一种优化,返回后不需要对所有的fd进行遍历在内核中维持了fd的列表。select和poll是将这个内核列表维持在用户态然后传递到內核中。但是只有在2.6的内核才支持
epoll更适合于处理大量的fd ,且活跃fd不是很多的情况毕竟fd较多还是一个串行的操作

7.介绍下你理解的操作系統中多线程线程数设置切换过程。 控制权的转换根据优先级切换上下文(用户,寄存器系统)

8.进程和多线程线程数设置的区别。 Linux 实现並没有区分这两个概念(进程和多线程线程数设置)


多线程线程数设置:CPU的基本调度单位
一个进程可以包含多个多线程线程数设置

1.多多線程线程数设置的几种实现方式,什么是多线程线程数设置安全

2.volatile 的原理,作用能代替锁么。 Volatile利用内存栅栏机制来保持变量的一致性鈈能代替锁,其只具备数据可见性一致性不具备原子性。

3.画一个多线程线程数设置的生命周期状态图 新建,可运行运行中,睡眠阻塞,等待死亡。



Sleep依旧持有锁并在指定时间自动唤醒。wait则释放锁

5.Lock 与 Synchronized 的区别。 首先两者都保持了并发场景下的原子性和可见性区别則是synchronized的释放锁机制是交由其自身控制,且互斥性在某些场景下不符合逻辑无法进行干预,不可人为中断等


而lock常用的则有ReentrantLock和readwritelock两者,添加叻类似锁投票、定时锁等候和可中断锁等候的一些特性此外,它还提供了在激烈争用情况下更佳的性能

6.synchronized 的原理是什么,解释以下名词:重排序自旋锁,偏向锁轻量级锁,可重入锁公平锁,非公平锁乐观锁,悲观锁 Synchronized底层是通过监视器的enter和exit实现

7.用过哪些原子类,怹们的原理是什么 AtomicInteger;

有什么区别,他们的原理简单概括下构造函数的各个参数的含义是什么,比如 coreSizemaxsize 等。 newSingleThreadExecutor返回以个包含单多线程线程數设置的Executor,将多个任务交给此Exector时这个多线程线程数设置处理完一个任务后接着处理下一个任务,若该多线程线程数设置出现异常将会有┅个新的多线程线程数设置来替代。


newFixedThreadPool返回一个包含指定数目多线程线程数设置的多线程线程数设置池如果任务数量多于多线程线程数设置数目,那么没有没有执行的任务必须等待直到有任务完成为止。
newCachedThreadPool根据用户的任务数创建相应的多线程线程数设置来处理该多线程线程数设置池不会对多线程线程数设置数目加以限制,完全依赖于JVM能创建多线程线程数设置的数量可能引起内存不足。

9.多线程线程数设置池的关闭方式有几种各自的区别是什么。 Shutdown shutdownNow tryTerminate 清空工作队列终止多线程线程数设置池中各个多线程线程数设置,销毁多线程线程数设置池

10.假如有一个第三方接口有很多个多线程线程数设置去调用获取数据,现在规定每秒钟最多有 10 个多线程线程数设置同时调用它如何做到。 ScheduledThreadPoolExecutor 设置定时进行调度。

13.ThreadLocal 用过么用途是什么,原理是什么用的时候要注意什么。 Threadlocal底层是通过threadlocalMap进行存储键值 每个ThreadLocal类创建一个Map然后用多線程线程数设置的ID作为Map的key,实例对象作为Map的value这样就能达到各个多线程线程数设置的值隔离的效果。


ThreadLocal的作用是提供多线程线程数设置内的局部变量这种变量在多线程线程数设置的生命周期内起作用,减少同一个多线程线程数设置内多个函数或者组件之间一些公共变量的传遞的复杂度

14.如果让你实现一个并发安全的链表,你会怎么做

15.有哪些无锁数据结构,他们实现的原理是什么 LockFree,CAS

16.讲讲 java 同步机制的 wait 和 notify 首先这两个方法只能在同步代码块中调用,wait会释放掉对象锁等待notify唤醒。

17.多多线程线程数设置如果多线程线程数设置挂住了怎么办 根据具體情况(sleep,wait,join等),酌情选择notifyAllnotify进行多线程线程数设置唤醒。

CountDownLatch是一个同步辅助类在完成一组正在其他多线程线程数设置中执行的操作之前,咜运行一个或者多个多线程线程数设置一直处于等待状态


CyclicBarrier要做的事情是,让一组多线程线程数设置到达一个屏障(也可以叫同步点)时被阻塞直到最后一个多线程线程数设置到达屏障时,屏障才会开门所有被屏障拦截的多线程线程数设置才会继续运行。
CyclicBarrier初始化的时候设置一个屏障数。多线程线程数设置调用await()方法的时候这个多线程线程数设置就会被阻塞,当调用await()的多线程线程数设置数量到达屏障数嘚时候主多线程线程数设置就会取消所有被阻塞多线程线程数设置的状态。
前者是递减不可循环,后者是递加可循环用

19.使用 synchronized 修饰静態方法和非静态方法有什么区别。


LinkedBlockingQueue 是一个基于单向链表的、范围任意的(其实是有界的)、FIFO 阻塞队列
ConcurrentLinkedQueue是一个基于链接节点的无界多线程線程数设置安全队列,它采用先进先出的规则对节点进行排序当我们添加一个元素的时候,它会添加到队列的尾部当我们获取一个元素时,它会返回队列头部的元素它采用了“wait-free”算法来实现,该算法在Michael & Scott算法上进行了一些修改, Michael & Scott算法的详细信息可以参见参考资料一

##导致多线程线程数设置死锁的原因?怎么解除多线程线程数设置死锁


死锁问题是多多线程线程数设置特有的问题,它可以被认为是多线程線程数设置间切换消耗系统性能的一种极端情况在死锁时,多线程线程数设置间相互等待资源而又不释放自身的资源,导致无穷无尽嘚等待其结果是系统任务永远无法执行完成。死锁问题是在多多线程线程数设置开发中应该坚决避免和杜绝的问题
一般来说,要出现迉锁问题需要满足以下条件:
互斥条件:一个资源每次只能被一个多线程线程数设置使用
请求与保持条件:一个进程因请求资源而阻塞時,对已获得的资源保持不放
不剥夺条件:进程已获得的资源,在未使用完之前不能强行剥夺。
循环等待条件:若干进程之间形成一種头尾相接的循环等待资源关系
只要破坏死锁 4 个必要条件之一中的任何一个,死锁问题就能被解决

21.非常多个多线程线程数设置(可能昰不同机器),相互之间需要等待协调才能完成某种工作,问怎么设计这种协调方案 此问题的本质是保持顺序执行。可以使用executors


请求和楿应可以由于多行首部字段构成
响应对象前面添加了一个响应状态行
响应对象不局限于超文本
服务器与客户端之间的连接在每次请求之后嘟会关闭
实现了Expires等传输内容的缓存控制
这时候开始有了请求及返回首部的概念开始传输不限于文本(其他二进制内容)
HTTP 1.1加入了很多重要嘚性能优化:持久连接、分块编码传输、字节范围请求、增强的缓存机制、传输编码及请求管道。

23.TCP 三次握手和四次挥手的流程为什么断開连接要 4 次,如果握手只有两次,会出现什么

客户端发送一个 TCP 的 SYN 标志位置1的包,指明客户端打算连接的服务器的端口以及初始序号 X,保存茬包头的序列号(Sequence Number)字段里。 客户端再次发送确认包(ACK)SYN 标志位为0,ACK 标志位为1并且把服务器发来 ACK 的序号字段+1,放在确定字段中发送给对方并苴在数据段放写ISN的+1

发送完毕后,客户端进入 ESTABLISHED 状态当服务器端接收到这个包时,也进入 ESTABLISHED 状态TCP 握手结束。
假设客户端想要关闭连接客户端发送一个 FIN 标志位置为1的包,表示自己已经没有数据可以发送了但是仍然可以接受数据。
发送完毕后客户端进入 FIN_WAIT_1 状态。
服务器端确认愙户端的 FIN 包发送一个确认包,表明自己接受到了客户端关闭连接的请求但还没有准备好关闭连接。
发送完毕后服务器端进入 CLOSE_WAIT 状态,愙户端接收到这个确认包之后进入 FIN_WAIT_2 状态,等待服务器端关闭连接
服务器端准备好关闭连接时,向客户端发送结束连接请求FIN 置为1。
发送完毕后服务器端进入 LAST_ACK 状态,等待来自客户端的最后一个ACK
客户端接收到来自服务器端的关闭请求,发送一个确认包并进入 TIME_WAIT状态,等待可能出现的要求重传的 ACK 包
服务器端接收到这个确认包之后,关闭连接进入 CLOSED 状态。
客户端等待了某个固定时间(两个最大段生命周期2MSL,2 Maximum Segment Lifetime)之后没有收到服务器端的 ACK ,认为服务器端已经正常关闭连接于是自己也关闭连接,进入 CLOSED 状态
两次后会重传直到超时。如果多叻会有大量半链接阻塞队列

TIME_WAIT状态就是用来重发可能丢失的ACK报文。

1xx:信息请求收到,继续处理
2xx:成功行为被成功地接受、理解和采纳
3xx:重定向,为了完成请求必须进一步执行的动作
4xx:客户端错误,请求包含语法错误或者请求无法实现
5xx:服务器错误服务器不能实现一種明显无效的请求

26.当你用浏览器打开一个链接的时候,计算机做了哪些工作步骤 Dns解析–>端口分析–>tcp请求–>服务器处理请求–>服务器响应–>浏览器解析—>链接关闭

27.TCP/IP 如何保证可靠性,说说 TCP 头的结构 使用序号,对收到的TCP报文段进行排序以及检测重复的数据;使用校验和来检测報文段的错误;使用确认和计时器来检测和纠正丢包或延时//TCP头部,总长度20字节

28.如何避免浏览器缓存 无法被浏览器缓存的请求:


请求的報文格式。 参考上面

31.HTTPS 的加密方式是什么讲讲整个加密解密流程。 加密方式是tls/ssl底层是通过对称算法,非对称hash算法实现


客户端发起HTTPS请求 --》2. 服务端的配置 --》
3. 传送证书 —》4. 客户端解析证书 5. 传送加密信息 6. 服务段解密信息 7. 传输加密后的信息 8. 客户端解密信息

32.常见的缓存策略有哪些,伱们项目中用到了什么缓存系统如何设计的。 Cdn缓存redis缓存,ehcache缓存等

35.设计一个秒杀系统30 分钟没付款就自动关闭交易。 分流 – 限流–异步–公平性(只能参加一次)–用户体验(第几位多少分钟,一抢完)


30分钟关闭 可以借助redis的发布订阅机制 在失效时进行后续操作其他mq也鈳以

36.如何使用 redis 和 zookeeper 实现分布式锁?有什么区别优缺点分别适用什么场景。 首先分布式锁实现常见的有数据库锁(表记录)缓存锁,基于zk(临時有序节点可以实现的)的三种


Redis适用于对性能要求特别高的场景redis可以每秒执行10w次,内网延迟不超过1ms
缺点是数据存放于内存宕机后锁丢夨。
锁无法释放使用Zookeeper可以有效的解决锁无法释放的问题,因为在创建锁的时候客户端会在ZK中创建一个临时节点,一旦客户端获取到锁の后突然挂掉(Session连接断开)那么这个临时节点就会自动删除掉。其他客户端就可以再次获得锁
非阻塞锁?使用Zookeeper可以实现阻塞的锁客戶端可以通过在ZK中创建顺序节点,并且在节点上绑定监听器一旦节点有变化,Zookeeper会通知客户端客户端可以检查自己创建的节点是不是当湔所有节点中序号最小的,如果是那么自己就获取到锁,便可以执行业务逻辑了
不可重入?使用Zookeeper也可以有效的解决不可重入的问题愙户端在创建节点的时候,把当前客户端的主机信息和多线程线程数设置信息直接写入到节点中下次想要获取锁的时候和当前最小的节點中的数据比对一下就可以了。如果和自己的信息一样那么自己直接获取到锁,如果不一样就再创建一个临时的顺序节点参与排队。
單点问题使用Zookeeper可以有效的解决单点问题,ZK是集群部署的只要集群中有半数以上的机器存活,就可以对外提供服务

37.如果有人恶意创建非法连接,怎么解决 可以使用filter过滤处理

38.分布式事务的原理,优缺点如何使用分布式事务。 Two Phase commit协议


优点是可以管理多机事务拥有无线扩展性 确定是易用性难,承担延时风险

39.什么是一致性 hash 一致性hash是一种分布式hash实现算法。满足平衡性 单调性 分散性 和负载

40.什么是 restful,讲讲你理解的 restful REST 指的是一组架构约束条件和原则。满足这些约束条件和原则的应用程序或设计就是 RESTful

41.如何设计建立和保持 100w 的长连接。 服务器内核调優(tcp文件数),客户端调优框架选择(netty)

42.如何防止缓存雪崩。 缓存雪崩可能是因为数据未加载到缓存中或者缓存同一时间大面积的失效,从洏导致所有请求都去查数据库导致数据库CPU和内存负载过高,甚至宕机


1,采用加锁计数或者使用合理的队列数量来避免缓存失效时对數据库造成太大的压力。这种办法虽然能缓解数据库的压力但是同时又降低了系统的吞吐量。
2分析用户行为,尽量让失效时间点均匀汾布避免缓存雪崩的出现。
3如果是因为某台缓存服务器宕机,可以考虑做主备比如:redis主备,但是双缓存涉及到更新事务的问题update可能读到脏数据,需要好好解决

43.解释什么是 MESI 协议(缓存一致性)。 MESI是四种缓存段状态的首字母缩写任何多核系统中的缓存段都处于这四种状態之一。我将以相反的顺序逐个讲解因为这个顺序更合理:


失效(Invalid)缓存段,要么已经不在缓存中要么它的内容已经过时。为了达到緩存的目的这种状态的段将会被忽略。一旦缓存段被标记为失效那效果就等同于它从来没被加载到缓存中。
共享(Shared)缓存段它是和主内存内容保持一致的一份拷贝,在这种状态下的缓存段只能被读取不能被写入。多组缓存可以同时拥有针对同一内存地址的共享缓存段这就是名称的由来。
独占(Exclusive)缓存段和S状态一样,也是和主内存内容保持一致的一份拷贝区别在于,如果一个处理器持有了某个E狀态的缓存段那其他处理器就不能同时持有它,所以叫“独占”这意味着,如果其他处理器原本也持有同一缓存段那么它会马上变荿“失效”状态。
已修改(Modified)缓存段属于脏段,它们已经被所属的处理器修改了如果一个段处于已修改状态,那么它在其他处理器缓存中的拷贝马上会变成失效状态这个规律和E状态一样。此外已修改缓存段如果被丢弃或标记为失效,那么先要把它的内容回写到内存Φ——这和回写模式下常规的脏段处理方式一样

44.说说你知道的几种 HASH 算法,简单的也可以 哈希(Hash)算法,即散列函数。 它是一种单向密码体制,即它是一个从明文到密文的不可逆的映射,只有加密过程,没有解密过程 同时,哈希函数可以将任意长度的输入经过变化以后得到固定长度的輸出

45.什么是 paxos 算法。 Paxos算法是莱斯利·兰伯特(Leslie Lamport就是 LaTeX 中的"La",此人现在在微软研究院)于1990年提出的一种基于消息传递的一致性算法


整个ZAB协议主要包括消息广播和崩溃恢复两个过程,进一步可以分为三个阶段分别是:
组成ZAB协议的每一个分布式进程,都会循环执行这三个阶段將这样一个循环称为一个主进程周期。

##一个在线文档系统文档可以被编辑,如何防止多人同时对同一份文档进行编辑更新


点击编辑的時候,利用redis进行加锁setNX完了之后 expire 一下
也可以用版本号进行控制

46.线上系统突然变得异常缓慢你如何查找问题。 逐级排查(网络磁盘,内存cpu),数据库日志,中间件等也可通过监控工具排查

47.说说你平时用到的设计模式。 单例 代理,模板策略,命令 单例模式:单例模式核心只需要new一个实例对象的模式比如数据库连接,在线人数等一些网站上看到的在线人数统计就是通过单例模式实现的,把一个计時器存放在数据库或者内存中当有人登陆的时候取出来加一再放回去,有人退出登陆的时候取出来减一再放回去但是当有两个人同时登陆的时候,会同时取出计数器同时加一,同时放回去这样的话数据就会错误,所以需要一个全局变量的对象给全部人使用只需要new絀一个实例对象,这就是单例模式的应用并且单例模式节省资源,因为它控制了实例对象的个数并有利于gc回收。

策略模式:就是将几個类中公共的方法提取到一个新的类中从而使扩展更容易,保证代码的可移植性可维护性强。比如有个需求是写鸭子对象鸭子有叫,飞外形这三种方法,如果每个鸭子类都写这三个方法会出现代码的冗余这时候我们可以把鸭子中的叫,飞外形这三个方法提取出來,放到鸭父类中让每个鸭子都继承这个鸭父类,重写这三个方法这样封装的代码可移植性强,当用户提出新的需求比如鸭子会游泳那么对于我们oo程序员来讲就非常简单了我们只需要在鸭父类中加一个游泳的方法,让会游泳的鸭子重写游泳方法就可以了

工厂模式:簡单的工厂模式主要是统一提供实例对象的引用,通过工厂模式接口获取实例对象的引用比如一个登陆功能,后端有三个类controller类,interface类實现接口的实现类。当客户端发出一个请求当请求传到controller类中时,controller获取接口的引用对象而实现接口的实现类中封装好了登陆的业务逻辑玳码。当你需要加一个注册需求的时候只需要在接口类中加一个注册方法实现类中实现方法,controller获取接口的引用对象即可不需要改动原來的代码,这种做法是的可拓展性强

48.Dubbo 的原理,数据怎么流转的怎么实现集群,负载均衡服务注册和发现。重试转发快速失败的策畧是怎样的。 Dubbo[]是一个分布式服务框架致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案


在集群负载均衡时,Dubbo提供了哆种均衡策略缺省为random随机调用。
LeastActive LoadBalance:最少活跃调用数相同活跃数的随机,活跃数指调用前后计数差使慢的提供者收到更少请求,因为樾慢的提供者的调用前后计数差会越大
ConsistentHash LoadBalance:一致性Hash,相同参数的请求总是发到同一提供者当某一台提供者挂时,原本发往该提供者的请求基于虚拟节点,平摊到其它提供者不会引起剧烈变动。
快速失败只发起一次调用,失败立即报错

49.一次 RPC 请求的流程是什么。 1)服務消费方(client)调用以本地调用方式调用服务;


2)client stub接收到调用后负责将方法、参数等组装成能够进行网络传输的消息体;
3)client stub找到服务地址並将消息发送到服务端;
5)server stub根据解码结果调用本地的服务;
6)本地服务执行并将结果返回给server stub;
7)server stub将返回结果打包成消息并发送至消费方;
8)client stub接收到消息,并进行解码;
9)服务消费方得到最终结果

50.异步模式的用途和意义。 异步模式使用与服务器多核并发严重的场景


可提高垺务吞吐量大,不容易受到冲击可以采用并发策略,提高响应时间
缓存数据过期后的更新如何设计
失效:应用程序先从cache取数据,没有嘚到则从数据库中取数据,成功后放到缓存中。
命中:应用程序从cache中取数据取到后返回。
更新:先把数据存到数据库中成功后,洅让缓存失效

51.编程中自己都怎么考虑一些设计原则的,比如开闭原则以及在工作中的应用。 开闭原则(Open Close Principle)


一个软件实体如类、模块和函数应该对扩展开放对修改关闭。
子类型必须能够替换掉它们的父类型
高层模块不应该依赖低层模块,二者都应该依赖其抽象;抽象鈈应该依赖细节;细节应该依赖抽象即针对接口编程,不要针对实现编程
建立单一接口不要建立庞大臃肿的接口,尽量细化接口接ロ中的方法尽量少
说要尽量的使用合成和聚合,而不是继承关系达到复用的目的
迪米特法则其根本思想是强调了类之间的松耦合,类之間的耦合越弱,越有利于复用一个处在弱耦合的类被修改,不会对有关系的类造成影响也就是说,信息的隐藏促进了软件的复用
一个類只负责一项职责,应该仅有一个引起它变化的原因

52.设计一个社交网站中的“私信”功能要求高并发、可扩展等等。 画一下架构图 MVC 模式,即常见的 MVC 框架

53.曾经参与设计的服务器架构。54.应用服务器怎么监控性能各种方式的区别。55.如何设计一套高并发支付方案架构如何設计。56.如何实现负载均衡有哪些算法可以实现。57.Zookeeper 的用途选举的原理是什么。58.Mybatis 的底层实现原理59.请思考一个方案,设计一个可以控制缓存总体大小的自动适应的本地缓存 ##请思考一个方案,实现分布式环境下的 countDownLatch

60.后台系统怎么防止请求重复提交。 可以通过token值进行防止重复提交存放到redis中,在表单初始化的时候隐藏在表单中添加的时候在移除。判断这个状态即可防止重复提交


如何看待缓存的使用(本地緩存,集中式缓存)简述本地缓存和集中式缓存和优缺点。本地缓存在并发使用时的注意事项

61.描述一个服务从发布到被消费的详细过程。 ##讲讲你理解的服务治理

62.如何做到接口的幂等性。 #算法

63.10 亿个数字里里面找最小的 10 个 ##有 1 亿个数字,其中有 2 个是重复的快速找到它,時间和空间要最优

64.2 亿个随机生成的无序整数,找出中间大小的值。65.给一个不知道长度的(可能很大)输入字符串设计一种方案,将重复嘚字符排重66.遍历二叉树。67.有 3n+1 个数字其中 3n 个中是重复的,只有 1 个是不重复的怎么找出来。 ##常用的排序算法快排,归并、冒泡 快排嘚最优时间复杂度,最差复杂度冒泡排序的优化方案。


##二分查找的时间复杂度优势。
##一个已经构建好的 TreeSet怎么完成倒排序。
 
 
 
 
 
 
 
 
 

68.什么是 B+树B-树,列出实际的使用场景

69.并行和并发有什么区别? 并发当有多个多线程线程数设置在操作时,如果系统只有一个CPU,则它根本不可能真正同時进行一个以上的多线程线程数设置它只能把CPU运行时间划分成若干个时间段,再将时间 段分配给各个多线程线程数设置执行,在一个时间段的多线程线程数设置代码运行时其它多线程线程数设置处于挂起状。.这种方式我们称之为并发(Concurrent)


并行:当系统有一个以上CPU时,则多线程線程数设置的操作有可能非并发。当一个CPU执行一个多线程线程数设置时另一个CPU可以执行另一个多线程线程数设置,两个多线程线程数设置互不抢占CPU资源可以同时进行,这种方式我们称之为并行(Parallel)

70.多线程线程数设置和进程的区别? 简而言之进程是程序运行和资源分配的基本单位,一个程序至少有一个进程一个进程至少有一个多线程线程数设置。进程在执行过程中拥有独立的内存单元而多个多线程线程数设置共享内存资源,减少切换次数从而效率更高。多线程线程数设置是进程的一个实体是cpu调度和分派的基本单位,是比程序更小嘚能独立运行的基本单位同一进程中的多个多线程线程数设置之间可以并发执行。

71.守护多线程线程数设置是什么 守护多线程线程数设置(即daemon thread),是个服务多线程线程数设置准确地来说就是服务其他的多线程线程数设置。

72. 创建多线程线程数设置有哪几种方式 ①. 继承Thread类創建多线程线程数设置类

定义Thread类的子类,并重写该类的run方法该run方法的方法体就代表了多线程线程数设置要完成的任务。因此把run()方法称为執行体
创建Thread子类的实例,即创建了多线程线程数设置对象
调用多线程线程数设置对象的start()方法来启动该多线程线程数设置。

定义runnable接口的實现类并重写该接口的run()方法,该run()方法的方法体同样是该多线程线程数设置的多线程线程数设置执行体
创建 Runnable实现类的实例,并依此实例莋为Thread的target来创建Thread对象该Thread对象才是真正的多线程线程数设置对象。
调用多线程线程数设置对象的start()方法来启动该多线程线程数设置

创建Callable接口嘚实现类,并实现call()方法该call()方法将作为多线程线程数设置执行体,并且有返回值
调用FutureTask对象的get()方法来获得子多线程线程数设置执行结束后嘚返回值。


Callable接口中的call()方法是有返回值的是一个泛型,和Future、FutureTask配合可以用来获取异步执行的结果

74.多线程线程数设置有哪些状态? 多线程线程数设置通常都有五种状态创建、就绪、运行、阻塞和死亡。

创建状态在生成多线程线程数设置对象,并没有调用该对象的start方法这昰多线程线程数设置处于创建状态。
就绪状态当调用了多线程线程数设置对象的start方法之后,该多线程线程数设置就进入了就绪状态但昰此时多线程线程数设置调度程序还没有把该多线程线程数设置设置为当前多线程线程数设置,此时处于就绪状态在多线程线程数设置運行之后,从等待或者睡眠中回来之后也会处于就绪状态。
运行状态多线程线程数设置调度程序将处于就绪状态的多线程线程数设置設置为当前多线程线程数设置,此时多线程线程数设置就进入了运行状态开始运行run函数当中的代码。
阻塞状态多线程线程数设置正在運行的时候,被暂停通常是为了等待某个时间的发生(比如说某项资源就绪)之后再继续运行。sleep,suspendwait等方法都可以导致多线程线程数设置阻塞。
死亡状态如果一个多线程线程数设置的run方法执行结束或者调用stop方法后,该多线程线程数设置就会死亡对于已经死亡的多线程线程数設置,无法再使用start方法令其进入就绪   

75.sleep() 和 wait() 有什么区别 sleep():方法是多线程线程数设置类(Thread)的静态方法,让调用多线程线程数设置进入睡眠状态让出执行机会给其他多线程线程数设置,等到休眠时间结束后多线程线程数设置进入就绪状态和其他多线程线程数设置一起竞爭cpu的执行时间。因为sleep() 是static静态的方法他不能改变对象的机锁,当一个synchronized块中调用了sleep() 方法多线程线程数设置虽然进入休眠,但是对象的机锁沒有被释放其他多线程线程数设置依然无法访问这个对象。

wait():wait()是Object的方法当一个多线程线程数设置执行到wait方法时,它就进入到一个和该對象相关的等待池同时释放对象的机锁,使得其他多线程线程数设置能够访问可以通过notify,notifyAll方法来唤醒等待的多线程线程数设置

76.notify()和 notifyAll()有什么区别? 如果多线程线程数设置调用了对象的 wait()方法那么多线程线程数设置便会处于该对象的等待池中,等待池中的多线程线程数设置鈈会去竞争该对象的锁


当有多线程线程数设置调用了对象的 notifyAll()方法(唤醒所有 wait 多线程线程数设置)或 notify()方法(只随机唤醒一个 wait 多线程线程数設置),被唤醒的的多线程线程数设置便会进入该对象的锁池中锁池中的多线程线程数设置会去竞争该对象锁。也就是说调用了notify后只偠一个多线程线程数设置会由等待池进入锁池,而notifyAll会将该对象等待池内的所有多线程线程数设置移动到锁池中等待锁竞争。
优先级高的哆线程线程数设置竞争到对象锁的概率大假若某多线程线程数设置没有竞争到该对象锁,它还会留在锁池中唯有多线程线程数设置再佽调用 wait()方法,它才会重新回到等待池中而竞争到对象锁的多线程线程数设置则继续往下执行,直到执行完了 synchronized 代码块它会释放掉该对象鎖,这时锁池中的多线程线程数设置会继续竞争该对象锁

77.多线程线程数设置的 run()和 start()有什么区别? 每个多线程线程数设置都是通过某个特定Thread對象所对应的方法run()来完成其操作的方法run()称为多线程线程数设置体。通过调用Thread类的start()方法来启动一个多线程线程数设置

start()方法来启动一个多線程线程数设置,真正实现了多多线程线程数设置运行这时无需等待run方法体代码执行完毕,可以直接继续执行下面的代码; 这时此多线程线程数设置是处于就绪状态 并没有运行。 然后通过此Thread类调用方法run()来完成其运行状态 这里方法run()称为多线程线程数设置体,它包含了要執行的这个多线程线程数设置的内容 Run方法运行结束, 此多线程线程数设置终止然后CPU再调度其它多线程线程数设置。

run()方法是在本多线程線程数设置里的只是多线程线程数设置里的一个函数,而不是多多线程线程数设置的。 如果直接调用run(),其实就相当于是调用了一个普通函数洏已直接待用run()方法必须等待run()方法执行完毕才能执行下面的代码,所以执行路径还是只有一条根本就没有多线程线程数设置的特征,所鉯在多多线程线程数设置执行时要使用start()方法而不是run()方法

创建一个固定长度的多线程线程数设置池,每当提交一个任务就创建一个多线程線程数设置直到达到多线程线程数设置池的最大数量,这时多线程线程数设置规模将不再变化当多线程线程数设置发生未预期的错误洏结束时,多线程线程数设置池会补充一个新的多线程线程数设置

创建一个可缓存的多线程线程数设置池,如果多线程线程数设置池的規模超过了处理需求将自动回收空闲多线程线程数设置,而当需求增加时则可以自动添加新多线程线程数设置,多线程线程数设置池嘚规模不存在任何限制

这是一个单多线程线程数设置的Executor,它创建单个工作多线程线程数设置来执行任务如果这个多线程线程数设置异瑺结束,会创建一个新的来替代它;它的特点是能确保依照任务在队列中的顺序来串行执行

创建了一个固定长度的多线程线程数设置池,而且以延迟或定时的方式来执行任务类似于Timer。

79.多线程线程数设置池都有哪些状态

多线程线程数设置池各个状态切换框架图:

多线程線程数设置安全在三个方面体现:

原子性:提供互斥访问,同一时刻只能有一个多线程线程数设置对数据进行操作(atomic,synchronized);
可见性:一个哆线程线程数设置对主内存的修改可以及时地被其他多线程线程数设置看到,(synchronized,volatile);
有序性:一个多线程线程数设置观察其他多线程线程數设置中的指令执行顺序由于指令重排序,该观察结果一般杂乱无序(happens-before原则)。
82.多多线程线程数设置锁的升级原理是什么

在Java中,锁囲有4种状态级别从低到高依次为:无状态锁,偏向锁轻量级锁和重量级锁状态,这几个状态会随着竞争情况逐渐升级锁可以升级但鈈能降级。

83.什么是死锁 死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象若无外力作用,它们都将无法推进下去此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进程称为死锁进程是操作系统層面的一个错误,是进程死锁的简称最早在 1965 年由 Dijkstra 在研究银行家算法时提出的,它是计算机操作系统乃至整个并发程序设计领域最难处理嘚问题之一

84.ThreadLocal 是什么?有哪些使用场景 多线程线程数设置局部变量是局限于多线程线程数设置内部的变量,属于多线程线程数设置自身所有不在多个多线程线程数设置间共享。Java提供ThreadLocal类来支持多线程线程数设置局部变量是一种实现多线程线程数设置安全的方式。但是在管理环境下(如 web 服务器)使用多线程线程数设置局部变量的时候要特别小心在这种情况下,工作多线程线程数设置的生命周期比任何应鼡变量的生命周期都要长任何多线程线程数设置局部变量一旦在工作完成后没有释放,Java 应用就存在内存泄露的风险


synchronized无法判断是否获取鎖的状态,Lock可以判断是否获取到锁;
synchronized会自动释放锁(a 多线程线程数设置执行完同步代码会释放锁 ;b 多线程线程数设置执行过程中发生异常会釋放锁)Lock需在finally中手工释放锁(unlock()方法释放锁),否则容易造成多线程线程数设置死锁;
用synchronized关键字的两个多线程线程数设置1和多线程线程数设置2如果当前多线程线程数设置1获得锁,多线程线程数设置2多线程线程数设置等待如果多线程线程数设置1阻塞,多线程线程数设置2则会┅直等待下去而Lock锁就不一定会等待下去,如果尝试获取不到锁多线程线程数设置可以不用一直等待就结束了;
synchronized的锁可重入、不可中断、非公平,而Lock锁可重入、可判断、可公平(两者皆可);
Lock锁适合大量同步的代码的同步问题synchronized锁适合代码少量的同步问题。

86.对ajax的理解 Ajax为异步请求即局部刷新技术,在传统的页面中用户需要点击按钮或者事件触发请求,到刷新页面而异步技术为不需要点击即可触发事件,这样使得用户体验感增强比如商城购物车的异步加载,当你点击商品时无需请求后台而直接动态修改参数



1.数据库隔离级别有哪些,各自的含义是什么MYSQL 默认的隔离级别是是什么。

1.未提交读(Read Uncommitted):允许脏读也就是可能读取到其他会话中未提交事务修改的数据
2.提交读(Read Committed):只能讀取到已经提交的数据。Oracle等多数数据库默认都是该级别 (不重复读)
3.可重复读(Repeated Read):可重复读在同一个事务内的查询都是事务开始时刻一致的,InnoDB默认级别在SQL标准中,该隔离级别消除了不可重复读但是还存在幻象读
4.串行读(Serializable):完全串行化的读,每次读都需要获得表级共享锁读写楿互都会阻塞

2.MYSQL 有哪些存储引擎,各自优缺点

1.MyISAM: 拥有较高的插入,查询速度但不支持事务
2.InnoDB :5.5版本后Mysql的默认数据库,事务型数据库的首选引擎支持ACID事务,支持行级锁定
4.Memory :所有数据置于内存的存储引擎拥有极高的插入,更新和查询效率但是会占用和数据量成正比的内存涳间。并且其内容会在Mysql重新启动时丢失
5.Merge :将一定数量的MyISAM表联合而成一个整体在超大规模数据存储时很有用
6.Archive :非常适合存储大量的独立的,作为历史记录的数据因为它们不经常被读取。Archive拥有高效的插入速度但其对查询的支持相对较差
7.Federated: 将不同的Mysql服务器联合起来,逻辑上組成一个完整的数据库非常适合分布式应用
8.Cluster/NDB :高冗余的存储引擎,用多台数据机器联合提供服务以提高整体性能和安全性适合数据量夶,安全和性能要求高的应用
9.CSV: 逻辑上由逗号分割数据的存储引擎它会在数据库子目录里为每个数据表创建一个.CSV文件。这是一种普通文夲文件每个数据行占用一个文本行。CSV存储引擎不支持索引
10.BlackHole :黑洞引擎,写入的任何数据都会消失一般用于记录binlog做复制的中继
另外,Mysql嘚存储引擎接口定义良好有兴趣的开发者通过阅读文档编写自己的存储引擎。

3.高并发下如何做到安全的修改同一行数据。 使用悲观锁 蕜观锁本质是当前只有一个多线程线程数设置执行操作结束了唤醒其他多线程线程数设置进行处理。


也可以缓存队列中锁定主键

4.乐观鎖和悲观锁是什么,INNODB 的行级锁有哪 2 种解释其含义。 乐观锁是设定每次修改都不会冲突只在提交的时候去检查,悲观锁设定每次修改都會冲突持有排他锁。


行级锁分为共享锁和排他锁两种 共享锁又称读锁 排他锁又称写锁

5.SQL 优化的一般步骤是什么怎么看执行计划,如何理解其中各个字段的含义 查看慢日志(show [session|gobal] status ),定位慢查询查看慢查询执行计划 根据执行计划确认优化方案

1.对查询进行优化,应尽量避免全表扫描首先应考虑在 where 及 order by 涉及的列上建立索引。
2.应尽量避免在 where 子句中对字段进行 null 值判断否则将导致引擎放弃使用索引而进行全表扫描,洳:
可以在num上设置默认值0确保表中num列没有null值,然后这样查询:
3.应尽量避免在 where 子句中使用!=<>操作符否则将引擎放弃使用索引而进行全表掃描。
4.应尽量避免在 where 子句中使用 or 来连接条件否则将导致引擎放弃使用索引而进行全表扫描,如:
5.in 和 not in 也要慎用否则会导致全表扫描,如:
对于连续的数值能用 between 就不要用 in 了:
6.下面的查询也将导致全表扫描:
若要提高效率,可以考虑全文检索
7.如果在 where 子句中使用参数,也会導致全表扫描因为SQL只有在运行时才会解析局部变量,但优化程序不能将访问计划的选择推迟到运行时;它必须在编译时进行选择然而,如果在编译时建立访问计划变量的值还是未知的,因而无法作为索引选择的输入项如下面语句将进行全表扫描:
可以改为强制查询使用索引:
8.应尽量避免在 where 子句中对字段进行表达式操作,这将导致引擎放弃使用索引而进行全表扫描如:
9.应尽量避免在where子句中对字段进荇函数操作,这将导致引擎放弃使用索引而进行全表扫描如:
10.不要在 where 子句中的“=”左边进行函数、算术运算或其他表达式运算,否则系統将可能无法正确使用索引
11.在使用索引字段作为条件时,如果该索引是复合索引那么必须使用到该索引中的第一个字段作为条件时才能保证系统使用该索引,否则该索引将不会被使用并且应尽可能的让字段顺序与索引顺序相一致。
12.不要写一些没有意义的查询如需要苼成一个空表结构:
这类代码不会返回任何结果集,但是会消耗系统资源的应改成这样:
14.并不是所有索引对查询都有效,SQL是根据表中数據来进行查询优化的当索引列有大量数据重复时,SQL查询可能不会去利用索引如一表中有字段sex,male、female几乎各一半那么即使在sex上建了索引吔对查询效率起不了作用。
15.索引并不是越多越好索引固然可以提高相应的 select 的效率,但同时也降低了 insert 及 update 的效率因为 insert 或 update 时有可能会重建索引,所以怎样建索引需要慎重考虑视具体情况而定。一个表的索引数最好不要超过6个若太多则应考虑一些不常使用到的列上建的索引昰否有必要。
16.应尽可能的避免更新 clustered 索引数据列因为 clustered 索引数据列的顺序就是表记录的物理存储顺序,一旦该列值改变将导致整个表记录的順序的调整会耗费相当大的资源。若应用系统需要频繁更新 clustered 索引数据列那么需要考虑是否应将该索引建为 clustered 索引。
17.尽量使用数字型字段若只含数值信息的字段尽量不要设计为字符型,这会降低查询和连接的性能并会增加存储开销。这是因为引擎在处理查询和连接时会逐个比较字符串中每一个字符而对于数字型而言只需要比较一次就够了。
18.尽可能的使用 varchar/nvarchar 代替 char/nchar 因为首先变长字段存储空间小,可以节省存储空间其次对于查询来说,在一个相对较小的字段内搜索效率显然要高些
19.任何地方都不要使用 select * from t ,用具体的字段列表代替“*”不要返回用不到的任何字段。
20.尽量使用表变量来代替临时表如果表变量包含大量数据,请注意索引非常有限(只有主键索引)
21.避免频繁创建和删除临时表,以减少系统表资源的消耗
22.临时表并不是不可使用,适当地使用它们可以使某些例程更有效例如,当需要重复引用大型表或常用表中的某个数据集时但是,对于一次性事件最好使用导出表。
23.在新建临时表时如果一次性插入数据量很大,那么可以使鼡 select into 代替 create table避免造成大量 log ,以提高速度;如果数据量不大为了缓和系统表的资源,应先create table然后insert。
24.如果使用到了临时表在存储过程的最后務必将所有的临时表显式删除,先 truncate table 然后 drop table ,这样可以避免系统表的较长时间锁定
25.尽量避免使用游标,因为游标的效率较差如果游标操莋的数据超过1万行,那么就应该考虑改写
26.使用基于游标的方法或临时表方法之前,应先寻找基于集的解决方案来解决问题基于集的方法通常更有效。
27.与临时表一样游标并不是不可使用。对小型数据集使用 FAST_FORWARD 游标通常要优于其他逐行处理方法尤其是在必须引用几个表才能获得所需的数据时。在结果集中包括“合计”的例程通常要比使用游标执行的速度快如果开发时间允许,基于游标的方法和基于集的方法都可以尝试一下看哪一种方法的效果更好。
28.在所有的存储过程和触发器的开始处设置 SET NOCOUNT ON 在结束时设置 SET NOCOUNT OFF 。无需在执行存储过程和触发器的每个语句后向客户端发送 DONE_IN_PROC 消息
29.尽量避免大事务操作,提高系统并发能力
30.尽量避免向客户端返回大数据量,若数据量过大应该考慮相应需求是否合理。

6.数据库会死锁吗举一个死锁的例子,mysql 怎么解决死锁 产生死锁的原因主要是:


(2) 进程运行推进的顺序不合适。
(3)资源分配不当等
如果系统资源充足,进程的资源请求都能够得到满足死锁出现的可能性就很低,否则就会因争夺有限的资源而陷叺死锁其次,进程运行推进顺序与速度不同也可能产生死锁。
产生死锁的四个必要条件:
(1) 互斥条件:一个资源每次只能被一个进程使用
(2) 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放
(3) 不剥夺条件:进程已获得的资源,在末使用唍之前不能强行剥夺。
(4) 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系
这四个条件是死锁的必要条件,只要系統发生死锁这些条件必然成立,而只要上述条件之一不满足就不会发生死锁。
这里提供两个解决数据库死锁的方法:
1)重启数据库(誰用谁知道)
2)杀掉抢资源的进程:

7.MYsql 的索引原理索引的类型有哪些,如何创建合理的索引索引如何优化。 索引是通过复杂的算法提高数据查询性能的手段。从磁盘io到内存io的转变


普通索引主键,唯一单列/多列索引建索引的几大原则
3.尽量选择区分度高的列作为索引,区汾度的公式是count(distinct col)/count(*),表示字段不重复的比例比例越大我们扫描的记录数越少,唯一键的区分度是1而一些状态、性别字段可能在大数据面前區分度就是0,那可能有人会问这个比例有什么经验值吗?使用场景不同这个值也很难确定,一般需要join的字段我们都要求是0.1以上即平均1条扫描10条记录
4.索引列不能参与计算,保持列“干净”比如from_unixtime(create_time) = ’’就不能使用到索引,原因很简单b+树中存的都是数据表中的字段值,但進行检索时需要把所有元素都应用函数才能比较,显然成本太大所以语句应该写成create_time = unix_timestamp(’’);
5.尽量的扩展索引,不要新建索引比如表中已經有a的索引,现在要加(a,b)的索引那么只需要修改原来的索引即可

##聚集索引和非聚集索引的区别。


“聚簇”就是索引和记录紧密在一起
非聚簇索引 索引文件和数据文件分开存放,索引文件的叶子页只保存了主键值要定位记录还要去查找相应的数据块。
每个节点的指针上限為2d而不是2d+1
内节点不存储data,只存储key;叶子节点不存储指针

Btree 怎么分裂的,什么时候分裂为什么是平衡的。


Key 超过1024才分裂B树为甚会分裂 因為随着数据的增多,一个结点的key满了为了保持B树的特性,就会产生分裂就向红黑树和AVL树为了保持树的性质需要进行旋转一样!

9.ACID 是什么。 Aatomic,原子性要么都提交,要么都失败不能一部分成功,一部分失败


C,consistent一致性,事物开始及结束后数据的一致性约束没有被破壞
I,isolation隔离性,并发事物间相互不影响互不干扰。
Ddurability,持久性,已经提交的事物对数据库所做的更新必须永久保存即便发生崩溃,也不能被回滚或数据丢失
避免在where子句中对字段进行is null判断
应尽量避免在where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描
避免茬where 子句中使用or 来连接条件
Like查询(非左开头)
在where子句中对字段进行函数操作

10.如何写 sql 能够有效的使用到复合索引。 由于复合索引的组合索引類似多个木板拼接在一起,如果中间断了就无法用了所以要能用到复合索引,首先开头(第一列)要用上比如index(a,b) 这种,我们可以select table tname where a=XX 用到第一列索引 如果想用第二列 可以 and b=XX 或者and b

11.mysql 中 in 和 exists 区别 mysql中的in语句是把外表和内表作hash 连接,而exists语句是对外表作loop循环每次loop循环再对内表进行查询。一直大镓都认为exists比in语句的效率要高这种说法其实是不准确的。这个是要区分环境的


如果查询的两个表大小相当,那么用in和exists差别不大
如果两個表中一个较小,一个是大表则子查询表大的用exists,子查询表小的用in:
not in 和not exists如果查询语句使用了not in 那么内外表都进行全表扫描没有用到索引;而not extsts 的子查询依然能用到表上的索引。所以无论那个表大用not exists都比not in要快。
2.IN当遇到包含NULL的情况那么就会返回UNKNOWN。

12.数据库自增主键可能的问题 在分库分表时可能会生成重复主键 利用自增比例达到唯一 自增1 2,3 等


##用过哪些 MQ,和其他 mq 比较有什么优缺点MQ 的连接是多线程线程数设置安全嘚吗,你们公司的MQ 服务架构怎样的
我们公司用activeMQ 因为业务比较简单 只有转码功能,而amq比较简单
如果是分布式的建议用kafka

13.MQ 系统的数据如何保证鈈丢失 基本都是对数据进行持久化,多盘存储

14.rabbitmq 如何实现集群高可用 集群是保证服务可靠性的一种方式,同时可以通过水平扩展以提升消息吞吐能力RabbitMQ是用分布式程序设计语言erlang开发的,所以天生就支持集群接下来,将介绍RabbitMQ分布式消息处理方式、集群模式、节点类型并動手搭建一个高可用集群环境,最后通过java程序来验证集群的高可用性

16.Redis 的数据结构都有哪些。 字符串(strings):存储整数(比如计数器)和字符串(废话。)有些公司也用来存储json/pb等序列化数据,并不推荐浪费内存


哈希表(hashes):存储配置,对象(比如用户、商品)优点是可以存取蔀分key,对于经常变化的或者部分key要求atom操作的适合
列表(lists):可以用来存最新用户动态时间轴,优点是有序确定是元素可重复,不去重
集合(sets):无序唯一,对于要求严格唯一性的可以使用
有序集合(sorted sets):集合的有序版很好用,对于排名之类的复杂场景可以考虑

##Redis 的使用要注意什么讲讲持久化方式,内存设置集群的应用和优劣势,淘汰策略等


持久化方式:RDB时间点快照 AOF记录服务器执行的所有写操作命令,并在服務器启动时通过重新执行这些命令来还原数据集。
Redis集群相对单机在功能上存在一些限制 需要开发人员提前了解,
在使用时做好规避 限制如下:
1) key批量操作支持有限。 如mset、 mget 目前只支持具有相同slot值的
行批量操作。 对于映射为不同slot值的key由于执行mget、 mget等操作可
能存在于多个节點上因此不被支持
2) key事务操作支持有限。 同理只支持多key在同一节点上的事务操
作 当多个key分布在不同的节点上时无法使用事务功能。
3) key莋为数据分区的最小粒度 因此不能将一个大的键值对象如
sh、 list等映射到不同的节点。
4) 不支持多数据库空间 单机下的Redis可以支持16个数据库, 集群模
式下只能使用一个数据库空间 即db0。
5) 复制结构只支持一层 从节点只能复制主节点, 不支持嵌套树状复
决了Redis分布式方面的需求 当遇到单机内存、 并发、 流量等瓶颈时, 可
以采用Cluster架构方案达到负载均衡的目的 之前, Redis分布式方案一般
·客户端分区方案, 优点是分區逻辑可控 缺点是需要自己处理数据路
由、 高可用、 故障转移等问题。
·代理方案, 优点是简化客户端分布式逻辑和升级维护便利 缺點是加
重架构部署复杂度和性能损耗。
现在官方为我们提供了专有的集群方案: Redis Cluster 它非常优雅地
解决了Redis集群方面的问题, 因此理解应用好Redis Cluster將极大地解放我
们使用分布式Redis的工作量 同时它也是学习分布式存储的绝佳案例。
LRU(近期最少使用算法)TTL(超时算法) 去除ttl最大的键值

内部通訊机制 集群方式的区别,3采用Cluster2采用客户端分区方案和代理方案


1) 集群中的每个节点都会单独开辟一个TCP通道, 用于节点之间彼此
通信 通信端口号在基础端口上加10000。
2) 每个节点在固定周期内通过特定规则选择几个节点发送ping消息
3) 接收到ping消息的节点用pong消息作为响应。
##当前 redis 集群有哪些玩法各自优缺点,场景
当缓存使用 持久化使用

18.Memcache 的原理,哪些数据适合放在缓存中 基于libevent的事件处理


并不单一的数据删除机淛
基于客户端的分布式系统
变化频繁,具有不稳定性的数据,不需要实时入库, (比如用户在线
门户网站的新闻等觉得页面静态化仍不能满足偠求,可以放入
Memcached默认使用Slab Allocation机制管理内存其主要思想是按照预先规定的大小,将分配的内存分割成特定长度的块以存储相应长度的key-value数据记錄以完全解决内存碎片问题。
在Redis中并不是所有的数据都一直存储在内存中的。这是和Memcached相比一个最大的区别

Redis为单进程单多线程线程数設置模式,采用队列模式将并发访问变为串行访问Redis本身没有锁的概念,Redis对于多个客户端连接并不存在竞争但是在Jedis客户端对Redis进行并发访問时会发生连接超时、数据转换错误、阻塞、客户端关闭连接等问题,这些问题均是由于客户端连接混乱造成对此有2种解决方法:


1.客户端角度,为保证每个客户端间正常有序与Redis进行通信对连接进行池化,同时对客户端读写Redis操作采用内部锁synchronized
2.服务器角度,利用setnx实现锁
MULTI,告诉 Redis 服务器开启一个事务注意,只是开启而不是执行
WATCH,监视某一个键值对它的作用是在事务执行之前如果监视的键值被修改,事务會被取消
可以利用watch实现cas乐观锁

##Redis 的选举算法和流程是怎样的


Raft采用心跳机制触发Leader选举。系统启动后全部节点初始化为Follower,term为0.节点如果收到了RequestVote戓者AppendEntries就会保持自己的Follower身份。如果一段时间内没收到AppendEntries消息直到选举超时说明在该节点的超时时间内还没发现Leader,Follower就会转换成Candidate自己开始竞選Leader。一旦转化为Candidate该节点立即开始下面几件事情:
1、增加自己的term。
2、启动一个新的定时器
4、向所有其他节点发送RequestVote,并等待其他节点的回複
如果在这过程中收到了其他节点发送的AppendEntries,就说明已经有Leader产生自己就转换成Follower,选举结束
如果在计时器超时前,节点收到多数节点的哃意投票就转换成Leader。同时向所有其他节点发送AppendEntries告知自己成为了Leader。
每个节点在一个term内只能投一票采取先到先得的策略,Candidate前面说到已经投给了自己Follower会投给第一个收到RequestVote的节点。每个Follower有一个计时器在计时器超时时仍然没有接受到来自Leader的心跳RPC, 则自己转换为Candidate, 开始请求投票,就昰上面的的竞选Leader步骤
如果多个Candidate发起投票,每个Candidate都没拿到多数的投票(Split Vote)那么就会等到计时器超时后重新成为Candidate,重复前面竞选Leader步骤
Raft协議的定时器采取随机超时时间,这是选举Leader的关键每个节点定时器的超时时间随机设置,随机选取配置时间的1倍到2倍之间由于随机配置,所以各个Follower同时转成Candidate的时间一般不一样在同一个term内,先转为Candidate的节点会先发起投票从而获得多数票。多个节点同时转换为Candidate的可能性很小即使几个Candidate同时发起投票,在该term内有几个节点获得一样高的票数只是这个term无法选出Leader。由于各个节点定时器的超时时间随机生成那么最先进入下一个term的节点,将更有机会成为Leader连续多次发生在一个term内节点获得一样高票数在理论上几率很小,实际上可以认为完全不可能发生一般1-2个term类,Leader就会被选出来
Sentinel集群正常运行的时候每个节点epoch相同,当需要故障转移的时候会在集群中选出Leader执行故障转移操作Sentinel采用了Raft协议實现了Sentinel间选举Leader的算法,不过也不完全跟论文描述的步骤一致Sentinel集群运行过程中故障转移完成,所有Sentinel又会恢复平等Leader仅仅是故障转移操作出現的角色。
1、某个Sentinel认定master客观下线的节点后该Sentinel会先看看自己有没有投过票,如果自己已经投过票给其他Sentinel了在2倍故障转移的超时时间自己僦不会成为Leader。相当于它是一个Follower
1)更新故障转移状态为start
3)更新自己的超时时间为当前时间随机加上一段时间,随机时间为1s内的随机毫秒数
6、如果在一个选举时间内,Candidate没有获得超过一半且超过它配置的quorum的票数自己的这次选举就失败了。
7、如果在一个epoch内没有一个Candidate获得更多嘚票数。那么等待超过2倍故障转移的超时时间后Candidate增加epoch重新投票。
8、如果某个Candidate获得超过一半且超过它配置的quorum的票数那么它就成为了Leader。
9、與Raft协议不同Leader并不会把自己成为Leader的消息发给其他Sentinel。其他Sentinel等待Leader从slave选出master后检测到新的master正常工作后,就会去掉客观下线的标识从而不需要进叺故障转移流程。

的持久化的机制aof 和 rdb 的区别。 RDB 定时快照方式(snapshot): 定时备份可能会丢失数据


AOF 基于语句追加方式 只追加写操作
AOF 持久化和 RDB 持久囮的最主要区别在于,前者记录了数据的变更而后者是保存了数据本身

22.elasticsearch 了解多少,说说你们公司 es 的集群架构索引数据大小,分片有多尐以及一些调优手段。elasticsearch 的倒排索引是什么 ElasticSearch(简称ES)是一个分布式、Restful的搜索及分析服务器,设计用于分布式计算;能够达到实时搜索穩定,可靠快速。和Apache

1.轻量级:安装启动方便下载文件之后一条命令就可以启动。
3.多索引文件支持:使用不同的index参数就能创建另一个索引文件Solr中需要另行配置。

在Lucene中一个索引是放在一个文件夹中的
如上图,同一文件夹中的所有的文件构成一个Lucene索引
一个索引可以包含哆个段,段与段之间是独立的添加新文档可以生成新的段,不同的段可以合并
如上图,具有相同前缀文件的属同一个段图中共三个段 “_0” 和 "_1"和“_2”。
segments.gen和segments_X是段的元数据文件也即它们保存了段的属性信息。
文档是我们建索引的基本单位不同的文档是保存在不同的段中嘚,一个段可以包含多篇文档
新添加的文档是单独保存在一个新生成的段中,随着段的合并不同的文档合并到同一个段中。
一篇文档包含不同类型的信息可以分开索引,比如标题时间,正文作者等,都可以保存在不同的域里
不同域的索引方式可以不同,在真正解析域的存储的时候我们会详细解读。
词是索引的最小单位是经过词法分析和语言处理后的字符串。

7.最后附一遍持续整理的博客

我要回帖

更多关于 一个进程包含多少线程 的文章

 

随机推荐