近期JAVA常见的面试题

近期常见的JAVA面试题

近期,博主一直在面试,面试的也是1-3年开发的岗位,坐标上海,前前后后面试了20家左右,有大公司,
有小公司.和大家分享常见的面试题. 马98

java基础
一 : hashmap和hashtable的区别

一. HashMap可以接受null键和值,HashTable不行
二. HashTable是线程安全的,通过synchronized来保证,而HashMap线程不安全
三. HashMap的迭代器是fail-fast迭代器,而HashTable的enumerator迭代器不是fail-fast.

接口和抽象类的区别

接口是公开的,不能有私有的方法或变量,接口中的所有方法都没有方法体,通过关键字interface实现。
(1)接口只有定义,不能有方法的实现,java 1.8中可以定义default方法体,而抽象类可以有定义与实现,方法可在抽象类中实现。
(2)实现接口的关键字为implements,继承抽象类的关键字为extends。一个类可以实现多个接口,但一个类只能继承一个抽象类。所以,使用接口可以间接地实现多重继承。
(3)接口强调特定功能的实现,而抽象类强调所属关系。
(4)接口成员变量默认为public static final,必须赋初值,不能被修改;其所有的成员方法都是public、abstract的。抽象类中成员变量默认default,可在子类中被重新定义,也可被重新赋值;抽象方法被abstract修饰,不能被private、static、synchronized和native等修饰,必须以分号结尾,不带花括号。
(5)接口被用于常用的功能,便于日后维护和添加删除,而抽象类更倾向于充当公共类的角色,不适用于日后重新对立面的代码修改。功能需要累积时用抽象类,不需要累积时用接口。

== 和 equals 的区别是什么?

一. 对于==,比较的是值是否相等,如果比较的是基本数据类型的变量,则直接比较其存储的值是否相等,
如果比较的是引用数据类型,则比较的是所指向的对象的地址值.
二. equals不能作用于基本数据类型,它比较的是是否是同一个对象
如果没有对equals方法进行重写,则比较的是引用类型的变量所指向的对象的地址值.
如String,Date等类对equals方法进行了重写,比较的则是所指向的对象的内容

两个对象的 hashCode()相同,则 equals()也一定为 true,对吗?

首先,两个对象equals相等,hashcode一定相等;但是hashcode相等时,equals不一定相等.
其次,两个不同的对象,因为可能存在哈希碰撞,所以hashcode可能是相等的,但是显然equals不为true.
还有就是,在object类中,euqals方法还是用的==来判断的,==对于对象而言比较的是地址值,所以equals相等
hashcode一定一样,反之就不一定了.

java 中的 Math.round(-1.5) 等于多少 ?这道题目笔试很容易出现

Math的round方法是四舍五入,如果参数是负数,则往大的数如,Math.round(-1.5)=-1

java 中操作字符串都有哪些类?它们之间有什么区别? 也是经典题目了

有String,StringBuilder,StringBuffer
1. String是不可变的,每次对String的操作都会产生一个String对象
2. StringBuilder和StringBuffer是可变的,能够被多次修改,并不会产生新的对象.
3. StringBuilder是线程不安全的,StringBuffer是线程安全的.
4. StringBuilder的处理速度比StringBuffer要快

String str="i"与 String str=new String(“i”)一样吗

他们的值相等,用equals得到true,但是他们是两个对象,如果用==判断返回false.
且str="i"是直接在常量池中引用字符串,而new String(“i”)是在堆中根据i再创建一个对象.

Collection 和 Collections 有什么区别?

Collection是集合类的一个顶级接口,它提供了对集合对象进行基本操作的通用接口方法.
Collections是集合类的一个工具类,它提供了一系列的静态方法,用于对集合中元素进行排序,搜索以及线程同步等操作.

List、Set、Map 之间的区别是什么?

List: 可以允许重复的对象;
可以插入多个null元素;
有序,输入顺序就是输出顺序;
Set: 不允许重复对象;
无序,且只允许一个null对象;
Map: 存储键值对,只能有唯一的key,value可以重复
只能有一个null键

说一下 HashMap 的实现原理?

数组+链表,初始16,75扩容,数据存在内部类Map.Entry中,其中包含key value hashcode和next.

ArrayList 和 LinkedList 的区别是什么?

  1. ArrayList底层基于动态数组,LinkedList基于链表实现,底层是循环双向链表
    2. 对于随机访问get和set,ArrayList优于LinkedList.
    3. 对于新增add和删除remove,LinkedList比较快

哪些集合类是线程安全的?

Vector HashTable ConcurrentHashMap Stack

上面是容器,下面是多线程,也是常被问到的一些问题

守护线程是什么?

守护线程是服务其他线程的,在java中,线程有两种:守护线程和用户线程.
java中的jvm垃圾回收线程就是一个典型的守护线程.当用户线程全部执行完,包括main线程也执行完毕,那么
jvm会自动退出,此时守护线程也就停止了.

创建线程有哪几种方式?

三种: 1. 继承Thread类,重写run方法,用子类实例调用start()方法;
2. 实现Runnable接口并重写run方法,创建Thread实例并传入Runnable实例,代用Thread的start()方法
3. 创建Callable接口的实现类,重写call方法;
构造此实现类的实例,将其作为参数构造一个FutureTask类的实例;
以FutureTask的实例为参数构造一个Thread对象执行start()方法.
第三种方式可以允许有返回值,也可以声明抛出异常类.

线程有哪些状态?

  1. NEW 新建状态,此时线程还没有运行线程中的代码
    2. RUNNABLE 就绪状态;处于就绪状态的线程并不一定立即运行run方法,必须还要和其他线程竞争CPU时间
    3. RUNNING 运行状态;线程获得CPU时间后才进入运行状态,开始执行run方法
    4. BLOCKED 阻塞状态;线程运行过程中会有各种原因来进入阻塞状态,如:调用sleep方法进入休眠;
    在IO操作中被阻塞;试图得到一个锁,该锁正被其他线程持有;等待某个触发条件.
    阻塞状态的线程此时没有结束,暂时让出CPU时间给其他线程.
    5. DEAD 死亡状态;有两个原因导致线程死亡:第一是run方法正常退出自然死亡;第二是一个未捕获的
    异常终止了run方法使线程死亡.
    为了确定线程在当前是否存活着(就是要么是可运行的,要么是被阻塞了),需要使用isAlive方法,如果是可运行或被阻塞,这个方法返回true;如果线程仍旧是new状态且不是可运行的,或者线程死亡了,则返回false

sleep() 和 wait() 有什么区别?

  1. sleep方法是Thread类的,而wait方法使Object类中的
    2. sleep方法使线程暂停指定的时间,让出CPU给其他线程,但是他的监控状态依然保持着,时间到了以后会自动恢复运行状态
    在这个过程中,线程不会释放同步对象锁.
    而调用wait方法,线程会放弃对象锁,进入等待队列,待调用notify/notifyAll方法后才会进入锁池,获取对象锁后才进入运行状态.

notify()和 notifyAll()有什么区别?

notify()方法随机唤醒一个wait线程到锁池中去竞争锁,而notifyAll方法唤醒所有wait线程到锁池.
notity()方法可能产生死锁,notifyAll则不会.

线程的 run()和 start()有什么区别?

run()方法只是定义了线程的执行单元并非直接开启了线程资源,只有start()方法被调用,才可以启动一个线程.
如果直接调用run方法,会被当成普通方法在main线程执行,并不会创建线程.

创建线程池有哪几种方式?经常被问到

java中的Executors可以为我们创建现成的线程池,有以下几种:
1. newSingleThreadExecutor 创建一个单线程的线程池,它只有一个工作线程,操作无界工作队列,可以保证任务顺序
2. newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待
3. newCachedThreadPool 创建一个可缓存线程池,有空闲线程时会回收,但是任务过多,会一直创建,消耗资源
4. newScheduledThreadPool 创建一个大小无线的线程池,此线程池支持定时以及周期性任务的需求.

什么是死锁?怎么防止死锁?

死锁是指两个或两个以上的进程或线程在执行过程中,因争夺资源而造成的一种相互等待的过程,如果没有外力作用,他们讲无法推进下去.

  1. 以确定的顺序获取锁
    2. 超时放弃.(Lock锁中就使用了这种方式)
    3. 银行家算法

ThreadLocal 是什么?有哪些使用场景?

也成为线程本地变量,ThreadLocal在每个线程中对一个变量创建了一个副本,且在线程内部任何地方都可以使用,线程间互不影响.
应用场景:spring的声明式事物管理.

什么是反射?

在运行过程中,对任何一个类,都能知道这个类的所有属性和方法,对于任意一个对象,都能改变其属性

什么是 java 序列化?什么情况下需要序列化?

序列化就是一种用来处理对象流的机制,简单来说,就是把对象存储在某一个地方,硬盘或者网络,即把对象的内容转变为字节序列.
当想把内存中的对象状态保存在一个文件或者数据库,或者在网络上传输的时候,就需要序列化,在java中需要实现Serializable接口.

动态代理是什么?有哪些应用?

动态代理是将对象中不同方法的调用重新定向到一个统一处理函数,做自定义的逻辑处理,但是调用者察觉不到.
应用: Spring的AOP,事物,权限,日志.RPC框架

怎么实现动态代理?

  1. 利用JDK的反射机制实现
    2. 使用CGLIB代理.

java web

jsp 和 servlet 有什么区别?

  1. jsp擅长表现页面显示,servlet擅长逻辑控制
    2. servlet没有内置对象,jsp有内置对象
    3. servlet的应用逻辑在.java文件中,而jsp中,java和html组合为一个.jsp文件.
    4. servlet在java代码中嵌入html代码,jsp是在html中嵌入java代码

jsp 有哪些内置对象?作用分别是什么?

jsp有9个内置对象:
request 用户端请求,此请求会包含来自GET/POST请求的参数
response 网页传回用户端的回应
pageContext 网页的属性是在这里管理
session 与请求有关的会话期
application servlet正在执行的内容
out 用来传送回应的输出
config servlet的构架部件
page JSP网页本身
exception 针对错误网页,未捕捉的例外

session 和 cookie 有什么区别?

1.数据存放位置不同.session在服务器,cookie在客户端浏览器
2. 安全程度不同,别人可以分析存放在本地的cookie进行cookie欺骗.
3. 单个cookie保存的数据不能超过4k,而session是在服务器的,所以没有限制
4. cookie只能存储string类型的数据,session可以存储对象.

说一下 session 的工作原理?

当用户第一次访问一个服务器,服务器就会为该用户创建一个session,并生成一个和该session有关的session_id,
这个id是唯一的,不可重复.这个id将会在本次响应中返回,保存在客户端的cookie中,下次方法的时客户端浏览器
的cookie中含有session_id,服务器基于这个id就可以识别该用户.

如何避免 sql 注入?

1.采用预编译语句
2. 使用正则过滤传入的参数.
3. 屏蔽不安全的字符

异常
throw 和 throws 的区别?

throws:用来声明一个方法可能抛出的所有异常信息,不会处理异常,只是将异常向上传,交给调用者
throw:抛出一个具体的异常类型.
throws出现在方法声头,而throw出现在函数体
throws表示出现异常的可能,并不一定会发生,throw则是抛出了一个存在的异常实例.

final、finally、finalize 有什么区别?经典笔试题

final: 修饰类,表示该类不可继承
修饰方法,表示该方法不可重写
修饰变量,表示该变量不允许被修改
finally:是保证代码一定要被执行的一种机制.常用来关闭连接资源或者解锁等.
finalize:是Object的一个方法,它的目的是保证对象在被垃圾收集前完成特定资源的回收.1.9后已经过时.

try-catch-finally 中哪个部分可以省略?

catch可以省略
不管有没有捕获到异常,finally中的代码都会被执行;
finally是在return之后执行的,程序在执行完return之后,会将值保存起来,当执行完finally中的代码之后再将return值返回
如果finally中存在return,会导致最后返回的是finally中的值.

try-catch-finally 中,如果 catch 中 return 了,finally 还会执行吗?

会执行,return的值会暂时保存.等到运行完finally中的代码块时才会返回return的值

常见的异常类有哪些?

空指针异常类型:NullPointerException
类型强制转换类型:ClassCastException
数组下标越界异常:ArrayIndexOutOfBoundsException
输入输出异常:IOException

forward 和 redirect 的区别?

forward:直接转发,客户端浏览器只发出一次请求,由第二个信息资源响应该请求,共享同一个request对象
redirect:间接转发,服务端响应第一次请求的时候,让浏览器去访问另外一个URL,从而达到转发的目的.本质上是两次HTTP请求.
forward地址栏不变,redirect地址栏改变

tcp 为什么要三次握手,两次不行吗?为什么?

1.为了实现可靠数据传输,TCP 协议的通信双方,都必须维护一个序列号以标识发送出去的数据包中哪些是已经被对方收到的。
三次握手的过程即是通信双方相互告知序列号起始值,并确认对方已经收到了序列号起始值的必经步骤
2. 如果只是两次握手,至多只有连接发起方的起始序列号能被确认,另一方选择的序列号则得不到确认

如何实现跨域?

1.JSONP技术
2.CORS规范
3.通过服务端实现
4.websocket

说一下你熟悉的设计模式?

单例模式,装饰者模式,代理模式,适配器模式,策略模式

简单工厂和抽象工厂有什么区别?

简单工厂只能生产同一等级结构中的任一产品
抽象工厂用来生产不同产品族中的全部产品

为什么要使用 spring?

1.方便解耦,可以将对象间的依赖关系交给spring
2. spring支持aop编程,可以很方便的对程序进行监控,拦截
3. 方便测试,支持junit
4. 集成其他框架比较方便
5. 声明式事务

解释一下什么是 aop? 问烂的东西

aop即面向切面编程,在原有功能的基础上通过aop添加新的功能,而原有的功能并不知道新添加的功能.
简单来说,就是在某个类或者方法执行前后打个标记,声明在执行到这里之前要先执行什么,之后执行什么,插入了新的执行方法.

解释一下什么是 ioc?烂中烂

ioc控制反转.即把创建对象和维护对象之间关系的权利交给spring容器去做,程序自己不再维护.
传统:自己使用new 或者getInstance直接或者间接创建一个对象(高耦合,不易测试)
spring:容器使用工厂模式为了创建了所需要的对象,我们不用自己创建,直接调用即可.

spring 常用的注入方式有哪些?

1.构造器注入:可以在xml中通过constructor-arg标签来注入一个对象到构造器中
2. setter方法注入: 首先要配置被注入的bean,在该bean对应的类中,应该有要注入的对象属性或者基本数据类型的属性。
例如:为UserBiz类注入UserDAO,同时为UserBiz注入基本数据类型String,那么这时,
就要为UserDAO对象和String类型设置setter方法.,用于进行依赖注入。
3. 注解注入:基于注解在xml文件中开启注解扫描以后,就可以在filed上使用注解@Autowired或者@Rsource来注入对象

spring 中的 bean 是线程安全的吗?

不是的,spring并没有对单例bean做多线程的封装.

spring 支持几种 bean 的作用域?

1.singleton: 单例,默认作用域,在spring容器中此种类型的bean只有一个
2.prototype: 原型,每次调用getBean方法就会产生一个新的实例.
3.request: 每次HTTP请求都会产生不同的bean实例.
4.session: 每次会话产生一个实例
5.global-session: 所有会话共享一个实例

spring 自动装配 bean 有哪些方式?

1.xml配置方式
2.注解扫描方式

spring 事务实现方式有哪些?

1.编程式事务 允许用户在代码中精确定义事务的边界
2.声明式事务 基于AOP,将操作和事务管理分离.

说一下 spring mvc 运行流程?超级问烂的问题

1.用户向服务器发送请求,被springMVC的前端控制器拦截(DispatcherServlet)
2.前端控制器对请求的URL进行解析,得到标识符URI,根据URI调用处理器映射器
3.处理器映射器与该Handler有关的对象和拦截器信息返回给DispatcherServlet
4.前端控制器根据获得的处理器信息,调用对应的处理器适配器HandlerAdapter处理数据
5.处理器适配器提取request中的模型数据,开始执行Handler,在此之前还可以做数据合适的转换和数据验证等.
处理完成后向DispatcherServlet返回一个ModelAndView对象
6.前端控制器根据ModelAndView选择合适的视图解析器ViewResolver处理数据
7.视图解析器根据model和view渲染视图,将结果返回给客户端

@RequestMapping 的作用是什么?

映射请求,指定哪些URL可以被该处理器处理.

什么是 spring cloud?

springcloud是一个微服务框架,提供全套的分布式系统解决方案,它为微服务架构开发提供配置管理、服务治理、熔断机制、智能路由
控制总线等一系列的管理操作.

spring cloud 断路器的作用是什么?

微服务架构中,存在很多的微服务,彼此之间存在依赖关系,当某个单元出现故障时,就会因为依赖关系导致整个系统的瘫痪.
断路器的作用是当某个微服务发生故障时,通过断路器的故障监控,向调用方返回一个错误响应,使之不至于长时间等待,避免了故障在分布式系统中的蔓延

spring cloud 的核心组件有哪些?

服务发现: Netflix Eureka
客户端负载均衡: Netflix Ribbon
断路器: Netflix Hystrix
服务网关: Netflix Zuul
分布式配置: Spring cloud Config

mybatis 中 #{}和 ${}的区别是什么?

1.前者会将传入的数据当成字符串,在之前加入双引号,后者是直接将数据显示在sql中
2. 前者会当做占位符,防sql注入,后者不能

mybatis 有几种分页方式?

两种,一种是内存分页,一种是物理分页
内存分页: 一次性查询出所有满足条件的数据,临时保存在集合中,通过List的subList的方式获取分页数据.
物理分页: 借助sql进行分页或者利用拦截器分页

mybatis 逻辑分页和物理分页的区别是什么?

1.逻辑分页一次性查询很多数据,然后再结果中检索分页的数据,消耗内存.
2. 物理分页是从数据库查询指定条数的数据.

mybatis 是否支持延迟加载?延迟加载的原理是什么?

支持,在配置文件的标签中设置就可以激活
原理: 在调用的时候出发加载,而不是在初始化的时候加载信息.如a.getB().getName(),如果a.getB()的值为null,会触发保存好的关联B对象的sql语句查询出B,然后再调用getName()

说一下 mybatis 的一级缓存和二级缓存?

一级缓存是SqlSession级别的,在一个sqlsession中,第一次查询缓存中是否有数据,没有就会查询数据库,并将数据保存在一级缓存中.第二次去查的时候会直接从缓存中查询.如果这中间sqlsession进行了commit操作则会清空缓存.
2. 二级缓存是Mapper级别的,多个sqlsession共享,默认关闭.它基于Mapper文件的namespace,如果两个mapper的namespace相同,那么会共享缓存的数据.使用二级缓存要在配置文件中开启,并且序列化po类.

mybatis 分页插件的实现原理是什么?再被一家大型公司被问到过

分页插件的基本原理是使用 MyBatis 提供的插件接口,实现自定义插件,在插件的拦截方法内拦截待执行的SQL,然后重写SQL,根据dialect方言,添加对应的物理分页语句和参数

消息中间件

RabbitMQ的使用场景

1.抢购活动,削峰填谷,防止系统崩塌。
2. 延迟信息处理,比如 10 分钟之后给下单未付款的用户发送邮件提醒。
3. 解耦系统

rabbitmq 的消息是怎么发送的?

首先客户端必须连接到 RabbitMQ 服务器才能发布和消费消息,客户端和 rabbit server 之间会创建一个 tcp 连接,一旦 tcp 打开并通过了认证(认证就是你发送给 rabbit 服务器的用户名和密码),你的客户端和 RabbitMQ 就创建了一条 amqp 信道(channel),信道是创建在“真实” tcp 上的虚拟连接,amqp 命令都是通过信道发送出去的,每个信道都会有一个唯一的 id,不论是发布消息,订阅队列都是通过这个信道完成的。

rabbitmq 怎么保证消息的稳定性?

1.提供了事物功能
2. 通过将 channel 设置为 confirm(确认)模式

rabbitmq 怎么避免消息丢失?

1.把消息持久化磁盘,保证服务器重启消息不丢失。
2. 每个集群中至少有一个物理磁盘,保证消息落入磁盘

要保证消息持久化成功的条件有哪些?

1.声明队列必须设置持久化 durable 设置为 true.
2. 消息推送投递模式必须设置持久化,deliveryMode 设置为 2(持久)。
3. 消息已经到达持久化交换器。
4. 消息已经到达持久化队列。

rabbitmq 持久化有什么缺点?

因为使用了磁盘来存储而不是内存,所以降低了服务器的吞吐量.

rabbitmq 怎么实现延迟消息队列?

1.通过消息过期后进入死信交换器,再由交换器转发到延迟消费队列,实现延迟功能
2. 使用 RabbitMQ-delayed-message-exchange 插件实现延迟功能。

rabbitmq 集群有什么用?

高可用:某个服务器出现问题,整个 RabbitMQ 还可以继续使用;
高容量:集群可以承载更多的消息量。

mysql 索引是怎么实现的?

索引是满足某种特定查找算法的数据结构,而这些数据结构会以某种方式指向数据,从而实现高效查找数据。
具体来说 MySQL 中的索引,不同的数据引擎实现有所不同,但目前主流的数据库引擎的索引都是 B+ 树实现的,B+ 树的搜索效率,可以到达二分法的性能,找到数据区域之后就找到了完整的数据结构了,所有索引的性能也是更好的

怎么验证 mysql 的索引是否满足需求?

使用 explain 查看 SQL 是如何执行查询语句的,从而分析你的索引是否满足需求。
explain 语法:explain select * from table where type=1。

说一下 mysql 常用的引擎?

InnoDB 引擎:InnoDB 引擎提供了对数据库 acid 事务的支持,并且还提供了行级锁和外键的约束,它的设计的目标就是处理大数据容量的数据库系统。MySQL 运行的时候,InnoDB 会在内存中建立缓冲池,用于缓冲数据和索引。但是该引擎是不支持全文搜索,同时启动也比较的慢,它是不会保存表的行数的,所以当进行 select count() from table 指令的时候,需要进行扫描全表。由于锁的粒度小,写操作是不会锁定全表的,所以在并发度较高的场景下使用会提升效率的。
MyIASM 引擎:MySQL 的默认引擎,但不提供事务的支持,也不支持行级锁和外键。因此当执行插入和更新语句时,即执行写操作的时候需要锁定这个表,所以会导致效率会降低。不过和 InnoDB 不同的是,MyIASM 引擎是保存了表的行数,于是当进行 select count(
) from table 语句时,可以直接的读取已经保存的值而不需要进行扫描全表。所以,如果表的读操作远远多于写操作时,并且不需要事务的支持的,可以将 MyIASM 作为数据库引擎的首选。

说一下乐观锁和悲观锁?

乐观锁:每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在提交更新的时候会判断一下在此期间别人有没有去更新这个数据。
悲观锁:每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会阻止,直到这个锁被释放。
数据库的乐观锁需要自己实现,在表里面添加一个 version 字段,每次修改成功值加 1,这样每次修改的时候先对比一下,自己拥有的 version 和数据库现在的 version 是否一致,如果不一致就不修改,这样就实现了乐观锁

sql优化就不写了,网上一搜一大推

Redis
redis 是什么?都有哪些使用场景?

Redis 是一个使用 C 语言开发的高速缓存数据库。
记录帖子点赞数、点击数、评论数;
缓存近期热帖;
缓存文章详情信息;
记录用户会话信息。

redis 为什么是单线程的?

因为 cpu 不是 Redis 的瓶颈,Redis 的瓶颈最有可能是机器内存或者网络带宽。既然单线程容易实现,而且 cpu 又不会成为瓶颈,那就顺理成章地采用单线程的方案了

什么是缓存穿透?怎么解决?

缓存穿透:指查询一个一定不存在的数据,由于缓存是不命中时需要从数据库查询,查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到数据库去查询,造成缓存穿透。
解决方案:最简单粗暴的方法如果一个查询返回的数据为空(不管是数据不存在,还是系统故障),我们就把这个空结果进行缓存,但它的过期时间会很短,最长不超过五分钟

redis 支持的数据类型有哪些?

redis 支持的数据类型:string(字符串)、list(列表)、hash(字典)、set(集合)、zset(有序集合)。

怎么保证缓存和数据库数据的一致性?

合理设置缓存的过期时间
新增、更改、删除数据库操作时同步更新 Redis,可以使用事物机制来保证数据的一致性。

redis 持久化有几种方式?

RDB(Redis Database):指定的时间间隔能对你的数据进行快照存储。
AOF(Append Only File):每一个收到的写命令都通过write函数追加到文件中。

redis 怎么实现分布式锁?

Redis 分布式锁其实就是在系统里面占一个“坑”,其他程序也要占“坑”的时候,占用成功了就可以继续执行,失败了就只能放弃或稍后重试。
一般使用 setnx(set if not exists)指令,只允许被一个程序占有,使用完调用 del 释放锁。

Redis有哪几种数据淘汰策略?

volatile-lru:从设置了过期时间的 数据集 中,选择最近最久未使用的数据释放;
allkeys-lru:从 数据集 中(包括设置过期时间以及未设置过期时间的数据集中),选择最近最久未使用的数据释放;
volatile-random:从设置了过期时间的 数据集 中,随机选择一个数据进行释放;
allkeys-random:从 数据集 中(包括了设置过期时间以及未设置过期时间)随机选择一个数据进行入释放;
volatile-ttl:从设置了过期时间的 数据集 中,选择马上就要过期的数据进行释放操作;
[默认]noeviction:不删除任意数据(但redis还会根据引用计数器进行释放),这时如果内存不够时,会直接返回错误。

怎么理解Redis事务?

事务是一个单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。
事务是一个原子操作:事务中的命令要么全部被执行,要么全部都不执行

【集群】Redis集群方案应该怎么做?都有哪些方案?

redis的集群方案大致分为四种:
1.使用twitter开源的Twemproxy代理
Twemproxy作为代理,可接受来自多个程序的访问,按照路由规则,转发给后台的各个Redis服务器,再原路返回。缺点就是:无法平滑地扩容/缩容。对运维考验力度比较大。
2.使用豌豆荚开源的Codis
Codis 是一个分布式 Redis 解决方案, 对于上层的应用来说, 连接到 Codis Proxy 和连接原生的 Redis Server 没有明显的区别 (有一些命令不支持), 上层应用可以像使用单机的 Redis 一样使用, Codis 底层会处理请求的转发, 不停机的数据迁移等工作, 所有后边的一切事情, 对于前面的客户端来说是透明的, 可以简单的认为后边连接的是一个内存无限大的 Redis 服务。支持在 节点数量改变情况下,旧节点数据可恢复到新hash节点。
3.redis 3.0 自带的集群功能
和 Codis差不多。特点在于他的分布式算法不是一致性hash,而是hash槽的概念,以及自身支持节点设置从节点。
4.客户端处理
起几个毫无关联的redis实例,在代码层,对key 进行hash计算,然后去对应的redis实例操作数据。对代码层要求很高,需要处理很多异常情况:节点失效后的替代算法方案,数据震荡后的自动脚本恢复,实例的监控,等等。

Redis集群的主从复制模型是怎样的?

为了使在部分节点失败或者大部分节点无法通信的情况下集群仍然可用,所以集群使用了主从复制模型,每个节点都会有N-1个复制品。
工作原理:从slave服务启动连接master节点,从slave节点发送一个sync命令到master,master节点收到命令后启动后台存盘进程,收集所有的操作命令,收集完之后将整个数据库文件发送给slave节点。来完成一次同步。slave节点收到数据库文件之后存盘加载到内存。此后,master节点继续收集命令依次发送给slave节点,slave节点再依次执行这些命令,从而达到数据同步。
Redis集群 -主从复制模式
配置主节点的配置文件不需要任何改动
配置从节点只需要在配置文件中slaveof
如果设置了密码,就要设置:masterauth 即可

Redis集群如何选择数据库?

Redis集群目前无法做数据库选择,默认在0数据库。

你知道有哪些Redis分区实现方案?

范围分区:比如,ID从0到10000的用户会保存到实例R0,ID从10001到 20000的用户会保存到R1,以此类推。
哈希分区:加入有四个实例,比如,对ID进行hash,然后对4取模,得到0-3的数字,分别保存到对应的实例上

JVM详解及调优

栈是运行时的单位,而堆是存储的单位,栈是解决如何处理数据,而堆是数据如何存放,放在什么地方;
堆里面有GC回收机制,有分代回收,基于对象生命周期进行垃圾回收,把对象分为年青代,年老代,持久代,不同生命周期的对象使用不同的算法进行回收;
年青代:新创建的对象存放的位置;
年老代:年青代中经历了多次回收后依然存活的对象
持久代:用于存放静态文件,如Java类,方法等;
GC回收:垃圾收集,负责清除对象并释放内存.Java提供的GC功能可以自动检测对象是否超过作用域从而达到自动回收内存的目的,从而防止内存泄露;
Java回收算法:
两个最基本的Java回收算法:复制算法和标记清理算法
复制算法:两个区域A和B,初始化对象在A,继续存活的对象被转移到B,此为新生代最常用的算法;
标记清理:一块区域,标记要回收的对象,然后回收,一定会出现碎片,那么引出;
标记-整理算法:多了碎片整理,整理出更大的内存放更大的对象;
新生代基本采用复制算法,老年代采用标记整理算法.cms采用标记清理
整个JVM分为四部分:
类加载器:加载类文件到内存;
执行引擎:也称为解释器,负责解释命令,提交操作系统执行;
本地接口:作用是融合不同的编程语言为Java使用;很少使用;
运行数据区: 是整个JVM的重点,所写的程序都被加载到这里才开始执行;
JVM的内存管理:
Stack栈: 栈内存,是Java程序的运行区,是在线程创建的时候创建,生命期跟随线程的生命期,栈不存在垃圾回收问题,只要线程结束,该栈就Over了;
Heap堆内存:一个JVM实例只存在一个堆内存,大小可调节,类加载器读取文件后,需要把类,方法,常变量放在堆内存中,方便执行,堆分为:新生区,老年区,永久存储区;
方法区:就是被所有线程共享,该区域保存所有的方法和方法字节码,以及一些特殊方法如构造函数,接口代码也在此定义;
程序计数器:每个线程都有一个程序计数器,就是一个指针,指向方法区中的方法字节码,由执行引擎读取下一条命令;
本地方法栈:当线程调用一个本地方法的时候,就会进入一个不接受虚拟机限制的地方,就是本地方法栈;

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值