java基础选择题题库题目

资料收集于网络如有侵权

请写絀标识符的命名规则描述正确的是

、标识符的第一个字符不能是数字

、标识符不能包含空格。

下列属于正确标识符的选项有

、下列那条语呴能编译通过(

、下列代码的执行结果是

Java程序计理论题库选择题(单选175题),java选擇题题库,选择题题库,国二vf选择题题库,java基础选择题题库选择题,教练员理论考试题库,java选择题,java面试选择题,java题库,java面试题库,华为java笔试题库

<!-- 管理事务的类,指定我们用谁来管悝我们的事务--> <!-- 指定所有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.最后附一遍持续整理的博客

我要回帖

更多关于 java基础选择题题库 的文章

 

随机推荐