还剩23页未读,继续阅读
本资源只提供10页预览,全部文档请下载后查看!喜欢就下载吧,查找使用更方便
文本内容:
历年Java面试分类100题
一一、Java基础篇
1、Java中的Mathround-
1.5等于多少?【仅供参考】等于-1因为在数轴上取值时,中间值
0.5向右取整,所以正
0.5是往上取整,负
0.5是直接舍弃
2、为什么不能用浮点型表示金额?【仅供参考】由于计算机中保存的小数其实是十进制的小数的近似值,并不是准确值,所以,千万不要在代码中使用浮点数来表示金额等重要的指标建议使用BigDecimal或者Long来表示金额
3、Strings=xyz和Strings=newStringxyz”区别?【仅供参考】两个语句都会先去字符串常量池中检查是否已经存在“xyz”,如果有则直接使用,如果没有则会在常量池中创建“xyz”对象另外,Strings=newStringxyz还会通过newString在堆里创建一个内容与xyz”相同的对象实例所以前者其实理解为被后者的所包含
4、Files的常用方法都有哪些?【仅供参考】Filesexists检测文件路径是否存在Files.createFile创建文件Files.createDirectory创建文件夹Filesdelete删除一个文件或目录Filescopy复制文件Filesmove移动文件Filessize查看文件个数Filesread读取文件Fileswrite写入文件因此,interrupt加上手动抛异常的方式是目前中断一个正在运行的线程最为正确的方式了
9、什么是AQS【仅供参考】AQS是AbustactQueuedSynchronizer的简称,它是一个Java提高的底层同步工具类,用一个int类型的变量表示同步状态,并提供了一系列的CAS操作来管理这个同步状态AQS是一个用来构建锁和同步器的框架,使用AQS能简单且高效地构造出应用广泛的大量的同步器,比如我们提到的ReentrantLockSemaphore其他的诸如ReentrantReadWriteLockSynchronousQueueFutureTask等等皆是基于AQS的
10、线程的sleep方法和yieldO方法有什么区别?【仅供参考】线程执行sleepO方法后进入超时等待TIMED_WAITING状态,而执行yieldO方法后进入就绪READY状态sleepO方法给其他线程运行机会时不考虑线程的优先级,因此会给低优先级的线程运行的机会;yieldO方法只会给相同优先级或更高优先级的线程以运行的机会
11、线程有哪些状态?【仅供参考】线程的状态NEW尚未启动RUNNABLE正在执行中BLOCKED阻塞的被同步锁或者10锁阻塞WAITING永久等待状态TIMED_WAITING等待指定的时间重新被唤醒的状态TERMINATED执行完成
12、在Java程序中怎么保证多线程的运行安全?【仅供参考】方法一使用安全类,比如Java.utilconcurrent下的类方法二使用自动锁synchronizedo方法三使用手动锁Locko手动锁Java示例代码如下Locklock=newReentrantLock;lock.lock;trySystemout.printin〃获得锁〃;}catchExceptione{//TODO:handleexception}finally{System.out.printin〃释放锁〃;lockunlock;}13^synchronized各种加锁场景的作用范围【仅供参考】L作用于非静态方法,锁住的是对象实例this每一个对象实例有一个锁publicsynchronizedvoidmethod{}.作用于静态方法,锁住的是类的Class对象,因为Class的相关数据存储在永久代元空间,元空间是全局共享的,因此静态方法锁相当于类的一个全局锁,会锁所有调用该方法的线程publicstaticsynchronizedvoidmethod{}.作用于Lockclass锁住的是Lock的Class对象,也是全局只有一个synchronizedLockclass{}.作用于this锁住的是对象实例,每一个对象实例有一个锁synchronizedthis{}.作用于静态成员变量,锁住的是该静态成员变量对象,由于是静态变量,因此全局只有一个publicstaticObjectmonitor=newObject;synchronizedmonitor{}
14、什么是CAS【仅供参考】CAS是compareandswap的缩写,即我们所说的比较交换cas是一种基于锁的操作,而且是乐观锁在java中锁分为乐观锁和悲观锁悲观锁是将资源锁住,等一个之前获得锁的线程释放锁之后,下一个线程才可以访问而乐观锁采取了一种宽泛的态度,通过某种方式不加锁来处理资源,比如通过给记录加version来获取数据,性能较悲观锁有很大的提高CAS操作包含三个操作数一一内存位置V、预期原值A和新值B如果内存地址里面的值和A的值是一样的,那么就将内存里面的值更新成BoCAS是通过无限循环来获取数据的,若果在第一轮循环中,a线程获取地址里面的值被b线程修改了,那么a线程需要自旋,到下次循环才有可能机会执行java.utilconcurrentatomic包下的类大多是使用CAS操作来实现的AtomiclntegerAtomicBooleanAtomicLong
15、JavaConcurrencyAPI中的Lock接口Lockinterface是什么?对比同步它有什么优势?【仅供参考】Lock接口比同步方法和同步块提供了更具扩展性的锁操作他们允许更灵活的结构,可以具有完全不同的性质,并且可以支持多个相关类的条件对象它的优势有1可以使锁更公平2可以使线程在等待锁的时候响应中断3可以让线程尝试获取锁,并在无法获取锁的时候立即返回或者等待一段时间4可以在不同的范围,以不同的顺序获取和释放锁
16、JAVA两种方式的动态代理?【仅供参考】JDK动态代理利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理CGLIB动态代理利用ASM开源的Java字节码编辑库,操作字节码开源包,将代理对象类的class文件加载进来,通过修改其字节码生成子类来处理区别JDK代理只能对实现接口的类生成代理;CGlib是针对类实现代理,对指定的类生成一个子类,并覆盖其中的方法,这种通过继承类的实现方式,不能代理final修饰的类
17、java反射的作用是什么?【仅供参考】反射机制是在运行时,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意个对象,都能够调用它的任意一个方法在java中,只要给定类的名字,就可以通过反射机制来获得类的所有信息这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制
18、说一下堆栈的区别【仅供参考】功能方面堆是用来存放对象的,栈是用来执行程序的共享性堆是线程共享的,栈是线程私有的空间大小堆大小远远大于栈
19、什么是双亲委派模型?【仅供参考】如果一个类加载器收到了类加载的请求,它首先不会自己去尝试加载这个类,而是把这个请求委派给父类加载器去完成,每一个层次的类加载器都是如此,因此所有的加载请求最终都应该传送到顶层的启动类加载器中,只有当父加载器反馈自己无法完成这个加载请求(它的搜索范围中没有找到所需的类)时,子加载器才会尝试自己去加载
20、说一下JVM有哪些垃圾回收器?【仅供参考】Serial最早的单线程串行垃圾回收器SerialOld Serial垃圾回收器的老年版本,同样也是单线程的,可以作为CMS垃圾回收器的备选预案ParNew是Serial的多线程版本Parallel和ParNew收集器类似是多线程的,但Parallel是吞吐量优先的收集器,可以牺牲等待时间换取系统的吞吐量ParallelOld是Parallel老生代版本Parallel使用的是复制的内存回收算法,ParallelOld使用的是标记-整理的内存回收算法CMS一种以获得最短停顿时间为目标的收集器,非常适用B/S系统G1一种兼顾吞吐量和停顿时间的GC实现,是JDK9以后的默认GC选项
三、JavaWeb篇
1、常用HTTP状态码是怎么分类的?【仅供参考】状态码类别描述1XX信息状态码信息,服务器收到请求,需要请求者继续执行操作2xx成功状态码成功,操作被成功接收并处理3xx重定向状态码重定向,需要进一步的操作以完成请求4xx客户端错误状态码客户端错误,请求包含语法错误或无法完成请求5xx服务器错误状态码服务器错误,服务器在处理请求的过程中发生了错误HTTP
1.0和HTTP
1.1和HTTP
2.0的区别HTTP
1.0无状态,无连接HTTP
1.1长连接,请求管道化,增加缓存处理,增加Host字段,支持断点传输HTTP
2.0二进制分帧,多路复用连接共享,头部压缩,服务器推送
2、三次握手和四次挥手【仅供参考】三次握手1客户端向服务器发出连接请求等待服务器确认2服务器向客户端返回一个响应告诉客户端收到了请求3客户端向服务器再次发出确认信息,此时连接建立四次挥手1客户端向服务器发出取消连接请求2服务器向客户端返回一个响应表示收到客户端取消请求3服务器向客户端发出确认取消信息向客户端表明可以取消连接了4客户端再次发送确认消息此时连接取消
3、说一下tcp粘包是怎么产生的?【仅供参考】tcp粘包可能发生在发送端或者接收端,分别来看两端各种产生粘包的原因发送端粘包发送端需要等缓冲区满才发送出去,造成粘包;接收方粘包接收方不及时接收缓冲区的包,造成多个包接收
4、http和https的基本概念【仅供参考】-HTTP:是互联网上应用最为广泛的一种网络协议,是一个客户端和服务器端请求和应答的标准TCP用于计算机之间传输文字,图片,音频,视频等超文本数据的协议,它可以使浏览器更加高效,使网络传输减少-HTTPS:是以安全为目标的HTTP通道,简单讲是HTTP的安全版,即HTTP下加入SSL层,HTTPS的安全基础是SSLHTTPS就是从HTTP加上加密处理一般是SSL安全通信线路+认证+完整性保护-HTTPS协议的主要作用:建立一个信息安全通道,来保证数据传输的安全确认网站的真实性
5、http响应码301和302代表的是什么?有什么区别?【仅供参考】301永久重定向302暂时重定向它们的区别是,301对搜索引擎优化(SE0)更加有利;302有被提示为网络拦截的风险
6、说一下JSP的4种作用域?【仅供参考】page代表与一个页面相关的对象和属性request代表与客户端发出的一个请求相关的对象和属性一个请求可能跨越多个页面,涉及多个Web组件;需要在页面显示的临时数据可以置于此作用域session代表与某个用户与服务器建立的一次会话相关的对象和属性跟某个用户相关的数据应该放在用户自己的session中application代表与整个Web应用程序相关的对象和属性,它实质上是跨越整个Web应用程序,包括多个页面、请求和会话的一个全局作用域
7、什么是长连接和短连接【仅供参考】在HTTP/L0中默认使用短连接也就是说,客户端和服务器每进行一次HTTP操作,就建立一次连接,任务结束就中断连接而从HTTP/L1起,默认使用长连接,用以保持连接特性使用长连接的HTTP协议,会在响应头加入这行代码Connection:keep-alive在使用长连接的情况下,当一个网页打开完成后,客户端和服务器之间用于传输HTTP数据的TCP连接不会关闭,客户端再次访问这个服务器时,会继续使用这一条已经建立的连接Keep-Alive不会永久保持连接,它有一个保持时间,可以在不同的服务器软件(如Apache)中设定这个时间实现长连接需要客户端和服务端都支持长连接
8、forward和redirect的区别?【仅供参考】forward是转发和redirect是重定向地址栏url显示fowardurl不会发生改变,redirecturl会发生改变;数据共享forward可以共享request里的数据,redirect不能共享;效率forward比redirect效率高9^spring有哪些主要模块?【仅供参考】springcore框架的最基础部分,提供ioc和依赖注入特性springcontext构建于core封装包基础上的context封装包,提供了一种框架式的对象访问方法springdao DataAccessObject提供了JDBC的抽象层springaop提供了面向切面的编程实现,让你可以自定义拦截器、切点等springWeb提供了针对Web开发的集成特性,例如文件上传,利用servletlisteners进行ioc容器初始化和针对Web的ApplicationContextospringWebmvc spring中的mvc封装包提供了Web应用的Model-View-ControllerMVC的实现
10、说一下springmvc运行流程?【仅供参考】springmvc先将请求发送给DispatcherServletoDispatcherServlet查询一个或多个HandlerMapping找到处理请求的ControlleroDispatcherServlet再把请求提交到对应的ControllerController进行业务逻辑处理后,会返回一个ModelAndViewDispathcher查询一个或多个ViewResolver视图解析器,找到ModelAndView对象指定的视图对象视图对象负责渲染返回给客户端
11、SpringBoot的核心注解是哪个?它主要由哪几个注解组成的?【仅供参考】启动类上面的注解是@SpringBootApplication它也是SpringBoot的核心注解,主要组合包含了以下3个注解@SpringBootConfiguration组合了©Configuration注解,实现配置文件的功能@Enab1eAutoConfiguration打开自动配置的功能,也可以关闭某个自动配置的选项,如关闭数据源自动配置功能@SpringBootApplicationexclude={DataSourceAutoConfiguration.class}@ComponentScan Spring组件扫描
12、SpringBootSpringMVC和Spring有什么区别?【仅供参考】Spring:Spring最重要的特征是依赖注入所有SpringModules不是依赖注入就是I0C控制反转当我们恰当的使用DI或者是I0C的时候,我们可以开发松耦合应用松耦合应用的单元测试可以很容易的进行SpringMVC:SpringMVC提供了一种分离式的方法来开发Web应用通过运用像DispatcherServeletMoudlAndView和ViewResolver等一些简单的概念,开发Web应用将会变的非常简单SpringBoot:Spring和SpringMVC的问题在于需要配置大量的参数SpringBoot通过一个自动配置和启动的项来目解决这个问题为了更快的构建产品就绪应用程序,SpringBoot提供了一些非功能性特征
13、springboot读取配置文件的方式【仅供参考】springboot默认读取配置文件为applicationproperties或者是applicationyml
14、JPA和Hibernate有哪些区别?【仅供参考】简而言之JPA是一个规范或者接口Hibernate是JPA的一个实现当我们使用JPA的时候,我们使用javax.persistence包中的注释和接口时,不需要使用hibernate的导入包我们建议使用JPA注释,因为哦我们没有将其绑定到Hibernate作为实现后来我知道-小于百分之一的几率,我们可以使用另一种JPA实现
15、SpringBoot还提供了其它的哪些StarterProjectOptions【仅供参考】SpringBoot也提供了其它的启动器项目包括,包括用于开发特定类型应用程序的典型依赖项spring-boot-starter-web-services-SOAPWebServices;spring-boot-starter-web-Web和RESTful应用程序;spring-boot-starter-test-单元测试和集成测试;spring-boot-starter-jdbc-传统的JDBC;spring-boot-starter-hateoas-为服务添加HATEOAS功能;spring-boot-starter-security一使用SpringSecurity进行身份验证和授权;spring-boot-starter-data-jpa一带有Hibeernate的SpringDataJPA;spring-boot-starter-data-rest-使用SpringDataREST公布简单的REST服务;16^为什么我们需要spring-boot-maven-plugin【仅供参考】spring-boot-maven-plugin提供了一些像jar一样打包或者运行应用程序的命令
1、spring-boot:run运行你的SpringBooty应用程序
2、spring-boot repackage重新打包你的jar包或者是war包使其可执行
3、spring-boot start和spring-boot stop管理SpringBoot应用程序的生命周期也可以说是为了集成测试
4、spring-boot:build-info生成执行器可以使用的构造信息
17、开启SpringBoot特性有哪几种方式?【仅供参考】1且米承spring-boot-starter-parent项目导入spring-boot-dependencies项目依赖
18、MyBatis有哪些执行器Executor.【仅供参考】MyBatis有三种基本的Executor执行器SimpleExecutor每执行一次update或select就开启一个Statement对象,用完立刻关闭Statement对象;ReuseExecutor执行update或select以SQL作为key查找Statement对象,存在就使用,不存在就创建,用完后不关闭Statement对象,而是放置于Map内供下一次使用简言之,就是重复使用Statement对象;BatchExecutor执行update没有selectjdbc批处理不支持select将所有SQL都添加到批处理中addBatchO等待统一执行executeBatch它缓存了多个Statement对象,每个Statement对象都是addBatch完毕后,等待逐一执行executeBatch批处理,与jdbc批处理相同
19、为什么要使用hibernate【仅供参考】hibernate是对jdbc的封装,大大简化了数据访问层的繁琐的重复性代码hibernate是一个优秀的ORM实现,很多程度上简化了DAO层的编码功能可以很方便的进行数据库的移植工作提供了缓存机制,是程序执行更改的高效
20、hibernate实体类必须要有无参构造函数吗?为什么?【仅供参考】hibernate中每个实体类必须提供一个无参构造函数,因为hibernate框架要使用reflectionapi通过调用Classnewlnstance来创建实体类的实例,如果没有无参的构造函数就会抛出异常
四、Java数据缓存,消息队列篇
1、RabbitMQ集群中唯一一个磁盘节点崩溃了会发生什么情况?【仅供参考】如果唯一磁盘的磁盘节点崩溃了,不能进行以下操作不能创建队列不能创建交换器不能创建绑定不能添加用户不能更改权限不能添加和删除集群节点唯一磁盘节点崩溃了,集群是可以保持运行的,但你不能更改任何东西
2、RabbitMQ有哪些重要的角色?
5、为什么不能根据返回类型来区分重载?【仅供参考】如果我们有两个方法如下,当我们调用test1时,编译器无法确认要调用的是哪个//方法1inttestinta;//方法2longtestinta;方法的返回值只是作为方法运行之后的一个“状态”,但是并不是所有调用都关注返回值,所以不能将返回值作为重载的唯一区分条件
6、重载Overload和重写Override的区别?【仅供参考】方法的重载和重写都是实现多态的方式,区别在于前者实现的是编译时的多态性,而后者实现的是运行时的多态性重载一个类中有多个同名的方法,但是具有有不同的参数列表参数类型不同、参数个数不同或者二者都不同重写发生在子类与父类之间,子类对父类的方法进行重写,参数都不能改变,返回值类型可以不相同,但是必须是父类返回值的派生类即外壳不变,核心重写!重写的好处在于子类可以根据需要,定义特定于自己的行为
7、抽象类abstractclass和接口interface有什么区别?【仅供参考】抽象类只能单继承,接口可以多实现抽象类可以有构造方法,接口中不能有构造方法抽象类中可以有成员变量,接口中没有成员变量,只能有常量默认就是publicstaticfinal抽象类中可以包含非抽象的方法,在Java7之前接口中的所有方法都是抽象的,在Java8之后,接口支持非抽象方法default方法、静态方法等Java9支持私有方法、私有静态方法抽象类中的方法类型可以是任意修饰符,Java8之前接口中的方法只能是public类型,Java9支持private类型设计思想的区别接口是自上而下的抽象过程,接口规范了某些行为,是对某一行为的抽象我需要这个行为,我就去实现某个接口,但是具体这个行为怎么实现,完全由自己决定抽象类是自下而上的抽象过程,抽象类提供了通用实现,是对某一类事物的抽【仅供参考】RabbitMQ中重要的角色有生产者、消费者和代理生产者消息的创建者,负责创建和推送数据到消息服务器;消费者消息的接收方,用于处理数据和确认消息;代理就是RabbitMQ本身,用于扮演“快递”的角色,本身不生产消息,只是扮演“快递”的角色
3、RabbitMQ的使用场景有哪些?【仅供参考】抢购活动,削峰填谷,防止系统崩塌延迟信息处理,比如10分钟之后给下单未付款的用户发送邮件提醒解耦系统,对于新增的功能可以单独写模块扩展,比如用户确认评价之后,新增了给用户返积分的功能,这个时候不用在业务代码里添加新增积分的功能,只需要把新增积分的接口订阅确认评价的消息队列即可,后面再添加任何功能只需要订阅对应的消息队列即可
4、RabbitMQ的消息是怎么发送的?【仅供参考】首先客户端必须连接到RabbitMQ服务器才能发布和消费消息,客户端和rabbitserver之间会创建一个tcp连接,一旦tcp打开并通过了认证(认证就是你发送给rabbit服务器的用户名和密码),你的客户端和RabbitMQ就创建了一条amqp信道(channel)信道是创建在“真实”tcp上的虚拟连接,amqp命令都是通过信道发送出去的,每个信道都会有一个唯一的id不论是发布消息、,订阅队列都是通过这个信道完成的
5、RabbitMQ怎么避免消息丢失?【仅供参考】把消息持久化磁盘,保证服务器重启消息不丢失每个集群中至少有一个物理磁盘,保证消息落入磁盘
6、zookeeper怎么保证主从节点的状态同步?【仅供参考】zookeeper的核心是原子广播,这个机制保证了各个server之间的同步实现这个机制的协议叫做zab协议zab协议有两种模式,分别是恢复模式(选主)和广播模式(同步)当服务启动或者在领导者崩溃后,zab就进入了恢复模式,当领导者被选举出来,且大多数server完成了和leader的状态同步以后,恢复模式就结束了状态同步保证了leader和server具有相同的系统状态
7、kafkaproducer如何优化打入速度?【仅供参考】增加线程提高batchsize增加更多producer实例增加partition数设置acks=-l时,如果延迟增大可以增大num.replicafetchers(follower同步数据的线程数)来调解;跨数据中心的传输增加socket缓冲区设置以及OStcp缓冲区设置
8、使用ka妹a集群需要注意什么?【仅供参考】集群的数量不是越多越好,最好不要超过7个,因为节点越多,消息复制需要的时间就越长,整个群组的吞吐量就越低集群数量最好是单数,因为超过一半故障集群就不能用了,设置为单数容错率更高9^集群中有3台服务器,其中一个节点宕机,这个时候zookeeper还可以使用吗?【仅供参考】可以继续使用,单数服务器只要没超过一半的服务器宕机就可以继续使用
10、kafka中的broker是干什么的?【仅供参考】broker是消息的代理,Producers往Brokers里面的指定Topic中写消息,Consumers从Brokers里面拉取指定Topic的消息,然后进行业务处理,broker在中间起到一个代理保存消息的中转站
11、说一下zookeeper的通知机制?【仅供参考】客户端端会对某个znode建立一个watcher事件,当该znode发生变化时,这些客户端会收到zookeeper的通知,然后客户端可以根据znode变化来做出业务上的改变
12、当你使用kafka-topics.sh创建删除了一个topic之后,Kafka背后会执行什么逻辑?【仅供参考】1会在zookeeper中的/brokers/topics节点下创建一个新的topic节点,如/brokers/topics/first2触发Controller的监听程序kafkaController负责topic的创建工作,并更新metadatacache
13、什么情况会导致kafka运行变慢?【仅供参考】cpu性能瓶颈磁盘读写瓶颈网络瓶颈
14、Redis持久化有几种方式?【仅供参考】Redis的持久化有两种方式,或者说有两种策略RDBRedisDatabase指定的时间间隔能对你的数据进行快照存储AOFAppendOnlyFile每一个收到的写命令都通过write函数追加到文件中
15、Redis有哪些功能?【仅供参考】数据缓存功能分布式锁的功能支持数据持久化支持事务支持消息队列
16、怎么保证缓存和数据库数据的一致性?【仅供参考】合理设置缓存的过期时间新增、更改、删除数据库操作时同步更新Redis可以使用事物机制来保证数据的一致性
17、Redis和memcache有什么区别?【仅供参考】存储方式不同memcache把数据全部存在内存之中,断电后会挂掉,数据不能超过内存大小;Redis有部份存在硬盘上,这样能保证数据的持久性数据支持类型memcache对数据类型支持相对简单;Redis有复杂的数据类型使用底层模型不同它们之间底层实现方式,以及与客户端之间通信的应用协议不一样,Redis自己构建了vm机制,因为一般的系统调用系统函数的话,会浪费一定的时间去移动和请求value值大小不同Redis最大可以达到512mb;memcache只有lmb
018、Redis为什么是单线程的?【仅供参考】因为cpu不是Redis的瓶颈,Redis的瓶颈最有可能是机器内存或者网络带宽既然单线程容易实现,而且cpu又不会成为瓶颈,那就顺理成章地采用单线程的方案了关于Redis的性能,官方网站也有,普通笔记本轻松处理每秒几十万的请求而且单线程并不代表就慢nginx和nodejs也都是高性能单线程的代表
19、Redis怎么实现分布式锁?【仅供参考】Redis分布式锁其实就是在系统里面占一个“坑”,其他程序也要占“坑”的时候,占用成功了就可以继续执行,失败了就只能放弃或稍后重试占坑一般使用setnxsetifnotexists指令,只允许被一个程序占有,使用完调用del释放锁
20、Redis是什么?都有哪些使用场景?【仅供参考】Redis是一个使用C语言开发的高速缓存数据库Redis使用场景记录帖子点赞数、点击数、评论数;缓存近期热帖;缓存文章详情信息;记录用户会话信息
五、MySQL篇
1、char和varchar的区别是什么?【仅供参考】rcharnJ固定长度类型,比如订阅char10当你输入〃abc〃三个字符的时候,它们占的空间还是10个字节,其他7个是空字节chat优点效率高;缺点占用空间;适用场景存储密码的md5值,固定长度的,使用char非常合适rvarcharnJ可变长度,存储的值是每个值占用的字节再加上一个用来记录其长度的字节的长度所以,从空间上考虑varcahr比较合适;从效率上考虑char比较合适,二者使用需要权衡
2、说一下MySQL的行锁和表锁?【仅供参考】MyISAM只支持表锁,InnoDB支持表锁和行锁,默认为行锁表级锁开销小,加锁快,不会出现死锁锁定粒度大,发生锁冲突的概率最高,并发量最低行级锁开销大,加锁慢,会出现死锁锁力度小,发生锁冲突的概率小,并发度最高
3、说一下MySQL常用的引擎?【仅供参考】InnoDB引擎mysql
5.1后默认的数据库引擎,提供了对数据库acid事务的支持,并且还提供了行级锁和外键的约束,它的设计的目标就是处理大数据容量的数据库系统MySQL运行的时候,InnoDB会在内存中建立缓冲池,用于缓冲数据和索引但是该引擎是不支持全文搜索,同时启动也比较的慢,它是不会保存表的行数的,所以当进行selectcount*fromtable指令的时候,需要进行扫描全表由于锁的粒度小,写操作是不会锁定全表的所以在并发度较高的场景下使用会提升效率的MylASM引擎不提供事务的支持,也不支持行级锁和外键因此当执行插入和更新语句时,即执行写操作的时候需要锁定这个表,所以会导致效率会降低不过和InnoDB不同的是,MylASM引擎是保存了表的行数,于是当进行selectcount*fromtable语句时,可以直接的读取已经保存的值而不需要进行扫描全表所以,如果表的读操作远远多于写操作时,并且不需要事务的支持的,可以将MylASM作为数据库引擎的首选
4、MySQL是如何保证主备同步?【仅供参考】主备关系的建立:一开始创建主备关系的时候,是由备库指定的,比如基于位点的主备关系,备库说“我要从binlog文件A的位置P”开始同步,主库就从这个指定的位置开始往后发而主备关系搭建之后,是主库决定要发给数据给备库的,所以主库有新的日志也会发给备库MySQL主备切换流程客户端读写都是直接访问A而节点B是备库,只要将A的更新都同步过来,到本地执行就可以保证数据是相同的当需要切换的时候就把节点换一下,A的节点B的备库一个事务完整的同步过程备库B和主库A建立来了长链接,主库A内部专门线程用于维护了这个长链接在备库B上通过changemaster命令设置主库A的IP端口用户名密码以及从哪个位置开始请求binlog包括文件名和日志偏移量在备库B上执行start-slave命令备库会启动两个线程io_thread和sql_thread分别负责建立连接和读取中转日志进行解析执行备库读取主库传过来的binlog文件备库收到文件写到本地成为中转日志后来由于多线程复制方案的引入,sqljhread演化成了多个线程
5、什么是WAL技术,有什么优点?【仅供参考】WAL中文全称是Write-AheadLogging它的关键点就是日志先写内存,再写磁盘MySQL执行更新操作后,在真正把数据写入到磁盘前,先记录日志好处是不用每一次操作都实时把数据写盘,就算crash后也可以通过redolog恢复,所以能够实现快速响应SQL语句
6、Xid在MySQL内部是怎么生成的呢?【仅供参考】MySQL内部维护了一个全局变量global_query_id每次执行语句(包括select语句)的时候将它赋值给Query_id然后给这个变量加1如果当前语句是这个事务执行的第一条语句,那么MySQL还会同时把Query_id赋值给这个事务的Xido而global_query_id是一个纯内存变量,重启之后就清零了所以你就知道了,在同一个数据库实例中,不同事务的Xid也是有可能相同的但是MySQL重启之后会重新生成新的binlog文件,这就保证了,同一个binlog文件里,Xid一定是惟一的
7、索引的常见类型以及它是如何发挥作用的【仅供参考】根据叶子节点的内容,索引类型分为主键索引和非主键索引主键索引的叶子节点存的整行数据,在InnoDB里也被称为聚簇索引非主键索引叶子节点存的主键的值,在InnoDB里也被称为二级索引
8、短时间提高MySQL性能的方法?【仅供参考】第一种方法先处理掉那些占着连接但是不工作的线程或者再考虑断开事务内空闲太久的连接killconnection+id第二种方法减少连接过程的消耗慢查询性能问题在MySQL中,会引发性能问题的慢查询,大体有以下三种可能索引没有设计好;SQL语句没写好;MySQL选错了索引forceindex
9、MySQL是如何保证数据不丢失的?【仅供参考】只要redolog和binlog保证持久化磁盘就能确保MySQL异常重启后回复数据在恢复数据时,redolog状态为commit则说明binlog也成功,直接恢复数据;如果redolog是prepare则需要查询对应的binlog事务是否成功,决定是回滚还是执行
10、count*实现方式以及各种count对比【仅供参考】对于count主键id来说,InnoDB引擎会遍历整张表,把每一行的id值都取出来,返回给server层server层拿到id后,判断是不可能为空的,就按行累加对于count1来说,InnoDB引擎遍历整张表,但不取值server层对于返回的每一行,放一个数字“1”进去,判断是不可能为空的,按行累加单看这两个用法的差别的话,你能对比出来,count1执行得要比count主键id快因为从引擎返回id会涉及到解析数据行,以及拷贝字段值的操作对于count字段来说如果这个“字段”是定义为notnull的话,一行行地从记录里面读出这个字段,判断不能为null按行累加;如果这个“字段”定义允许为null那么执行的时候,判断到有可能是null还要把值取出来再判断一下,不是null才累加也就是前面的第一条原则,server层要什么字段,InnoDB就返回什么字段但是count*是例外,并不会把全部字段取出来,而是专门做了优化,不取值count*肯定不是null按行累加所以结论是按照效率排序的话,count(字段)(count(主键id)〈count
(1)gcount(X)所以建议尽量使用count(*)o
11、说一下数据库的事务隔离?【仅供参考】MySQL的事务隔离是在MySQLini配置文件里添加的,在文件的最后添加«transaction-isolation=REPEATABLE-READ笫可用的配置值READ-UNCOMMITTED.READ-COMMITTEDREPEATABLE-READ、SERIALIZABLEoREAD-UNCOMMITTED未提交读,最低隔离级别、事务未提交前,就可被其他事务读取(会出现幻读、脏读、不可重复读)READ-COMMITTED提交读,一个事务提交后才能被其他事务读取到(会造成幻读、不可重复读)REPEATABLE-READ可重复读,默认级别,保证多次读取同一个数据时,其值都和事务开始时候的内容是一致,禁止读取到别的事务未提交的数据(会造成幻读)SERIALIZABLE序列化,代价最高最可靠的隔离级别,该隔离级别能防止脏读、不可重复读、幻读「脏读」表示一个事务能够读取另一个事务中还未提交的数据比如,某个事务尝试插入记录A此时该事务还未提交,然后另一个事务尝试读取到了记录Ao「不可重复读」是指在一个事务内,多次读同一数据「幻读」指同一个事务内多次查询返回的结果集不一样比如同一个事务A第一次查询时候有n条记录,但是第二次同等条件下查询却有n+1条记录,这就好像产生了幻觉发生幻读的原因也是另外一个事务新增或者删除或者修改了第一个事务结果集里面的数据,同一个记录的数据内容被修改了,所有数据行的记录就变多或者变少了
12、怎么验证MySQL的索引是否满足需求?【仅供参考】使用explain查看SQL是如何执行查询语句的,从而分析你的索引是否满足需求explain语法explainselect*fromtablewheretype=lo
13、数据库的三范式是什么?【仅供参考】第一范式强调的是列的原子性,即数据库表的每一列都是不可分割的原子数据项第二范式要求实体的属性完全依赖于主关键字所谓完全依赖是指不能存在仅依赖主关键字一部分的属性第三范式任何非主属性不依赖于其它非主属性
14、在MySQL中有两个kill命令?【仅供参考】一个是killquery+线程id表示终止这个线程中正在执行的语句一个是killconnection+线程id这里connection可缺省,表示断开这个线程的连接kill不掉的原因kill命令被堵了,还没到位kill命令到位了,但是没被立刻触发kill命令被触发了,但执行完也需要时间
15、MySQL的changebuffer是什么?【仅供参考】当需要更新一个数据页时,如果数据页在内存中就直接更新;而如果这个数据页还没有在内存中的话,在不影响数据一致性的前提下,InnoDB会将这些更新操作缓存在changebuffer中这样就不需要从磁盘中读入这个数据页了,在下次查询需要访问这个数据页的时候,将数据页读入内存,然后执行changebuffer中与这个页有关的操作通过这种方式就能保证这个数据逻辑的正确性注意唯一索引的更新就不能使用changebuffer实际上也只有普通索引可以使用适用场景-对于写多读少的业务来说,页面在写完以后马上被访问到的概率比较小,此时changebuffer的使用效果最好这种业务模型常见的就是账单类、日志类的系统-反过来,假设一个业务的更新模式是写入之后马上会做查询,那么即使满足了条件,将更新先记录在changebuffer但之后由于马上要访问这个数据页,会立即触发merge过程这样随机访问10的次数不会减少,反而增加了changebuffer的维护代价
16、MySQL的并行策略有哪些【仅供参考】按表分发策略如果两个事务更新不同的表,它们就可以并行因为数据是存储在表里的,所以按表分发,可以保证两个worker不会更新同一行缺点如果碰到热点表,比如所有的更新事务都会涉及到某一个表的时候,所有事务都会被分配到同一个worker中,就变成单线程复制了按行分发策略如果两个事务没有更新相同的行,它们在备库上可以并行如果两个事务没有更新相同的行,它们在备库上可以并行执行显然,这个模式要求binlog格式必须是row0缺点相比于按表并行分发策略,按行并行策略在决定线程分发的时候,需要消耗更多的计算资源
17、MySQL的大表查询为什么不会爆内存?【仅供参考】由于MySQL是边读变发,因此对于数据量很大的查询结果来说,不会再server端保存完整的结果集,所以,如果客户端读结果不及时,会堵住MySQL的查询过程,但是不会把内存打爆InnoDB引擎内部,由于有淘汰策略,InnoDB管理Buffer_Pool使用的是改进的LRU算法,使用链表实现,实现上,按照5:3的比例把整个LRU链表分成了young区域和old区域对冷数据的全扫描,影响也能做到可控制
18、关系型和非关系型数据库的区别?【仅供参考】关系型数据库的优点容易理解,因为它采用了关系模型来组织数据可以保持数据的一致性数据更新的开销比较小支持复杂查询(带where子句的查询)非关系型数据库(NOSQL)的优点无需经过SQL层的解析,读写效率高基于键值对,读写性能很高,易于扩展可以支持多种类型数据的存储,如图片,文档等等扩展(可分为内存性数据库以及文档型数据库,比如RedisMongoDBHBase等,适合场景数据量大高可用的日志系统/地理位置存储系统)
19、什么是覆盖索引和索引下推【仅供参考】覆盖索引在某个查询里面,索引k已经“覆盖了”我们的查询需求,称为覆盖索引象我们在写实现类的时候,发现某些实现类具有几乎相同的实现,因此我们将这些相同的实现抽取出来成为抽象类,然后如果有一些差异点,则可以提供抽象方法来支持自定义实现我在网上看到有个说法,挺形象的普通类像亲爹,他有啥都是你的抽象类像叔伯,有一部分会给你,还能指导你做事的方法接口像干爹,可以给你指引方法,但是做成啥样得你自己努力实现
8、==和equals的区别是什么?【仅供参考】==运算符,用于比较基础类型变量和引用类型变量对于基础类型变量,比较的变量保存的值是否相同,类型不一定要相同对于引用类型变量,比较的是两个对象的地址是否相同equals Object类中定义的方法,通常用于比较两个对象的值是否相等equals在Object方法中其实等同于==但是在实际的使用中,equals通常被重写用于比较两个对象的值是否相同
9、如何实现对象克隆?【仅供参考】实现Cloneable接口并重写Object类中的clone方法实现Serializable接口,通过对象的序列化和反序列化实现克隆,可以实现真正的深度克隆
10、StringStringBuffer和StringBuiIder区别【仅供参考】可变性String不可变StringBuffer和StringBuilder可变线程安全String不可变,因此是线程安全的StringBuilder不是线程安全的StringBuffer是线程安全的,内部使用synchronized进行同步
11、阐述final、finally、finalize的区别【仅供参考】其实是三个完全不相关的东西,只是长的有点像final如上所示覆盖索引可以减少树的搜索次数,显著提升查询性能,所以使用覆盖索引是一个常用的性能优化手段索引下推MySQL
5.6引入的索引下推优化indexconditionpushdown可以在索引遍历过程中,对索引中包含的字段先做判断,直接过滤掉不满足条件的记录,减少回表次数
20、MySQL使用索引的原因?【仅供参考】根本原因索引的出现,就是为了提高数据查询的效率,就像书的目录一样对于数据库的表而言,索引其实就是它的“目录”扩展创建唯一性索引,可以保证数据库表中每一行数据的唯一性帮助引擎层避免排序和临时表将随机10变为顺序10加速表和表之间的连接finally finally是对Java异常处理机制的最佳补充,通常配合try、catch使用,用于存放那些无论是否出现异常都一定会执行的代码在实际使用中,通常用于释放锁、数据库连接等资源,把资源释放方法放到finally中,可以大大降低程序出错的几率finalize Object中的方法,在垃圾收集器将对象从内存中清除出去之前做必要的清理工作finalize方法仅作为了解即可,在Java9中该方法已经被标记为废弃,并添加新的java.lang.ref.Cleaner提供了更灵活和有效的方法来释放资源这也侧面说明了,这个方法的设计是失败的,因此更加不能去使用它
12、BIO、NIO、AI0有什么区别【仅供参考】BIO Block10同步阻塞式10就是我们平常使用的传统10它的特点是模式简单使用方便,并发处理能力低NIO Non10同步非阻塞10是传统10的升级,客户端和服务器端通过Channel通道通讯,实现了多路复用AIO Asynchronous10是NI0的升级,也叫NI02实现了异步非堵塞10异步10的操作基于事件和回调机制
13、Object常用方法有哪些?【仅供参考】Java面试经常会出现的一道题目,Object的常用方法下面给大家整理一下Object常用方法有toStringOequalshashCodeclone等
14、==和equals的区别是什么?【仅供参考】对于基本类型和引用类型==的作用效果是不同的基本类型比较的是值是否相同;引用类型比较的是引用是否相同;equals本质上就是==只不过String和Integer等重写了equals方法==对于基本类型来说是值比较,对于引用类型来说是比较的是引用;而equals默认情况下是引用比较,只是很多类重新了equals方法,比如StringsInteger等把它变成了值比较,所以一般情况下equals比较的是值是否相等
15、Java常见异常有哪些【仅供参考】java.lang.IllegalAccessError违法访问错误当一个应用试图访问、修改某个类的域(Field)或者调用其方法,但是又违反域或方法的可见性声明,则抛出该异常java.lang.InstantiationError实例化错误当一个应用试图通过Java的new操作符构造一个抽象类或者接口时抛出该异常.java.lang.OutOfMemoryError内存不足错误当可用内存不足以让Java虚拟机分配给一个对象时抛出该错误java.lang.StackOverflowError堆栈溢出错误当一个应用递归调用的层次太深而导致堆栈溢出或者陷入死循环时抛出该错误java.lang.ClassCastException类造型异常假设有类A和B(A不是B的父类或子类),是A的实例,那么当强制将构造为类B的实例时抛出该异常该异常经常被称为强制类型转换异常java.lang.ClassNotFoundException找不到类异常当应用试图根据字符串形式的类名构造类,而在遍历CLASSPAH之后找不到对应名称的class文件时,抛出该异常java.lang.ArithmeticException算术条件异常譬如:整数除零等java.lang.ArraylndexOutOfBoundsException数组索引越界异常当对数组的索引值为负数或大于等于数组大小时抛出java.lang.IndexOutOfBoundsException索引越界异常当访问某个序列的索引值小于0或大于等于序列大小时,抛出该异常java.lang.InstantiationException实例化异常当试图通过newlnstance()方法创建某个类的实例,而该类是一个抽象类或接口时,抛出该异常java.lang.NoSuchFieldException属性不存在异常当访问某个类的不存在的属性时抛出该异堂rpojava.lang.NoSuchMethodException方法不存在异常当访问某个类的不存在的方法时抛出该异常-java.lang.NullPointerException空指针异常当应用试图在要求使用对象的地方使用了null时:抛出该异常譬如调用null对象的实例方法、访问null对象的属性、计算null对象的长度、使用throw语句抛出null等等java.lang.NumberFormatException数字格式异常当试图将一个String转换为指定的数字类型,而该字符串确不满足数字类型要求的格式时,抛出该异常java.lang.StringlndexOutOfBoundsException字符串索引越界异常当使用索引值访问某个字符串中的字符,而该索引值小于0或大于等于序列大小时,抛出该异常
16、throw和throws的区别是什么?【仅供参考】Java中的异常处理除了包括捕获异常和处理异常之外,还包括声明异常和抛出异常,可以通过throws关键字在方法上声明该方法要抛出的异常,或者在方法内部通过throw抛出异常对象throws关键字和throw关键字在使用上的几点区别如下throw关键字用在方法内部,只能用于抛出一种异常,用来抛出方法或代码块中的异常,受查异常和非受查异常都可以被抛出throws关键字用在方法声明上,可以抛出多个异常,用来标识该方法可能抛出的异常列表一个方法用throws标识了可能抛出的异常列表,调用该方法的方法中必须包含可处理异常的代码,否则也要在方法签名中用throws关键字声明相应的异常
17、try-catch-finally中,如果catch中return了,finally还会执行吗?【仅供参考】答会执行,在return前执行注意在finally中改变返回值的做法是不好的,因为如果存在finally代码块,try中的return语句不会立马返回调用者,而是记录下返回值待finally代码块执行完毕之后再向调用者返回其值,然后如果在finally中修改了返回值,就会返回修改后的值显然,在finally中返回或者修改返回值会对程序造成很大的困扰,C#中直接用编译错误的方式来阻止程序员干这种龌龊的事情,Java中也可以通过提升编译器的语法检查级别来产生警告或错误
18、finalfinally、finalize有什么区别?【仅供参考】final是修饰符,如果修饰类,此类不能被继承;如果修饰方法和变量,则表示此方法和此变量不能在被改变,只能使用finally是try{}catch{}finally{}最后一部分,表示不论发生任何情况都会执行,finally部分可以省略,但如果finally部分存在,则一定会执行finally里面的代码finalize是Object类的一个方法,在垃圾收集器执行的时候会调用被回收对象的此方法
19、Error和Exception区别是什么?【仅供参考】Error类型的错误通常为虚拟机相关错误,如系统崩溃,内存不足,堆栈溢出等,编译器不会对这类错误进行检测,JAVA应用程序也不应对这类错误进行捕获,一旦这类错误发生,通常应用程序会被终止,仅靠应用程序本身无法恢复;Exception类的错误是可以在应用程序中进行捕获并处理的,通常遇到这种错误,应对其进行处理,使应用程序可以继续正常运行
20、运行时异常和一般异常受检异常区别是什么【仅供参考】运行时异常包括RuntimeException类及其子类,表示JVM在运行期间可能出现的异常Java编译器不会检查运行时异常受检异常是Exception中除RuntimeException及其子类之外的异常Java编译器会检查受检异常RuntimeException异常和受检异常之间的区别是否强制要求调用者必须处理此异常,如果强制要求调用者必须进行处理,那么就使用受检异常,否则就选择非受检异常RuntimeExceptiono一般来讲,如果没有特殊的要求,我们建议使用RuntimeException异常
二、Java进阶篇
1、HashMap的插入流程是怎么样的?【仅供参考】略,从基本逻辑处理,到红黑树,到链表讲解2^多线程中synchronized锁升级的原理是什么?【仅供参考】synchronized锁升级原理在锁对象的对象头里面有一个threadid字段,在第一次访问的时候threadid为空,jvm让其持有偏向锁,并将threadid设置为其线程id再次进入的时候会先判断threadid是否与其线程id一致,如果一致则可以直接使用此对象,如果不一致,则升级偏向锁为轻量级锁,通过自旋循环一定次数来获取锁,执行一定次数之后,如果还没有正常获取到要使用的对象,此时就会把锁从轻量级升级为重量级锁,此过程就构成了synchronized锁的升级锁的升级的目的锁升级是为了减低了锁带来的性能消耗在Java6之后优化synchronized的实现方式,使用了偏向锁升级为轻量级锁再升级到重量级锁的方式,从而减低了锁带来的性能消耗
3、什么是死锁?【仅供参考】当线程A持有独占锁a并尝试去获取独占锁b的同时,线程B持有独占锁b并尝试获取独占锁a的情况下,就会发生AB两个线程由于互相持有对方需要的锁,而发生的阻塞现象,我们称为死锁
4、守护线程是什么?【仅供参考】守护线程是运行在后台的一种特殊进程它独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件在Java中垃圾回收线程就是特殊的守护线程
5、说一下atomic的原理?【仅供参考】atomic主要利用CASCompareAndWwap和volatile和native方法来保证原子操作,从而避免synchronized的高开销,执行效率大为提升
6、线程B怎么知道线程A修改了变量【仅供参考】volatile修饰变量synchronized修饰修改变量的方法wait/notifywhile轮询
7、线程和进程的区别?【仅供参考】一个程序下至少有一个进程,一个进程下至少有一个线程,一个进程下也可以有多个线程来增加程序的执行速度
8、如何停止一个正在运行的线程?【仅供参考】有几种方式
1、使用线程的stop方法使用stop方法可以强制终止线程不过stop是一个被废弃掉的方法,不推荐使用使用stop方法,会一直向上传播ThreadDeath异常,从而使得目标线程解锁所有锁住的监视器,即释放掉所有的对象锁使得之前被锁住的对象得不到同步的处理,因此可能会造成数据不一致的问题
2、使用intemppt方法中断线程,该方法只是告诉线程要终止,但最终何时终止取决于计算机调用interrupt方法仅仅是在当前线程中打了一个停止的标记,并不是真的停止线程接着调用Thread.currentThread.islnterrupted方法,可以用来判断当前线程是否被终止,通过这个判断我们可以做一些业务逻辑处理,通常如果islnterrupted返回true的话,会抛一个中断异常,然后通过try-catch捕狄
3、设置标志位设置标志位,当标识位为某个值时,使线程正常退出设置标志位是用到了共享变量的方式,为了保证共享变量在内存中的可见性,可以使用volatile修饰它,这样的话,变量取值始终会从主存中获取最新值但是这种volatile标记共享变量的方式,在线程发生阻塞时是无法完成响应的比如调用Threadsleep方法之后,线程处于不可运行状态,即便是主线程修改了共享变量的值,该线程此时根本无法检查循环标志,所以也就无法实现线程中断。