JAVA面试题总结(一)

    技术2023-10-12  103

    ⼀、⾃我介绍 ⼆、什么是mybatis 1、Mybatis 是⼀个半 ORM(对象关系映射)框架,它内部封装了 JDBC,开发时只需要关注 SQL 语句本身,不需要花费精⼒去处理加载驱动、创建连接、创建statement 等繁杂的过程。程序员直接编写原 ⽣态 sql,可以严格控制 sql 执⾏性能,灵活度⾼。 2、MyBatis 可以使⽤ XML 或注解来配置和映射原⽣信息,将 POJO 映射成数据库中的记录,避免 了⼏乎所有的 JDBC 代码和⼿动设置参数以及获取结果集。    3、通过 xml ⽂件或注解的⽅式将要执⾏的各种 statement 配置起来,并通过java 对象和 statement 中 sql 的动态参数进⾏映射⽣成最终执⾏的 sql 语句,最后由 mybatis 框架执⾏ sql 并将结果 映射为 java 对象并返回。(从执⾏ sql 到返回 result 的过程)。 三、Mybaits 的优点 1、基于 SQL 语句编程,相当灵活,不会对应⽤程序或者数据库的现有设计造成任何影响,SQL 写在 XML ⾥,解除 sql 与程序代码的耦合,便于统⼀管理;提供 XML标签,⽀持编写动态 SQL 语句,并可重 ⽤。 2、与 JDBC 相⽐,减少了 50%以上的代码量,消除了 JDBC ⼤量冗余的代码,不需要⼿动开关连 接; 3、很好的与各种数据库兼容(因为 MyBatis 使⽤ JDBC 来连接数据库,所以只要JDBC ⽀持的数据 库 MyBatis 都⽀持)。 4、能够与 Spring 很好的集成; 5、提供映射标签,⽀持对象与数据库的 ORM 字段关系映射;提供对象关系映射标签,⽀持对象关系 组件维护。 四、#{}和KaTeX parse error: Expected 'EOF', got '#' at position 12: {}的区别是什么? #̲{}是预编译处理,{}是字符串替换。 Mybatis 在处理#{}时,会将 sql 中的#{}替换为?号,调⽤ PreparedStatement 的set ⽅法来赋值; Mybatis 在处理 时 , 就 是 把 {}时,就是把 {}替换成变量的值。 使⽤#{}可以有效的防⽌ SQL 注⼊,提⾼系统安全性 五、当实体类中的属性名和表中的字段名不⼀样 ,怎么办 ? 第 1 种: 通过在查询的 sql 语句中定义字段名的别名,让字段名的别名和实体类的属性名⼀致。 第 2 种: 通过resultmap来映射字段名和实体类属性名的⼀⼀对应的关系。 第 3 种:命名规范的可以开启驼峰映射 六、通常⼀个 Xml 映射⽂件,都会写⼀个 Dao 接⼝与之对应,请问,这个 Dao 接⼝的⼯作原理是什么?Dao 接⼝⾥的⽅法,参数不同时,⽅法能重载吗? Dao 接⼝即 Mapper 接⼝。接⼝的全限名,就是映射⽂件中的 namespace 的值;接⼝的⽅法名, 就是映射⽂件中 Mapper 的 Statement的 id 值; 接⼝⽅法内的参数,就是传递给 sql 的参数。Mapper 接⼝是没有实现类的,当调⽤接⼝⽅法时,接 ⼝全限名+⽅法名拼接字符串作为 key 值,可唯 ⼀定位⼀个 MapperStatement。在 Mybatis 中,每⼀个然后在 java 代码中像下⾯这样执⾏批处理 插⼊

    七、如何获取⾃动⽣成的(主)键值? usegeneratedkeys=”true” keyproperty=”id” ⼋、在 mapper 中如何传递多个参数? 第⼀种:#{0}代表接收的是 dao 层中的第⼀个参数,#{1}代表 dao 层中第⼆个参数; 第⼆种: 使⽤ @param 注解 第三种:多个参数封装成 map 九、Mybatis 的 Xml 映射⽂件中,不同的 Xml 映射⽂件,id 是否可以重复? 不同的 Xml 映射⽂件,如果配置了 namespace,那么 id 可以重复;如果没有配置 namespace,那 么 id 不能重复; 原因就是 namespace+id 是作为 Map<String, MapperStatement>的 key使⽤的,如果没有 namespace,就剩下 id,那么,id 重复会导致数据互相覆盖。 有了 namespace,⾃然 id 就可以重复,namespace 不同,namespace+id ⾃然也就不同 ⼗、为什么说 Mybatis 是半⾃动 ORM 映射⼯具? 对象关系模型直接获取,所以它是全⾃动的。⽽ Mybatis在查询关联对象或关联集合对象时,需要⼿ 动编写 sql 来完成 ⼗⼀、Mybatis 是否⽀持延迟加载?如果⽀持,它的实现原理是什么? Mybatis 仅⽀持 association 关联对象和 collection 关联集合对象的延迟加载,association 指的 就是⼀对⼀,collection 指的就是⼀对多查询。在 Mybatis配置⽂件中,可以配置是否启⽤延迟加载 lazyLoadingEnabled=true|false。它的原理是,使⽤ CGLIB 创建⽬标对象的代理对象,当调⽤⽬标⽅法 时,进⼊拦截器⽅法,⽐如调⽤ a.getB().getName(),拦截器 invoke()⽅法发现 a.getB()是null 值,那么 就会单独发送事先保存好的查询关联 B 对象的 sql,把 B 查询上来,然后调⽤ a.setB(b),于是 a 的对象 b 属性就有值了,接着完成 a.getB().getName()⽅法的调⽤。这就是延迟加载的基本原理。当然了,不光是 Mybatis,⼏乎所有的包括 Hibernate,⽀持延迟加载的原理都是⼀样的。 ⼗⼆、mybatis的⼀级和⼆级缓存 1)⼀级缓存: 基于 PerpetualCache 的 HashMap 本地缓存,其存储作⽤域为Session,当 Session flush 或 close 之后,该 Session 中的所有 Cache 就将清空,默认打开⼀级缓存。 2)⼆级缓存与⼀级缓存其机制相同,默认也是采⽤ PerpetualCache,HashMap存储,不同在于其 存储作⽤域为 Mapper(Namespace),并且可⾃定义存储源,如 Ehcache。默认不打开⼆级缓存,要开启 ⼆级缓存,使⽤⼆级缓存属性类需要实现 Serializable 序列化接⼝(可⽤来保存对象的状态),可在它的映射⽂ 件中配置 ; 3)对于缓存数据更新机制,当某⼀个作⽤域(⼀级缓存 Session/⼆级缓存Namespaces)的进⾏了 C/U/D 操作后,默认该作⽤域下所有 select 中的缓存将被 clear。 ⼗三、什么是 MyBatis 的接⼝绑定?有哪些实现⽅式? 接⼝绑定,就是在 MyBatis 中任意定义接⼝,然后把接⼝⾥⾯的⽅法和 SQL 语句绑定, 我们直接调⽤ 接⼝⽅法就可以,这样⽐起原来了 SqlSession 提供的⽅法我们可以有更加灵活的选择和设置。接⼝绑定有两 种实现⽅式,⼀种是通过注解绑定,就是在接⼝的⽅法上⾯加上@Select、@Update 等注解,⾥⾯包含 Sql 语句来绑定;另外⼀种就是通过 xml⾥⾯写 SQL 来绑定,在这种情况下,要指定 xml 映射⽂件⾥⾯的 namespace 必须为接⼝的全路径名。当 Sql 语句⽐较简单时候,⽤注解绑定, 当 SQL 语句⽐较复杂时候,⽤ xml 绑定,⼀般⽤ xml 绑定的⽐较多。

    ⼗四、什么是 Spring IOC 容器? Spring 框架的核⼼是 Spring 容器。容器创建对象,将它们装配在⼀起,配置它们并管理它们的完整 ⽣命周期。Spring 容器使⽤依赖注⼊来管理组成应⽤程序的组件。 容器通过读取提供的配置元数据来接收对象进⾏实例化,配置和组装的指令。该元数据可以通过 XML,Java 注解或 Java 代码提供。 ⼗五、什么是依赖注⼊? 在依赖注⼊中,您不必创建对象,但必须描述如何创建它们。您不是直接在代码中将组件和服务连接 在⼀起,⽽是描述配置⽂件中哪些组件需要哪些服务。由 IoC容器将它们装配在⼀起。 ⼗六、可以通过多少种⽅式完成依赖注⼊? 通常,依赖注⼊可以通过三种⽅式完成,即: 构造函数注⼊, setter 注⼊,接⼝注⼊ ⼗七、Spring IoC 的实现机制 Spring 中的 IoC 的实现原理就是⼯⼚模式加反射机制 ⼗⼋、什么是 spring bean 它们是构成⽤户应⽤程序主⼲的对象, Bean 由 Spring IoC 容器管理,它们由 Spring IoC 容器实例 化,配置,装配和管理,Bean 是基于⽤户提供给容器的配置元数据创建 ⼗九、spring bean的⽣命周期 1、Spring 容器根据配置中的 bean 定义中实例化 bean。    2、Spring 使⽤依赖注⼊填充所有属性,如 bean 中所定义的配置。    3、如果 bean 实现BeanNameAware 接⼝,则⼯⼚通过传递 bean 的 ID 来调⽤ setBeanName()。 4、如果 bean 实现 BeanFactoryAware 接⼝,⼯⼚通过传递⾃身的实例来调⽤ setBeanFactory()。 5、如果存在与bean 关联的任何BeanPostProcessors,则调⽤ preProcessBeforeInitialization() ⽅法。    6、如果为 bean 指定了 init ⽅法( 的 init-method 属性),那么将调    ⽤它。    7、最后,如果存在与 bean 关联的任何 BeanPostProcessors,则将调⽤ postProcessAfterInitialization() ⽅法。    8、如果 bean 实现DisposableBean 接⼝,当 spring 容器关闭时,会调⽤ destory()。    9、如果为bean 指定了 destroy ⽅法( 的 destroy-method 属性),那么将调⽤ 它 ⼆⼗、@Component, @Controller, @Repository的区别 @Component :这将 java 类标记为 bean。它是任何 Spring 管理组件的通⽤构造型。spring 的组 件扫描机制现在可以将其拾取并将其拉⼊应⽤程序环境中。 @Controller :这将⼀个类标记为 Spring Web MVC 控制器。标有它的Bean 会⾃动导⼊到 IoC 容 器中。 @Service :此注解是组件注解的特化。它不会对 @Component 注解提供任何其他⾏为。您可以在 服务层类中使⽤ @Service ⽽不是 @Component,因为它以更好的⽅式指定了意图 @Repository :这个注解是具有类似⽤途和功能的@Component 注解的特化。它为 DAO 提供了额 外的好处。它将 DAO 导⼊ IoC 容器,并使未经检查的异常有资格转换为 Spring DataAccessException。

    ⼆⼗⼀、列举 spring ⽀持的事务管理类型 1、 程序化事务管理:在此过程中,在编程的帮助下管理事务。它为您提供极⼤的灵活性,但维护起 来⾮常困难。 2、 声明式事务管理:在此,事务管理与业务代码分离。仅使⽤注解或基于 XML的配置来管理事务 ⼆⼗⼆、什么是 AOP,什么是 Aspect?什么是切⼊点和连接点?什么是通知 (Advice)?什么是通知?通知的五⼤类型?基于什么原理去实现的业务扩展    1.AOP(Aspect Orient Programming)是⼀种设计思想,是软件设计领域中的⾯向切⾯编程,它 是⾯向对象编程(OOP)的⼀种补充和完善。它以通过预编译⽅式和运⾏期动态代理⽅式,实现在不修改源代 码的情况下给程序动态统⼀添加额外功能的⼀种技术.    2.Aspect:横切⾯对象,⼀般为⼀个具体类对象(可以借助@Aspect声明)    3.切⼊点(pointcut):对多个连接点(Joinpoint)⼀种定义,⼀般可以理解为多个连接点的集合。    4.连接点(joinpoint):程序执⾏过程中某个特定的点,⼀般指被拦截到的的⽅法    5.Advice:在切⾯的某个特定连接点上执⾏的动作(扩展功能)    6.前置通知 (@Before) ;返回通知 (@AfterReturning);异常通知 (@AfterThrowing) ;后置通知 (@After);环绕通知 (@Around) :重点掌握(优先级最⾼)    7.Spring AOP底层基于代理机制实现功能扩展 ⼆⼗三、MVC对的执⾏流程 ⾸先⽤户发送请求到前端控制器,前端控制器根据请求信息(如 URL)来决定选择哪⼀个⻚⾯控制器 进⾏处理并把请求委托给它,即以前的控制器的控制逻辑部分;图中的 1、2 步骤; ⻚⾯控制器接收到请求后,进⾏功能处理,⾸先需要收集和绑定请求参数到⼀个对象,这个对象在 Spring Web MVC 中叫命令对象,并进⾏验证,然后将命令对象委托给业务对象进⾏处理;处理完毕后返回⼀个 ModelAndView(模型数据和逻辑视图名);图中的 3、4、5 步骤; 前端控制器收回控制权,然后根据返回的逻辑视图名,选择相应的视图进⾏渲染,并把模型数据传⼊以便视 图渲染;图中的步骤 6、7; 前端控制器再次收回控制权,将响应返回给⽤户,图中的步骤 8;⾄此整个结束。 ⼆⼗四、cookie和session的区别    1、存储位置不同    cookie的数据信息存放在客户端浏览器上。    session的数据信息存放在服务器上。    2、存储容量不同    单个cookie保存的数据<=4KB,⼀个站点最多保存20个Cookie。    对于session来说并没有上限,但出于对服务器端的性能考虑,session内不要存放过多的东⻄,并 且设置session删除机制。    3、存储⽅式不同    cookie中只能保管ASCII字符串,并需要通过编码⽅式存储为Unicode字符或者⼆进制数据。    session中能够存储任何类型的数据,包括且不限于string,integer,list,map等。    4、隐私策略不同    cookie对客户端是可⻅的,别有⽤⼼的⼈可以分析存放在本地的cookie并进⾏cookie欺骗,所以它 是不安全的。    session存储在服务器上,对客户端是透明对,不存在敏感信息泄漏的⻛险。    5、有效期上不同    开发可以通过设置cookie的属性,达到使cookie⻓期有效的效果。    session依赖于名为JSESSIONID的cookie,⽽cookie JSESSIONID的过期时间默认为-1,只需关 闭窗⼝该session就会失效,因⽽session不能达到⻓期有效的效果。

    6、服务器压⼒不同    cookie保管在客户端,不占⽤服务器资源。对于并发⽤户⼗分多的⽹站,cookie是很好的选择。    session是保管在服务器端的,每个⽤户都会产⽣⼀个session。假如并发访问的⽤户⼗分多,会产 ⽣⼗分多的session,耗费⼤量的内存。    7、浏览器⽀持不同    假如客户端浏览器不⽀持cookie:    cookie是需要客户端浏览器⽀持的,假如客户端禁⽤了cookie,或者不⽀持cookie,则会话跟踪会 失效。关于WAP上的应⽤,常规的cookie就派不上⽤场了。    运⽤session需要使⽤URL地址重写的⽅式。⼀切⽤到session程序的URL都要进⾏URL地址重写, 否则session会话跟踪还会失效。    假如客户端⽀持cookie:    cookie既能够设为本浏览器窗⼝以及⼦窗⼝内有效,也能够设为⼀切窗⼝内有效。    session只能在本窗⼝以及⼦窗⼝内有效。    8、跨域⽀持上不同    cookie⽀持跨域名访问。    session不⽀持跨域名访问。 ⼆⼗五、请求转发和重定向区别    重定向和转发有⼀个重要的不同:当使⽤转发时,JSP容器将使⽤⼀个内部的⽅法来调⽤⽬标⻚⾯, 新的⻚⾯继续处理同⼀个请求,⽽浏览器将不会知道这个过程。 与之相反,重定向⽅式的含义是第⼀个⻚⾯ 通知浏览器发送⼀个新的⻚⾯请求。因为,当你使⽤重定向时,浏览器中所显示的URL会变成新⻚⾯的 URL,⽽当使⽤转发时,该URL会保持不变。重定向的速度⽐转发慢,因为浏览器还得发出⼀个新的请求。 同时,由于重定向⽅式产⽣了⼀个新的请求,所以经过⼀次重 定向后,request内的对象将⽆法使⽤。 ⼆⼗六、jdbc连接数据库的流程

    jar 包的引⼊加载JDBC驱动程序建⽴连接(Connection创建执⾏SQL语句的(Statement处理执⾏结果(ResultSet)释放资源 ⼆⼗七、mvc的注解 1、@Controller 在SpringMVC 中,控制器Controller 负责处理由DispatcherServlet 分发的请求,它把用户请求的数 据经过业务处理层处理之后封装成一个Model ,然后再把该Model 返回给对应的View 进行展示. 2、@RequestMapping RequestMapping是一个用来处理请求地址映射的注解,可用于类或方法上。用于类上,表示类中的所 有响应请求的方法都是以该地址作为父路径 3、@Resource和@Autowired @Resource和@Autowired都是做bean的注入时使用,其实@Resource并不是Spring的注解,它的包 是javax.annotation.Resource,需要导入,但是Spring支持该注解的注入。 4、@ModelAttribute和 @SessionAttributes 代表的是:该Controller的所有⽅法在调⽤前,先执⾏此@ModelAttribute⽅法,可⽤于注解和⽅法 参数中,可以把这个@ModelAttribute特性,应⽤在BaseController当中,所有的Controller继承 BaseController,即可实现在调⽤Controller时,先执⾏@ModelAttribute⽅法。 5、@PathVariable 用于将请求URL中的模板变量映射到功能处理方法的参数上,即取出uri模板中的变量作为参数。 6、@requestParam

    @requestParam主要⽤于在SpringMVC后台控制层获取参数,类似⼀种是 request.getParameter(“name”),它有三个常⽤参数:defaultValue = “0”, required = false, value = “isApp”;defaultValue 表示设置默认值,required 铜过boolean设置是否是必须要传⼊的参数,value 值表示接受的传⼊的参数类型。 7、@ResponseBody 作用: 该注解用于将Controller的方法返回的对象,通过适当的HttpMessageConverter转换为指定格 式后,写入到Response对象的body数据区。 8、@Component 相当于通用的注解,当不知道一些类归到哪个层时使用,但是不建议。 9、@Repository 用于注解dao层,在daoImpl类上面注解。 ⼆⼗⼋、springboot和spring的区别    1、Spring Boot提供极其快速和简化的操作,让 Spring 开发者快速上⼿。    2、Spring Boot提供了Spring 运⾏的默认配置。    3、Spring Boot为通⽤ Spring项⽬提供了很多⾮功能性特性,例如:嵌⼊式 Serve、Security、统 计、健康检查、外部配置等等。 ⼆⼗九、Spring Boot 的核⼼注解是哪个?它主要由哪⼏个注解组成的? 启动类上⾯的注解是@SpringBootApplication,它也是 Spring Boot 的核⼼注解,主要组合包含了 以下 3 个注解: @SpringBootConfiguration:组合了 @Configuration 注解,实现配置⽂件的功能。 @EnableAutoConfiguration:打开⾃动配置的功能,也可以关闭某个⾃动配置的选项,如关闭数据 源⾃动配置功能: @SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })。 @ComponentScan:Spring组件扫描 三⼗、如何理解 Spring Boot 中的 Starters? Starters可以理解为启动器,它包含了⼀系列可以集成到应⽤⾥⾯的依赖包,你可以⼀站式集成 Spring及其他技术,⽽不需要到处找示例代码和依赖包。 如你想使⽤Spring JPA访问数据库,只要加⼊springboot-starter-data-jpa启动器依赖就能使⽤ 了。Starters包含了许多项⽬中需要⽤到的依赖,它们能快速持续的运⾏,都是⼀系列得到⽀持的管理传递 性依赖。Starters命名:Spring Boot官⽅的启动器都是以spring-boot-starter-命名的,代表了⼀个特定 的应⽤类型。第三⽅的启动器不能以spring-boot开头命名,它们都被Spring Boot官⽅保留。⼀般⼀个第 三⽅的应该这样命名,像mybatis的mybatis-spring-boot-starter。 Starters分类:

    Spring Boot应⽤类启动器Spring Boot⽣产启动器 三⼗⼀、Spring Boot 需要独⽴的容器运⾏吗 可以不需要,内置了 Tomcat/ Jetty 等容器 三⼗⼆、如何理解 Spring Boot 配置加载顺序 1)properties⽂件; 2)YAML⽂件; 3)系统环境变量; 4)命令⾏参数;等

    三⼗三、Eureka和Zookeeper区别 1.Eureka取CAP的AP,注重可⽤性,Zookeeper取CAP的CP注重⼀致性。 2.Zookeeper在选举期间注册服务瘫痪,虽然服务最终会恢复,但选举期间不可⽤。 3.eureka的⾃我保护机制,会导致⼀个结果就是不会再从注册列表移除因⻓时间没收到⼼跳⽽过期的 服务。依然能接受新服务的注册和查询请求,但不会被同步到其他节点。 不会服务瘫痪。 4.Zookeeper有Leader和Follower⻆⾊,Eureka各个节点平等。 5.Zookeeper采⽤过半数存活原则,Eureka采⽤⾃我保护机制解决分区问题。 6.eureka本质是⼀个⼯程,Zookeeper只是⼀个进程。 三⼗四、eureka⾃我保护机制是什么? 当Eureka Server 节点在短时间内丢失了过多实例的连接时(⽐如⽹络故障或频繁启动关闭客户端) 节点会进⼊⾃我保护模式,保护注册信息,不再删除注册数据,故障恢复时,⾃动退出⾃我保护模式 三⼗五、spring cloud 和dubbo区别 1.服务调⽤⽅式 dubbo是RPC springcloud Rest Api 2.注册中⼼,dubbo 是zookeeper; springcloud是eureka,也可以是zookeeper 3.服务⽹关,dubbo本身没有实现,只能通过其他第三⽅技术整合,springcloud有Zuul路由⽹关,作 为路由服务器,进⾏消费者的请求分发,springcloud⽀持断路器,与git完美集成配置⽂件⽀持版本控制,事 物总线实现配置⽂件的更新与服务⾃动装配等等⼀系列的微服务架构要素。 三⼗六、什么是 Ribbon负载均衡 1.Spring Cloud Ribbon是基于Netflix Ribbon实现的⼀套客户端 负载均衡的⼯具。 2. Ribbon客户端组件提供⼀系列完善的配置项如连接超时,重试等。简单的说,就是在配置⽂件中列 出Load Balancer(简称LB)后⾯所有的机器,Ribbon会⾃动的帮助你基于某种规则(如简单轮询,随机 连接等)去连接这些机器。我们也很容易使⽤Ribbon实现⾃定义的负载均衡算法。 三⼗七、说说 RPC 的实现原理 ⾸先需要有处理⽹络连接通讯的模块,负责连接建⽴、管理和消息的传输。其次需要有编解码的模 块,因为⽹络通讯都是传输的字节码,需要将我们使⽤的对象序列化和反序列化。剩下的就是客户端和服务 器端的部分,服务器端暴露要开放的服务接⼝,客户调⽤服务接⼝的⼀个代理实现,这个代理实现负责收集 数据、编码并传输给服务器然后等待结果返回 三⼗⼋、sevlet⽣命周期    1.加载和实例化    2.初始化    3.请求处理    4.服务终⽌ 三⼗九、Servlet和Jsp的关系 JSP是Servlet技术的扩展,本质上是Servlet的简易⽅式,更强调应⽤的外表表达。 JSP编译后是"类servlet"。 Servlet和JSP最主要的不同点在于,Servlet的应⽤逻辑是在Java⽂件中,并且完全从表示层中的 HTML⾥分离开来。 ⽽JSP的情况是Java和HTML可以组合成⼀个扩展名为.jsp的⽂件。 JSP侧重于视图,Servlet主要⽤于控制逻辑。

    四⼗、Spring⽀持的⼏种bean的作⽤域 Spring框架⽀持以下五种bean的作⽤域: (1)singleton:默认,每个容器中只有⼀个bean的实例,单例的模式由 BeanFactory⾃身来维护。 (2)prototype:为每⼀个bean请求提供⼀个实例。 (3)request:为每⼀个⽹络请求创建⼀个实例,在请求完成以后,bean会失效并 被垃圾回收器回收。 (4)session:与request范围类似,确保每个session中有⼀个bean的实例,在 session过期后,bean会随之失效。 (5)global-session:全局作⽤域,global-session和Portlet应⽤相关。当你的 应⽤部署在Portlet容器中⼯作时,它包含很多portlet。如果你想要声明让所有的 portlet共⽤全局的存储变量的话,那么这全局变量需要存储在global-session中。 全局作⽤域与Servlet中的session作⽤域效果相同。 四⼗⼀、BIO、NIO、AIO的区别 ⼀、同步阻塞I/O(BIO): 同步阻塞I/O,服务器实现模式为⼀个连接⼀个线程,即客户端有连接请求时服务器就需要启动⼀个线 程进⾏处理,如果这个连接不做任何事情会造成不必要的线程开销,可以通过线程池机制来改善。BIO ⽅式适⽤于连接数⽬⽐较⼩且固定的架构,这种⽅式对服务端资源要求⽐较⾼,并发局限于应⽤中,在 jdk1.4以前是唯⼀的io现在,但程序直观简单易理解 ⼆、同步⾮阻塞I/O(NIO): 同步⾮阻塞I/O,服务器实现模式为⼀个请求⼀个线程,即客户端发送的连接请求都会注册到多路复⽤ 器上,多路复⽤器轮询到连接有IO请求时才启动⼀个线程进⾏处理。NIO⽅式适⽤于连接数⽬多且连接 ⽐较短(轻操作)的架构,⽐如聊天服务器,并发局限于应⽤中,编程⽐较复杂,jdk1,4开始⽀持 三、异步⾮阻塞I/O(AIO): 异步⾮阻塞I/O,服务器实现模式为⼀个有效请求⼀个线程,客户端的IO请求都是由操作系统先完成了 再通知服务器⽤其启动线程进⾏处理。AIO⽅式适⽤于连接数⽬多且连接⽐较⻓(重操作)的架构,⽐ 如相册服务器,充分调⽤OS参与并发操作,编程⽐较复杂,jdk1.7开始⽀持。 四、IO与NIO区别: IO⾯向流,NIO⾯向缓冲区 IO的各种流是阻塞的,NIO是⾮阻塞模式 Java NIO的选择允许⼀个单独的线程来监视多个输⼊通道,可以注册多个通道使⽤⼀个选择器,然后 使⽤⼀个单独的线程来“选择”通道:这些通道⾥已经有可以处理的输⼊或选择已准备写⼊的通道。这种 选择机制,使得⼀个单独的线程很容易来管理多个通道 五、同步与异步的区别: 同步:发送⼀个请求,等待返回,再发送下⼀个请求,同步可以避免出现死锁,脏读的发⽣ 异步:发送⼀个请求,不等待返回,随时可以再发送下⼀个请求,可以提⾼效率,保证并发 同步异步关注点在于消息通信机制, 阻塞与⾮阻塞关注的是程序在等待调⽤结果时(消息、返回值)的状态: 阻塞调⽤是指调⽤结果返回之前,当前线程会被挂起。调⽤线程只有在得到结果之后才会返回。 ⾮阻塞调⽤指在不能⽴刻得到结果之前,该调⽤不会阻塞当前线程 不同层次: CPU层次:操作系统进⾏IO或任务调度层次,现代操作系统通常使⽤异步⾮阻塞⽅式进⾏IO(有少部分 IO可能会使⽤同步⾮阻塞),即发出IO请求后,并不等待IO操作完成,⽽是继续执⾏接下来的指令(⾮ 阻塞),IO操作和CPU指令互不⼲扰(异步),最后通过中断的⽅式通知IO操作的完成结果。 线程层次:操作系统调度单元的层次,操作系统为了减轻程序员的思考负担,将底层的异步⾮阻塞的IO ⽅式进⾏封装,把相关系统调⽤(如read和write)以同步的⽅式展现出来,然⽽同步阻塞IO会使线程 挂起,同步⾮阻塞IO会消耗CPU资源在轮询上,3个解决⽅法;

    多线程(同步阻塞) IO多路复⽤(select、poll、epoll) 直接暴露出异步的IO接⼝,kernel-aio和IOCP(异步⾮阻塞) Linux IO模型: 阻塞/⾮阻塞:等待I/O完成的⽅式,阻塞要求⽤户程序停⽌执⾏,直到IO完成,⽽⾮阻塞在IO完成之前 还可以继续执⾏ 同步/异步:获知IO完成的⽅式,同步需要时刻关⼼IO是否完成,异步⽆需主动关⼼,在IO完成时它会 收到通知 四⼗⼆ 、HashMap和Hashtable的区别 相同点: 实现原理相同,功能相同,底层都是哈希表结构,查询速度快,在很多情况下可以互⽤。 不同点: 1、Hasht able是早期提供的接⼝,HashMap是新版JDK提供的接⼝。 2、Hasht able继承Dictionary类,HashMap实现Map接⼝。 3、Hasht able线程安全,HashMap线程⾮安全。 4、Hasht able不允许null值,HashMap允许null值。 四十三、创建线程的方式 1、继承T hread类型重写run⽅法; 2、实现Runnable接⼝; 3、实现Callable接⼝; 四⼗四、线程和进程的区别 根本区别: 进程是操作系统资源分配的基本单位,⽽线程是任务调度和执⾏的基本单位 在开销⽅⾯: 每个进程都有独⽴的代码和数据空间(程序上下⽂),程序之间的切换会有较⼤的开 销;线程可以看做轻量级的进程,同⼀类线程共享代码和数据空间,每个线程都有⾃⼰独⽴的运⾏栈和 程序计数器(PC),线程之间切换的开销⼩。 所处环境: 在操作系统中能同时运⾏多个进程(程序);⽽在同⼀个进程(程序)中有多个线程同时 执⾏(通过CPU调度,在每个时间⽚中只有⼀个线程执⾏) 内存分配⽅⾯: 系统在运⾏的时候会为每个进程分配不同的内存空间;⽽对线程⽽⾔,除了CPU外, 系统不会为线程分配内存(线程所使⽤的资源来⾃其所属进程的资源),线程组之间只能共享资源。 包含关系:只有⼀个 线程的进程可以看做是单线程的,如果⼀个进程内有多个线程,则执⾏过程不是 ⼀条线的,⽽是多条线(线程)共同完成的;线程是进程的⼀部分,所以线程也被称为轻权进程或者轻 量级进程。 四⼗五、如何防⽌sql注⼊ 1:遵循编程规范,首先执行预编译,随后再填写参数,这样参数会替换掉编译好的语句中的?占位 符,最后执行完整的sql语句。 2:使用存储过程。 存储过程(Stored Procedure)是一组完成特定功能的SQL语句集,经编译后存储在数据库中, 用户通过调用存储过程并给定参数(如果该存储过程带有参数)就可以执行它,也可以避免SQL注入攻 击 3:mybatis半自动持久化框架,其底层原理也是预编译,参数替换占位符?。 四⼗六、get和post请求的区别 1.get是不安全的,因为在传输过程中,数据被放在请求的URL中;post的所有操作对用户来说都是不 可见的。 2.get传送的数据量较小,这主要是因为受URL长度的限制;post传送的数据量较大,一般被默认为不受 限制。 3.get限制from表单的数据集的值必须为ASCLL字符;而post支持整个ISO10646字符集。 4.get执行效率却比post方法好。get是from提交的默认方法。

    四⼗七、spring主要的模块 1.Spring AOP ⾯向切⾯编程 2.Spring ORM Hibernate|mybatis|JDO 3.Spring Core 提供bean⼯⼚IOC 4.Spring Dao JDBC⽀持 5.Spring Context 提供了关于UI⽀持,邮件⽀持等 6.Srpring Web 提供了web的⼀些⼯具类的⽀持 7.Spring MVC 提供了web mvc,webviews,jsp,pdf,export 四⼗⼋、springboot 的配置⽂件和区别 Spring Boot 的核⼼配置⽂件是 application 和 bootstrap 配置⽂件。 application 配置⽂件这个容易理解,主要⽤于 Spring Boot 项⽬的⾃动化配置。 bootstrap 配置⽂件有以下⼏个应⽤场景。 使⽤ Spring Cloud Config 配置中⼼时, 这时需要在 bootstrap 配置⽂件中添加连接到配置中⼼的配置属性来加载外部配置中⼼的配置信息; ⼀些固定的不能被覆盖的属性; ⼀些加密/解密的场景; 四⼗九、springboot实现热部署的⽅法 模板引擎 在SpringBoot开发情况下禁⽤模板引擎的cache,⻚⾯模板改变后使⽤Ctrl+F9快捷键可以重新编译当 前⻚⾯并⽣效。 Spring Loaded Spring官⽅提供的热部署程序,实现修改类⽂件的热部署。 JRebel JRebel是一个收费的热部署软件,只需安装插件使用即可。 SpringBoot Devtools(推荐) 引入依赖。 五⼗、maven常⻅命令 maven 命令的格式为 mvn [plugin-name]:[goal-name],可以接受的参数如下, -D 指定参数,如 -Dmaven.test.skip=true 跳过单元测试; -P 指定 Profile 配置,可以用于区分环境; -e 显示maven运行出错的信息; -o 离线执行命令,即不去远程仓库更新包; -X 显示maven允许的debug信息; -U 强制去远程更新snapshot的插件或依赖,默认每天只更新一次。 常用maven命令 创建maven项目:mvn archetype:create 指定 group: -DgroupId=packageName 指定 artifact:-DartifactId=projectName 创建web项目:-DarchetypeArtifactId=maven-archetype-webapp 创建maven项目:mvn archetype:generate 验证项目是否正确:mvn validatemaven 打包:mvn package 只打jar包:mvn jar:jar 生成源码jar包:mvn source:jar 产生应用需要的任何额外的源代码:mvn generate-sources

    编译源代码: mvn compile 编译测试代码:mvn test-compile 运行测试:mvn test 运行检查:mvn verify 清理maven项目:mvn clean 生成eclipse项目:mvn eclipse:eclipse 清理eclipse配置:mvn eclipse:clean 生成idea项目:mvn idea:idea 安装项目到本地仓库:mvn install 发布项目到远程仓库:mvn:deploy 在集成测试可以运行的环境中处理和发布包:mvn integration-test 显示maven依赖树:mvn dependency:tree 显示maven依赖列表:mvn dependency:list 下载依赖包的源码:mvn dependency:sources 安装本地jar到本地仓库:mvn install:install-file -DgroupId=packageName - DartifactId=projectName -Dversion=version -Dpackaging=jar -Dfile=path 五十一、git命令 下⾯是我整理的常⽤ Git 命令清单。⼏个专⽤名词的译名如下。 Workspace:⼯作区 Index / Stage:暂存区 Repository:仓库区(或本地仓库) Remote:远程仓库 ⼀、新建代码库

    在当前⽬录新建⼀个Git代码库

    $ git init

    新建⼀个⽬录,将其初始化为Git代码库

    $ git init [project-name]

    下载⼀个项⽬和它的整个代码历史

    $ git clone [url] ⼆、配置 Git的设置⽂件为.gitconfig,它可以在⽤户主⽬录下(全局配置),也可以在项⽬⽬录下(项⽬配 置)。

    显示当前的Git配置

    $ git config --list

    编辑Git配置⽂件

    $ git config -e [–global]

    设置提交代码时的⽤户信息

    $ git config [–global] user.name “[name]” $ git config [–global] user.email “[email address]” 三、增加/删除⽂件

    添加指定⽂件到暂存区

    $ git add [file1] [file2] …

    添加指定⽬录到暂存区,包括⼦⽬录

    $ git add [dir]

    添加当前⽬录的所有⽂件到暂存区

    $ git add .

    添加每个变化前,都会要求确认

    对于同⼀个⽂件的多处变化,可以实现分次提交

    $ git add -p

    删除⼯作区⽂件,并且将这次删除放⼊暂存区

    $ git rm [file1] [file2] …

    停⽌追踪指定⽂件,但该⽂件会保留在⼯作区

    $ git rm --cached [file]

    改名⽂件,并且将这个改名放⼊暂存区

    $ git mv [file-original] [file-renamed] 四、代码提交

    提交暂存区到仓库区

    $ git commit -m [message]

    提交暂存区的指定⽂件到仓库区

    $ git commit [file1] [file2] … -m [message]

    提交⼯作区⾃上次commit之后的变化,直接到仓库区

    $ git commit -a

    提交时显示所有diff信息

    $ git commit -v

    使⽤⼀次新的commit,替代上⼀次提交

    如果代码没有任何新变化,则⽤来改写上⼀次commit的提交信息

    $ git commit --amend -m [message]

    重做上⼀次commit,并包括指定⽂件的新变化

    $ git commit --amend [file1] [file2] … 五、分⽀

    列出所有本地分⽀

    $ git branch

    列出所有远程分⽀

    $ git branch -r

    列出所有本地分⽀和远程分⽀

    $ git branch -a

    新建⼀个分⽀,但依然停留在当前分⽀

    $ git branch [branch-name]

    新建⼀个分⽀,并切换到该分⽀

    $ git checkout -b [branch]

    新建⼀个分⽀,指向指定commit

    $ git branch [branch] [commit]

    新建⼀个分⽀,与指定的远程分⽀建⽴追踪关系

    $ git branch --track [branch] [remote-branch]

    切换到指定分⽀,并更新⼯作区

    $ git checkout [branch-name]

    切换到上⼀个分⽀

    $ git checkout -

    建⽴追踪关系,在现有分⽀与指定的远程分⽀之间

    $ git branch --set-upstream [branch] [remote-branch]

    合并指定分⽀到当前分⽀

    $ git merge [branch]

    选择⼀个commit,合并进当前分⽀

    $ git cherry-pick [commit]

    删除分⽀

    $ git branch -d [branch-name]

    删除远程分⽀

    $ git push origin --delete [branch-name] $ git branch -dr [remote/branch] 六、标签

    列出所有tag

    $ git tag

    新建⼀个tag在当前commit

    $ git tag [tag]

    新建⼀个tag在指定commit

    $ git tag [tag] [commit]

    删除本地tag

    $ git tag -d [tag]

    删除远程tag

    $ git push origin :refs/tags/[tagName]

    查看tag信息

    $ git show [tag]

    提交指定tag

    $ git push [remote] [tag]

    提交所有tag

    $ git push [remote] --tags

    新建⼀个分⽀,指向某个tag

    $ git checkout -b [branch] [tag] 七、查看信息

    显示有变更的⽂件

    $ git status

    显示当前分⽀的版本历史

    $ git log

    显示commit历史,以及每次commit发⽣变更的⽂件

    $ git log --stat

    搜索提交历史,根据关键词

    $ git log -S [keyword]

    显示某个commit之后的所有变动,每个commit占据⼀⾏

    $ git log [tag] HEAD --pretty=format:%s

    显示某个commit之后的所有变动,其"提交说明"必须符合搜索条件

    $ git log [tag] HEAD --grep feature

    显示某个⽂件的版本历史,包括⽂件改名

    $ git log --follow [file] $ git whatchanged [file]

    显示指定⽂件相关的每⼀次diff

    $ git log -p [file]

    显示过去5次提交

    $ git log -5 --pretty --oneline

    显示所有提交过的⽤户,按提交次数排序

    $ git shortlog -sn

    显示指定⽂件是什么⼈在什么时间修改过

    $ git blame [file]

    显示暂存区和⼯作区的差异

    $ git diff

    显示暂存区和上⼀个commit的差异

    $ git diff --cached [file]

    显示⼯作区与当前分⽀最新commit之间的差异

    $ git diff HEAD

    显示两次提交之间的差异

    $ git diff [first-branch]…[second-branch]

    显示今天你写了多少⾏代码

    $ git diff --shortstat “@{0 day ago}”

    显示某次提交的元数据和内容变化

    $ git show [commit]

    显示某次提交发⽣变化的⽂件

    $ git show --name-only [commit]

    显示某次提交时,某个⽂件的内容

    $ git show [commit]:[filename]

    显示当前分⽀的最近⼏次提交

    $ git reflog ⼋、远程同步

    下载远程仓库的所有变动

    $ git fetch [remote]

    显示所有远程仓库

    $ git remote -v

    显示某个远程仓库的信息

    $ git remote show [remote]

    增加⼀个新的远程仓库,并命名

    $ git remote add [shortname] [url]

    取回远程仓库的变化,并与本地分⽀合并

    $ git pull [remote] [branch]

    上传本地指定分⽀到远程仓库

    $ git push [remote] [branch]

    强⾏推送当前分⽀到远程仓库,即使有冲突

    $ git push [remote] --force

    推送所有分⽀到远程仓库

    $ git push [remote] --all 九、撤销

    恢复暂存区的指定⽂件到⼯作区

    $ git checkout [file]

    恢复某个commit的指定⽂件到暂存区和⼯作区

    $ git checkout [commit] [file]

    恢复暂存区的所有⽂件到⼯作区

    $ git checkout .

    重置暂存区的指定⽂件,与上⼀次commit保持⼀致,但⼯作区不变

    $ git reset [file]

    重置暂存区与⼯作区,与上⼀次commit保持⼀致

    $ git reset --hard

    重置当前分⽀的指针为指定commit,同时重置暂存区,但⼯作区不变

    $ git reset [commit]

    重置当前分⽀的HEAD为指定commit,同时重置暂存区和⼯作区,与指定commit⼀致

    $ git reset --hard [commit]

    重置当前HEAD为指定commit,但保持暂存区和⼯作区不变

    $ git reset --keep [commit]

    新建⼀个commit,⽤来撤销指定commit

    后者的所有变化都将被前者抵消,并且应⽤到当前分⽀

    $ git revert [commit]

    暂时将未提交的变化移除,稍后再移⼊

    $ git stash $ git stash pop ⼗、其他

    ⽣成⼀个可供发布的压缩包

    $ git archive 五⼗⼆、数据库连接池原理和优点 数据库连接池的基本原理是在内部对象池中维护一定数量的数据库连接,并对外 暴露数据库连接获取和返回方法。 数据库连接池技术带来的优势: 1. 资源重用 2. 更快的系统响应速度 3. 新的资源分配手段 4. 统一的连接管理,避免数据库连接泄漏

    Processed: 0.020, SQL: 9