面试题

  • “==”和equal()的区别

答:“==”既可以比较基础数据类型也可以比较引用类型,equal()只能比较引用类型(基本数据类型的包装类也属于这一类)。“==”比较基本数据类型时比较的是值是否相等,比较引用数据类型是比较的是对象的地址值是否相同;equal()比较的是内容是否相等,但是由于所有类的超类都是object,而object中有默认的equal(),并且这个默认equal()比较的是“==”判断结果,所以对于一般的两个对象进行比较是其实也是比较的是地址值;但在一些类库当中这个方法被覆盖掉了,如String,Integer,Date在这些类当中equals有其自身的实现,而不再是比较类在堆内存中的存放地址了

相关学习链接

String,Stringbuffer和Stringbuilder的区别

答:

  • String是字符窜常量,放在字符串常量池;Stringbuffer和Stringbuilder是字符窜变量,和一般的对象一样,放在堆和栈中
  • Stringbuffer是线程安全的,Stringbuilder是线程不安全的。原因:Stringbuffer中的方法中很多都有Synchronized关键字,Stringbuilder中没有这个关键字。
  • String效率比较低,Stringbuffer和Stringbuilder效率比较高(但是有个特殊场景下是例外的,见下面链接中的举例);String适合操作比较少的情况下,Stringbuffer适合多线程适合操作比较多,Stringbuilder适合单线程操作比较多的情况下。原因:string在改变时需要从新创建String常量同时然后赋值,然后java内存垃圾回收机制清除以前的String常量,这个过长比较耗时;而Stringbuffer和Stringbuilder在对象本身上进行改变,没有创建新变量和回收就变量的过程。三者在执行速度方面的比较:StringBuilder >  StringBuffer  >  String

详细讲解链接

list,set和map的区别

 答:学习链接

什么控制反转(ioc)和依赖注入(DI)?

 答:在解释什么是控制反转和依赖注入之前我们先了解一个例子:当一个对象A(调用者)需要调用对象B(被调用者)中的方法时,我们该怎么做?传统的做法是在对象A中通过new来创建对象B,然后再调用B里面的方法,这样就把对象A和对象B强行的耦合到的了一起,并且如果此过程被大量的占用的话,创建B对象的过程就会很耗内存。但spring中为了解决紧耦合的问题,让创建被调用者的过程交给第三方组件来完成,这个过程就是控制反转。然后将创建好的被调用者注入到调用者中,成为依赖注入。通过依赖注入,对象的依赖关系将由系统中负责协调各对象的第三方组件在创建对象的时候进行设定;依赖注入会将所依赖的关系自动交给目标对象,而不是让对象自己去获取依赖。

依赖注入的方式:属性(Setter方法)注入,构造注入和接口注入,基于注解注入。

学习链接

谈谈你对面向对象的理解?

为什么在程序中用异常?

谈谈你对spring的理解(什么是spring)?

 答:Spring是一个轻量级的,为了解决企业级的应用开发的复杂性的开源框架。说白了就是为了简化java的开发。简化的手段:1.基于POJO的轻量级和

Mybatis和hibernate相比有哪些优点?或Mybatis的优点有哪些?

springmvc和struts2的区别?或者springmvc有哪些好处?

  springMvc是一个mvc框架,通过实现model-view-controller模式,很好的将数据,业务和展现分开。这点和struts2很相似,但是和struts2的实现方式有很大的区别。

SpringMvc和struts2实现流程的区别:

springmvc:

  当服务端收到一个请求后,springMvc的所有请求会通过一个前端控制器(在这里就是一个单实例的DispatcherServlet),前端控制器是常用的web应该用程序模式,它会将请求委托给应用程序的其他组件来执行实际的处理。

  DispatcherServlet的主要任务就是将请求发送给SpringMvc控制器。SpringMvc控制器控制器就是一个处理请求的spring组件。在典型的应用程序中可能会有多个控制器,所以DispatcherServlet会依据请求所携带的URL信息并且查询多个处理器映射(handler mapping)最后决策将请求发送到那个springMvc控制器。

  请求找到合适的控制器之后,DispatcherServlet就会卸下请求的所携带的用户信息,耐心等待控制器返回回来信息。当然设计良好的控制器本身只会处理甚至不处理工作,而是将业务逻辑委托给一个或多个服务对象进行处理。

  控制器在完成逻辑处理后,会返回用户需要的信息,这些信息被称为模型。但是只返回原始的数据信息是不行的,因为小白用户看不懂,要对信息加以修饰,通常用HTML格式展示,所以要将信息发送给一个视图,例如JSP。控制器要做的最后一件事就是将模型数据打包,并标识出用于渲染数据的特定的视图名称。然后控制器将请求连同模型数据和视图名一起返回给DispatcherServlet。

注意:从上面的流程中我们可以看出控制器和视图是没有耦合。并且实际情况是控制器返回的并不是真实的视图名,而是返回一个逻辑名称,然后DispatcherServlet使用这个逻辑名称通过视图解析器找到真正的视图实现。

 Struts2:

什么是线程?线程有哪些状态,每个状态对应什么方法?

 线程状态详解

线程的实现方法?为什么要用线程池?

 线程实现的两种方式:

   1.继承thread 2.实现Runnable接口

    使用实现Runnable接口的的方法的好处:1.可以实现多继承1.创建时可以实现自己定义线程对象的共享,减少内存的使用

  使用线程池最主要是减少频繁的创建销毁线程的资源消耗。

Synchronized,validate和lock的区别?

答:

  synchronized和lock都是可重入锁,也就是当同一个线程需要进入同步代码块时可以获得自己已经获得锁。

  synchronized是悲观锁,独占锁,当线程A占有琐时,另外线程B只能等待,直到线程A释放了锁。而lock是每次不加锁而是假设是没有冲突的,如果有冲突就重试,直到获得锁或者超过获得锁等待的时间。

  synchronized是jvm级别的锁,如果出现冲突,系统会自动释放锁;但是lock是程序级别的锁,所以所得释放一定要手动进行否者会出现很严重的问题。

  在竞争不太大的时候,synchronized的性能会比lock的好点,但是当竞争比较大时,synchronized的性能下降的非常快,远不如lock和Atomic,但是Atomic有一个缺点就是在同步代码块中智能有一个Atomic变量,多个变量时无效。

   所以,我们写同步的时候,优先考虑synchronized,如果有特殊需要,再进一步优化。ReentrantLock和Atomic如果用的不好,不仅不能提高性能,还可能带来灾难。

  validate一般用来修饰内存中的共享变量。用validate修饰的变量有两个重要含义:1.通过缓存一致性原则解决并发中的可见型问题的但是不保证原子性2.禁止重排序。

 并发编程的三个特性

  答:原子性:既一个操作或者多个操作要么都成功要么都失败

     可见性:再多线程中,对于一个共享变量,当在一个线程中发生改变时,其他线程能立即看到这个修改后的值。

     有序性:程序的执行顺序按着代码的顺序执行。

 缓存一致性问题的认知

  在执行一行代码比如:i=i+1时,正常的做法是,先从主存中获取i的值,并将此值放到线程对应的高速缓存中,然后cpu发出指令进行加1操作,然后加一后的结果更新到高速缓存中,然后在运算完毕之后再将值刷新到主存中,如果在单线程中这个操作没有什么问题,但是在多线程中会出现问题,因为每个线程都有自己的高速缓存,相当于对于一个共享变量在多个高速缓存中都有一个复制,这样就会出现在一个线程中修改了这个值,但是在其他线程的高速缓存中还是以前的旧值,这就是著名的缓存一致性问题。解决这个问题一般有两种方案:1.在主存上加lock所,但是一旦加了所,cpu就无法访问主存了,效率很低。2.缓存一致性原则:当共享变量在一个线程中发生改变时,会立即更新主存中的值同时发出指令告诉cpu此共享变量已经发生改变,cpu就会把其他高速缓存中的此值置为失效,当其他线程访问这个变量时就会重新从主存中读取。

http和https的介绍

http协议的请求流程: http--->tcp--->ip

https协议的请求流程:http--->ssl--->tcp--->ip

 https的证书加密流程?

  答:https其实就是http和ssl的结合。加密的方式简单的来说就是用公钥加密,用私钥解密,但是为了保证公钥不被掉包,就药保证公钥的合法性,就有权威的第三方机构对公钥就行监管,这也就涉及到公钥证书,就是为公钥颁发一个合格证。请求发送之后客户端会先验证证书是否过期,如果过期了会给出提示,如果没有过期会生成一个随机数,然后对随机数进行加密;然后将加密后的随机数进行传送给服务端,服务端用私钥解密数据得到随机数;然后将内容和随机数通过一定算法进行对称加密,只要加密算法够复杂,数据就会够安全;然后将机密信息传送给客户端,客户端进行可用之生成的生成的私钥进行加密就拿到了被加密的内容。

Http和Https的区别?

  答:1.http是超文本传输协议,明文传输内容的,所以不安全;https(就是建立在ssl基础上的http)是具有安全性的ssl加密传输协议,所以安全。

     2.http耗时较短;https耗时较长,因为有加密的过程。

     3.使用https需要申请证书,需要一定的费用

     4.http和https使用完全不同链接方式,前者的端口是80,后者是443

     5.http链接很简单,是无状态的;https是通过ssl协议和http协议构建的可进行加密传输和身份验证的网络协议

分布式事物的解决方案?

jvm的原理

  答:类文件通过编译器编译成字节码文件也就是.class文件后,最终需要使用到时加载到jvm中才能运行。jvm加载class文件并创建对象后,会将文件中不同的内容放到jvm内存中不用的空间中,其中创建的对象会放到java堆内存中,jvm又把java堆内存分为新生代,老年代,永久代(java8之后被替换成了元空间)。当一个对象准备被放到java堆中时会首先放到新生代内存中,而新生代内存又被分为Eden和两个Survivor Space(s0,s1),其实对象会首先被放到Eden中,如果Eden中内存不够,jvm会执行一次垃圾回收(Minor GC),同时会告诉虚拟机打印内存回收日志;然后将仍然存活的对象放到s0中,,如果再次发生垃圾回收操作(Minor GC),就会将eden和s0中仍然存活的对象放到s1中,这样存活的对象会反复的在s0和s1之间进行移动,当对象从Eden和Survivor之间或者在Survivor之间移动时,对象的GC年龄也会自动增加,当GC的年龄增加到默认的阈值15时,jvm会将此对象移动到老年代中。当老年代内存不足时,也会出发一种垃圾回收操作(MajorGC/FullGC),但是这个操作会比MinorGC操作慢十倍。

  虚拟机团队在JDK8的HotSpot中,把永久代从Java堆中移除了,并把类的元数据直接保存在本地内存区域(堆外内存),称之为元空间。

   如何判断对象是否存活?

     1.引数计数法:每个对象都有一个计数标识,每有一次引用时标识加一,引用消失时,此标识减一;如果标识为0时表示没有被引用既可以被回收,如果大于零说明仍然存活,不能被回收。

    2.可达性分析法

      

类加载器的工作原理

      

  答:一个java文件通过编译器编译成.class文件,而class文件中保存了java代码经转化后的虚拟机指令。当需要使用某个class文件时,虚拟机就会找到这个class文件,并创建对应的class对象,将class文件加载到虚拟机内存中,这个过程就是类加载。

  类加载器分为

    1.启动类加载器

    2.扩展类加载器

    3.应用程序类加载器

    4.自定义类加载器

  类加载的原理:

    类加载操作是放在jvm外部实现通过双亲加载模型实现的。所谓双亲加载模型是指:当一个类加载器收到类加载任务时,会优先将加载任务发给其父类执行,这也就是说所有的类加载任务最终都会传到顶层的启动类加载器,只有当父类无法完成加载任务时才会有当前类加载器去加载。

悲观锁和乐观锁的区别?

  答:悲观锁就是先获取所在进行操作。也就是说在操作之前就假设别人会修改这个数据,所以就首先把数据锁起来,只有自己能修改,以便面同时修改产生冲突;

    乐观锁就是假设不认为别人会修改这条数据,如果自己修改了数据需要提交时,这是会判断自己在之前读的此数据的版本和先在的数据版本是否一致,如果一直说明没有人修改,则可以成功提交,如果不一致说明已经有人提交过了,则事物回滚,返回错误信息进行其他的处理操作。

如何实现redis的分布式锁?

  redis分布式锁实现秒杀

线程如何实现返回结果?

  答:线程要想返回结果必须实现Callable接口然后重写call方法,如果不需返回结果可以实现Runnable接口的run()方法。

线程返回值的实现

husdon的构建步骤?

  答:编译-->打包发布-->测试

实现跨域操作的方法?

  第一种:通过jsonp实现 

    原理:利用script标签中src属性可以进行跨域访问的特性来进行跨域操作,同时在src链接中添加callback参数,用于指向我们需要接受结果的方法。

    特点:1.只能发送http的个头请求不能发送post请求

       2.只解决了不同域的http的访问的问题,无法解决不同域的两个页面之间如何进行javascript调用的问题

例如:

<script type="text/javascript">    
    function jsonpCallback(result){     
       alert(result[1].name);     
    }     
</script>  
<script type="text/javascript"src="http://localhost:8080/Jsonp/jsonp.jsp?callback=jsonpCallback"></script> 

  第二种通过ajax实现

  方式:

  • JSONP方式

  • CORS方式

  • 代理请求方式

 Ajax通过jsonp方式实现跨域: 

$.ajax({
type:"get",
url:"http://localhost:3000/showAll",/*url写异域的请求地址*/
dataType:"jsonp",/*加上datatype*/
jsonpCallback:"cb",/*设置一个回调函数,名字随便取,和下面的函数里的名字相同就行*/
success:function(){
。。。
}
});

 springboot的优点是什么?

  优点:

    1.减少了大量的xml配置

    2.减少了maven依赖,通过springboot提供的web就可以得到我们web应用开发所需的jar包

    2.创建项目简单

    3.嵌入了tomcat,jetty容器,无需部署war

    4.做了大量的依赖包,使一些扩展功能能够很方便的使用

   缺点:

    1.无法看到项目的基本配置,对于了解项目配置实现原理来说是个麻烦事

什么是持续集成?

  答:就是通过项目中的每个人每天字少提交一次,每次集成都通过自动化的构建(包括编译,发布,测试),以减少传统意义上各模块代码开发完之后再集成造成的大量返工的情况

java8新特性?

  lamab表达式,和函数式编程

tomcat优化配置

  1.tomcat内存参数的配置  

    

    2.tomcat对线程数的优化

    

    3.tomcat使用线程池

        

     4.tomcat connector的处理方式有三种,BIO(tomcat7之前的版本默认使用),NIO(tomcat8之后的版本默认使用),apr(安装插件后使用)

  tomcat内存参数

Mybatis的一级缓存和二级缓存?

  一级缓存:

    mybatis的一级缓存是sqlSession级别的缓存,默认是开启的,sqlSession关闭一级缓存中的数据跟着被清除。

     如果mybatis不和spring整合,只是一级缓存的关闭可以通过sql语句中的flushCache=“true”的设置来关闭,如果不行,可以获取sqlSession对象然后通过clearCache()清除缓存

  二级缓存:

    mybatis的二级缓存是mapper级别的缓存,是多个sqlsession可以共享的缓存,默认是关闭的。可以通过mapper文件的<cache></cache>标签来开启,也可以通过mybatis的配置文件中的<setting name="cacheEnabled" value="true"/>全局开启,如果一个mapper中的某个查询需要关闭二级缓存可以通过userCache属性来关闭

netty的优点

原文地址:https://www.cnblogs.com/htyj/p/8385689.html