1)List与Set的区别:
a) List有序【有索引】、Set无序【没有索引、TreeSet底层使用二叉树结构实现,所以有序】
b) List允许数据重复、Set不允许重复
c) 实际开发中可以使用Set集合来去除重复数据
2)列举你熟悉的几种数据结构?
a) 数组结构
b) 链表结构【单向链表、双向链表】
c) 键值对
d) 二叉树
e) 矩阵
3)HashMap与HashTable的区别
a) HashMap允许null键和nul值,HashTable不允许null键也不允许null值
b) HashMap线程不安全,HashTable线程安全
c) HashMap与HashTable都是无序的,但是TreeMap是有序的
d) 项目中通常情况下要使用properties,Properties是HashTable的子类,但是要求键和值都必须是字符串【一般用来配置一些项目中的初始化数据,例如jdbc、连接池等】
4)Java访问数据库有哪些技术?
a) JDBC
b) 自己封装JDBC的工具类
c) Commons-Dbutils+dbcp【QueryRunner】
d) SpringJDBC【JdbcTemplate】
e) JPA【配置文件、domain实体类+注解、EntityManager】
f) SpringDataJpa【是Spring对JPA的封装,用起来更简单快捷,很可能还要使用文浩对SpringDataJpa的扩展】
g) Hibernate框架
h) Mybatis
5)谈一谈你对Spring框架的感受?
a) Spring代表春天的意思,其实就是程序员的春天
b) Spring有两大核心特点:控制反转(创建对象的权力交给Spring)/依赖注入(创建对象之后,对象的某些属性需要初始化,使用set方法或者构造方法对这些属性进行初始化)、AOP(面向切面编程,在方法执行前后添加其他业务逻辑、底层使用动态代理技术实现,可以用来做例如:权限验证、事务管理、日志记录等功能)
c) Spring是一个容器型框架,内部有很多子框架,分别实现了很多不同功能,而且相互之间可以无缝集成【spring-jdbc,springMVC,SpringDataJPA】
d) Spring可以和目前市面上其他几乎所有框架集成到一起,通常情况下使用FactoryBean方式进行配置
e) 我在项目中使用Spring,哪里需要对象的时候,直接使用@Autowired自动注入就可以了,非常方便。
6)你刚才提到了SpringMVC,怎么用?底层有什么原理?
a) SpringMVC是对Servlet/JSP技术的封装,原来的Servlet用来做项目的时候使用不是太方便【一个Servlet只能处理一种请求】
b) 使用SpringMVC首先要配置中央控制器【DispatcherServlet】(还要加上初始化参数指定SpringMVC的配置文件路径),然后SpringMVC的配置文件中添加配置,通过请求访问路径进行匹配(/xxx/yyy:/xxx匹配Controller类,/yyy匹配类中的方法)
c) /xxx/yyy: 请求首先来到中央控制器中,通过HandlerMapping(处理器映射器)找到相应的处理器(Controller类),然后再使用处理器适配器(HandlerAdapter)处理请求参数的封装以及类型自动转化,通过反射方式执行该控制器类中的该方法,方法执行完毕后一般情况下要求返回一个字符串,再经过视图解析器(ViewResolver)进行解析,最后再默认利用请求转发方式跳转页面。
7)刚才提到了Spring的AOP,请你说一说Spring的AOP?
a) 面向切面编程(Aspect Oriented Programming)
b) AOP本身是由AOP联盟推出的一套接口规范,Spring的AOP实现了AOP联盟规范中的一部分
c) 基于动态代理技术实现:原本有一个接口一个实现类,使用JDK动态代理或者CGLIB动态代理技术生成一个代理类,代理类和被代理类型要求必须实现相同接口,代理类中持有一个被代理类的对象作为属性,在重写接口的方法中调用被代理对象的相应方法,并且在调用之前或者之后添加其他业务逻辑。最后将这个代理对象返回。
d) 好处:降低耦合度(方法调用者与被代理对象之间的耦合度)
e) 可以用来实现事务管理、日志管理、权限验证等等功能,感觉在调用方法的时候不知不觉间就插入了其他业务逻辑。
f) Spring的AOP支持配置文件方式和注解方式实现AOP
g) Spring中对事务管理业务增强类还写了很多实现类,只需要把它配置成bean就可以直接使用了。
8)请你解释一下Spring的控制反转(IOC)和依赖注入(DI)?
a) 控制反转(IOC):将创建对象的权力交给Spring来管理,可以通过配置bean标签或者扫描包(@Controller、@Service、@Repository、@Component)的方式,默认使用类名称(首字母小写)作为键,创建的对象作为值存入Spring容器中,而且默认是单例模式,也可以自己指定一个名称作为键
如果是bean标签,可以使用id或者name属性指定
如果是注解方式,可以在注解后面加上字符串指定
b) 依赖注入(DI):创建对象之后要给对象的某些属性进行赋值,利用set方法或者构造方法给对象属性赋值。因为在项目中经常要在一个对象中持有另一个对象作为属性【这种关系称为关联关系】,但是关联关系耦合度太高,为了降低耦合度,利用set方法或者构造方法的参数【从Spring容器中获取,获取到的对象还有可能是代理对象】传入,将关联关系变为依赖关系。
9)请你说一下Spring的bean标签有哪些配置方式?
a) 最简单的bean标签
b) 实例工厂:配置一个工厂bean,再配置一个目标bean,使用factory-bean属性引用工厂bean的id,使用factory-method指定工厂bean对象中的方法名称,这个方法必须返回一个目标bean对象。
c) 静态工厂:配置工厂bean,但是要加上factory-method指定工厂bean对象中的方法名称,这个方法必须返回一个目标bean对象。
d) FactoryBean:其实就是实例工厂方式,专门用来与其他框架集成【变相的实例工厂,但是工厂方法名称是固定的,必须叫getObject】
10)你的进销存系统中使用的哪些框架?说一说SpringDataJpa
a) SpringDataJpa是Spring对JPA的实现封装,用起来更方便,现在目前市面上还是有20%左右的公司在使用SpringDataJpa
b) 核心接口是Respotory、JpaRepository、JpaSpecificationExecutor
c) SpringDataJpa好处是DAO层只需要写接口继承JpaRepository、JpaSpecificationExecutor接口,不需要我们自己写实现类
d) 还不够方便,往往我们都要使用文浩的扩展【只是封装了获取Specification对象的方法】,然后自己再扩展。
11)项目前端用的什么框架?Easyui与后端怎么交互数据?
a) 前端使用的是easyui框架:easyui框架非常适合用来做管理系统的后台系统,方便实用,基于js、jQuery、css实现,方便理解和学习,easyui内部集成了很多插件,包括我们使用的tree、datagrid、tabs、form、validatebox、combobox、window、dialog、messager。。。。。这些插件都有一个共同点,创建的时候通常情况下都需要传入一个json对象作为参数。
b) 发送数据到后台:通常情况下都是利用jQuery的ajax,传递json格式请求参数
c) 后台方法中往往也是返回JSON格式的数据:@ResponseBody(SpringMVC就不再使用视图解析器进行页面跳转,而是利用jackson工具将方法返回值转化为JSON格式的字符串进行响应)
12)SpringMVC如何接收请求参数?
a) 传统方式:req.getParameter()
b) 直接在方法形参列表中写形参变量:形参变量名称与请求参数名称一致
c) 直接在方法形参列表中写形参变量+@ReqquestParam:形参变量名称与请求参数名称不一致
d) 直接使用domain实体类对象接收:实体类对象的属性名称与请求参数名称一致,而且属性必须有set方法、domain实体类必须有无参构造
e) 使用RESTFUL风格:@PathVariable(“aa”) aa字符串仍然要与方法映射中的变量名称一致
f) 请求参数传递过来都是字符串类型,SpringMVC会自动进行类型转化,若转化失败会报400错误
13)SpringMVC如何传递数据给页面前端?
a) 传统方式:三大作用域.setAttribute,在转发到页面,在页面中就可以取出数据,但是这种只支持同步请求
b) Model
c) ModelMap
d) ModelAndView:这三个其实就是将数据保存到请求作用域中,转发之后能获取数据,也只支持同步请求
e) @ResponseBody注解将返回的值【对象、数组、集合、Map集合】自动转化为JSON格式字符串,再利用响应对象中的输出流,这种方式是今后用得最多的,支持异步请求
14)有没有自己研发过类似SpringMVC的小框架?说一下思路
a) 服务器启动时候【listener配置】
- 加载配置文件、扫描包(读取bean的配置信息)
- 获取到完全限定名
- 利用反射创建对象
- 以注解值为键,以创建的对象为值,保存到Map集合中
- 将这个Map集合保存到ServletContext作用域中
b) 请求访问的时候【所有请求都来到一个中央控制器中,再进行统一分发】
- 解析到请求地址中的uri
- 解析Map集合中所有保存的对象的注解,来进行匹配,如果没匹配到就抛出异常
- 再解析类中的所有方法的注解,再与uri进行匹配,如果又没匹配到就抛出异常
- 找到相应的对象,以及方法,再通过反射去执行该对象的该方法,并且将请求和响应对象传过去。
15)说几个项目开发中你遇到的印象比较深刻的问题,你是怎么解决的?
a) 列举具有代表性的问题,但是千万不要说技术性问题
b) N to n错误:断开关联关系,设置为null
c) Datagrid上展示数据,数据中某个属性是懒加载对象的时候,会出现no session:web.xml中添加一个过滤器
d) No Serializer:懒加载对象原理(JPA会自动创建一个类继承懒加载对象的类,并且重写属性的get方法,目的是为了在get方法被调用的时候发送SQL去加载数据,会额外添加几个属性)
@JsonIgnoreProperties(value={"hibernateLazyInitializer","handler","fieldHandler"})
e) Easyui中经常容易把id选择器写错:在浏览器中按F12查看js报错信息
f) 请求参数传递错误:也可以按F12,去查看请求的参数以及响应消息
16)SpringDataJpa如何自定义扩展?说一下思路
a) 经过查看SpringDataJpa接口的继承体系,发现SpringDataJpa默认使用SimpleJpaRepository来创建子类对象,并且生成代理对象,最后返回出来
b) 我们可以给我们所有的业务Repository抽取一个公共父接口(BaseRepository+@NoRepositoryBean注解),扩展的方法写在这个父接口中
c) 然后写一个父接口的实现类,继承SimpleJpaRepository,并且实现自定义的父接口中扩展的方法
d) 然后将所有业务Repository继承我们自定义的父接口(BaseRepository)
e) 因为SpringDataJpa默认使用SimpleJpaRepository来创建子类对象,所以我们要让SpringDataJpa默认使用我们自定义的BaseRepository父接口的实现类来创建子类,就需要修改配置文件
factory-class="cn.itsource.ibs.repository.BaseRepositoryFactoryBean
17)项目中做了权限管理吗?说一下权限管理的设计?
a) 任何系统中都需要权限管理
b) 权限管理一般情况下需要6张表
- 用户表
- 角色
- 用户角色中间表
- 权限
- 角色权限中间表
- 菜单表
c) 关系:
- 用户与角色之间:多对多
- 角色与权限之间:多对多
- 权限与菜单之间:多对一
d) 通过角色管理功能:可以去控制角色关联哪些用户、也可以控制角色拥有哪些权限
18)进销存系统中的采购是怎么回事?
a) 采购模块是进销存系统中必要的核心功能模块,因为销售的商品不是自主生产的,是作为一个中间商赚差价
b) 采购分为采购申请和采购入库两部分
c) 采购是公司内部某部门某员工发起申请,由主管或者经理审核之后实施
d) 采购员线下采购
e) 采购申请完毕
f) 供应商送货上门
- 发起一个入库单、入库单明细
- 每一个入库单明细后面都要有一个“确认”按钮
- 确认之后,商品都放入仓库中,修改入库单的状态为“已审”、审核人、审核时间
- 根据商品和仓库确定当前仓库中是否已有这个商品
i) 没有:直接新增一条数据到库存表中
ii) 有:数量累加、金额累加、入库日期以当前时间为准、单价使用加权平均法计算
19)谈一下进销存系统中的导入导出功能?
20)谈一下报表功能
1. 面试技巧
(1) 面试的时候切忌说话不流畅、结巴
(2) 将面试官的问题引导到自己熟悉的方向去
(3) 到面试场合中切忌耍手机、注意坐姿
(4) 提升自己沟通表达能力
(5) 回答问题时注意逻辑、条理清晰