我的java面试经验总结

                                                                                         本宝宝的Java面试经历

1.一个网上商城的开发流程,你会写需求文档吗(ceo问)


2.介绍ajax,ajax为什么可以实现局部刷新。(以下都为项目经理所问)

     实现局部刷新,原文: https://blog.csdn.net/fyxxq/article/details/22219361

     Overriew: onReadyStateChange被回调函数赋值,则能实现异步调用,回调函数直接操作DOM,则能实现局部刷新。那么XMLHttpRequest的onReadyStateChange如何知道服务ready了呢?状态如何change了呢(观察者模式)?则是通过客户端对服务的状态询问(定期轮询)所实现的。
    (1)  XMLHttpRequest 负责与服务器端的通讯,其内部有很多重要的属性:readyStatus=4,status=200等等。当XMLHttpRequest的整体状态并且保证它已经完成(readyStatus=4),即数据已经发送完毕。然后根据服务器的设定询问(类似于客户端会轮询服务器的返回状态,仍然是http短连接,并非长连接的服务器端push)请求状态,如果一切已经就绪(status=200),那么就执行需要的操作。操作一般就是直接操作DOM,所以AJAX能做到所谓的“无刷新”用户体验

    (2)  那么在AJAX客户端如何做到的异步呢?实际上就是Javascript的回调函数起的作用提供一个回调JavaScript函数,一旦服务器响应可用,该函数就被执行

    (3) req.onreadystatechange = callback
   req.open("GET", url, true)

    第一行定义了JavaScript回调函数,一旦响应就绪它就自动执行,而req.open()方法中所指定的“true”标志说明想要异步执行该请求。一旦服务器处理完XmlHttpRequest并返回给浏览器,使用req.onreadystatechange指派所设置的回调方法将被自动调用。
 

3.介绍shiro的认证和授权

      原文:https://blog.csdn.net/qq_34409255/article/details/80667995

扫描二维码关注公众号,回复: 4498370 查看本文章

      shiro是一个安全框架,是Apache的一个子项目。shiro提供了:认证、授权、加密、会话管理、与web集成、缓存等

      Authentication:用户身份识别,可以认为是登录; 
      Authorization:授权,即权限验证,验证某个已认证的用户是否拥有某个权限;即判断用户是否能做事情,常见的如:验证某个用户是否拥有某个角色。或者细粒度的验证某个用户对某个资源是否具有某个权限。
   其他: 

      Session Manager:会话管理,即用户登录后就是一次会话,在没有退出之前,它的所有信息都在会话中;会话可以是普通 JavaSE 环境的,也可以是如 Web 环境的。
     Cryptography:加密,保护数据的安全性,如密码加密存储到数据库,而不是明文存储。
     Web Support:Web支持,可以非常容易的集成到 web 环境。
     Caching:缓存,比如用户登录后,其用户信息、拥有的角色/权限不必每次去查,这样可以提高效率。
     Concurrency:shiro 支持多线程应用的并发验证,即如在一个线程中开启另一个线程,能把权限自动传播过去。
     Testing:提供测试支持。
     Run As:允许一个用户假装为另一个用户(如果他们允许)的身份进行访问。
      Remember Me:记住我,这个是非常常见的功能,即一次登录后,下次再来的话不用登录了。

4.介绍md5

      md5信息摘要算法,只能加密不能解密,一种被广泛使用的密码散列函数,可以产生出一个128位(16字节)的散列值(hash value),用于确保信息传输完整一致。一般使用随机生成的盐值来进行加密。将密文和盐值存放在数据库,用于登录时认证用户。


5.reddis集群怎么搭建

       1)第一步创建实例:创建/usr/local/redis_cluster目录,在里面创建创建6个redis实例,端口号从7001~7006
        2)第二步修改redis的配置文件:修改端口号,修改端口号从7001 ~ 7006、打开cluster-enable前面的注释、注释掉绑定ip
        3)第三步复制ruby脚本:把创建集群的ruby脚本复制到redis-cluster目录下
        4)第四步启动6个redis实例:
            (1)/usr/local/redis/bin/redis-server /usr/local/redis-cluster/800*/redis.conf
            (2)ps -ef | grep redis 查看是否启动成功
        5)第五步创建集群:把6个实例加入到集群
            ./redis-trib.rb create --replicas 1 192.168.2.10:7001 192.168.2.10:7002 192.168.2.10:7003 192.168.2.10:7004 192.168.2.10:7005  192.168.2.10:7006

6.介绍多线程,开多线程和内存的关系

         线程安全就是多线程访问时,采用了加锁机制,当一个线程访问该类的某个数据时,进行保护,其他线程不能进行访问直到该线程读取完,其他线程才可使用。不会出现数据不一致或者数据污染。
7.创建线程,以及其生命周期

    1)继承Thread类创建线程,我们考虑类只能单继承不常使用。
    2)实现Runnable接口创建线程,常用因为可以多实现接口我们常使用它创建线程。
    3)实现Callable接口通过FutureTask包装器来创建Thread线程
    4)线程安全理解:线程安全就是多线程访问时,采用了加锁机制,当一个线程访问该类的某个数据时,进行保护,其他线程不能进行访问直到该线程读取完,其他线程才可使用。不会出现数据不一致或者数据污染。

      生命周期:

      1、 新建状态:当程序使用new关键字创建了一个线程之后,该线程就处于新建状态,此时仅由JVM为其分配内存,并初始化其成员变量的值
        2、就绪状态:当线程对象调用了start()方法之后,该线程处于就绪状态。Java虚拟机会为其创建方法调用栈和程序计数器,等待调度运行
        3、运行状态:如果处于就绪状态的线程获得了CPU,开始执行run()方法的线程执行体,则该线程处于运行状态
        4、阻塞状态:当处于运行状态的线程失去所占用资源之后,便进入阻塞状态
            4.1、当占用CPU的时间片刻用完(Thread.yield()),线程进入到阻塞状态;需要再一次被选中调度才能再次进入就绪状态。
            4.2、当遇到了synchronized线程进入阻塞状态,需要拿到对象所标记才能再次进入就绪状态。
            4.3、当线程调用了某个对象的wait()方法时;也会使线程进入阻塞状态;需要用notify()或者notifyall()方法来唤醒。
            4.4、一个线程调用了另一个线程的join()方法时,当前线程进入阻塞状态。等新加入的线程运行结束后会结束阻塞状态,进入就绪状态。
            4.5、调用了Thread的sleep(long millis)。线程睡眠时间到了会自动进入就绪状态。
            4.6、当遇到用户输入时候也会进入阻塞状态;要等待用户结束才能再次就绪状态。
            4.7、线程从阻塞状态只能进入就绪状态,而不能直接进入运行状态,即结束阻塞的线程需要重新进入可运行池中,等待系统的调度。
        5、死亡状态:线程的run()方法正常执行完毕或者线程抛出一个未捕获的异常(Exception)、错误(Error),线程就进入死亡状态。一旦进入死亡状态,线程将不再拥有运行的资格,也不能转换为其他状态。

8.介绍关系型数据库和非关系型数据库


9.java的三大特征

     封装、继承、多态
10.http协议

1、Http状态码有哪些

    200 – 请求成功;301 – 资源(网页等)被永久转移到其它URL;404 – 请求的资源(网页等)不存在;500 – 内部服务器错误
    1**信息:服务器收到请求,需要请求者继续执行操作(100Continue继续。客户端应继续其请求)
    2**成功:操作被成功接收并处理(200 – 请求成功)
    3**重定向:需要进一步的操作以完成请求(301 – 资源(网页等)被永久转移到其它URL)
    4**客户端错误:请求包含语法错误或无法完成请求(404 – 请求的资源(网页等)不存在)
    5**服务器错误:服务器在处理请求的过程中发生了错误(500 – 内部服务器错误)

2、Http协议中TCP三次握手和四次挥手的流程
    三次握手:首先Client端发送连接请求报文,Server段接受连接后回复ACK=1的报文,并为这次连接分配资源。Client端接收到ACK报文后也向Server段发出ACK=(服务的seq+1)的报文,并分配资源,这样TCP连接就建立了。
        1)连接请求(SYN=1, seq=x):客户端向服务器发送一个 TCP 的 SYN 标志位置1的包,指明客户端打算连接的服务器的端口,以及保存在包头的序列号(Sequence Number)字段里初始序号X。
        2)授予连接(给出响应;SYN=1, ACK=1, seq=y, ACKnum=x+1):服务器给客户端给出响应;服务器发回确认包(ACK)应答。即 SYN 标志位和 ACK 标志位均为1。服务器端选择自己 ISN 序列号,放到 Seq 域里,同时将确认序号(Acknowledgement Number)设置为客户的 ISN 加1,即X+1。
        3)确认连接(ACK=1,ACKnum=y+1):客户端再次发送确认包(ACK),SYN 标志位为0,ACK 标志位为1,并且把服务器发来 ACK 的序号字段+1,放在确定字段中发送给对方,并且在数据段放写ISN的+1
发送完毕后,客户端进入?ESTABLISHED?状态,当服务器端接收到这个包时,也进入?ESTABLISHED?状态,TCP 握手结束。
        
    四次挥手:
        1)发送关闭请求(FIN=1,seq=x):客户端发送一个 FIN 标志位置为1的包,表示自己已经没有数据可以发送了,但是仍然可以接受数据。发送完毕后,客户端进入 FIN_WAIT_1 状态。
        2)给出响应(ACK=1,ACKnum=x+1):服务器端确认客户端的 FIN 包,发送一个确认包,表明自己接受到了客户端关闭连接的请求,但还没有准备好关闭连接。发送完毕后,服务器端进入 CLOSE_WAIT 状态,客户端接收到这个确认包之后,进入 FIN_WAIT_2 状态,等待服务器端关闭连接。
        3)服务器准备关闭(FIN=1,seq=y):服务器端准备好关闭连接时,向客户端发送结束连接请求,FIN 置为1。发送完毕后,服务器端进入 LAST_ACK 状态,等待来自客户端的最后一个ACK。
        4)客户端确认关闭(ACK=1,ACKnum=y+1):客户端接收到来自服务器端的关闭请求,发送一个确认包,并进入 TIME_WAIT状态,等待可能出现的要求重传的 ACK 包。服务器端接收到这个确认包之后,关闭连接,进入 CLOSED 状态。客户端等待了某个固定时间(两个最大段生命周期,2MSL,2 Maximum Segment Lifetime)之后,没有收到服务器端的 ACK ,认为服务器端已经正常关闭连接,于是自己也关闭连接,进入 CLOSED 状态。?
    【问题1】为什么连接的时候是三次握手,关闭的时候却是四次握手?
        答:因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。但是关闭连接时,当Server端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉Client端,"你发的FIN报文我收到了"。只有等到我Server端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四步握手。
    【问题2】为什么TIME_WAIT状态需要经过2MSL(最大报文段生存时间)才能返回到CLOSE状态?
        答:虽然按道理,四个报文都发送完毕,我们可以直接进入CLOSE状态了,但是我们必须假象网络是不可靠的,有可以最后一个ACK丢失。所以TIME_WAIT状态就是用来重发可能丢失的ACK报文。

3、Http协议中Get和Post请求方式的区别
    1)请求报文格式不同:即Get使用Url或cookie传参数,而post使用body传参数
    2)对数据的长度限制不同:get的url会有长度限制(最大2048个字符),而Post数据则可以不受url的限制,可以很大
    3)对数据类型限制不同:GET只允许ASCII码字符;POST没有限制;也可以是二进制数据
    4)安全性不同:post比get安全,因为传递参数在url中不可见;
    5)细分用途不同:get请求主要用于获取、查询资源信息;post请求,更新数据,一般要到form(表单),比较麻烦。
    6)响应速度不同:GET速度快;POST速度慢


11.介绍多态

      父类引用指向子类对象,重载和重写都是多态的表现形式
12.介绍gc

 原:https://blog.csdn.net/yuexianchang/article/details/74025140

  1.根据Java虚拟机规范,JVM将内存划分为:

  • New(年轻代)——年轻代用来存放JVM刚分配的Java对象

                        Eden:Eden用来存放JVM刚分配的对象

                        Survivor1

                        Survivro2:两个Survivor空间一样大,当Eden中的对象经过垃圾回收没有被回收掉时,会在两个Survivor之间来   回Copy,当满足某个条件,比如Copy次数,就会被Copy到Tenured。显然,Survivor只是增加了对象在年轻代中的逗留时间,增加了被垃圾回收的可能性。 

  • Tenured(年老代)- ——年轻代中经过垃圾回收没有回收掉的对象将被Copy到年老代
  • 永久代(Perm)—— 永久代存放Class、Method元信息,其大小跟项目的规模、类、方法的量有关,一般设置为128M就足够,设置原则是预留30%的空间。

   New和Tenured属于堆内存,堆内存会从JVM启动参数(-Xmx:3G)指定的内存中分配

  Perm不属于堆内存,有虚拟机直接分配,但可以通过-XX:PermSize -XX:MaxPermSize等参数调整其大小

2.垃圾回收算法

  垃圾回收算法可以分为三类,都基于标记-清除(复制)算法:

  • Serial算法(单线程)
  • 并行算法
  • 并发算法

  JVM会根据机器的硬件配置对每个内存代选择适合的回收算法,比如,如果机器多于1个核,会对年轻代选择并行算法,关于选择细节请参考JVM调优文档。


13.java中有没有指针和goto

    java中没有指针,Java中有goto保留字,但并没有实际使用它。


14.二叉树、链表

各位兄弟百度吧···


15.分页
使用了PageHelper插件来进行数据分页
      

使用了PageHelper插件来进行数据分页
		@RequestMapping("/emps")
    
public String list(@RequestParam(required =false,defaultValue = "1",value = "pn") Integerpn,
                       Map<String,Object> map)
{
 
       	 //引入分页查询,使用PageHelper分页功能
        
	//在查询之前传入当前页,然后多少记录
        
	PageHelper.startPage(pn,5);
        
	//startPage后紧跟的这个查询就是分页查询
        
	List<Employee> emps = employeeService.getAll();
        
	//使用PageInfo包装查询结果,只需要将pageInfo交给页面就可以
        
	PageInfo pageInfo = new PageInfo<>(emps,5);
        
	//pageINfo封装了分页的详细信息,也可以指定连续显示的页数
 
        
	map.put("pageInfo",pageInfo);
        
	return "list";

}





实现mysql的分页?Oracle的分页?
        1)mysql分页:mysql的分页sql格式是:select * from table limit (start-1)*limit,limit; 其中start是页码,limit是每页显示的条数。
            例:select * from test limit 3,5;--查询test从3开始,5条数据  
        2)Oracle分页:使用rownum使其重新排列,从1开始
            例:select rownum,rowid,tt.* from t_user5 tt where rownum<=3 and sex=1 and  rownum>=2

16.switch中可以float,long和String吗

      switch中只能为int类型。由于byte、char、short、int在底部使用时会转换成int类型所以他们可以作为参数。而long、float不可以,在jdk7之后Stirng也可以作为参数。


17.数据库执行计划
18.分布式的事务控制
19.数据库的函数
20.存储过程,触发器,游标

    看我plsql总结
21.泛型
22.反射


23.SSM框架的流程

    看我专门总结
24.springmvc的执行流程
25.spring的事务
26.spring的核心思想
27.linux的发展史,和window的区别,以及命令
28.jvm性能调优
29.冯诺依曼原理和哈佛原理

30.数据库索引,以及最左原则

31.流量的削峰

31.双亲委托机制

32.跨域、同源的问题

   推荐:https://www.cnblogs.com/fengli9998/p/6731661.html

33.http和https的区别

34.如何创建索引,索引会影响什么的性能

35.数据库常用的类型

36.什么是序列化,为什么使用序列化

37.为什么使用xml,它的作用是啥

38.常用排序算法

39.cpu使用率过高,cpu如何调优

40.单列模式你认为最优的模式

41.正则表达式的使用

42.公平锁和不公平锁

43.在前后端的交互上,websocket是怎么实现的,原理是什么?

websocket是一个持久化的协议,它实现了浏览器与服务器全双工(full-duplex)通信——允许服务器主动发送信息给客户端,它是基于HTTP协议的,但它只是借用了HTTP的协议来完成一部分握手,例如:客户端发送请求到服务器,里面指明用的websocket协议,和确定连接的key,不同的服务名,协议版本;然后服务器返回接受请求的信息,信息包括加密后的key和哪个服务;经过这些操作后接下就按照websocket协议进行了。websocket只需要经过一次请求就能做到源源不断的信息传送。

 

44.一级缓存和二级缓存的区别?

(1)一级缓存基于sqlSession默认开启,在操作数据库时需要构造SqlSession对象,在对象中有一个HashMap用于存储缓存数据。不同的SqlSession之间的缓存数据区域是互相不影响的。一级缓存的作用域是SqlSession范围的,当在同一个sqlSession中执行两次相同的sql语句时,第一次执行完毕会将数据库中查询的数据写到缓存(内存),第二次查询时会从缓存中获取数据,不再去底层数据库查询,从而提高查询效率。

(2)二级缓存的作用域是mapper的同一个namespace。不同的sqlSession两次执行相同的namespace下的sql语句,且向sql中传递的参数也相同,即最终执行相同的sql语句,则第一次执行完毕会将数据库中查询的数据写到缓存,第二次查询会从缓存中获取数据,不再去底层数据库查询,从而提高效率。

 

 

45.为什么要用springboot?

spring boot提高了Java的开发速度,快速构建项目;简化了开发过程、配置过程、部署过程、监控过程;项目可独立运行,无需外部依赖servlet容器;

 

 

46.高并发的解决方案?

1.应用程序和静态资源文件进行分离;

2.页面缓存;

3.集群与分布式;

4.反向代理;

5.CDN

 

47.JDK动态代理和cglib代理的区别?

java动态代理是利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理。

而cglib动态代理是利用asm开源包,对代理对象类的class文件加载进来,通过修改其字节码生成子类来处理。

48.反射机制是什么?

   Java 反射机制是在运行状态中,对于任意一个类,都能够获得这个类的所有属性和方法,对于任意一个对象都能够调用它的任意一个属性和方法。这种在运行时动态的获取信息以及动态调用对象的方法的功能称为 Java 的反射机制。 有属性和方法,对于任意一个对象都能够调用它的任意一个属性和方法

49.介绍一下二叉树,以及前序、中序、后序遍历以及深度遍历和广度遍历。

50.手写生产者和消费者

51.内连接和外连接

猜你喜欢

转载自blog.csdn.net/qq_35316228/article/details/84134135