粗略整理的java面试题

时间:2022-05-22 20:57:32

1.垃圾回收 

是回收的空闲堆空间

只有在cpu空闲并且堆空间不足的情况下才回收

2.threadlocal  就是为线程的变量都提供了一个副本,每个线程运行都只是在更新这个副本。

Threadlocal可以解决线程不安全的情况,比如说SimpleDateFormat

ThreadLocal和Synchonized都用于解决多线程并发访问。

但是ThreadLocal与synchronized有本质的区别。synchronized是利用锁的机制,使变量或代码块在某一时该只能被一个线程访问。

而ThreadLocal为每一个线程都提供了变量的副本,使得每个线程在某一时间访问到的并不是同一个对象,这样就隔离了多个线程对数据的数据共享。

而Synchronized却正好相反,它用于在多个线程间通信时能够获得数据共享。

3.volatile作用

关系到内存模型的可见性:当一个共享变量被volatile修饰时,它会保证修改的值会立即被更新到主存,当有其他线程需要读取时,它会去内存中读取新值。(可见性)

通过synchronized和Lock也能够保证可见性

禁止进行指令重排序。

a.volatile关键字为域变量的访问提供了一种免锁机制b.使用volatile修饰域相当于告诉虚拟机该域可能会被其他线程更新c.

因此每次使用该域就要重新计算,而不是使用寄存器中的值d.volatile不会提供任何原子操作,它也不能用来修饰final类型的变量

4.jvm 原理

jvm编译器编译java文件后变成.class字节码程序,然后jvm的执行引擎就把字节码程序翻译成不同平台可识别的机器码,然后就可以执行啦。

5.jvm 体系结构

a.栈  ===》栈帧  保存运行时状态,解决程序如何执行的问题

stack里面存放的是方法的入参,运行环境等

b.堆

heap存放对象实例以及数组

c.程序计数器

多线程相关

d. 方法区域

存放方法相关 访问修饰符 方法名

e.字符串常量池

f. 本地方法区域 native

6.类加载器 classLoader 负责将类加载进jvm,供程序间进行调用

a.bootstrap classloader: 启动类加载器

加载 jdk核心类库,比如rt.jar

b.app  classloader:系统类加载器

加载应用程序classpath所依赖的所有类库

c.extend classloader :扩展类加载器

默认加载JAVA_HOME/jre/lib/ext/目下的所有jar。

可以自定义类加载器

7.Synchronized和lock区别

Synchronized :悲观锁,如果被锁住,如果没有释放,那么就会一直被锁住

lock : 中间会中断,不会一直等着被解锁,适用于某一线程在等待这一锁的控制权期间需要中断。

8.string,stringbuffer和stringbuilder

string 不可变量,虽然可以用+拼接,但是这样每次拼接是在操作新的对象,gc也是在一直回收之前的对象。所以效率最差

stringbuffer 线程安全的

stringbuilder 线程不安全但是效率最快

9.Volatile和Synchronized四个不同点:

a. 粒度不同,前者针对变量 ,后者锁对象和类

b. syn阻塞,volatile线程不阻塞

c. syn保证三大特性,volatile不保证原子性

d. syn编译器优化,volatile不优化 volatile具备两种特性:

10.线程池 ExecutorService

降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗

newFixedThreadPool()

newcachedTheadPool()

11.类加载器工作机制:

1.装载:将Java二进制代码导入jvm中,生成Class文件。

2.连接:a)校验:检查载入Class文件数据的正确性 b)准备:给类的静态变量分配存储空间 c)解析:将符号引用转成直接引用

3:初始化:对类的静态变量,静态方法和静态代码块执行初始化工作。

双亲委派模型:类加载器收到类加载请求,首先将请求委派给父类加载器完成 用户自定义加载器->应用程序加载器->扩展类加载器->启动类加载器。

12.SpringMVC运行原理

客户端请求提交到DispatcherServlet

由DispatcherServlet控制器查询HandlerMapping,找到并分发到指定的Controller中。

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

DispatcherServlet查询一个或多个ViewResoler视图解析器,找到ModelAndView指定的视图

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

13.Session与Cookie:Cookie可以让服务端跟踪每个客户端的访问,但是每次客户端的访问都必须传回这些Cookie,如果Cookie很多,则无形的增加了客户端与服务端的数据传输量,

而Session则很好地解决了这个问题,同一个客户端每次和服务端交互时,将数据存储通过Session到服务端,

不需要每次都传回所有的Cookie值,而是传回一个ID,每个客户端第一次访问服务器生成的唯一的ID,

客户端只要传回这个ID就行了,这个ID通常为NAME为JSESSIONID的一个Cookie。这样服务端就可以通过这个ID,来将存储到服务端的KV值取出了。

14.适配器模式:将一个接口适配到另一个接口,Java I/O中InputStreamReader将Reader类适配到InputStream,从而实现了字节流到字符流的准换。

装饰者模式:保持原来的接口,增强原来有的功能。

FileInputStream 实现了InputStream的所有接口,BufferedInputStreams继承自FileInputStream是具体的装饰器实现者,

将InputStream读取的内容保存在内存中,而提高读取的性能。

15.Spring事务配置方法

1.切点信息,用于定位实施事物切面的业务类方法

2.控制事务行为的事务属性,这些属性包括事物隔离级别,事务传播行为,超时时间,回滚规则。

Spring通过aop/tx Schema 命名空间和@Transaction注解技术来进行声明式事物配置。

16.Mybatis

每一个Mybatis的应用程序都以一个SqlSessionFactory对象的实例为核心。首先用字节流通过Resource将配置文件读入,

然后通过SqlSessionFactoryBuilder().build方法创建SqlSessionFactory,

然后再通过SqlSessionFactory.openSession()方法创建一个SqlSession为每一个数据库事务服务。

经历了Mybatis初始化 –>创建SqlSession –>运行SQL语句,返回结果三个过程

17.谈下servlet,filter,listener以及intecepter的区别

a. servlet是一个应用程序,跟action一样,可以动态返回页面,在web程序起一个接收参数,调用service,返回页面的作用。doget()和dopost()

b.filter 是servlet加强版,Filter对用户请求进行预处理,接着将请求交给Servlet进行预处理并生成响应,最后Filter再对服务器响应进行后处理

写一个Filter类实现Filter类,配置进web.xml文件中,doFilter()

主要是编码做一下过滤

基于函数回调 链似的,依赖servlet容器,对所有请求起作用(比如说图片)

c.listener 监听器

d.intecepter 拦截器 类似filter

写进spring.xml文件中

基于反射,不依赖与servlet容器,只对action起作用

检查是否登录,

18.反射

反射就是把Java的各种成分映射成相应的Java类。是java体现动态语言的一个特性

19.java值传递和引用传递

java里面方法传参都是值传递,也就是副本,不改变值的

20.如果synchronized关键字能满足用户的需求,就用synchronized,因为它能简化代码

如果需要更高级的功能,就用ReentrantLock类,此时要注意及时释放锁,否则会出现死锁,通常在finally代码释放锁.

ThreadLocal与同步机制都是为了解决多线程中相同变量的访问冲突问题b.前者采用以”空间换时间”的方法,后者采用以”时间换空间”的方式.

volatile不能保证原子操作导致的,因此volatile不能代替synchronized。此外volatile会组织编译器对代码优化,因此能不使用它就不适用它吧。

它的原理是每次要线程要访问volatile修饰的变量时都是从内存中读取,而不是存缓存当中读取,因此每个线程访问到的变量值都是一样的。这样就保证了同步。

http://www.jianshu.com/p/e513dea5492b

21.futureTask你用过?

FutureTask表示一个异步运算的任务。

FutureTask里面可以传入一个Callable的具体实现类,可以对这个异步运算的任务的结果进行等待获取、判断是否已经完成、取消任务等操作。

当然,由于FutureTask也是Runnable接口的实现类,所以FutureTask也可以放入线程池中。

之前做项目,导入excel做过。

22、怎么唤醒一个阻塞的线程

如果线程是因为调用了wait()、sleep()或者join()方法而导致的阻塞,可以中断线程,并且通过抛出InterruptedException来唤醒它;

如果线程遇到了IO阻塞,无能为力,因为IO是操作系统实现的,Java代码并没有办法直接接触到操作系统。

23.Thread.sleep(0)的作用是什么

由于Java采用抢占式的线程调度算法,因此可能会出现某条线程常常获取到CPU控制权的情况,为了让某些优先级比较低的线程也能获取到CPU控制权,

可以使用Thread.sleep(0)手动触发一次操作系统分配时间片的操作,这也是平衡CPU控制权的一种操作。

24.乐观锁:就像它的名字一样,对于并发间操作产生的线程安全问题持乐观状态,乐观锁认为竞争不总是会发生,因此它不需要持有锁,

将比较-设置这两个动作作为一个原子操作尝试去修改内存中的变量,如果失败则表示发生冲突,那么就应该有相应的重试逻辑。

(2)悲观锁:还是像它的名字一样,对于并发间操作产生的线程安全问题持悲观状态,悲观锁认为竞争总是会发生,因此每次对某资源进行操作时,

都会持有一个独占的锁,就像synchronized,不管三七二十一,直接上了锁就操作资源了。

25.集合类 :hashmap,hashtable

hashmap :线程不安全

hashtable :线程安全 类似于 ConcurrentHashMap

Vector, Hashtable, Properties and Stack都是同步的(synchronized)类,因此是线程安全的,可以在多线程环境下使用.

Java 1.5 Concurrent API 引入了一些允许在迭代过程中可以修改集合的并发类,由于它们会在迭代时会clone一份集合,所以在多线程环境下也是安全的。

26.spring 面试题

1).spring核心其实就是控制反转和依赖注入,

控制反转就是把类的实例化的控制权交给spring去给我们完成,BeanFactory来做的

2).spring作用域

singletion :单例

prototype: 为每个bean创建一个实例

3).说下spring

首先Spring是一个大的概念,Spring从最开始的一个Library到现在一个系列,

其中最主要的包括Spring Framework, Spring Data, Spring Security, Spring Batch等等,

以及快速框架Spring Boot,其中最重要的项目是Spring Framework,这个项目包括了IoC, AOP, MVC以及Testing。

第一个需要明白的是Spring的核心思想是什么?Spring整个系列的最最核心的概念当属IoC, AOP,什么是IoC和AOP就不展开了,

简而言之,将对象创建过程的职责赋予容器,通过容器管理对象的生老病死,

将对象创建过程从编译时延期到运行时,即通过配置进行加载,这样一来就解决了不用编译后期选择具体实现,

其实就是面向对象的核心理念,针对接口编程。IoC开始就是个factory加上依赖管理罢了,

这样一来,一个系统的创建过程就从原先的new改为配置组装,内部通过注入解决了依赖关系,

只要满足接口协议即插即用。通过IoC, AOP事实上形成了一个套路,通过这个套路完成了系统的整合。

所以Spring并没有说自己写一个ORM,而是用统一的套路完成了多个ORM的集成,

这也是Spring越做越大的基础,慢慢就形成了Spring Way,其实这个才是Spring最有价值的地方。

27.说下springboot

Spring 是一个“引擎”

Spring MVC 是基于 Spring 的一个 MVC 框架

Spring Boot 是基于 Spring4 的条件注册的一套快速开发整合包

Spring 最初利用“工厂模式”( DI )和“代理模式”( AOP )解耦应用组件。大家觉得挺好用,于是按照这种模式搞了一个 MVC 框架(一些用 Spring 解耦的组件),

用开发 web 应用( SpringMVC )。然后有发现每次开发都要搞很多依赖,写很多样板代码很麻烦,于是搞了一些懒人整合包( starter ),这套就是 Spring Boot 。

数十年来, Spring 的努力就是为了减少复杂度,解耦,少些一些代码。

我的感觉是,复杂度不会凭空产生,也不会凭空消失,只会从一个地方转移到另一个地方。

虽然掌握 Spring 可以减少很多多余的工作,但是掌握 Spring 本身也变成很复杂的一件事。

Spring 的 XML ,注解配置, EL 表达式这种 DSL ,把很多很简单的事情搞复杂了,当 Spring Boot 自动配置失灵时就带来了更多的麻烦。

28.分布式锁:

分布式锁:是控制分布式系统之间同步访问共享资源的一种方式。在分布式系统中,常常需要协调他们的动作。如果不同的系统或是同一个系统的不同主机之间共享了一个或一组资源,

那么访问这些资源的时候,往往需要互斥来防止彼此干扰来保证一致性,在这种情况下,便需要使用到分布式锁。

目前我用过的是redis实现的

zookeeper实现没有用过

java交流群669823128