Java面试题(99%会问)

spring的IOC和AOP

Spring:

Spring:框架是个轻量级的Java EE框架。所谓轻量级,是指不依赖于容器就能运行的。

spring提供了AOP技术,支持将一些通用任务,如安全,事物,日志,权限等进行集中

式管理,从而提供了跟那个好的复用

springAOP

一般为面向切面,作为面向对象的一种补充。他减少了系统中的重复代码,降低了

模块间的耦合度,同时提高了系统的可维护性。可用于权限认证,日志,事务处理

spring的五种通知类型:前置通知,正常返回通知 ,异常返回通知,返回通知,环绕通知

springAOP使用的动态代理,所谓的动态代理就是说AOP框架不会去修改字节码,而是每

次运行时在内存中临时为方法生成一个AOP对象,这个AOP对象包含了目标对象的全部方法,

并且在特定的切点做了增强处理,并回调对象的方法。

Spring AOP中的动态代理主要有两种模式,JDK动态代理和CGLIB动态代理:

spring IOC

ioc是一个容器,在spring中,他会认为一切Java资源都是JavaBean。容器的目标

就是管理这些bean和他们之间的关系;spring ioc容器能够对其管理,只是springioc

管理。对象和其依赖关系,采取的不是为的主动创建。

SpringMVC

Spring MVC 提供了一种分离式的方法来开发 Web 应用。通过运用像 DispatcherServelet,MoudlAndView 和 ViewResolver 等一些简单的概念,开发 Web 应用将会变的非常简单。

spring boot

为什么使用springboot(或者说有点)!

独立于运行,简单配置,自动配置,无代码生成和XML配置,应用监控,上手容易

什么是spring boot

是spring开源组织下的子项目,是spring组成一站式解决方案,主要简化了使用spring

的难度,简省了繁重的配置,提供了各种启动器

如何理解springboot中的starters

Starters可以理解成启动器,它包含了一系列可以集成到应用里面看你的依赖包,

你可以一站式集成spring及其其他技术,而不需要到处找示例代码和依赖包,

如果你想使用springJPA访问数据库,只要加入spring-boot-starter-data-jpa启动器,依赖

就能使用了

springboot支持那些日志框架,推荐和默认那个

支持:java util logging,log4j,logback,如果使用starters启动器,springboot将使用

log back作为默认日志框架

springcloud

什么是Eureka的自我保护机制?

Eureka如果收到的微服务心跳相对于应该收到的微服务心跳来说,如果低于了85%,那么就会触发Eureka的自我保护机制。一旦自我保护机制启动,Eureka会保护所有的微服务,不被移除,哪怕当前微服务已经下线,仍然会保留到Eureka微服务列表中。

自我保护机制的作用

为什么Eureka要一种看起来如此傻逼的设计?- 自我保护机制是为了保证微服务间的高可用性,避免脑裂的影响

为什么Zookeeper要设计一个过半数存活原则?感觉特别浪费资源? - 为了让整个集群一定只有一个Leader

CAP原则:任何一个分布式系统,都只能满足CAP中的2个原则,因为分区问题不可避免,所以P是必选的,一般的系统,都是从C和A中做选择。Zookeeper是CP设计,而Eureka是AP设计。

C(一致性)

A(可用性)

P(分区容错性)

什么是Ribbon?

Ribbon是一个客户端的负载均衡器,用来进行SpringCloud间的微服务负载均衡调用

为什么有了Ribbon还有用Feign?

Feign底层也调用了Ribbon,Feign其实本质上是Ribbon + Hystrix(豪猪)的集合体,因为Ribbon本身的写法不够面向对象,很多Java程序员对这种写法会很不习惯。

Hystrix-断路器

1、 什么是断路器

断路器 - 就是微服务架构的保险丝

2、为什么需要Hystrix(保险丝)?

在微服务架构中,根据业务会拆分成一个一个为微服务,服务于服务之间可以互相调用。为了保证高可用性,单个服务通常会集群部署,但是由于网络等原因,不能保证服务100%可用。如果单个服务出现问题,调用这个服务的服务就有可能出现线程阻塞,刚好这个时候大量的请求在访问当前服务,就会导致当前服务的线程资源不足,从而导致服务瘫痪,形成故障转移,导致**“服务雪崩”**

3、Hystrix是如何解决服务间调用问题的

资源隔离:鸡蛋不要放在一个篮子里(线程池隔离、信号量隔离)

服务降级:当调用目标服务出问题(超时、报错…)时,会自动的调用一个本地的方法,返回一个默认值

请求熔断:一旦确定目标服务出问题(失败比例),Hystrix的熔断器会自动打开,拦截后续的所有请求,立刻判定失败,进行服务降级。过了单位时间之后,熔断器变成半开状态,放行一个请求,如果还是失败,继续全开,拦截请求,否则熔断器关闭。

Hystrix是如何解决服务间调用问题的?

资源的隔离:线程池、信号量隔离

服务的降级(自动降级):当调用目标服务出问题后,会自动降级调用一个默认的方法返回一个默认值

调用的熔断:一旦目标服务出现问题,熔断器就会触发,后续的服务就不会再尝试调用目标服务,而是直接走降级流程

路由网关

1、什么是路由网关?

简单来说,路由网关往往是微服务架构的入口组件,外来的所有的请求,都需要通过路由网关进行分发和过滤。路由网关的核心功能:请求的路由请求的过滤

2、为什么需要路由网关?

路由网关提供了外部请求的访问入口,所有的外部请求都只需要知道路由网关的地址就行了,无需知道每个微服务的访问地址,路由网关可以将外部的请求负载分发给不同的微服务,这样可以对外屏蔽微服务架构内部的结构。因为路由网关往往是外部请求访问微服务架构的入口,所以可以在路由网关做请求过滤的工作。

SpringCloud默认提供了2个路由网关,Zuul和Gateway,Zuul是网飞(netflix)提供的路由组件,而Gateway是SpringCloud团队自己开发的一款路由组件,用来替换Zuul的

微服务配置的统一管理(其他微服务的配置全部交由统一配置中心管理)

1)将所有微服务的application.yml放到统一配置中心的指定目录下(git、svn需要传到指定的仓库中)

2)所有微服务添加依赖

3、统一配置需要注意的一些地方

1、如果配置文件是放在Config Server本地管理的,那么每次修改配置文件,都必须重启Config Server才会生效

2、如果配置文件是放在Config Server的git、SVN仓库中管理的,那么每次修改配置文件,不用重启Config Server,会自动生效

3、不管配置文件放在哪里,每次修改配置文件,所有的Config Client(微服务),都必须重启才有效。原因在于Config Client只有在启动的时候会去抓一次配置,然后配置就缓存到本地了,后续所有的代码都是从本地获得配置,因此服务的变化,是无感知的,这也是一种优化的结果

1、什么是RabbitMQ(Message Queue)?

rabbitmq是实现了AMQP通讯协议的一种MQ组件。主要是用于分布式服务之间的消息通讯。类似的产品有(RocketMQ、Kafka、ActiveMQ…)

为什么有了Dubbo,还需要学习RabbitMQ?

​ 因为Dubbo是同步请求,MQ是可以将消息异步化处理,提高服务和服务间的通讯效率(消息异步化不止是MQ的唯一的作用)。

Redis

什么是Redis?

redis是一种非关系型(NoSQL)数据库,主要以Key-Value形式存储数据,数据存储在内存中,读写速度很快(10W/s)。

五种类型

1)字符串(String)- 数据结构特点 :key - value

​ 2)哈希结构(Hash)- 数据结构特点:key - (field-value,field2-value2…)

​ 主要作用:存储复杂对象

​ 3)链表(List)- 数据结构特点:key - value1,value2,value3… 有序可重复,因为是双向链表,可以从两头操作元素

​ 底层是一个双向链表 - LinkedList

​ 主要作用:可以用来模拟队列、栈

​ 4)集合(Set)- 数据结构特点:key - value3,value2,value6,value4… 无序不可重复

​ 底层是一个哈希表 - HashMap

​ 主要作用:判定元素是否存在

​ 5)有序集合(SortSet)- 数据结构特点:key - (score1 value1),(score2 value2)… 根据权重排序,小->大

​ 底层是一个跳跃表

​ 主要作用:可以用来模拟优先级队列

redis的持久化

​ redis相对于其他的nosql数据库的区别,在于提供了数据持久化的功能两个,也就是redis的数据除了会放入内存,也会按照一定的频率写入硬盘,以此保证数据的安全。

redis的有两种持久化方式:

​ 1)rdb - (快照,默认采用快照)

什么是快照? - 就是将当前redis的内存结构,整体保存下载,写入磁盘。

2)aof - (append only file 只追加文件,默认关闭)

什么是只追加文件? - 从redis服务启动之后,记录下所有的写命令,到磁盘文件中,当需要恢复数据时,依次执行这些写命令。

缓存服务的相关概念:

1、缓存穿透:

有人恶意的访问不存在的数据,因为缓存中和数据中都不存在,所以这些请求都会到达数据库,依次增加数据的压力,导致数据库崩溃

解决方案:

​ 1)根据访问频率,在上游拦截恶意ip的请求

​ 2)redis中直接缓存null值

​ 3)基于布隆过滤器做数据过滤,布隆过滤器可以判断出来一个值是否不存在或者可能存在

2、缓存失效:

有一个非常非常非常热点的数据,到达了过期时间,这时大量的请求访问这个数据,可能导致大量的请求去访问数据库进行缓存重建。

解决方案:

​ 1)通过分布式锁,只让一个请求去重建缓存

​ 2)热点数据设置为不过期(不推荐)

3、缓存雪崩:

多个缓存在同一时间,一起失效,导致大量的请求同时去重建缓存

解决方案:

​ 1)可以将缓存的时间设置为:固定值 + 随机数,比如5分钟 + (5~10分钟随机时间)

4、缓存预热:

在项目上线前,提前将热点数据放入缓存中 (大数据分析)

Zookeeper

什么是Zookeeper?

​ Zookeeper是高效的分布式一致性协调服务,通常可以用来进行服务的管理、分布式锁、配置的统一管理、命名服务等等…

Solr

Solr是如何实现高效的全文检索的

​ Solr的底层是基于Lucene全文检索框架实现的一个高性能检索服务

ElasticSearch

什么是ElasticSearch?

Elasticsearch是一个基于Lucene的搜索引擎。它提供了具有HTTP Web界面和无架构JSON文档的分布式,多租户能力的全文搜索引擎。Elasticsearch是用Java开发的,根据Apache许可条款作为开源发布。

Elasticsearch中的倒排索引是什么?

倒排索引是搜索引擎的核心。搜索引擎的主要目标是在查找发生搜索条件的文档时提供快速搜索。倒排索引是一种像数据结构一样的散列图,可将用户从单词导向文档或网页。它是搜索引擎的核心。其主要目标是快速搜索从数百万文件中查找数据。

一般情况下,像下面的一样,在书中我们已经倒过来索引。根据这个词,我们可以找到这个词所在的页面。

Mybatis

1、什么是Mybatis?

在Mybatis的所有操作都是基于一个SqlSession的,而SqlSession是由SqlSessionFactory来产生
的,SqlSessionFactory又是由SqlSessionFactoryBuilder来生成的

(1)Mybatis是一个半ORM(对象关系映射)框架,它内部封装了JDBC,开发时只需要关注SQL语句本身,不需要花费精力去处理加载驱动、创建连接、创建statement等繁杂的过程。程序员直接编写原生态sql,可以严格控制sql执行性能,灵活度高。

(2)MyBatis 可以使用 XML 或注解来配置和映射原生信息,将 POJO映射成数据库中的记录,避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。

(3)通过xml 文件或注解的方式将要执行的各种 statement 配置起来,并通过java对象和 statement中sql的动态参数进行映射生成最终执行的sql语句,最后由mybatis框架执行sql并将结果映射为java对象并返回。(从执行sql到返回result的过程)。

2、Mybaits的优点:

(1)基于SQL语句编程,相当灵活,不会对应用程序或者数据库的现有设计造成任何影响,SQL写在XML里,解除sql与程序代码的耦合,便于统一管理;提供XML标签,支持编写动态SQL语句,并可重用。

(2)与JDBC相比,减少了50%以上的代码量,消除了JDBC大量冗余的代码,不需要手动开关连接;

(3)很好的与各种数据库兼容(因为MyBatis使用JDBC来连接数据库,所以只要JDBC支持的数据库MyBatis都支持)。

(4)能够与Spring很好的集成;

(5)提供映射标签,支持对象与数据库的ORM字段关系映射;提供对象关系映射标签,支持对象关系组件维护。

3、MyBatis框架的缺点:

(1)SQL语句的编写工作量较大,尤其当字段多、关联表多时,对开发人员编写SQL语句的功底有一定要求。

(2)SQL语句依赖于数据库,导致数据库移植性差,不能随意更换数据库。

4、MyBatis框架适用场合:

(1)MyBatis专注于SQL本身,是一个足够灵活的DAO层解决方案。

(2)对性能的要求很高,或者需求变化较多的项目,如互联网项目,MyBatis将是不错的选择。

5、MyBatis与Hibernate有哪些不同?

(1)Mybatis和hibernate不同,它不完全是一个ORM框架,因为MyBatis需要程序员自己编写Sql语句。

(2)Mybatis直接编写原生态sql,可以严格控制sql执行性能,灵活度高,非常适合对关系数据模型要求不高的软件开发,因为这类软件需求变化频繁,一但需求变化要求迅速输出成果。但是灵活的前提是mybatis无法做到数据库无关性,如果需要实现支持多种数据库的软件,则需要自定义多套sql映射文件,工作量大。

(3)Hibernate对象/关系映射能力强,数据库无关性好,对于关系模型要求高的软件,如果用hibernate开发可以节省很多代码,提高效率。

6、#{}和${}的区别是什么?

#{}是预编译处理,${}是字符串替换。

Mybatis在处理#{}时,会将sql中的#{}替换为?号,调用PreparedStatement的set方法来赋值;

Mybatis在处理 时 , 就 是 把 {}时,就是把 {}替换成变量的值。

使用#{}可以有效的防止SQL注入,提高系统安全性。

Spring SSM

SpringMVC

Spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面。Spring MVC 分离了控制器、模型对象、分派器以及处理程序对象的角色,这种分离让它们更容易进行定制。

Spring MVC主要由DispatcherServlet、处理器映射、处理器(控制器)、视图解析器、视图组成

他的两个核心是:

处理器映射:选择使用哪个控制器来处理请求
视图解析器:选择结果应该如何渲染

通过以上两点,Spring MVC保证了如何选择控制处理请求和如何选择视图展现输出之间的松耦合。

Redis

缓存服务的相关概念:
1、缓存穿透:有人恶意的访问不存在的数据,因为缓存中和数据中都不存在,所以这些请求都会到达数据库,依次增加数据的压力,导致数据库崩溃

解决方案:

​ 1)根据访问频率,在上游拦截恶意ip的请求

​ 2)redis中直接缓存null值

​ 3)基于布隆过滤器做数据过滤,布隆过滤器可以判断出来一个值是否不存在或者可能存在

2、缓存失效:有一个非常非常非常热点的数据,到达了过期时间,这时大量的请求访问这个数据,可能导致大量的请求去访问数据库进行缓存重建。

解决方案:

​ 1)通过分布式锁,只让一个请求去重建缓存

​ 2)热点数据设置为不过期(不推荐)

3、缓存雪崩:多个缓存在同一时间,一起失效,导致大量的请求同时去重建缓存

解决方案:

​ 1)可以将缓存的时间设置为:固定值 + 随机数,比如5分钟 + (5~10分钟随机时间)

4、缓存预热:在项目上线前,提前将热点数据放入缓存中 (大数据分析)
什么是Redis

Redis(Remote Dictionary Server) 是一个使用 C 语言编写的,开源的(BSD许可)高性能非关系型(NoSQL)的键值对数据库。

Redis 可以存储键和五种不同类型的值之间的映射。键的类型只能为字符串,值支持五种数据类型:字符串、列表、集合、散列表、有序集合。

与传统数据库不同的是 Redis 的数据是存在内存中的,所以读写速度非常快,因此 redis 被广泛应用于缓存方向,每秒可以处理超过 10万次读写操作,是已知性能最快的Key-Value DB。另外,Redis 也经常用来做分布式锁。除此之外,Redis 支持事务 、持久化、LUA脚本、LRU驱动事件、多种集群方案。

Redis有哪些优缺点

优点

读写性能优异, Redis能读的速度是110000次/s,写的速度是81000次/s。
支持数据持久化,支持AOF和RDB两种持久化方式。
支持事务,Redis的所有操作都是原子性的,同时Redis还支持对几个操作合并后的原子性执行。
数据结构丰富,除了支持string类型的value外还支持hash、set、zset、list等数据结构。
支持主从复制,主机会自动将数据同步到从机,可以进行读写分离。

缺点

数据库容量受到物理内存的限制,不能用作海量数据的高性能读写,因此Redis适合的场景主要局限在较小数据量的高性能操作和运算上。
Redis 不具备自动容错和恢复功能,主机从机的宕机都会导致前端部分读写请求失败,需要等待机器重启或者手动切换前端的IP才能恢复。
主机宕机,宕机前有部分数据未能及时同步到从机,切换IP后还会引入数据不一致的问题,降低了系统的可用性。
Redis 较难支持在线扩容,在集群容量达到上限时在线扩容会变得很复杂。为避免这一问题,运维人员在系统上线时必须确保有足够的空间,这对资源造成了很大的浪费。
Redis为什么这么快

1、完全基于内存,绝大部分请求是纯粹的内存操作,非常快速。数据存在内存中,类似于 HashMap,HashMap 的优势就是查找和操作的时间复杂度都是O(1);

2、数据结构简单,对数据操作也简单,Redis 中的数据结构是专门进行设计的;

3、采用单线程,避免了不必要的上下文切换和竞争条件,也不存在多进程或者多线程导致的切换而消耗 CPU,不用去考虑各种锁的问题,不存在加锁释放锁操作,没有因为可能出现死锁而导致的性能消耗;

4、使用多路 I/O 复用模型,非阻塞 IO;

5、使用底层模型不同,它们之间底层实现方式以及与客户端之间通信的应用协议不一样,Redis 直接自己构建了 VM 机制 ,因为一般的系统调用系统函数的话,会浪费一定的时间去移动和请求;

缓存雪崩

缓存雪崩是指缓存同一时间大面积的失效,所以,后面的请求都会落到数据库上,造成数据库短时间内承受大量请求而崩掉。

解决方案

缓存数据的过期时间设置随机,防止同一时间大量数据过期现象发生。
一般并发量不是特别多的时候,使用最多的解决方案是加锁排队。
给每一个缓存数据增加相应的缓存标记,记录缓存的是否失效,如果缓存标记失效,则更新数据缓存。
缓存穿透

缓存穿透是指缓存和数据库中都没有的数据,导致所有的请求都落到数据库上,造成数据库短时间内承受大量请求而崩掉。

解决方案

接口层增加校验,如用户鉴权校验,id做基础校验,id<=0的直接拦截;
从缓存取不到的数据,在数据库中也没有取到,这时也可以将key-value对写为key-null,缓存有效时间可以设置短点,如30秒(设置太长会导致正常情况也没法使用)。这样可以防止攻击用户反复用同一个id暴力攻击
采用布隆过滤器,将所有可能存在的数据哈希到一个足够大的 bitmap 中,一个一定不存在的数据会被这个 bitmap 拦截掉,从而避免了对底层存储系统的查询压力

附加

对于空间的利用到达了一种极致,那就是Bitmap和布隆过滤器(Bloom Filter)。
Bitmap: 典型的就是哈希表
缺点是,Bitmap对于每个元素只能记录1bit信息,如果还想完成额外的功能,恐怕只能靠牺牲更多的空间、时间来完成了。

布隆过滤器(推荐)

就是引入了k(k>1)k(k>1)个相互独立的哈希函数,保证在给定的空间、误判率下,完成元素判重的过程。
它的优点是空间效率和查询时间都远远超过一般的算法,缺点是有一定的误识别率和删除困难。
Bloom-Filter算法的核心思想就是利用多个不同的Hash函数来解决“冲突”。
Hash存在一个冲突(碰撞)的问题,用同一个Hash得到的两个URL的值有可能相同。为了减少冲突,我们可以多引入几个Hash,如果通过其中的一个Hash值我们得出某元素不在集合中,那么该元素肯定不在集合中。只有在所有的Hash函数告诉我们该元素在集合中时,才能确定该元素存在于集合中。这便是Bloom-Filter的基本思想。
Bloom-Filter一般用于在大数据量的集合中判定某元素是否存在。

缓存击穿

缓存击穿是指缓存中没有但数据库中有的数据(一般是缓存时间到期),这时由于并发用户特别多,同时读缓存没读到数据,又同时去数据库去取数据,引起数据库压力瞬间增大,造成过大压力。和缓存雪崩不同的是,缓存击穿指并发查同一条数据,缓存雪崩是不同数据都过期了,很多数据都查不到从而查数据库。

解决方案

设置热点数据永远不过期。
加互斥锁,互斥锁

持久化

什么是Redis持久化?

持久化就是把内存的数据写到磁盘中去,防止服务宕机了内存数据丢失。

Redis 的持久化机制是什么?各自的优缺点?

Redis 提供两种持久化机制 RDB(默认) 和 AOF 机制:

RDB:是Redis DataBase缩写快照

RDB是Redis默认的持久化方式。按照一定的时间将内存的数据以快照的形式保存到硬盘中,对应产生的数据文件为dump.rdb。通过配置文件中的save参数来定义快照的周期。

优点:

1、只有一个文件 dump.rdb,方便持久化。
2、容灾性好,一个文件可以保存到安全的磁盘。
3、性能最大化,fork 子进程来完成写操作,让主进程继续处理命令,所以是 IO 最大化。使用单独子进程来进行持久化,主进程不会进行任何 IO 操作,保证了 redis 的高性能
4.相对于数据集大时,比 AOF 的启动效率更高。

缺点:

1、数据安全性低。RDB 是间隔一段时间进行持久化,如果持久化之间 redis 发生故障,会发生数据丢失。所以这种方式更适合数据要求不严谨的时候)
2、AOF(Append-only file)持久化方式: 是指所有的命令行记录以 redis 命令请 求协议的格式完全持久化存储)保存为 aof 文件。

AOF:持久化

AOF持久化(即Append Only File持久化),则是将Redis执行的每次写命令记录到单独的日志文件中,当重启Redis会重新将持久化的日志中文件恢复数据。

当两种方式同时开启时,数据恢复Redis会优先选择AOF恢复。

img

优点:

1、数据安全,aof 持久化可以配置 appendfsync 属性,有 always,每进行一次 命令操作就记录到 aof 文件中一次。
2、通过 append 模式写文件,即使中途服务器宕机,可以通过 redis-check-aof 工具解决数据一致性问题。
3、AOF 机制的 rewrite 模式。AOF 文件没被 rewrite 之前(文件过大时会对命令 进行合并重写),可以删除其中的某些命令(比如误操作的 flushall))

缺点:

1、AOF 文件比 RDB 文件大,且恢复速度慢。
2、数据集大的时候,比 rdb 启动效率低。

优缺点是什么?

AOF文件比RDB更新频率高,优先使用AOF还原数据。
AOF比RDB更安全也更大
RDB性能比AOF好
如果两个都配了优先加载AOF

事务管理(ACID)概述

原子性(Atomicity)

原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。

一致性(Consistency)

事务前后数据的完整性必须保持一致。

隔离性(Isolation)

多个事务并发执行时,一个事务的执行不应影响其他事务的执行

持久性(Durability)

持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响

hashMap和hashtable方面的知识点:

  1. 关于HashMap的一些说法:

a) HashMap实际上是一个“链表散列”的数据结构,即数组和链表的结合体。HashMap的底层结构是一个数组,数组中的每一项是一条链表。

c) HashMap实现不同步,线程不安全。

e) HashMap可以存null键和null值

Hashtable中的方法是同步的,而HashMap中的方法在缺省情况下是非同步的。在多线程并发的环境下,可以直接使用Hashtable,但是要使用HashMap的话就要自己增加同步处理了。

c) Hashtable 中, key 和 value 都不允许出现 null 值。

hashMap和hashtable的区别

HashMap和Hashtable都实现了Map接口。主要的区别有:线程安全性,同步(synchronization),以及速度。

HashMap几乎可以等价于Hashtable,除了HashMap是非synchronized的,并可以接受null(HashMap可以接受为null的键值(key)和值(value),而Hashtable则不行)。

HashMap是非synchronized,而Hashtable是synchronized,这意味着Hashtable是线程安全的,多个线程可以共享一个Hashtable;而如果没有正确的同步的话,多个线程是不能共享HashMap的。Java 5提供了ConcurrentHashMap,它是HashTable的替代,比HashTable的扩展性更好。

JVM内存调优

对JVM内存的系统级的调优主要的目的是减少GC的频率和Full GC的次数,过多的GC和Full GC是会占用很多的系统资源(主要是CPU),影响系统的吞吐量。

Java源码编译机制

类加载机制

类执行机制

Java 源码编译由以下三个过程组成:

分析和输入到符号表

注解处理

语义分析和生成class文件

SSM框架原理,作用及使用方法

作用:

SSM框架是spring MVC ,spring和mybatis框架的整合,是标准的MVC模式,将整个系统划分为表现层,controller层,service层,DAO层四层

使用spring MVC负责请求的转发和视图管理

spring实现业务对象管理,mybatis作为数据对象的持久化引擎

原理:

SpringMVC:

1.客户端发送请求到DispacherServlet(分发器)

2.由DispacherServlet控制器查询HanderMapping,找到处理请求的Controller

3.Controller调用业务逻辑处理后,返回ModelAndView

4.DispacherSerclet查询视图解析器,找到ModelAndView指定的视图

5.视图负责将结果显示到客户端

SQL优化:

个人理解:主要是对查询的优化。对于sql的优化主要就是下面几个方面的优化,

1.避免全表扫描

2.避免索引失效

3.避免排序,不能避免,尽量选择索引排序

4.避免查询不必要的字段

5.避免临时表的创建,删除

StringBuffer与StringBuilder的区别

String : 是java.lang包中的immutable类,String里面所有的属性几乎也是final,由于它的不可变性,类似拼接,裁剪字符串等动作都会产生大量无用的中间对象。由于字符串操作在项目中很常见,所以对String的操作对项目的性能往往有很明显的影响。
StringBuffer : 这个类是为了解决String拼接产生多余对象的问题而提供的一个类。StringBuffer保证了线程的安全,也带来了多余的开销。
StringBuilder : StringBuilder的功能与StringBuffer一样。但是区别是StringBuilder没有处理线程安全,减少了开销。

区别

1、StringBuffer 与 StringBuilder 中的方法和功能完全是等价的,

2、只是StringBuffer 中的方法大都采用了 synchronized 关键字进行修饰,因此是线程安全的,

而 StringBuilder 没有这个修饰,可以被认为是线程不安全的。

3、在单线程程序下,StringBuilder效率更快,因为它不需要加锁,不具备多线程安全

而StringBuffer则每次都需要判断锁,效率相对更低

设计模式

单例:

饿汉模式 :从第一次主动调用该类开始就创建实例对象,一直到程序死亡。
懒汉模式 :从第一次调用获取实例的方法的时候才创建对象,一直到程序死亡。

Java多线程实现的方式有四种

1.继承Thread类,重写run方法
2.实现Runnable接口,重写run方法,实现Runnable接口的实现类的实例对象作为Thread构造函数的target
3.通过Callable和FutureTask创建线程

4.通过线程池创建线程

你可能感兴趣的:(Java面试题(99%会问))