提及:下面的面试题基础可以保障你能通过技术性的面试,但是经历的项目,对自己工作的理解,感觉和提升才是通往大厂的门票!
一面:文章源自玩技e族-https://www.playezu.com/191758.html
先介绍自己,然后讲项目经历,讲项目的时候,有问到有没有考虑到多个用户并发问题(没有),之后问一些问题。
大部分都是 Java 基础,还有一些 Spring 相关,多线程相关;文章源自玩技e族-https://www.playezu.com/191758.html
面试官问的面试题:
1、String str = new String("abc");会建几个对象?String str1 = "abc",str == str1?//false;
2 个,abc 和 str,false,==对比的是地址,因为两个对象对应的空间不同,所以 false文章源自玩技e族-https://www.playezu.com/191758.html
2、你用过一些什么数据结构?(这是一个套路)
数组
链表
二叉树
红黑树
栈和队列
堆和堆栈文章源自玩技e族-https://www.playezu.com/191758.html
3、你说说 ArrayList 和 LinkedList 的区别;
ArrayList 针对 List 的数组方式的实现,允许数据重复存储,初始化时自动新建一个数据存储,时间复杂度为 1
LinkedList 是链表实现,封装的是链表,时间复杂度是 n文章源自玩技e族-https://www.playezu.com/191758.html
ArrayList 自动扩容机制:
初始化时自动分配一个 10 大小的空间,扩容通过 grow 方法实现。填入参数时,分三种情况:
1、小于 10,不扩容,直接写入
2、大于 10 但是小于 10 的 2 倍,扩容 10 个单位
3、大于 10 且大于 10 的两倍,调用 copy 方法,将数组复制生成新的数组文章源自玩技e族-https://www.playezu.com/191758.html
4、说说 HashMap 的底层实现,扩容机制,线程安全问题;(说到红黑树,为什么用红黑树代替而不是二叉搜索树?)
(建议去看源码或者一些对源码进行分析的博客)
HashMap 底层是链表模式存储的。当链表复杂度达到一定层次后,会采用红黑树的形式取数。一个 key 过来后,
先根据 key 的 hashcode 对比 treenode 获取位置,之后再进行取数。
因为 hashmap 是异步操作,所以线程不安全
红黑树的好处就是可以切换。通过旋转或者变色维持树的平衡性文章源自玩技e族-https://www.playezu.com/191758.html
高并发使用 concurrentHashMap 可保证线程安全 array文章源自玩技e族-https://www.playezu.com/191758.html
5、说说 JVM 的内存模型,紧接着引用,紧接着垃圾回收算法,具体讲一下分代算法的实现;
java 堆,方法区,本地方法区,虚拟机栈,程序计数器
程序运行主要在 java 对中,java 数组,对象存在区域。
方法区存放静态变量,常量等
垃圾回收算法:
清除算法,复制算法,压缩算法文章源自玩技e族-https://www.playezu.com/191758.html
6、线程的状态;调用 start()会发生什么,会执行什么方法;
start() 方法会先创建一个新线程然后等待,cpu 分配时间后,jvm 再调用 run 方法运行线程主体
主线程 A 调用子线程 B,B 可以看到主线程启动子线程的操作。文章源自玩技e族-https://www.playezu.com/191758.html
7、了解线程池吗?为什么引入线程池,有哪些参数?
ExecutorService newScheduledThreadPool 定时处理 newcacheThreadPool 无限制大小线程池
FixThreadPool 固定大小
创建线程和销毁线程需要占用 cpu 和内存资源,线程池的作用就是提前准备好线程,需要的时候调用下就行,而不是现场造
线程池干掉了 outofmemory 问题
线程的生命周期:新建、就绪、运行、阻塞、销毁。
8、synchronized 修饰实例方法和静态方法的区别;volatile 关键字了解吗?
修饰实例方法的时候,其实锁的是调用该方法的对象;而修饰静态方法时,是锁的静态方法类的对象。
一般线程操作内容是从主内存中读取一份后,进对副本行各类操作,存在延迟问题,最终将结果写入主内存;
而 volatile 处理变量则是直接对主内存中原始数据进行操作,不存在同步问题
synchronized 和锁 lock 的区别;
Synchronized Lock
本质 内置语言实现 接口
发生异常 自动释放占有的锁 发生死锁,直到 unlock 被调用
等待中线程 不可中断 可中断
锁试探 无法感知锁是否存在 可以验证锁是否存在
读写效率 低 高
9、Spring 用过那些注解?依赖注入怎么实现的?AOP 怎么实现的?(代理);AOP 中用的是哪种代理?
spring 的注解:
@Controller 声明 Action 组件
@Service 声明 Service 组件 @Service("myMovieLister")
@Repository 声明 Dao 组件
@Component 泛指组件, 当不好归类时.
@RequestMapping("/menu") 请求映射
@Resource 用于注入,( j2ee 提供的 ) 默认按名称装配,@Resource(name="beanName")
@Autowired 用于注入,(srping 提供的) 默认按类型装配
@Transactional( rollbackFor={Exception.class}) 事务管理
@ResponseBody
@Scope("prototype") 设定 bean 的作用域
依赖注入的实现:
依赖,通过容器对设置 bean,并配置响应 id 等参数;一般容器初始化或者首次调用 getbean 时触发; 通过 setbean 的形式实现参数注入
注入:构造器注入,通过 xml 设置 property 实现;通过 set 注入,通过 setbean 实现
AOP 的实现:动态代理
将公共的业务类,类似日志,安全和常规业务类等领域业务结合,当执行领域业务时,会加载公共业务,最终实现公共业务重复应用。
自定义实现 execution
10、算法题
(1)遍历一次,找到单链表最中间的节点(偶数长度返回其中一个即可);
标签左移右移进行遍历
(2)对一亿个不重复的 int 进行排序,但是内存只有 200M(桶排序);
归并排序 ,桶排序方法实现。主要思想:分而治之
(3)使用 pattern,对"abbad","北京 杭州 杭州 北京 上海" 进行校验
举例:abbad 对应 北京 杭州 杭州 北京 上海 则为 true
abbad 对应 北京 杭州 杭州 北京 上海 上海 则为 false
//modelStr:校验规则 target:校验目标
public Boolean method1(String modelStr,String target){
final String regexAnyWithoutSpace = "([s]+)";
final String regexSpace = "s";
Map regexPlaceholderIndexMap = new HashMap<>();
Integer regexPlaceholderIndex = 1;
List regexPatternArray = new ArrayList<>();
Integer patternLength = modelStr.length();
for (Integer index = 0; index < patternLength; index++) {
String needle = new String(new char[]{modelStr.charAt(index)
Integer currentPlaceHolderIndex = regexPlaceholderIndexMap.get(needle);
if (currentPlaceHolderIndex == null) {
regexPatternArray.add(regexAnyWithoutSpace);
regexPlaceholderIndexMap.put(needle, regexPlaceholderIndex);
regexPlaceholderIndex++;
} else {
regexPatternArray.add(String.format("%d", currentPlaceHolderIndex));
}
}
String patternStr = String.format("%s$", String.join(regexSpace, regexPatternArray));
System.out.println("组装完成的正则表达式"+patternStr);
Pattern pattern = Pattern.compile(patternStr);
Boolean isMatch = pattern.matcher(target).find();
return isMatch;
}
(4) 一个小球从 200 米高处落地,每次谈起的举例是上次的一半,请问在 N 此谈起后经过了多少距离
public double mehtod(double height,int count) {
double countheight = height;
double currentheight = height;
double returnNum;
if (count > 0) {
if (count == 1) {
returnNum = height;
} else {
for (int i = 2; i <= count; i++) {
currentheight = currentheight / 2;
countheight = countheight + currentheight;
}
}
}
return countheight;
}
(5) 纯算法题。25 匹马,5 个赛道,没有计时器,请问最低多少次可以找出跑得最快的 5 匹马?
这个直接贴链接了。个人认为这个讲解的是最全面的文章:https://zhuanlan.zhihu.com/p/86441697
11、订单下单场景测试用例设计
软件功能测试规范
未知地区 1F
沙发大佬,你这一面 没有俩小时下不来吧?