-
最近的一个项目的情况
问题:项目介绍不清,不流畅
-
工作内容全部都是coding是吗?就是经理安排任务,然后按模块做是吗?
-
你项目中自己解决的一个有难度的问题?
-
(根据我刚才回答的问题问的问题):你视频分块是用的什么技术?
前端使用的是
WebUploader
的一个文件上传技术,上传完毕后对会通过ffmpeg
完成对视频的合并和转码处理。 -
java里面实现多线程的一个方式
- 实现
Runnable
接口的run()
方法 ,然后通过Thread
的start()
方法开启线程。 - 继承
Thread
类,重写run()
方法,这个本质上与实现Runnable接口的方式一致,因为Thread类本身就实现了Runnable接口。 - 实现
Callable
接口的call()
方法,然后通过Future
的get()
方法进行开启线程。与另外两个的区别是这个有返回值。 - 通过JUC里面的线程池。
- 实现
-
对Spring里面AOP的理解?
AOP意为面向切面,是为了针对业务处理过程中的切面进行提取 ,比如非核心功能但是又重复的功能需求,比如日志、权限控制等。主要就是将于业务逻辑不相关的内容与业务分离出来,降低双方的耦合度。可以把AOP看成是更好地去OOP,也就是面向对象。
-
AOP的实现原理?
AOP的主要实现技术有
SpringAOP
和AspectJ
。 -
动态代理有哪几种方式?
SpringAOP采用的是动态代理,动态代理又分为
JDK动态代理
和CGlib动态代理
。JDK动态代理
只能为接口创建动态代理实例,而不能对类创建动态代理,所以必须要求目标类实现了某个接口,然后通过反射去获取这个接口信息,生成一个代理接口的动态代理类,再通过反射获取动态代理类的构造函数,利用动态代理类的构造函数生成其实例对象。CGlib动态代理
需要把被代理对象类的class文件加载进来,修改字节码生成子类。 -
如果对Map做循环处理,一般对map有哪几种迭代方式?(把map轮询一遍)
现有一map,如下:
Map<String, Object> map = new HashMap<String, Object>() {{ put("name", "jack"); put("sex", "M"); put("age", 23); }};
这里查资料时还无意间学到了一种HashMap初始化的文艺写法,如上面所写。
具体解释也查了下,new HashMap(){{put(“id”, “001”);}}的解释。是一种匿名内部类和实例初始化块的应用。
-
使用
entrySet()
的方式for (Map.Entry<String, Object> entry : map.entrySet()) { System.out.println(entry.getKey() + "=" + entry.getValue()); }
-
使用
keySet()
的方式for (String key : map.keySet()) { System.out.println("key:" + key + ",value:" + map.get(key)); }
-
使用
iterator迭代器
的方式Iterator<Map.Entry<String, Object>> iterator = map.entrySet().stream().iterator(); while (iterator.hasNext()) { Map.Entry<String, Object> entry = iterator.next(); System.out.println(entry.getKey() + "---" + entry.getValue()); } // 同理可以map.keySet().iterator()来获取迭代器。
-
使用
map.values()
的方式for (Object value : map.values()) { System.out.println("value:"+value); }
这种方式不能遍历key
-
使用
map.forEach()
(1.8新增)的方式map.forEach((key, value) -> System.out.println(key + "---" + value));
-
-
=和equals有什么区别?
==
是对地址值进行判断,equals()
是当类没有覆盖此方法时,等效于 ==。- 当类覆盖此方法时,要看方法的具体实现是什么。
- 常用的Object的equals方法是比较对象的内存地址;String的equals是比较对象的值。
-
SpringMVC和springboot有什么异同点?
Spring MVC是基于Servlet 的一个 MVC框架,主要解决 WEB 开发的问题。因为 Spring 的配置非常复杂,为了简化开发者的使用,从而SpringBoot,利用约定优于配置的方案简化了spring的配置流程。 可以说SpringBoot就是“懒人整合包”(maven工程里面引入的各类starter)。
spring boot就是一个大框架里面包含了许许多多的东西,其中spring就是最核心的内容之一,当然就包含spring mvc。
spring mvc 是只是spring 处理web层请求的一个模块。
因此他们的关系大概就是这样:
spring mvc < spring <springboot。 -
break和continue有什么区别??
用break语句可以使流程跳出switch语句体,也可以用break语句在循环结构终止本层循环体,从而提前结束本层循环。
continue是结束本次循环,继续下一次循环。
-
mybatis传参的话有哪几种方式?(没答上来,面试官就说其实就是问${}和#{}接参有什么差异)
-
通过方法的参数的出现顺序,直接
#{0}、#{1}
这样表示第1、2个参数。 -
基于注解传参。方法参数前添加
@Param("xxx")
注解,这样#{}里面就可以用xxx来指定此参数。 -
采用
Map
传多参。// service Map params = new HashMap<>(); params.put("name",name); params.put("age",age); List result= UserMapper.selectByMapParams(params); //dao List<User> selectByMapParams(Map params); //xml <select id="selectByMapParams" resultMap="BaseResultMap" parameterType="map"> select * from user where name = #{name} and age = #{age} </select>
-
用
javaBean
来传递多个参数。//dao List<User> selectByBeans(User user); //xml <select id="selectByBeans" resultMap="BaseResultMap" parameterType="com.ymx.pojo.User"> select * from user where name = #{name} and age = #{age} </select>
#{}
是预编译处理,${}
是字符串替换。mysql在处理#时会将sql中的#{}替换为?号,调用PreparedStatement的set方法来赋值;
$只是简单地字符串替换和拼接。使用#{}可以防止SQL注入。
-
-
数据库里面如何在查询条件里面使用聚合函数?
count(col)
: 表示求指定列的总行数max(col)
: 表示求指定列的最大值min(col)
: 表示求指定列的最小值sum(col)
: 表示求指定列的和avg(col)
: 表示求指定列的平均值
聚合函数默认忽略字段为null的记录 要想列值为null的记录也参与计算,必须使用ifnull函数对null值做替换。
-
把两个字段合并成一个值向前端返回,该怎么做?(连字符,函数什么的)
CONCAT(str1,str2,…),比如说现在有两个字段是id和name,想要一个id_name的字段,可以这样:
SELECT (Concat(Concat(id,"_"),name)) from user;
-
怎么优化sql查询语句的性能
-
不使用
*
而是使用具体的字段; -
减少使用
IN
和NOT IN
,能用between
就不用IN。 -
分段查询,比如固定查询的时间范围。
-
避免在where子句中进行null值判断、加减乘除等表达式操作(会造成引擎放弃使用索引而进行全表扫描)
-
避免使用
!=
或<>
操作符 -
避免使用
OR
来连接条件 -
不使用
%
前缀(会造成索引失效而进行全表扫描) -
避免隐式类型转换
-
使用“临时表”来缓存中间结果,避免多次扫描主表
-
尽可能的使用
varchar/nvarchar
代替char/nchar
,能使用数字类型就不要使用字符串。 -
可以强制查询使用索引
-- (强制使用主键) select * from table force index(PRI) limit 2; -- (强制使用索引"hollis_index") select * from table force index(hollis_index) limit 2; -- (强制使用索引"PRI和hollis_index") select * from table force index(PRI,hollis_index) limit 2;
-
-
对list数组进行一个最快捷的排序,一般有哪些方式?
不手写快排的话,一般考虑用java集合工具类
Collections
的两种排序方法:-
Collections.sort(List list)
,自然排序参与排序的对象需实现comparable接口,重写其compareTo()方法,方法体中实现对象的比较大小规则
-
Collections.sort(List list,Comparator c)
,自定义排序,需编写匿名内部类,先new一个Comparator接口的比较器对象,同时实现compare()其方法;
然后将比较器对象传给Collections.sort()方法的参数列表中,实现排序功能;//Collections排序,按年龄升序 Collections.sort(persons, new Comparator<Person>() { @Override public int compare(Person o1, Person o2) { return o1.getAge() - o2.getAge(); } });
详情可以看:几种排序的不同写法 和 遍历列表的另外形式
-
-
-
js里面,==和===的区别?
简单来说,
==
代表相同,===
代表严格相同。当双等比较时,先检查两个数据类型,若相同则进行三等比较 ;如果不同则先进行一次类型转换,转换成相同类型再比较;
而三等比较则数据类型不同时直接false。
-
var a;它的值是什么?和var a = null 的区别?
var a,a没有初始化,a的值为
undefined
,即未初始化。var a = null,a的值是
null
,null在js里面是Null类型,表示“空值”。两个比较的话不相等。
这里其实就是undefined和null的比较。
undefined==null = true; undefined===null = false;
另外还有一个
NaN
,它是Number类型的特殊数值:非数字值 。NaN与任何值都不相等,包括其本身。但是可以通过
isNaN()
来判断NaN:alert(isNaN(NaN)) ; //true alert(isNaN(10)) ; //false(10是一个数值) alert(isNaN(“10”)) ; //false(可以被转换为数值10) alert(isNaN(“blue”)) ; //true(不能被转换为数值) alert(isNaN(true)) ; //false(可以被转换为数值1)
-
jquery的选择器?(完全没答上来)
- 基本选择器
- 层级选择器
- 过滤选择器
- 表单选择器
参考链接:JQuery选择器
总结下来,面试过程中除开技术方面,需要改进的是语气助词过多,语气过于轻佻。换位思考下,面试官的体验会很不好。
知识点在非常基础的地方翻车,还是应该去好好看一下基础。
问及前端时,我对面试官说前端基本的阅读可以懂,但是敲的话要看着文档来,但是这个说法在最后对面试探性地提了两个前端问题后答得一塌糊涂的情况下完全无法取信于人。
知识点总结下来不能是自己的,自己能说出来才算是自己的。