Java面试错题集1

SpringBoot的注解:

1.@SpringBootApplication:
这个注解是用来声明springboot来给程序进行一些必要的配置,相当于
@Configuration:声明这是一个配置文件、相当于xml配置文件
@EnableAutoConfiguration:自动配置功能、
@ComponentScan组件扫描可以自动发现和装配一些bean
上述三个注解的整合版本。

2.@ResponseBody:表示该方法返回的结果直接写入到responsebody中,一般在异步获取数据时使用,用于构建restful风格的api。
在使用@RequesMapping后,返回值通常被解析为跳转路径,加上@ResponseBody后不会被解析成跳转路径,会直接写入到http response body中。
比如异步获取json数据,加上@responsebody后,会直接返回json数据。该注解一般会配合@RequestMapping一起使用。

3.@Controller:用于定义控制类,在spring项目中,由控制器负责将用户传递的url请求转发到对于的服务接口,就是service层。一般放在controller层的类里注解,配合@RequestMapping使用。

4.@RestController:用于标注控制层组件,比如action。相当于@Controller和@ResponseBody的整合。

5.@RequestMapping:提供路由信息,负责URL到Controller中的具体函数的映射。

6.@EnableAutoConfiguration:Spring Boot自动配置(auto-configuration):根据你添加的jar依赖自动配置你的Spring应用。
可以将@EnableAutoConfiguration或者@SpringBootApplication注解添加到一个@Configuration类上来选择自动配置。如果发现应用了你不想要的特定自动配置类,你可以使用@EnableAutoConfiguration注解的排除属性来禁用它们。

7.@ComponentScan:表示将该类自动发现扫描组件。个人理解相当于,如果扫描到有@Component、@Controller、@Service、@Repository等这些注解的类,并注册为Bean,可以自动收集所有的Spring组件,包括@Configuration类。我们经常使用@ComponentScan注解搜索beans,并结合@Autowired注解导入。可以自动收集所有的Spring组件,包括@Configuration类。

8.@ImportResource:用来加载xml配置文件。
@Component、@Controller、@Service、@Repository用来将类注册为组件
@component在web开发中有按MVC三层架构分别在service层,controller层,dao层(与上述排序相同)有不同的注解但是效果相同。

9.@Autowired和@Resource用来实现bean的自动装配
10.@PathVariable获取参数

servlet的生命周期

一、加载与实例化

第一阶段,我们知道,Servlet容器是负责加载与实例化Servlet的。当一个Servlet容器在启动或检测到容器需要这个Servlet来以此响应第一个请求时,会创建Servlet实例。Servlet容器启动后,它必须要知道所需的Servlet类是在什么位置,所以Servlet容器能够从本地文件系统、远程文件系统或其他的网络服务中通过类加载器来加载Servlet类,当成功加载后,容器就会创建Servlet的实例。

二、servlet初始化

第二阶段,Servlet实例化后,容器会调用init()方法来初始化对象,这是为了让Servlet对象在处理客户端请求前完成一些初始化的工作,像建立数据库的连接和获取配置信息等。对所有Servlet实例来说,init()方法只能被调用一次。在初始化期间,Servlet实例可以使用容器为它准备的ServletConfig对象从Web应用程序的配置信息中获取初始化的参数信息。

三、客户端请求处理

第三阶段,到这里就是Servlet容器调用Servlet中service()方法对请求进行处理了。需要注意的是,在service()方法调用之前,init()方法是必须成功执行的。在service()方法中,Servlet实例通过ServletRequest对象得到客户端的相关信息和请求信息,在它对请求进行处理后,会调用ServletResponse对象的方法设置响应信息。在service()方法执行时,如若发生错误,Servlet实例就可以抛出ServletException异常或UnavailableException异常。如果UnavailableException异常指示了该实例永久不可用,那么Servlet容器就会调用实例的destroy()方法。此后对该实例的任何请求,都将收到容器发送的HTTP 404响应。如果UnavailableException异常指示了该实例暂不可用,那么在暂不可用的时间段内,对该实例的任何请求,都会收到容器发送的HTTP 503响应。

四、servlet销毁

最后阶段,当servlet容器检测到Servlet实例该从服务中被移除时,容器会调用实例的destroy()方法,让该实例可以释放它所使用的资源,从而保存数据到持久存储设备中。一旦需要释放内存或关闭容器时,容器就会调用Servlet实例的destroy()方法。在destroy()方法调用之后,容器就会释放这个Servlet实例,随后这个实例就会被Java的垃圾收集器所回收。如果再次需要这个Servlet处理请求,则Servlet容器就会创建一个新的Servlet实例。在Servlet整个生命周期过程中,创建Servlet实例、调用实例的init()和destroy()方法都只能够进行一次,当初始化完成后,Servlet容器就会将该实例保存在内存中,通过调用它的service()方法,为接收到的请求服务。

流程图:
在这里插入图片描述

SpringMVC的流程

1.用户发送请求到前端控制器DispatcherServlet
2.前端控制器收到请求后调用映射处理器MappingHandler
3.映射处理器根据xml配置或者注解找到具体的处理器信息返回给前端控制器
4.前端控制器调用适配器HandlerAdapter
5.适配器找到具体的处理器controller执行然后将结果返回给前端控制器
6.前端控制器接收到结果后将结果传给视图解析器(6的结果是一些model和view)
7.解析后将数据传递给前端控制器
8.前端控制器响应用户

JDBC的连接数据库的步骤

1.注册加载数据库驱动
Class.forName(“com.mysql.jdbc.Driver”);成功加载后,会将Driver类的实例注册到DriverManager类中。

2.获取数据库连接
String url = “jdbc:mysql://localhost:3306/test” ;
String username = “root” ;
String password = “root” ;
Connection con = DriverManager.getConnection(url , username , password ) ;

3.创建一个Statement语句对象
要执行SQL语句,必须获得java.sql.Statement实例,Statement实例分为以下3 种类型:
1、执行静态SQL语句。通常通过Statement实例实现。
2、执行动态SQL语句。通常通过PreparedStatement实例实现。
3、执行数据库存储过程。通常通过CallableStatement实例实现。
•具体的实现方式:
Statement stmt = con.createStatement() ;
PreparedStatement pstmt = con.prepareStatement(sql) ;
CallableStatement cstmt = con.prepareCall("{CALL demoSp(? , ?)}") ;

4.编写并执行sql语句
•Statement接口提供了三种执行SQL语句的方法:executeQuery 、executeUpdate和execute
1、ResultSet executeQuery(String sqlString):执行查询数据库的SQL语句,返回一个结果集(ResultSet)对象。
2、int executeUpdate(String sqlString):用于执行INSERT、UPDATE或 DELETE语句以及SQL DDL语句,如:CREATE TABLE和DROP TABLE等
3、execute(sqlString):用于执行返回多个结果集、多个更新计数或二者组合的语句。

5.处理结果集
两种情况:
1、执行更新返回的是本次操作影响到的记录数。
2、执行查询返回的结果是一个ResultSet对象。
• ResultSet包含符合SQL语句中条件的所有行,并且它通过一套get方法提供了对这些行中数据的访问。
• 使用结果集(ResultSet)对象的访问方法获取数据:

6.关闭数据库连接
•操作完成以后要把所有使用的JDBC对象全都关闭,以释放JDBC资源,关闭顺序和声 明顺序相反:
1、先关闭requestSet
2、再关闭preparedStatement
3、最后关闭连接对象connection

前端传递给后端的json数据,后端接口以什么注解来接收

@Pathvarible(“id”):用来接收直接在url后传递的参数(xxx.com/id=1)
@RequestParam(“id”):用来接收作为参数传递参数(xxx.com?id=1)

wait()和sleep()有什么区别

1.wait()方法是当线程执行wait()方法时候,会释放当前的锁,然后让出CPU,进入等待状态。并且可以调用notify()方法或者notifyAll()方法通知正在等待的其他线程。notify()方法仅唤醒一个线程(等待队列中的第一个线程)并允许他去获得锁。notifyAll()方法唤醒所有等待这个对象的线程并允许他们去竞争获得锁。

2.sleep()方法是Thread类的静态方法,是线程用来控制自身流程的,他会使此线程暂停执行一段时间,而把执行机会让给其他线程,等到计时时间一到,此线程会自动苏醒。

锁的机制不同:两者都是使线程暂停执行的方法。由于sleep()方法的主要作用是让线程暂停执行一段时间,时间一到则自动恢复,不涉及线程间的通信,因此,调用sleep()方法并不会释放锁。而wait()方法则不同,当调用wait()方法后,线程会释放掉他所占用的锁,从而使线程所在对象中的其他synchronized数据可以被其他线程使用。

使用区域不同:wait()方法必须放在同步控制方法和同步代码块中使用,sleep()方法则可以放在任何地方使用。sleep()方法必须捕获异常,而wait()、notify()、notifyAll()不需要捕获异常。在sleep的过程中,有可能被其他对象调用他的interrupt(),产生InterruptedException。由于sleep不会释放锁标志,容易导致死锁问题的发生,因此一般情况下,推荐使用wait()方法。

代码块的执行顺序

静态代码块——>非静态代码块——>构造函数——>普通代码块
静态代码块随着类的加载只执行一次,非静态代码块类加载一次就执行一次
构造函数用于在类的对象创建时用来定义初始化的状态

在浏览器输入url到浏览器响应这段时间内发生了什么

在我们输入网址按下回车后,DNS服务器会通过当前网址解析这一网址的ip;在查找到IP之后,浏览器会向服务器发起一个tcp连接请求,此请求包含三次握手,如下:
第一次握手:建立链接时,客户端浏览器会发送syn包到服务器,并进入SYS_SENT状态,等待服务器的确认;

第二次握手:服务器收到syn包后,必须确认客户端的syn,同时之间发送一个ack包,即是syn加ack包,此时服务器进入SYN_RECV状态,此时服务器被动打开后,接收到客户端的syn并且发送了ack时状态;

第三次握手:客户端接收到服务器的syn+ack包后,给服务器发送确认包ack,包发送完毕之后,客户端和服务器端进入ESTABLISHED(tcp连接成功)状态,完成了第三次握手。
当三次握手结束后客户端和服务器端就建立好了连接,此时tcp协议断开,开始访问服务器下的默认index.html页面,并调用该访问的资源文件,展示相应的内容。

猜你喜欢

转载自blog.csdn.net/gsy_csdn1/article/details/114900349