Java面试点 -【笔记】

1. HashMap实现原理,HashTableConcurrentHashMapTreeMap相关内容. ArrayListVectorHashSetTreeSet

 

  - HashMap 基于哈希表的实现 底层使用数组与链表实现,放入数据时首先计算keyhashCode,根据(hashCode%数组长度)将数据放入余数所对应的数组下标的链表里面(java8中引入了红黑树的概念,当链表的长度到8时,将单向链表转成红黑树,提高map的效率)HashMap的默认数组为16,扩容为2的整数次幂

   - HashTable 基于哈希表的实现,keyvalue不允许出现null hashtable中的方法是Synchronize的,所以是线程安全的,默认容量11,扩容方式(old*2+1

  - ConcurrentHashMap 基于哈希表的实现,是线程安全的,JDK1.8之前使用Segment分段锁机制,JDK1.8开始利用CAS+Synchronized来保证并发更新的安全,CAS是指compareAndSwapnative)方法

  - HashSet 是无序的集合,不允许有重复的值,底层使用hashMap实现,set的值作为keyvalue是一个共用的Object对象

  - TreeMap基于红黑树的实现,value可以是nullkey不可为null

  - TreeSet也是用TreeMap实现的

  - Vector 是线程安全的,在底层数组不够用的时候,是在原来的基础上扩展1倍 关键性的方法,都添加synchronized关键字

  - ArrayList 不是线程安全的,在底层数组不够用的时候,是在原来的基础上扩展0.5

  - Synchronized关键字,尝试获取对象的锁,如果获取成功,计数器+1 释放时,计数器-1 0时,表示当前对象锁没有被人持有 monitorentermonitorexit字节码指令是实现原理

2. String相关

  不是基本数据类型,String是不可变的,考虑到安全,性能,多线程。所以设计为不可变类。JVM使用字符串池来存储所有的字符串对象

  - String 是不可变类,每当我们对String进行操作的时候,总是会创建新的字符串。操作String很耗资源,所以有StringBufferStringBuilder两个可变类操作StringStringBuffer是线程安全的,StringBuilder则不是线程安全的。StringBuilder的效率比StringBuffer

3. JAVA8新特性

  函数式接口,指仅包含一个抽象方法的接口,@FunctionalInterface 此注解限定接口为函数式接口,每一个该类型的lambda表达式都会被匹配到这个抽象方法。,所以你也可以给你的函数式接口添加默认方法

  接口的默认方法,默认方法不算抽象方法,但是需要使用default关键字声明

  - Lambda 表达式,简化匿名对象,只能适用于函数式接口,可以把Lambda 表达式理解为是一段可以传递的代码(将代码像数据一样进行传递,符合函数式接口的定义),Lambda表达式无法访问到默认方法。

  允许使用多重注解,指同一个注解可以注解多次,在此注解声明时需要声明一个注解容器存放此注解,并声明此注解是可以重复的注解

  - stream流 ,是API中的一个新成员,它允许你以声明性方式处理数据集合

4. SpringMVC工作原理

  客户端发送请求到DispatcherServlet

  - DispatcherServlet查询handlerMapping找到处理请求的Controller

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

  - DispatcherServlet查询ModelAndView 找到指定视图

  视图将结果返回到客户端

  -SpringMVC流程

    a. 用户发送请求到控制器DispatcherServlet

    b. DispatcherServlet 收到请求调用HandlerMapping处理器映射

    c. 处理器映射器找到具体的处理器,生成处理器对象和处理器拦截器返回给DispatcherServlet

    d. DispatcherServlet调用HandlerAdapter处理器适配器

    e. HandlerAdapter经过适配调用具体的处理器Controller

    f. Controller执行完返回ModelAndView

    g. HandlerAdapter controller执行结果ModelAndView返回给DispatcherServlet

    h. DispatcherServlet ModelAndView传给ViewReslover视图解析器

    i. ViewReslover 解析后返回具体的View

    j. DispatcherServlet 根据View进行渲染视图

    k. DispatcherServlet响应用户

5. Spring相关,IoCAOP,动态代理

  - IoC 控制反转,SpringServlet管理所有的Bean创建,依赖注入方式(基于注解的注入方式,set注入方式,构造器注入方式,静态工厂注入方式),实现IOC的主要设计模式就是工厂模式

  - AOP 面向切面编程(将一些与主业务无关,却为业务模块所共同调用的逻辑封装起来统一实现,便于减少系统重复代码,降低模块之间的耦合度。一般应用与权限控制,事务管理,日志记录,参数校验,签名校验,异常处理,性能统计等),实现AOP的主要设计模式是动态代理方式(代理模式是用户通过代理对象访问目标对象,静态代理在使用时,需要定义接口或者父类,被代理对象与代理对象一起实现相同的接口或者是继承相同的父类,典型代表Aspect

  动态代理,Spring动态代理有两种,a. JDK的动态代理(JDK动态代理的两个核心接口是InvocationHandlerProxy,是利用JDKAPI,动态的在内存中构建代理对象,需要我们指定创建代理对象实现的接口的类型,代理对象不需要实现接口,但是目标对象需要实现接口),b. cglib动态代理(cglib动态代理的两个核心接口是MethodInterceptorEnhancercglib代理也叫做子类代理,是在内存中动态构建一个子类对象-构建子类,设置父类,从而实现对目标对象功能的扩展调用)https://www.cnblogs.com/qlqwjy/p/7550609.html

6. 线程状态与转换

  初始(NEW ) 创建了线程,还未启动线程(未调用线程的start()方法)

  运行(RUNNABLEJava线程中将就绪(ready)和运行中(running)两种状态笼统的称为“运行”。线程对象创建后,其他线程(比如main线程)调用了该对象的start()方法。该状态的线程位于可运行线程池中,等待被线程调度选中,获取CPU的使用权,此时处于就绪状态(ready)。就绪状态的线程在获得CPU时间片后变为运行中状态(running

  阻塞(BLOCKED) 表示线程阻塞于锁

  等待(WAITING)进入该状态的线程需要等待其他线程做出一些特定动作(通知或中断)

  超时等待(TIMED_WAITING)该状态不同于WAITING,它可以在指定的时间后自行返回

  终止(TERMINATED)表示该线程已经执行完毕

  - java线程的两种实现方式,a) 继承Thread类(继承Thread类之后就不能继承其他类了,启动线程需要new xxx.start()),b) 实现Runnable接口,此种方法可以访问同一个变量,c) 可以使用java.util.concurrent.Executors 线程池,SpringThreadPoolTaskExecutor

7. JVM相关

  堆 堆存放的对象是线程共享的,所以多线程的时候需要同步机制。主要由新生代、老年代、永久代构成,1.8中移除整个永久代,取而代之的是一个叫元空间(Metaspace)的区域

  栈 线程私有,栈描述的是Java方法执行的内存模型栈帧是用来存储数据和部分过程结果的数据结构。

  方法区 用于存储已被虚拟机加载的类信息、常量、静态变量,如static修饰的变量加载类的时候就被加载到方法区中

  本地方法栈 主要是保存native 的一些方法

  程序计数器 程序计数器是一块很小的内存空间,它是线程私有的,可以认作为当前线程的行号指示器

8. Spring Boot(基于Spring,实现组件化配置java应用)

  简化配置,自动装配,支持快速构建一个基于Spring框架的Java Application

  使用 JavaConfiguration,用Java类替代XML的配置方式

  - Spring Boot 对常用的第三方库提供了配置方案,可以很好的和Spring进行整合,一键式搭建功能完备的java企业级应用

  优势,特点:

    不需要任何XML配置文件

    内嵌tomcat,可以直接部署

    默认支持JSON数据,不需要转换

    支持RESTful

    配置文件非常简单,支持YAML格式

  - Spring Boot2.x要求必须基于Spring5.xSpring5.x Java版本需求jdk8

9.Spring Boot Starter 的工作原理

  - Spring Boot在启动时有大概以下几个步骤:

    a) Spring Boot在启动时会去依赖的starter包中寻找/resources/META-INF/spring.factories文件,然后根据文件中的配置的jar包去扫描项目依赖的jar

    b) 根据spring.factories 配置加载AutoConfigure

    c) 根据@Conditional 注解的条件,进行自动配置并将 Bean注入SpringContext

10. 分布式事务

  事务补偿机制(定时任务补偿,消息补偿)

  基于可靠消息的最终一致性(业务处理服务在业务事务提交之前, 向实时消息服务请求发送消息, 实时消息服务只记录消息数据, 而不是真正的发送。 业务处理服务在业务事务提交之后, 向实时消息服务确认发送。 只有在得到确认发送指令后, 实时消息服务才会真正发送)

  - TCC事务补偿 (一个完整的业务活动由一个主业务服务于若干的从业务服务组成。 主业务服务负责发起并完成整个业务活动。 从业务服务提供TCC型业务操作。 业务活动管理器控制业务活动的一致性, 它登记业务活动的操作, 并在业务活动提交时确认所有的TCC型操作的Confirm操作, 在业务活动取消时调用所有TCC型操作的Cancel操作 )

11. Spring Spring Boot  Spring Cloud 的关系

  - Spring 最初最核心的两大核心功能 Spring Ioc  Spring Aop 成就了 SpringSpring 在这两大核心的功能上不断的发展,才有了 Spring 事务、Spring Mvc 等一系列伟大的产品,最终成就了 Spring 帝国,到了后期 Spring 几乎可以解决企业开发中的所有问题

  - Spring Boot 是在强大的 Spring 帝国生态基础上面发展而来,发明 Spring Boot 不是为了取代 Spring ,是为了让人们更容易的使用 Spring 

  - Spring Cloud 是一系列框架的有序集合。它利用 Spring Boot 的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等,都可以用 Spring Boot 的开发风格做到一键启动和部署。

  - Spring Cloud 是为了解决微服务架构中服务治理而提供的一系列功能的开发框架,并且 Spring Cloud 是完全基于 Spring Boot 而开发,Spring Cloud 利用 Spring Boot 特性整合了开源行业中优秀的组件,整体对外提供了一套在微服务架构中服务治理的解决方案

12. Spring Boot2.x 新版本特性

  响应式编程 Spring WebFlux/WebFlux.fn 响应式web编程,可用来构建异步的,非堵塞的,事件驱动的服务 来自Spring5.x

  - HTTP/2 支持

  - Kotlin 支持

  全新的执行器架构

  支持Quartz

  - Security 大大简化类安全自动配置

  - Metrics 引入Micrometer,来统一metrics的规范

  监控方面有所增强,也主要来自Micrometer 监控服务各项指标自动监控

  数据方面

    db:默认引入HikariCP 链接池(一个高性能的JDBC连接池)

    JOOQ的支持

    Redis:默认引入了 Lettuce(使用netty NIO框架来高效的管理多个连接),替代了jedis作为底层连接redis

    MongoDBHibernate优化

  - Thymeleaf3 Spring Boot2.x支持Thymeleaf3

  - OAuth2.0支持

  组件更新

    Jetty 9.4Tomcat 8.5Flyway 5Hibernate 5.2Gradle 3.4Thymeleaf 3.0

13. java classloader

  - 四种类加载器:a) 启动类加载器,b) 扩展类加载器,c) 系统类加载器,d) 自定义类加载器

    a) 启动类加载器(根类加载器bootstrap class loader) 负责加载<JAVA_HOME>/lib路径下的核心类库或-Xbootclasspath参数指定的路径下的jar出于安全考虑,Bootstrap启动类加载器只加载包名为javajavaxsun等开头的类,启动类加载器无法被java程序直接引用

    b) 扩展类加载器(extensions class loader)负责加载<JAVA_HOME>/lib/ext目录下或者由系统变量-Djava.ext.dir指定位路径中的类库,开发者可以直接使用扩展类加载器

    c) 系统类加载器(应用类加载器 system class loader)在jvm启动时负责加载来自JAVA命令-classpathjava.class.path系统属性(也就是classpath路径)下的类库

    d) 自定义类加载器(继承系统类加载器,实现用户自定义加载逻辑)重写findClass方法,通常web服务器都有自定义类加载器,如TomcatCommonClassLoaderCatalinaClassLoaderSharedClassLoaderWebappClassloader)没有遵守双亲委派机制,Spring类加载器(OverridingClassLoader默认先自己加载excludedPackagesexcludedClasses,只有加载不到才会委托给双亲加载,DecoratingClassLoader内部维护了两个集合,如果你不想你的类被自定义的加载器管理,可以添加到这两个集合中)

  - 类加载机制:全盘负责机制,双亲委派机制,缓存机制

    全盘负责机制:是指一个类加载器负责加载某个Class时,该Class所依赖和引用其他Class也将由该类加载器负责载入

    双亲委派机制:是指当加载某个Class时,先交由父类加载器视图加载该Class,只有父类加载器无法加载该类时,才尝试从自己的类路径中加载该类,此模式可以避免类的重复加载,也考虑了安全因素,保证java核心类不会被随意替换

    缓存机制: 缓存机制将保证所有加载过的Class都会被缓存,当程序中需要某个Class时,类加载器先从缓存区中搜寻该Class,只有当缓存区中不存在该Class对象时,系统使用类加载器加载该类

14. mysql相关

  - 存储引擎 MyISAM  InnodbBerkeleyDBMemoryMergeArchiveCSVMaxDB等十几个

    MyISAM是非事务的存储引擎,适用于频繁查询的应用,表锁,不会出现死锁现象

    Innodb 是支持事务,外键的存储引擎,行锁,适用于插入和更新操作比较多的应用。适合大数据,大并发

  - SQL优化

    选择合适的存储引擎

    添加合适的索引,联合索引(索引的底层实现是基于B+树实现的,Innodb建议大部分表使用默认自增的主键作为主索引)

    避免使用大字段,如textlongtext,尤其不能用做查询条件

    避免使用全表扫描,避免使用在where中使用!=null条件判断(会放弃使用索引而进行全表扫描),避免在where条件中使用 or,避免使用like%xxx%,避免使用innot in exists替代,避免使用子查询(使用join),避免在where条件中使用函数(会使索引失效),避免使用select *查询所有字段,避免使用临时表(使用 union),避免使用游标,避免多表关联(3张以上的表考虑拆分业务,表关联时,小数据表在前)

  - 数据库三范式

    第一范式:属性的原子性约束,要求属性具有原子性,不可再分解;

    第二范式:记录的 唯一性约束,要求记录有唯一性标识,即实体的唯一性;

    第三范式:字段冗余性的约束,任何字段不能有其他字段派生出来,要求字段没有冗余;

 

<wiz_tmp_tag id="wiz-table-range-border" contenteditable="false" style="display: none;">

原文地址:https://www.cnblogs.com/shizi1987/p/12968767.html