Java重点面试题

1、有没有用过消息队列?用的哪个?

        消息队列(Message Queue)是一种应用间的通信方式,消息发送后可以立即返回,有消息系统来确保信息的可靠专递,消息发布者只管把消息发布到MQ中而不管谁来取,消息使用者只管从MQ中取消息而不管谁发布的,这样发布者和使用者都不用知道对方的存在。

        消息队列中间件是分布式系统中重要的组件,主要解决异步处理,应用解耦,流量削锋和消息通讯四个问题,实现高性能,高可用,可伸缩和最终一致性架构。目前使用较多的消息队列有RabbitMQ,Kafka等。

2、mybatis与jpa区别?

        jpa的前身是著名的ssh中的h——>Hibernate。

        mybatis和jpa,两个持久层框架。从底层到用法都不同。但是实现的功能是一样的。在业务逻辑多是多表关联的情况下,mybatis绝对比jpa要更加适合。无论是以后的维护还是业务的变更都方便不少。

3、乐观锁和悲观锁

        当程序中可能出现并发的情况时,就需要保证在并发情况下数据的准确性,以此确保当前用户和其他用户一起操作时,所得到的结果和他单独操作时的结果是一样的。这就叫做并发控制。

        没有做好并发控制,就可能导致脏读、幻读、不可重复读等问题。

        悲观锁

        每次读取数据的时候,都会担心数据被修改,所以每次查询数据的时候都会加锁,确保自己在读取数据的时候不会被别人修改。使用完成后对数据经行解锁,由于数据经行加锁,期间对该数据进行读写的其他线程都会进行等待。

        乐观锁

        每次获取数据的时候,都不会担心数据被修改,所以每次获取数据的时候都不会进行加锁。但是在更新数据的时候需要判断该数据是否被别人修改过。如果数据被其他线程修改,则不进行数据更新,如果数据没有被其他线程修改,则进行数据更新。由于数据没有进行加锁,期间该数据可以被其他线程进行读写操作。

两种所各有优缺点,读取频繁使用乐观锁,写入频繁使用悲观锁。

4、SpringCloud用到了哪些组件?(五大组件)

  • 服务发现——Netflix Eureka (主要是把我们的各种服务注册进去,以便以后去调用服务)
  • 服务网关——Netflix Zuul (用于对用户的身份认证、请求限流,统一地址)
  • 负载均衡——Netflix Ribbon (有多个服务的时候,我们就需要用负载均衡策略去调用)
  • 熔断器——Netflix Hystrix (服务也可能会崩掉,这就需要去做服务的熔断,主要是做熔断、降级和限流的)
  • 分布式配置——Spring Cloud Config (不同的微服务中可能会有一些配置,管理起来是不好管理的,所以就得有一个统一的配置中心)

5、具体用什么操作的Redis?

        Jredis、Springdata redis(流行)

6、有没有用过Docker? k8s?

        docker是容器化技术,k8s是一套自动化部署的工具,可全生命周期管理docker容器。

        Docker:

        docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到不同的Linux机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。简言之,就是可以在Linux上镜像使用的这么一个容器。

        Docker是一个快速交付应用、运行应用的技术:

        (1).可以将程序及其依赖、运行环境一 起打包为一个镜像,可以迁移到任意Linux操作系统 

        (2).运行时利用沙箱机制形成隔离容器,各个应用互不干扰

        (3).启动、移除都可以通过一行命令完成,方便快捷

        大概了解了Docker,那我们接下来了解下什么是K8S?

        K8S:

        Kubernetes(k8s)是Google开源的容器集群管理系统(谷歌内部:Borg)它主要用于 容器编排 启动容器、自动化部署、扩展和管理容器应用和回收容器。k8s的目标是让部署容器化的应用简单并且高效,k8s提供了应用部署、规划、更新、维护的一种机制!

        首先,我们从容器技术谈起,在容器技术之前,大家开发用虚拟机比较多,比如vmware和openstack,我们可以使用虚拟机在我们的操作系统中模拟出多台子电脑(Linux),子电脑之间是相互隔离的,但是虚拟机对于开发和运维人员而言,存在启动慢,占用空间大,不易迁移的缺点。举一个我亲身经历过的场景吧,之前在vmware中开发了一个线下平台,为了保证每次能够顺利使用,我们就把这个虚拟机导出为OVF,然后随身携带,用的时候在服务器中部署,这里就充分体现了虚拟机的缺点。

        接着,容器化技术应运而生,它不需要虚拟出整个操作系统,只需要虚拟一个小规模的环境即可,而且启动速度很快,除了运行其中应用以外,基本不消耗额外的系统资源。Docker是应用最为广泛的容器技术,通过打包镜像,启动容器来创建一个服务。但是随着应用越来越复杂,容器的数量也越来越多,由此衍生了管理运维容器的重大问题,而且随着云计算的发展,云端最大的挑战,容器在漂移。在此业务驱动下,k8s问世,提出了一套全新的基于容器技术的分布式架构领先方案,在整个容器技术领域的发展是一个重大突破与创新。

        那么,K8S实现了什么?        

        从架构设计层面,我们关注的可用性,伸缩性都可以结合k8s得到很好的解决,如果你想使用微服务架构,搭配k8s,真的是完美,再从部署运维层面,服务部署,服务监控,应用扩容和故障处理,k8s都提供了很好的解决方案。总而言之,k8s可以使我们应用的部署和运维更加方便。

        具体来说,主要包括以下几点:

        服务发现与调度、 负载均衡、服务自愈、服务弹性扩容、横向扩容、存储卷挂载。

7、如何解决Ridis的双写一致性?

        产生的原因:

        当有数据修改时,无论是先修改数据库的值,还是先修改缓存中的值,都会发生数据不一致的情况,更好的解决方式,就是先更新数据库的值,再进行删除操作,但是这样的操作也会造成数据的不一致问题。主要是在两个方面,一个就是不能保证操作的原子性时,可能出现缓存不一致的情况,另一种就是在并发场景下,出现缓存不一致。

        原子性问题解决思路:

        重试机制:可以将修改的数据放入到消息中间件中(如Kafka),当我们操作redis失败,或者修改数据库失败时,可以再次从消息中间件中拿出数据,进行再次操作。

        并发下的问题解决思路:

        延迟双删:也就是在A线程更新完数据库之后,sleep一段时间,再次将缓存中的数据进行删除,这样后续的读取操作就是从数据库中读取到新值,回写给缓存;那么这个sleep的值应该设置为多少呢?就需要根据时间情况来定,一般就是稍大于B线程的操作时间。

方案一:Redis设置key的过期时间。

方案二:采用延时双删策略

(1)先淘汰缓存

(2)再写数据库(这两步和原来一样)

(3)休眠1秒,再次淘汰缓存 这么做,可以将1秒内所造成的缓存脏数据, 再次删除。

8、项目中有用到缓存吗?

        有,用户第一次查询时会将访问的数据先查一遍,然后缓存到redis中,这样即提升了查询速度又减轻了数据库的压力,大大提升了用户的体验感。

9、SpringBoot自动配置原理

        我们知道SpringBoot可以帮我们减少很多的配置,也肯定听过“约定大于配置”这么一句话,那SpringBoot是怎么做的呢?其实靠的就是@EnableAutoConfiguration注解。简单来说,这个注解可以帮助我们自动载入应用程序所需要的所有默认配置。

        SpringBoot启动时会通过@EnableAutoConfiguration注解找到META-INF/spring.factories文件的信息,然后筛选出以EnableAutoConfiguration为key的数据,加载到IOC容器中,实现自动配置功能!

10、项目中遇到的难点

        (1)Mysql里默认支持的是innoDb,有一次我们在做项目中生成订单修改库存的时候,始终没办法实现事务的统一性,后来我跟同事研究了半天,查看了以后才了解到是因为数据库中的引擎被修改了,改为了myisam,而MyIsam本身是不支持事务的。

        (2)项目中遇到了一些曾经没有用到过的技术,比如:ES、MQ,后来用自己的私人时间主动学习。

11、说一下你对Spring的了解

        它是一个轻量级的容器框架,它最主要的两个特点就是IOC和AOP,IOC就是控制反转,如果是自己创建对象的话管理起来就会比较麻烦,我们就可以用IOC把这个对象控制权交给Spring去管理,然后再通过DI依赖注入进行实现;AOP就是一个面向切面编程,相当于对代码进行了一个切割,不改变原有代码的情况下,对其进行一个增强功能。

        项目哪块用到了AOP? 事务、日志什么的。

12、Spring Bean的生命周期

Spring Bean的生命周期只有这四个阶段。

(1)实例化 Instantiation

(2)属性赋值 Populate

(3)初始化 Initialization

(4)销毁 Destruction

13、sql优化策略有哪些?

SQL优化策略适用于数据量较大的场景下,对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引。(全表扫描的意思就是要把表中所有数据过一遍才能显示数据结果)

  • 应尽量避免在 where 子句中对字段进行 null 值判断。优化方式:可以给字段添加默认值0,对0值进行判断。
  • 应尽量避免在 where 子句中使用!=或<>操作符。
  • 应尽量避免在 where 子句中使用 or 来连接条件。优化方式:可以用union代替or。
  • 应尽量避免在字段开头用模糊查询,会导致数据库引擎放弃索引进行全盘扫描。
  • in 和 not in 也要慎用,否则会导致全表扫描。
  •  任何地方都不要使用 select * from t ,用具体的字段列表代替“*”,不要返回用不到的任何字段。

14、Mybatis管理事务的两种方式?

  • 使用JDBC的事务管理机制:即利用java.sql.Connection对象完成对事务的提交(commit())、回滚(rollback())、关闭(close())等。
  • 使用managed的事务管理机制:这种机制MyBatis自身不会去实现事务管理,而是让程序的容器如(JBOSS,Weblogic)来实现对事务的管理

15、SpringMVC是单例还是多例?

SpringMVC默认都是单例,如果你bean配置多例了,依赖这个bean的bean也需要多例。

为什么是单例的?

  • 减少实例生成的系统消耗,效率会高
  • gc垃圾回收,就不会回收,因为没有生成实例
  • 可以更快的获取到bean ,第一次生成之后 ,就不会再次生成,每次取都是缓存中取

16、你Controller层的变量是在方法中还是类中写的?会不会有线程问题?

我是写在方法中的,我所有涉及到变量的东西都是写在方法中的,不会涉及到线程问题。如果写在类中的话会涉及到线程问题。

17、Mysql函数有哪些?

Max(最大值)、 Min(最小值)、 Sum(总和)、Count(统计次数)、avg(平均值)

18、Redis的使用场景?

对于经常查询的热门商品,不经常进行修改的数据,我们都会把它放到Redis缓存中。如果不用Reids数据库会压力大,会产生缓存穿透、雪崩、击穿等问题。

19、Dubbo的超时机制?

dubbo启动时默认有重试机制和超时机制。超时机制的规则是如果在一定的时间内,provider没有返回,则认为本次调用失败,如果出现超时,通常是业务处理太慢。如果设置的时间太短,一些复杂业务需要很长时间完成,导致在设定的超时时间内无法完成正常的业务处理。

超时在哪设置?

在引用dubbo服务时,可以设置timeout属性限制等待时间(单位毫秒)。

消费端和服务端:

@DubboReference(timeout = 3000) // 去dubbo注册中心中寻找
    private UserService userService;

当没有设置时,默认为dubbo:consumer的超时时间(1000毫秒)。

20、java 如何保证接口的安全性

在开发过程中,肯定会有和第三方或者app端的接口调用。在调用的时候,如何来保证非法链接或者恶意攻击呢?

第一种:签名

根据用户名或者用户id,结合用户的ip或者设备号,生成一个token。在请求后台,后台获取http的head中的token,校验是否合法(和数据库或者redis中记录的是否一致,在登录或者初始化的时候,存入数据库/redis)。

第二种:加密

客户端和服务器都保存一个秘钥,每次传输都加密,服务端根据秘钥解密。

客户端:

  •     设置一个key(和服务器端相同)
  •     根据上述key对请求进行某种加密(加密必须是可逆的,以便服务器端解密)
  •     发送请求给服务器

服务器端:

  •     设置一个key
  •     根据上述的key对请求进行解密(校验成功就是「信任」的客户端发来的数据,否则拒绝响应)
  •     处理业务逻辑并产生结果
  •     将结果反馈给客户端

21、单点登录怎么实现的?(SSO)

什么是单点登录?

        单点登录是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统的保护资源,若用户在某个应用系统中进行注销登录,所有的应用系统都不能再直接访问保护资源,像一些知名的大型网站,如:淘宝与天猫、新浪微博与新浪博客等都用到了这个技术。

单点登录原理:

        有一个独立的认证中心,只有认证中心才能接受用户的用户名和密码等信息进行认证,其他系统不提供登录入口,只接受认证中心的间接授权。间接授权通过令牌实现,当用户提供的用户名和密码通过认证中心认证后,认证中心会创建授权令牌,在接下来的跳转过程中,授权令牌作为参数发送给各个子系统,子系统拿到令牌即得到了授权,然后创建局部会话。

        如果在校验令牌过程中发现客户端令牌和服务器端令牌不一致或者令牌过期的话,则用户之前的登录就过期了,用户需要重新登录。

单点注销:

        在一个子系统中注销,全局会话也会被注销,所有子系统的会话都会被注销。

22、什么是热部署?

        对于Java来说,热部署就是在应用运行的时候,不需要重新启动应用就可以更新Java文件,配置文件除外。

实现热部署方式:

  • Jrebel
  • Spring Loaded
  • Spring-boot-devtools

配置pom.xml

<!-- 添加热部署的配置 -->
<configuration>
    <fork>true</fork>
</configuration>

23、List集合排序方法:

正序:collections.sort()

倒序排:collections.reverse()

24、RDB和AOF的区别?

        Redis 提供两种持久化机制 RDB(默认) 和 AOF 机制。持久化就是把内存的数据写到磁盘中去,防止服务宕机了内存数据丢失。

区别:

RDB是通过保存数据库中的键值对来记录数据库的状态,它是以快照的形式保存到硬盘中的;

AOF 则是通过保存Redis服务器所执行的写命令来记录数据库状态。

这两种我们应该怎么选择?        

        如果可以忍受一小段时间内数据的丢失,毫无疑问使用 RDB 是最好的,定时生成 RDB 快照(snapshot)非常便于进行数据库备份,并且 RDB 恢复数据集的速度也要比 AOF 恢复的速度要快,而且使用 RDB 还可以避免 AOF 一些隐藏的 bug;否则就使用 AOF 重写。但是一般情况下建议不要单独使用某一种持久化机制,而是应该两种一起用,在这种情况下,当redis重启的时候会优先载入AOF文件来恢复原始的数据,因为在通常情况下AOF文件保存的数据集要比RDB文件保存的数据集要完整。

25、数据库的主从复制

什么是主从复制?

        主从复制,就是用来建立一个和主数据库完全一样的数据库环境,称为从数据库,主数据库一般是准实时的业务数据库。

主从复制的作用?

        作为后备数据库,主数据库服务器故障后,可切换到从数据库继续工作,避免数据丢失。

        读写分离,使数据库能支持更大的并发。在报表中尤其重要。由于部分报表sql语句非常的慢,导致锁表,影响前台服务。如果前台使用master,报表使用slave,那么报表sql将不会造成前台锁,保证了前台速度。

26、Shiro的主要功能是什么?

  • 身份认证/登录:验证用户是不是拥有相应的身份,一般会使用用户名和密码作为认证信息。
  • 授权,即权限验证:判断某个已经认证过的用户是否拥有某些权限访问某些资源,一般授权会有角色授权和权限授权;
  • 会话管理:即用户登录后就是一次会话,在没有退出之前,它的所有信息都在会话中;会话可以是普通JavaSE环境的,也可以是如Web环境的,web 环境中作用是和 HttpSession 是一样的;
  • 加密:保护数据的安全性,如密码加密存储到数据库,而不是明文存储;

shiro架构:

  • Subject:主体,相当与是请求过来的"用户"
  • SecurityManager: 是 Shiro 的心脏;所有具体的交互都通过 SecurityManager 进行拦截并控制;它管理着所有 Subject、且负责进行认证和授权、及会话、缓存的管理
  • Authenticator:认证器,负责主体认证的,即确定用户是否登录成功,我们可以使用  Shiro 提供的方法来认证,有可以自定义去实现,自己判断什么时候算是用户登录成功
  • Authrizer:授权器,即权限授权,给 Subject 分配权限,以此很好的控制用户可访问的资源
  • Realm:一般我们都需要去实现自己的 Realm ,可以有1个或多个 Realm,即当我们进行登录认证时所获取的安全数据来源(帐号/密码)
  • SessionManager:为了可以在不同的环境下使用 session 功能,shiro 实现了自己的 sessionManager ,可以用在非 web 环境下和分布式环境下使用
  • SessionDAO:对 session 的 CURD 操作
  • CacheManager:缓存控制器,来管理如用户、角色、权限等的缓存的;
  • Cryptography:密码模块,Shiro提高了一些常见的加密组件用于如密码加密/解密的。

具体使用:

继承AuthorizingRealm 类,重写认证和授权方法。

27、线城池的创建方式

什么是线程池?

        Java中的线程池是运用场景最多的并发框架,几乎所有需要异步或并发执行任务的程序
都可以使用线程池。合理地使用线程池可以降低资源消耗、提高响应速度、提高线程的可管理性。

线程池的的四种创建方式:

  • newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
  • newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
  • newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行。
  • newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。

28、幂等性

幂等性的概念:

        任意多次执行所产生的影响均与一次执行的影响相同,即无论你请求了多少次,对数据库的影响都只能有一次,不能重复处理。

幂等性解决方案:

(1)防重表
        数据库建立唯一性索引,可以保证最终插入数据库的只有一条数据(比如订单表对订单号进行唯一索引,所有重复提交可能产生同一个订单号的都会被拆除。当然,订单号要按你自己的设定走,一般订单号设计会是时间戳加迭代。那么如果是这样,创建仍然不能保证幂等,具体根据业务需求来判定建立的唯一索引位置)。

(2)先查询后判断

        首先通过查询数据库是否存在数据,如果存在证明已经请求过了,直接拒绝该请求,如果没有存在,就证明是第一次进来,直接放行。

(3)支付缓冲区

        把订单的支付请求都快速地接下来,一个快速接单的缓冲管道。后续使用异步任务处理管道中的数据,过滤掉重复的待支付订单。优点是同步转异步,高吞吐。不足是不能及时地返回支付结果,需要后续监听支付结果的异步返回。(一般支付都是采用这种方式)

(4)悲观锁或者乐观锁

        悲观锁可以保证每次for update的时候其他sql无法update数据(在数据库引擎是innodb的时候,select的条件必须是唯一索引,防止锁全表)
        乐观锁,一般通过version来做乐观锁,这样既能保证执行效率,又能保证幂等。例如: UPDATE tab1 SET col1=1,version=version+1 WHERE version=#version# 不过,乐观锁存在失效的情况,就是常说的ABA问题,不过如果version版本一直是自增的就不会出现ABA的情况。

29、@Autowired和@Resource注解的区别是什么?

        @Autowired注解由Spring提供,默认按类型装配,默认情况下必须要求依赖对象存在,如果要允许null值,可以设置它的required属性为false。如果想使用名称装配可以结合@Qualifier注解进行使用。

        @resource注解由J2EE提供,默认按照名称进行装配,名称可以通过name属性进行指定,如果没有指定name属性,当注解写在字段上时,默认取字段名进行名称查找。如果注解写在setter方法上默认取属性名进行装配。当找不到与名称匹配的bean时才按照类型进行装配。但是需要注意的是,如果name属性一旦指定,就只会按照名称进行装配。

30、高并发下怎么生成唯一订单号

方案一:

        如果没有并发的话,订单号只在一个线程中产生,不同订单的时间戳不同,

                        时间戳+随机数(自增数)区分订单

        如果有并发的话,并且订单号在同-台主机产生多个进程,只要把进程的ID添加到序列号中就可以保证订单号唯一。

        如果有并发,订单在不同主机中,把IP地址CPU序列号能区分的号码添加到序列号中就能保证唯一。

方案二:

        时间戳+用户ID+随机数+乐观锁

方案三:

        可以用redis的原子递增,做高可用集群

31、mybatis四种分页方式

(1)借助数组进行分页(逻辑分页)

(2)借助Sql语句进行分页(物理分页)

(3)拦截器分页 (物理分页) 通过拦截器给sql语句末尾加上limit语句来查询,一劳永逸最优

(4)RowBounds实现分页  (逻辑分页)

32、Redis缓存满了以后怎么办?

内存淘汰策略:

  • noeviction策略:内存空间达到maxmemory时,不会淘汰数据,有新写入时会返回错误。
  • volatile-ttl策略:针对设置了过期时间的键值对,根据过期时间的先后进行修改,越早过期的越先被删除。
  • volatile-random策略:在设置了过期时间的键值对中,进行随机删除。
  • volatile-lru策略:使用LRU算法筛选设置了过期时间的键值对,进行删除。
  • volatile-lfu策略:使用LFU算法筛选设置了过期时间的键值对,进行删除。
  • allkeys-random策略:在所有键值对中随机选择并删除数据。
  • allkeys-lru策略:使用LRU算法在所有数据中进行筛选并删除数据。
  • allkeys-lfu策略:使用LFU算法在所有数据中进行筛选并删除数据。

设置集群

如何保证Redis保存的数据是热点数据?

        Redis 会根据自身数据淘汰策略,加载热数据到内存。所以,计算一下 20W 数据大约占用的内存,然后设置一下 Redis 内存限制即可。

33、MySql怎么开启事务?

        MySQL 默认开启事务自动提交模式,即除非显式的开启事务(BEGIN 或 START TRANSACTION),否则每条 SOL 语句都会被当做一个单独的事务自动执行。但有些情况下,我们需要关闭事务自动提交来保证数据的一致性。

MYSQL 事务处理主要有两种方法:

(1)用 begin, rollback, commit来实现

  • begin 开始一个事务
  • rollback 事务回滚
  • commit 事务确认

(2)直接用 SET 来改变 MySQL 的自动提交模式:

  • set Autocommit = 0 禁止自动提交 
  • set Autocommit = 1 开启自动提交

34、你们平常用Linux吗?说说查看日志命令

        当日志文件存储日志很大时,我们就不能用vi直接进去查看日志,需要Linux的命令去完成我们的查看任务。

  • tail -n 10 test.log 查询日志尾部最后10行的日志;
  • tail -n +10 test.log 查询10行之后的所有日志;
  • tail -fn 10 test.log 循环实时查看最后1000行记录(最常用的)

35、为什么要用线程?项目中什么时候用到了多线程

        多线程就类似N个工人同一时间去干同一件事情,比一个人同一时间去干快N倍。简称多线程并发执行,这个同一时间我的理解是同一秒里面,cpu在这一毫秒执行了A线程,然后下一毫秒执行挂起A线程,执行B线程,然后这样交替直到两个线程都执行完,就是并发结束。

线程关键字:

  • synchronized 可以保证方法或者代码块在运行时,同一时刻只有一个线程可以进入同步代码块中,同时它还可以保证共享变量的内存可见性。      
  • volatile 用volatile修饰的变量,线程在每次使用变量的时候,都会读取变量修改后的最的值。volatile很容易被误用,用来进行原子性操作。   
  • 区别:多线程访问volatile关键字不会发生阻塞,而synchronized关键字可能会发生阻塞

        volatile关键字能保证数据的可见性,但不能保证数据的原子性。synchronized关键字两者都能保证
        volatile关键字主要用于解决变量在多个线程之间的可见性,而 synchronized关键字解决的是多个线程之间访问资源的同步性。

使用多线程的好处:

  • 使用多线程可以提高CPU利用率,即占用大量处理时间的任务可以定期将处理器时间让给其它任务;
  • 多线程技术使程序的响应速度更快 ,因为用户界面可以在进行其它工作的同时一直处于活动状态;

缺点:

  • 等候使用共享资源时造成程序的运行速度变慢。这些共享资源主要是独占性的资源 ,如打印机等。
  • 线程的死锁。即对共享资源加锁实现同步的过程中可能会死锁。

synchronized 是如何保证线程安全的?

synchronized 是通过给对象加锁,保证了原子性和可见性来使线程安全的。

36、JVM垃圾回收机制

        GC中的垃圾,特指存于内存中、不会再被使用的对象,儿回收就是相当于把垃圾“倒掉”。垃圾回收有很多中算法:如 引用计数法、标记压缩法、复制算法、分代、分区的思想。

引用计数法:就是个比较古老而经典的垃圾收集算法,其核心就是在对象被其他所引用计数器加1,而当引用时效时则减1,但是这种方式有非常严重的问题:无法处理循环引用的情况、还有就是每次进行加减操作比较浪费系统性能。

标记清除法:分为标记和清除两个阶段进行处理内存中的对象,当然这种方式也有非常大的弊端,就是空间碎片问题,垃圾回收后的空间不是连续的,不连续的内存空间的工作效率要低于连续的内存空间。

复制算法:其核心思想就是将内存空间分为两块,每次只使用其中一块,在垃圾回收时,将正在使用的内存中的存留对象复制到未被使用的内存块中去,之后去清除之前正在使用的内存快中的所有的对象,反复去交换两个内存的角色,完成垃圾收集。

(java中的新生代的from和to空间使用的就是这个算法)

标记压缩法:标记压缩法在标记清除基础之上做了优化,把存活的对象压缩到内存一端,而后进行垃圾清理。(java中老年代使用的就是标记压缩法)

37、Redis常见数据结构以及使用场景

String

常用命令: set,get,decr,incr,mget 等。
String数据结构是简单的key-value类型,value其实不仅可以是String,也可以是数字。 常规key-value缓存应用;
常规计数:微博数,粉丝数等。

Hash

常用命令: hget,hset,hgetall 等。
Hash 是一个 string 类型的 field 和 value 的映射表,hash 特别适合用于存储对象,后续操作的时候,你可以直接仅
仅修改这个对象中的某个字段的值。 比如我们可以Hash数据结构来存储用户信息,商品信息等等。

List

常用命令: lpush,rpush,lpop,rpop,lrange等。

list 就是链表,Redis list 的应用场景非常多,也是Redis最重要的数据结构之一,比如微博的关注列表,粉丝列表,
消息列表等功能都可以用Redis的 list 结构来实现。

Set

常用命令: sadd,spop,smembers,sunion 等
set 对外提供的功能与list类似是一个列表的功能,特殊之处在于 set 是可以自动排重的。

当你需要存储一个列表数据,又不希望出现重复数据时,set是一个很好的选择,并且set提供了判断某个成员是否在一个set集合内的重要接口,这个也是list所不能提供的。可以基于 set 轻易实现交集、并集、差集的操作。
比如:在微博应用中,可以将一个用户所有的关注人存在一个集合中,将其所有粉丝存在一个集合。Redis可以非常方便的实现如共同关注、共同粉丝、共同喜好等功能。这个过程也就是求交集的过程。

Sorted Set

常用命令: zadd,zrange,zrem,zcard等
和set相比,sorted set增加了一个权重参数score,使得集合中的元素能够按score进行有序排列。
举例: 在直播系统中,实时排行信息包含直播间在线用户列表,各种礼物排行榜,弹幕消息(可以理解为按消息维
度的消息排行榜)等信息,适合使用 Redis 中的 SortedSet 结构进行存储。

38、RestFul和RPC的区别

从本质区别上看,RPC是基于TCP实现的,RestFul是基于HTTP来实现的。

从传输速度上来看,因为HTTP封装的数据量更多所以数据传输量更大,所以RPC的传输速度是比RestFul更快的。

39、redis和ElasticSearch的区别及使用场景

redis:

常规计数:粉丝数,微博数;用户信息变更;缓存处理,作为 mysql 的缓存;队列系统,建有优先级的队列系统,日志收集系统

Redis是现在最热门的key-value数据库。还支持持久化。

Redis的最大特点就是key-value存储所带来的简单和高性能了。   

如果你对数据的读写要求极高,并且你的数据规模不大,也不需要长期存储,选redis。

ElasticSearch:

分布式的搜索引擎和数据分析引擎,全文检索,结构化检索,数据分析,

对海量数据进行近实时的处理,站内搜索(电商,招聘,门户,等等), IT 系统搜索( OA , CRM , ERP ,等等),数据分析。

ES不是一个数据库,而是一个搜索引擎,ES的方方面面也都是围绕搜索设计的。

如果你需要构造一个搜索引擎或者你想搞一个看着高大上的数据可视化平台,并且你的数据有一定的分析价值或者你的老板是土豪,选ElasticSearch;

40、spring boot开启事务的注解

SpringBoot中开启事务,只需要在方法前加上@Transactional注解即可。

41、Union和Union All到底有什么区别

Union:对两个结果集进行并集操作,不包括重复行,同时进行默认规则的排序;

Union All:对两个结果集进行并集操作,包括重复行,不进行排序;

42、项目的开发环境有哪些?

一个项目开发,会分为三个环境,开发环境,测试环境,线上环境。

1、开发环境

概述:是在项目的开发阶段搭建的服务器

搭建人:运维

使用对象:前后端开发人员

发布人:前后端开发人员

包含:1、数据库 2、如果是前后端分离开发,开发环境要部署后端程序,以便前端调用接口 3、反向代理服务器等等

作用:方便开发人员开发,而且能让其他项目人员随时查看

2、测试环境

概述:当项目开发完成,开始测试,那么就需要搭建测试服务器,为什么不接着适用开发环境呢?因为开发环境不稳定,开发人员可能随时都会修改BUG,随时都会部署,不方便测试工程师测试。

搭建人:运维

发布人:运维

使用对象:测试工程师,产品经理

作用:1.用于测试工程师进行测试 2.BUG修改后验证。

3、线上环境

概述:项目上线,使用线上服务器

搭建人:运维

发布人:运维,发布时开发工程师、测试工程师、产品经理等需要在场。

使用对象:真实用户

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: Java 10k面试题是指一系列Java编程语言相关的面试题目,用于评估面试者的Java编程能力和知识水平。这些问题覆盖了Java语法、面向对象编程、集合框架、多线程、异常处理、IO操作等各个方面。 在回答这个题目之前,我想说明的是,Java的知识是非常广泛和深入的,任何一个程序员都不可能在所有方面都有完全掌握。而且,面试并不是只看一个人的答案,还会综合考虑其思考方式、解决问题能力等因素。因此,不管你是否能回答出这10k个面试题中的每一个,都不是衡量一个人能力的唯一标准。 针对Java 10k面试题,我建议以下三个步骤来进行准备和回答: 1. 先整体浏览面试题目清单:对于每个问题,快速浏览题目和要求,了解问题所涉及的领域和主题。 2. 根据自身经验和知识填补知识空缺:将那些你不熟悉或者不了解的问题进行标注,然后针对这些问题进行学习和复习。可以使用官方文档、编程书籍、网络资源等来获取相关的知识。 3. 练习和实践:在自己的编程环境中使用Java语言进行实践和练习,尽可能多地编写代码来加深对Java的理解。可以从简单的问题入手,逐渐扩展到更复杂的问题,这样能够更好地理解和应用Java的各种特性和用法。 总之,Java 10k面试题是一个全面挑战Java编程能力和知识深度的问题集合。准备和回答这个题目需要不断的学习和实践,通过不断提高自己的编程技能来应对各种问题和挑战。希望以上的建议能够帮到你。 ### 回答2: Java 10k面试题指的是Java相关的面试题目数量达到10,000道。这个数量非常庞大,覆盖了Java语言的方方面面。以下是简要回答: Java 10k面试题中包含了Java的基础知识、面向对象编程、多线程、集合框架、IO流、JVM等多个领域的知识点。对于想要在面试中脱颖而出的应聘者来说,掌握这些知识点非常重要。 基础知识方面,Java 10k面试题往往会考察基本数据类型、变量命名规范、运算符优先级等基础概念。此外,还需要了解Java的关键字、访问修饰符、异常处理机制等。 面向对象编程是Java的核心,也是Java 10k面试题重点。面试中可能会问到类与对象的概念、封装、继承与多态等概念,还可能会提问相关的设计原则,如单一职责原则、开闭原则等。 多线程和并发编程是Java的独特特性,也是面试的热点内容之一。Java 10k面试题会涉及线程的创建、同步、通信等问题,还有线程池的使用和死锁的避免等。 集合框架是Java的核心库之一,Java 10k面试题也会涉及到集合类的使用和常见问题,如ArrayList与LinkedList的区别、HashMap的实现原理等。 IO流是Java中进行文件和网络操作的重要手段,Java 10k面试题可能会涉及IO流的分类、字节流和字符流的区别、序列化和反序列化等。 还有JVM相关的知识在Java 10k面试题中也会涉及到,如垃圾回收机制、堆和栈的区别等。 总之,掌握这些Java的关键知识点是面试成功的前提。在面试中,不仅要掌握理论知识,还要注重实践经验和项目经验的积累。通过刷题、阅读书籍和实战练习,可以帮助应聘者更好地准备Java 10k面试题

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值