【面试】面试题汇总
后端
JAVA
1、集合的类型

2、集合中四种线程安全的结构
Vector : 就比ArrayList多了个同步化机制(线程安全)
Hashtable : 就比HashMap多了个线程安全
ConcurrentHashMap : 是一种高效但是线程安全的集合
Stack : 栈,也是线程安全的,继承于Vector,已过时,不建议使用
3、queue常用方法
添加元素
addFirst(E e) 在数组前面添加元素
addLast(E e) 在数组后面添加元素
offerFirst(E e) 在数组前面添加元素,并返回是否添加成功
offerLast(E e) 在数组最后添加元素,并返回是否添加成功
删除元素
removeFirst() 删除第一个元素,并返回删除元素的值,如果元素为 null,将抛出异常
pollFirst() 删除第一个元素,并返回删除元素的值,如果元素为 null,将返回 null
removeLast() 删除最后一个元素,并返回删除元素的值,如果为 null,将抛出异常
pollLast() 删除最后一个元素,并返回删除元素的值,如果为 null,将返回 null
removeFirstOccurrence(Object o) 删除第一次出现的指定元素
removeLastOccurrence(Object o) 删除最后一次出现的指定元素
获取元素
getFirst() 获取第一个元素,如果没有将抛出异常
getLast() 获取最后一个元素,如果没有将抛出异常
队列操作
add(E e) 在队列尾部添加一个元素
offer(E e) 在队列尾部添加一个元素,并返回是否成功
remove() 删除队列中第一个元素,并返回该元素的值,如果元素为 null,将抛出异常(其实底层调用的是 removeFirst())
poll() 删除队列中第一个元素,并返回该元素的值,如果元素为 null,将返回 null (其实调用的是 pollFirst())
pollLast(Obejct element) 此方法检索并删除此双端队列的最后一个元素,如果此双端队列为空,则返回 null。
element() 获取第一个元素,如果没有将抛出异常
peek() 获取第一个元素,如果返回 null
框架
Spirng
1、spring的功能
核心容器(Spring core)
核心容器提供spring框架的基本功能。 Spring以bean的方式组织和管理Java应用中的各个组件及其关系。 Spring使用BeanFactory来产生和管理Bean,它是工厂模式的实现。 BeanFactory使用控制反转(IoC)模式将应用的配置和依赖性规范与实际的应用程序代码分开。 BeanFactory使用依赖注入的方式提供给组件依赖。
Spring面向切面编程(Spring AOP)
通过配置管理特性,Spring AOP 模块直接将面向方面的编程功能集成到了 Spring框架中。 所以,可以很容易地使 Spring框架管理的任何对象支持 AOP。 Spring AOP 模块为基于 Spring 的应用程序中的对象提供了事务管理服务。 通过使用 Spring AOP,不用依赖 EJB 组件,就可以将声明性事务管理集成到应用程序中。
Spring ORM模块
Spring 与所有的主要的ORM映射框架都集成的很好,包括hibernate、JDO实现、TopLink和IBatis SQL Map等。 Spring为所有的这些框架提供了模板之类的辅助类,达成了一致的编程风格。
Spring DAO模块
DAO模式主要目的是将持久层相关问题与一般的的业务规则和工作流隔离开来。 Spring 中的DAO提供一致的方式访问数据库,不管采用何种持久化技术,Spring都提供一直的编程模型。 Spring还对不同的持久层技术提供一致的DAO方式的异常层次结构。
Spring Web模块
Web上下文模块建立在应用程序上下文模块之上,为基于Web的应用程序提供了上下文。 Web层使用Web层框架,可选的,可以是Spring自己的MVC框架, 或者提供的Web框架,如Struts、Webwork、tapestry和jsf。
Spring MVC框架(Spring WebMVC)
MVC框架是一个全功能的构建Web应用程序的MVC实现。 通过策略接口,MVC框架变成为高度可配置的。 Spring的MVC框架提供清晰的角色划分:控制器、验证器、命令对象、表单对象和模型对象、分发器、处理器映射和视图解析器。Spring支持多种视图技术
参考 回答
2、Spring框架三大核心思想是什么
DI(依赖注入)
依赖注入, 表示创建对象, 给属性赋值,点击传送门
IOC(控制反转)
Inversion of Control, 控制反转,IOC意味着将你设计好的类交给系统去控制
AOP(面向切面)
Aspected Oriented Programming , 面向切面编程
3、一个Pet接口两个实现类Dog,Cat,注入时如何使用Dog或者Cat
1 | public interface PetInterface{ |
1 | public class PetController { |
方案一:@Qualifier
+@Autowired
@Autowired
为Spring提供的注解,需要导入包
org.springframework.beans.factory.annotation.Autowired
@Autowired
可以对类成员变量、方法及构造函数进行标注,让 spring 完成 bean
自动装配的工作。 @Autowired 默认是
按照类型去匹配注入
,配合 @Qualifier 按照指定的 name
名称去装配 bean。
1 | public class PetController { |
注意:
需要注意的是: (1)如果实现类里,注解 @Service 没有指定实现类的 bean 名称,则注入的时候默认用该实现类首字母小写的bean的名字 (2)如果用注解 @Service(“dog”) 指定了实现类的 bean 名称,则用注解 @Qualifier(“dog”) 注入的时候,注意名称保持一致
方案二:@Resource
@Resource 注解由 J2EE 提供,需要导入包 javax.annotation.Resource
@Resource 与 @Autowired 差不多,但是
@Resource 默认按照 ByName 自动注入
。
@Resource(name = " ")
1 | public class PetController { |
@Resource(type = )
1 | public class PetController { |
参考回答
SpringMVC
1、spingMVC工作流程图
参考 回答
注解
1、SpringAOP的注解
Aspect (切面) : 通常是一个类,里面可以定义切入点和通知
Pointcut (切点) : 就是带有通知的连接点,在程序中主要体现为书写切入点表达式
JointPoint (连接点) : 程序执行过程中明确的点,一般是方法的调用
Advice (通知) : AOP在特定的切入点上执行的增强处理,有before,after,afterReturning,afterThrowing,around
AOP 代理:AOP框架创建的对象,代理就是目标对象的加强。Spring中的AOP代理可以使JDK动态代理,也可以是CGLIB代理,前者基于接口,后者基于子类
Before : 在目标方法被调用之前做增强处理,@Before只需要指定切入点表达式即可 AfterReturning : 在目标方法正常完成后做增强,@AfterReturning除了指定切入点表达式后,还可以指定一个返回值形参名returning,代表目标方法的返回值 AfterThrowing : 主要用来处理程序中未处理的异常,@AfterThrowing除了指定切入点表达式后,还可以指定一个throwing的返回值形参名,可以通过该形参名来访问目标方法中所抛出的异常对象 After : 在目标方法完成之后做增强,无论目标方法时候成功完成。@After可以指定一个切入点表达式 Around : 环绕通知,在目标方法完成前后做增强处理,环绕通知是最重要的通知类型,像事务,日志等都是环绕通知,注意编程中核心是一个ProceedingJoinPoint
1 |
|
参考 回答
2、@PostConstruct
@PostConstruct是Java自带的注解,在方法上加该注解会在项目启动的时候执行该方法,也可以理解为在spring容器初始化的时候执行该方法。
从Java EE5规范开始,Servlet中增加了两个影响Servlet生命周期的注解,@PostConstruct和@PreDestroy,这两个注解被用来修饰一个非静态的void()方法。
Mysql
导致索引失效的情况
查询条件不是全匹配
查询条件不按照左前缀法则
在索引列上做任何操作(计算,函数,类型转换)
存储引擎使用索引中范围条件右边的列
在使用不等于(!= 或者<>)的时候无法使用索引会导致全表扫描
is null ,is not null 也无法使用索引
like以通配符开头(%abc...) mysql索引失效会变成全表扫描的操作
字符串不加单引号索引失效
多用or,用它来连接时会索引失效
并发
1、创建线程的几种方式
1) 继承Thread,重写run方法
1 | class MyThread extends Thread { |
匿名内部类的写法
1 | public class Main { |
lambda表达式
1 | public class Main { |
2) 实现Runnable接口,重写run方法
1 | class MyRunnable implements Runnable { |
匿名内部类
1 | public class Main { |
实现Callable接口
1 | class MyCallableTest implements Callable<Integer> { |
线程池
在Java中,线程池的本体叫ThreadPoolExecutor,他的构造方法写起来十分麻烦,为了简化构造方法,标准库就提供了一系列工厂方法
newCachedThreadPool()
,简化使用;
线程池的单纯使用很简单,使用
submit方法
,把任务提交到线程池中即可,线程池中会有线程来完成这些任务;
1 | import java.util.concurrent.ExecutorService; |
前端
Vue
1、vue的生命周期的阶段与钩子函数
vue生命周期分为 四个阶段,八个钩子函数 第一阶段(创建阶段):beforeCreate,created 第二阶段(挂载阶段):beforeMount,mounted 第三阶段(更新阶段):beforeUpdate,updated 第四阶段(销毁阶段):beforeDestroy,destroyed
1)beforeCreate
在这个阶段,数据是获取不到的,并且真实dom元素也是没有渲染出来的
2)created
在这个阶段,可以访问到数据了,但是页面当中真实dom节点还是没有渲染出来,在这个钩子函数里面,可以进行相关初始化事件的绑定、发送请求操作
3)beforeMount
代表dom马上就要被渲染出来了,但是却还没有真正的渲染出来,这个钩子函数与created钩子函数用法基本一致,可以进行相关初始化事件的绑定、发送ajax操作
4)mounted
挂载阶段的最后一个钩子函数,数据挂载完毕,真实dom元素也已经渲染完成了,这个钩子函数内部可以做一些实例化相关的操作
5)beforeUpdate
这个钩子函数初始化的不会执行,当组件挂载完毕的时候,并且当数据改变的时候,才会立马执行,这个钩子函数获取dom的内容是更新之前的内容
6)updated
这个钩子函数获取dom的内容是更新之后的内容生成新的虚拟dom,新的虚拟dom与之前的虚拟dom进行比对,差异之后,就会进行真实dom渲染。在updated钩子函数里面就可以获取到因diff算法比较差异得出来的真实dom渲染了。
7)beforeDestroy
当组件销毁的时候,就会触发这个钩子函数代表销毁之前,可以做一些善后操作,可以清除一些初始化事件、定时器相关的东西。
8)destroyed
Vue实例失去活性,完全丧失功能
参考 回答
2、style标签scoped属性
scoped 属性是 style 标签上的一个特殊属性(布尔值)。表示当前style 里的样式只属于当前模块。(作用域、私有化的思想)
解决问题
关于css的作用域问题,即使是模块化编程下,在对应的模块的js中import css进来,这个css仍然是全局的。导致在css中需要加上对应模块的html的id/class 使用css选择器 保证css的作用域不会变成全局 而被其它模块的css污染。
在vue中引入了scoped这个概念,scoped的设计思想就是让当前组件的样式不会修改到其它地方的样式,使用了data-v-hash的方式来使css有了它对应模块的标识,这样写css的时候不需要加太多额外的选择器,方便很多。
参考 回答
3、watch函数
在vue框架中wathch监听函数 主要监听数值的变化 监听对象可以是一个变量也可以是一个对象 本次是监听文本框中内容的变化,监听的是一个value:’'中的值的变化
4、computed函数
1、支持缓存,只有当它所依赖的响应式数据发生改变时,才会重新进行计算
2、不支持异步,当computed内有异步操作时无效,无法监听数据的变化
3、computed 属性值会默认走缓存,计算属性是基于它们的响应式依赖进行缓存的,也就是基于data中声明过或者父组件传递的props中的数据通过计算得到的值
5、nextTick
nextTick所指定的回调会在浏览器更新DOM完毕之后再执行。
参考 回答
6、组件通信方式,父传子,子传父
父传子
父组件通过props
的方式向子组件传递数据
prop 只可以从上一级组件传递到下一级组件(父子组件),即所谓的单向数据流。而且 prop 只读,不可被修改,所有修改都会失效并警告。
1 | <!-- 父组件 --> |
1 | <!-- 子组件 child.vue --> |
子传父
而通过emit方式子组件可以向父组件通信
使用 $emit
向父组件传数据,原理这样的:
父组件在子组件通过v-on
监听函数并接收参数,vue框架就在子组件监听了你v-on="fn"
的fn事件函数,在子组件使用$emit
就能触发了,下面写个例子。
1 | <!-- 父组件 --> |
1 | <!-- 子组件 child.vue --> |
更多信息参考 回答