常见面试题

springmv执行流程

1、DispatcherServlet表示前置控制器,是整个SpringMVC的控制中心。用户发出请求,DispatcherServlet接收请求并拦截请求。

2、HandlerMapping为处理器映射。DispatcherServlet调用HandlerMapping,HandlerMapping根据请求url查找Handler。

3、返回处理器执行链,根据url查找控制器,并且将解析后的信息传递给DispatcherServlet

4、HandlerAdapter表示处理器适配器,其按照特定的规则去执行Handler。

5、执行handler找到具体的处理器

6、Controller将具体的执行信息返回给HandlerAdapter,如ModelAndView。

7、HandlerAdapter将视图逻辑名或模型传递给DispatcherServlet。

8、DispatcherServlet调用视图解析器(ViewResolver)来解析HandlerAdapter传递的逻辑视图名。

9、视图解析器将解析的逻辑视图名传给DispatcherServlet。

10、DispatcherServlet根据视图解析器解析的视图结果,调用具体的视图,进行试图渲染

11、将响应数据返回给客户端

bean生命周期

1.实例化,反射机制推断构造函数进行实例化

2.属性赋值,DI的体现,@autowired,循环依赖

3.初始化,回调beanfactoryaware,实现了aop,回调动态代理

4销毁,spring容器关闭时进行销毁

springboot启动顺序

一、加载启动类Spring Boot:应用程序的启动类必须使用

@SpringBootApplication注解标记,该注解包含了

@SpringBootConfiguration、@EnableAutoConfiguration和@ComponentScan三个注解的功能。Spring Boot通过扫描启动类所在的包和子包,自动装配配置类和Bean定义。

二、加载配置文件:Spring Boot应用程序默认从applicationproperties或application.vml文件中加载配置属性,也可以通过在启动类上使用@PropertySource注解指定其他的属性文件。

三、创建Spring容器Spring Boot使用SpringApplication类创建Spring容器,SpringApplication是Spring Boot的核心类,它提供了各种配置和管理Spring应用程序的方法。

SpringApplication会创建一个嵌入式的Tomcat或Jetty服务器,或者使用外部Tomcat或Jetty服务器。

四、加载自动配置:Spring Boot通过@EnableAutoConfiguration注解和spring-boot-autoconfigure项目提供了大量的自动配置,根据classpath中的jar包和Bean的装配情况,自动装配相应的Bean。

五、运行Spring Boot应用程序:当Spring容器准备就绪后,Spring Boot就会启动嵌入式的Web服务器并运行应用程序。如果使用的是外部Web服务器,Spring Boot就会将应用程序打包成一个可执行的jar文件,并启动外部Web服务器。

正确的答案是:#{}是预编译处理,${}是字符串替换。

(1)mybatis在处理#{}时,会将sql中的#{}替换为?号,调用PreparedStatement的set方法来赋值。

(2)mybatis在处理${}时,就是把${}替换成变量的值。

(3)使用#{}可以有效的防止SQL注入,提高系统安全性。原因在于:预编译机制。预编译完成之后,SQL的结构已经固定,即便用户输入非法参数,也不会对SQL的结构产生影响,从而避免了潜在的安全风险。

(4)预编译是提前对SQL语句进行预编译,而其后注入的参数将不会再进行SQL编译。我们知道,SQL注入是发生在编译的过程中,因为恶意注入了某些特殊字符,最后被编译成了恶意的执行操作。而预编译机制则可以很好的防止SQL注入。

1. 程序本质:代码是如何被执行的?CPU、操作系统、虚拟机各司何职?

先把Java代码编译成字节码也就是把.java类型的文件字节码生成器编译成.class类型的文件(语法,语义,抽象语法树)

我们执行的时候,会把class文件放置到Java虚拟机,

Java虚拟机使用类加载器,装载class文件

类加载完成后,JVM解释器会把字节码翻译成与机器码交给操作系统执行。当然了虚拟机本身也支持JIT动态编译器。

2. 基础语法:从CPU角度看变量、数组、类型、运算、跳转、函数等语法

大小,精度,优先级,方法

3. 引用类型:同样都是存储地址,为何Java引用比C/C++指针更安全?

java引用有类型检查(可以强转)

4. 基本类型:既然Java一切皆对象,那又为何要保留int等基本类型?

因为八种基本类型都有对应的包装类(自动拆箱和自动装箱),再有就是基本类型定义的变量创建和销毁很快,而类定义的变量还需要JVM去销毁。

6. 浮点数:计算机如何用二进制表示浮点数?为何0.1+0.1不等于0.2?

十进制转换成二进制(计算机只认识二进制)的时候,需要近似相等,所以加完了以后就不准确了

https://baijiahao.baidu.com/s?id=1680396399018883986&wfr=spider&for=pc

7. 字符:为何C/C++中char占1个字节,而Java中char占2个字节?

    C/C++用 ASCII 编码标准中,每个字符只占用一个字节,Java 采用了 16 位编码的Unicode 编码标准

8. 字符串:请解释String类用到的三大技术:压缩、常量池、不可变\

String类又称作不可变Unicode字符序列。

final修饰(工艺品)

修改只是拷贝个新的

String s = "aaaaa"会进入到常量池,new String(...)在堆上创建对象,不会入池,属于优化部分

10. 关键字:静态内部类实现的单例如何做到线程安全且可延迟加载?

单例模式:懒汉,饿汉,枚举,静态内部类,延迟加载,减少内存开销,访问成本低且线程安全

第一次new的时候会被加载,节约性能,建造者模式

11. 容器:为什么不推荐在项目中使用Vector、Stack、HashTable?

vector是线程安全的

Vector的空间扩容是一倍,内存不可复用,而ArrayList是一半 (C++ Made Easier: How Vectors Grow)

Vector分配内存是连续的存储空间

然后是stack:Stack 是 JDK 1.0 的产物。它继承自 Vector。

当初 JDK1.0 在开发时,可能为了快速的推出一些基本的数据结构操作,所以推出了一些比较粗糙的类。比如,Vector、Stack、Hashtable等。这些类中的一些方法加上了 synchronized 关键字,容易误导。

13. HashMap(上):为何HashMap中数组的大小必须是2的幂次方?

首先,HashMap的初始化的数组长度一定是2的n次的,每次扩容仍是原来的2倍的话,就不会破坏这个规律,每次扩容后,原数据都会进行数据迁移,根据二进制的计算,扩容后数据要么在原来位置,要么在【原来位置+扩容长度】,这样就不需要重新hash,效率上更高。扩容后

load factory=0.75的真正原因,在java7、8等中均有注释,负载因子太小了浪费空间并且会发生更多次数的resize,太大了哈希冲突增加会导致性能不好,所以0.75只是一个折中的选择,和泊松分布没有什么关系。原来位置还是在原脚标位+扩容长度的位置

1:当添加某个元素后,数组的总的添加元素数大于了 数组长度 * 0.75(默认,也可自己设定),数组长度扩容为两倍。(如开始创建HashMap集合后,数组长度为16,临界值为16 * 0.75 = 12,当加入元素后元素个数超过12,数组长度扩容为32,临界值变为24)

16. 迭代器:为什么使用迭代器遍历容器的同时修改容器会出错?

在用迭代器遍历容器的时候,试图去修改容器中的元素,可能会引起并发修改异常(遍历的时候,相当于一个指针从0索引开始移动,当试图修改某个数据时,系统无法去操作这个指针)

迭代器是依赖于集合而存在的,在判断成功之后,集合当中增加了新的元素,而迭代器却不知道,所以就报错了,这个就叫并发修改异常。

17. 异常(上):在项目开发中如何正确的定义、处理、打印异常?

枚举,定义异常类,

18. 异常(下):高并发下异常太多导致程序变慢的核心原因是什么?

CPU、内存、IO 设备的读写速度差异巨大,表现为 CPU 的速度 > 内存的速度 > IO 设备的速度。

20.nio类库:BIO、NIO、AIO三种Java I/O模型的实现原理和区别

BIO

Java BIO即Block I/O , 同步并阻塞的IO。

BIO就是传统的java.io包下面的代码实现。

NIO

什么是NIO? NIO 与原来的 I/O 有同样的作用和目的, 他们之间最重要的区别是数据打包和传输的方式。原来的 I/O 以流的方式处理数据,而 NIO 以块的方式处理数据。

面向流 的 I/O 系统一次一个字节地处理数据。一个输入流产生一个字节的数据,一个输出流消费一个字节的数据。为流式数据创建过滤器非常容易。链接几个过滤器,以便每个过滤器只负责单个复杂处理机制的一部分,这样也是相对简单的。不利的一面是,面向流的 I/O 通常相当慢。

一个 面向块 的 I/O 系统以块的形式处理数据。每一个操作都在一步中产生或者消费一个数据块。按块处理数据比按(流式的)字节处理数据要快得多。但是面向块的 I/O 缺少一些面向流的 I/O 所具有的优雅性和简单性。

AIO

Java AIO即Async非阻塞,是异步非阻塞的IO。

21. 高速I/O(上):普通的I/O读写流程都存在哪些性能问题?

多次内存复制   阻塞

Java NIO 提供了与标准 IO 不同的 IO 工作方式:

Channels and Buffers(通道和缓冲区):标准的 IO 基于字节流和字符流进行操作,而 NIO 是基于通道(Channel)和缓冲区(Buffer)进行操作,数据总是从通道读取到缓冲区中,或者从缓冲区写入到通道中。

非阻塞模式:Java NIO 是非阻塞的,每一次数据读写调用都会立即返回,并将目前可读(或可写)的内容写入缓冲区或者从缓冲区中输出,即使当前没有可用数据,调用仍然会立即返回并且不对缓冲区做任何操作。

Selectors(选择器):Java NIO 引入了选择器的概念,选择器用于监听多个通道的事件(比如:连接打开,数据到达)。因此,单个的线程可以监听多个数据通道。

23. 泛型:为什么C++泛型支持int等基本类型而Java泛型不支持呢?

基本数据类型不是对象

24. 反射:为什么通过反射创建对象要比使用new创建对象慢?

首先new 这是一个指令 系统接到这人命令,立马就是申请内存空间(堆空间,接下来就是调用无参构造,来初始化等一系列操作,因为你new明确的指定了是哪个类需要创建,而反射不同,他的先去你在某个包下类,找到了之后还要做解析,看看类里有什么东西,再去找构造方法,找到了还去执行这个方法,底层应该是通过一个角invoke的方法,接下来就是开辟内存空间,加载,初始化等,这能不慢嘛.

25. 注解:注解的配置方式相对于XML配置文件有什么优缺点?

Spring注解配置优点

1、使用注解配置可以减少XML配置文件,使得项目更加简洁,可读性更高,当项目变得越来越复杂时,可以更加简洁的管理项目;

2、注解配置可以减少大量XML配置文件中的重复代码,可以提高项目的可维护性,也可以提高开发效率;

3、注解配置可以更加直观的表达程序的功能,可以更加清晰的表达程序的本质;

4、注解配置可以更加方便的管理Spring容器中的Bean,可以更加灵活的进行Bean的定义;

Spring XML配置优点

1、XML配置使得项目更加简单,可读性更高,当项目变得越来越复杂时,可以更加简洁的管理项目;

2、XML配置可以减少大量注解配置中的重复代码,可以提高项目的可维护性,也可以提高开发效率;

3、XML配置可以更加直观的表达程序的功能,可以更加清晰的表达程序的本质;

4、XML配置可以更加方便的管理Spring容器中的Bean,可以更加灵活的进行Bean的定义;

26.动态代理:为什么基于JDK实现的动态代理要求原始类有接口?

因为 Java 是单继承的,因此在代理类 $Proxy0 继承了 Proxy 后,其只能通过实现目标接口的方式来实现方法的扩展,达到我们增强目标方法逻辑的目的

28. 线程概述:有了进程为什么还要有线程?线程越多执行就越快吗?

从资源上来讲:线程是一种非常"节俭"的多任务操作方式。而进程的创建

需要更多的资源。

从切换效率上来讲:运行于一个进程中的多个线程,它们之间使用相同的

地址空间,而且线程间彼此切换所需时间也远远小于进程间切换所需要的时间。

据统计,一个进程的开销大约是一个线程开销的 30 倍左右。

从通信机制上来讲:对不同进程来说,它们具有独立的数据空间,要进行

数据的传递只能通过进程间通信的方式进行,这种方式不仅费时,而且很不方便。

线程则不然,由于同一进程下的线程之间共享数据空间,所以一个线程的数据可

以直接为其他线程所用,这不仅快捷,而且方便。

50. 分段加锁:HashMap线程不安全原因及ConcurrentHashMap实现原理

1.7之前是头插法,多线程导致.next找不到了,1.8采用尾插法,多线程导致尾部丢失覆盖,实现原理是多片分区

51. 线程状态:为何synchronized和Lock这两种锁对应的线程状态不同?

52. 线程中断:如何安全地提前终止正在执行业务逻辑的线程?

volatile 关键字

使用 interrupt() + isInterrupted()来中断线程

使用 interrupt() + InterruptedException来中断线程

53. 线程池:线程池开多大最合适?为什么Redis单线程执行命令?

官方解释如下:因为Redis是基于内存的操作,CPU不是Redis的瓶颈,Redis的瓶颈最有可能是机器内存的大小或者网络带宽。既然单线程容易实现,而且CPU不会成为瓶颈,那就顺理成章地采用单线程的方案了。

上面的解释不是很好理解,我就简单说一说我自己的理解吧。我们知道,Redis将数据存放在内存当中,这也就意味着,Redis在操作数据时,不需要进行磁盘I/O。磁盘I/O是一个比较耗时的操作,所以对于需要进行磁盘I/O的程序,我们可以使用多线程,在某个线程进行I/O时,CPU切换到当前程序的其他线程执行,以此减少CPU的等待时间。而Redis直接操作内存中的数据,所以使用多线程并不能有效提升效率,相反,使用多线程反倒会因为需要进行线程的切换而降低效率。

除此之外,使用多线程的话,多个线程间进行同步,保证线程的安全,也是需要开销的。尤其是Redis的数据结构都是一些实现较为简单的集合结构,若使用多线程,将会频繁地发生线程冲突,线程的竞争频率较高,反倒会拖慢Redis的响应速度。

54.线程执行框架:如何获取一个线程所执行的代码的运行结果?

    Thread的join方法实现

    CountDownLatch

    ExecutorService.submit

    FutureTask    

    CompletableFuture

57. 类加载:双亲委派加载机制存在的意义是什么?

通过委派的方式,可以避免类的重复加载,当父加载器已经加载过某一个类时,子加载器就不会再重新加载这个类。

通过双亲委派的方式,还保证了安全性

被不同的类加载器加载的类也不一样

59. 可达性分析:虚拟机是如何判断一个对象是否可以被回收的?

引用计数法 可达性分析算法

60.spring事务的传播机制


bean创建流程

第一步:要进行bean创建,首先要有定义bean的配置,可以是注解、xml、json等配置方式

第二步:有了配置,要去读取配置(读取过程稍后细讲),并且将配置bean信息存储起来,spring使用beanDefinition进行存储

第三步:spring提供了BeanFactoryPostProcessor对beanDefinition信息做增强

第四步:当bean信息BeanDefinition处理操作完成,开始根据beanDefinition进行bean的实例化,这个过程创建了空的bean对象,只是分配了内存空间、创建了实例对象

第五步:有了实例对象开始对bean对象进行属性信息填充及依赖对象注入

第六步:对bean对象进行增强,包含Aware增强和spring提供的BeanPostProcessor增强

第七步:上述所有操作完成,即是一个完整地bean对象,此时将该bean对象缓存进ioc容器中。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,242评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,769评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,484评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,133评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,007评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,080评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,496评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,190评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,464评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,549评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,330评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,205评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,567评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,889评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,160评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,475评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,650评论 2 335

推荐阅读更多精彩内容