互联网Java工程师面试题——每天背诵二十道面试题(五)


前言

第五天


一、Radis面试题?

1、Redis集群的主从复制模型是怎样的你知道吗?

答:为了使在部分节点失败或者大部分节点无法通行的情况下集群仍然可用,所以集群使用了主从复制模型,每个节点都会有N-1个复制品。

2、你知道Redis集群会有写操作丢失吗?为什么呢?

答:Redis并不能保证数据的强一致性,则意味着在实际中集群在特定的条件下可能会丢失写数据。

3、假如 Redis 里面有 1 亿个 key,其中有 10w 个 key 是以某个固定的已知的前缀开头的,如果是你在操作你将如何将它们全部找出来?

答:使用 keys 指令可以扫出指定模式的 key 列表。 面试官会接着追问:如果这个 redis 正在给线上的业务提供服务,那使用 keys 指令会有什么问题?

2.)这个时候你要回答redis关键的一个特征:redis的单线程的,keys指令会导致线程阻塞一段时间,线上服务会停顿,直到指令执行完毕,服务才能恢复。这个时候可以使用scan指令,scan指令可以无阻塞的提取出指定模式的key列表,但是会有一定的重复概率,在客户端做一次去重就可以了,但是整体所花费的时间会比直接keys指令长。

二、Java并发编程面试题

1.你知道什么是Executors框架嘛?简单地说一下吧?

答:Executor 框架是一个根据一组执行策略调用,调度,执行和控制的异步任务的框架。

2.) 无限制的创建线程会引起应用程序内存溢出。所以创建一个线程池是个更好的解决方案,因为可以限制线程的数量并且可以回收再利用这些线程。利用Executors框架可以非常方便的创建一个线程池。

2、什么是竞争条件?你怎么发现和解决竞争?

答:当多个进程都企图对共享数据进行某种处理,而最后的结果又取决于进程运行的顺序时,则我们认为这发生了竞争条件(race condition)。

3.为什么我们调用 start()方法时会执行 run()方法,为什么我们不能直接调用 run()方法?

答:当你调用 start()方法时你将创建新的线程,并且执行在 run()方法里的代码。但是如果你直接调用 run()方法,它不会创建新的线程也不会执行调用线程的代码,只会把 run 方法当作普通方法去执行。

4、乐观锁和悲观锁的理解及如何实现的你知道吗?

答:

  1. 悲观锁: 总是假设最坏的情况,每次去拿数据的时候都认为别人会修改,所以雷池在拿数据的时候都会上锁,这样别人想拿这个数据就会阻塞直到它拿到锁。传统的关系型数据库里边就用到了很多这种锁机制,比如行锁,表级锁,读锁,写锁等,都是在做操作之前先上锁。再比如Java里面的同步
  2. 乐观锁:顾名思义,就是很乐观嘛,每次去拿数据的时候都认为别人不会修改,所以不会上锁,但是在更新的时候会判断一下在此期间别人有没有去更新这个数据,可以使用版本号等机制。乐观锁实用于多读的应用类型,这样可以提高吞吐量,像数据库提供的类似于write_condition机制,其实都是提供的乐观锁。在Java中java.util.concurrent.atomic包下面的原子变量就是使用了乐观锁的一种实现方式CAS实现的。

5、为什么你应该在循环中检查等待条件?

答:处于等待状态的线程可能会收到错误警报和伪唤醒,如果不在循环中检查等待条件,程序就会在没有满足结束条件的情况下退出。

6、你知道什么是线程池嘛? 为什么要使用它呢?

答:创建线程要花费昂贵的资源和时间,如果任务来呢才创建线程那么响应时间会变长,而且一个进程能创建的资源数有限。为了避免这些问题噢,在程序启动的时候就创建若干线程来响应处理。他们被称为线程池,里面的线程叫工作线程。从JDK1.5开始,JavaJPI提供了Executor框架让你可以创建不同的线程池。

7、你知道怎么检测一个线程时候拥有锁吗?

答:在 java.lang.Thread 中有一个方法叫 holdsLock(),它返回 true 如果当且仅当前线程拥有某个具体对象的锁。

8、你能说出线程池有什么优点嘛?

答:

  1. 重用存在的线程,减少对象创建销毁的开销。
  2. 可有效的控制最大并发线程数,提高系统资源的使用率,同时避免过多资源竞争,避免堵塞。
  3. 提供定时执行、定期执行、单线程、并发数控制等功能。

9、synchronized 的作用说一下你自己的理解吧?

答:在Java中,synchronized关键字是用来控制线程同步的,就是在多线程的环境下,控制synchronized代码段不被多个线程同时执行。synchronized既可以加在一段代码上,也可以加在方法上。

10、在Java中的死锁你知道吗?知道的话你给我说一下如何避免?

答:Java 中的死锁是一种编程情况,其中两个或多个线程被永久阻塞,Java 死锁情况出现至少两个线程和两个或更多资源。

Java 发生死锁的根本原因是:在申请锁时发生了交叉闭环申请。

三、Java面试题

1、你知道Java 中 ++ 操作符是线程安全的吗?

答:不是线程安全的操作。它涉及到多个指令,如读取变量值,增加,然后存储会内存,这个过程可能会出现多个线程交差。

2、int 和 Integer 哪个会占用更多的内存?

答: Integer 对象会占用更多的内存。Integer 是一个对象,需要存储对象的元数据。但是 int 是一个原始类型的数据,所以占用的空间更少

3、64 位 JVM 中,int 的长度是多数?

答:Java 中,int 类型变量的长度是一个固定值,与平台无关,都是 32 位,所以在 32 位 和 64 位 的 Java 虚拟机中,int 类型的长度是相同的。

4、你能保证 GC 执行吗?

答:不能,虽然你可以调用 System.gc() 或者 Runtime.gc(),但是没有办法保证 GC的执行。

5、Java 中堆和栈有什么区别?

答:JVM中堆和栈属于不同的内存区域,使用目的也不同。栈常用于保存方法帧和局部变量,而对象总是在堆上分配。栈通常都比堆小,也不会在多个线程之间共享,而被整个JVM的所有线程之间共享,而堆被整个JVM的所有线程共享。

6、“a==b”和”a.equals(b)”有什么区别?

答:

  • 如果 a 和 b 都是对象,则 a==b 是比较两个对象的引用,只有当 a 和 b
    指向的是堆中的同一个对象才会返回 true,而 a.equals(b) 是进行逻辑比较。
  • 所以通常需要重写该方法来提供逻辑一致性的比较。例如,String 类重写 equals() 方法,所以可以用于两个不同对象,但是包含的字母相同的比较。

7、List、Set之间的区别知道吗?

答:List 是一个有序集合,允许元素重复。它的某些实现可以提供基于下标值的常量访问时间,但是这不是 List 接口保证的。Set 是一个无序集合。

写在最后

如果本文对你有帮助的话,请给我点个赞再走吧。

猜你喜欢

转载自blog.csdn.net/qq_43055855/article/details/111660578