今儿参加了字节的测试开发实习面试,一面大概持续了50分钟,问了一些基础知识,然后面试官让等了4分钟就进入了2面,二面大概持续了40分钟就结束了,问了一点项目,然后就是java基础知识和测试相关基础知识及写测试用例,最后手撕代码,就结束了,也就凉了。
一面
自我介绍,问我学习中遇到的最大的问题,,,然后就是知识点
浏览器输入网址会发生什么
- 浏览器向DNS服务器发起域名解析根据域名找到其对应的ip地址
- 解析出ip地址后根据对应端口号80建立Tcp连接
- 浏览器发起读取文件的http请求
- 服务器对浏览器的请求作出响应,把对应的html资源返回给浏览器
- 释放Tcp连接
- 浏览器对返回的资源解析渲染
黑盒测试和白盒测试常用方法
TCP三次握手
进程和线程的区别
进程是操作系统进行资源分配的基本单位,线程是进行资源调度的基本单位,一个进程可以有多个线程
进程有几种状态
了解多线程吗,说一下什么是多线程,多线程一般会引发什么问题及解决方法?
为了同步完成多项任务,通过提高系统的资源利用率来提高系统的效率(效率和线程数以及单个线程内的任务量有关)
引发线程安全问题(多个线程访问共享变量)。
解决方法:
- 同步代码块 (隐式锁)
- 同步方法(隐式锁)
- 同步锁 Lock( jdk 1.5 后)
注意:是一个显示锁,需要通过 lock() 方法上锁,必须通过 unlock() 方法进行释放锁
死锁
乐观锁和悲观锁
多线程实现方式
-
继承Thread类
-
实现Runnable接口
-
实现Callable接口
-
线程池:提供了一个线程队列,队列中保存着所有等待状态的线程。避免了创建与销毁额外开销,提高了响应的速度。
ArrayList和LinkedList区别
- ArrayList基于动态数组实现的非线程安全的集合;LinkedList基于链表实现的非线程安全的集合。
- 对于随机index访问的get和set方法,一般ArrayList的速度要优于LinkedList。因为ArrayList直接通过数组下标直接找到元素;LinkedList要移动指针遍历每个元素直到找到为止。
- 新增和删除元素,一般LinkedList的速度要优于ArrayList。因为ArrayList在新增和删除元素时,可能扩容和复制数组;LinkedList实例化对象需要时间外,只需要修改指针即可。
- LinkedList集合不支持 高效的随机随机访问( RandomAccess )
- ArrayList的空间浪费主要体现在在list列表的结尾预留一定的容量空间,而LinkedList的空间花费则体现在它的每一个元素都需要消耗相当的空间
了解AOP嘛?什么样场景会用到AOP?
了解反射嘛
数据库的索引分为几类,索引的使用场景
一个表里查询非常频繁,那么我们一个表里所有子段都应该加索引吗?还是该怎么加?
写个sql(学生表(字段:姓名,分数,科目)查询每个学生分数最低的科目)
select 科目,min(grade) from student group by name (不知道对错)
考察点:分组、表的过滤查询,分组后差最低分、姓名,再进行子查询。
男女总成绩在前五的同学(变形)
假如你现在打开手机网页,页面空白的,如何排查
1.网络抓包(手机也可以安装模拟器抓包)
2. 响应的内容空白,有没有抓到网络数据包,响应数据包内容是怎样的(看响应状态码)
3. 响应内容是空的,或者响应体长度为0
购物车测试
数组中超过数组长度一半的数
二面
开始就是自我介绍,,,然后就问我项目,然后就说问我一些基础知识
三次握手四次挥手
栈和队列的区别
- 栈的插入和删除操作都是在一端进行的,而队列的操作却是在两端进行的。
- 栈是先进后出,队列是先进先出。
- 栈只允许在表尾一端进行插入和删除,队列只允许在表尾一端进行插入,在表头一端进行删除。
数组和链表的区别
-
数组:
在内存中,数组是一块连续的区域。
数组需要预留空间,在使用前要先申请占内存的大小,可能会浪费内存空间。
插入数据和删除数据效率低,插入数据时,这个位置后面的数据在内存中都要向后移。
随机读取效率很高。因为数组是连续的,知道每一个数据的内存地址,可以直接找到给定地址的数据。
并且不利于扩展,数组定义的空间不够时要重新定义数组。 -
链表
在内存中可以存在任何地方,不要求连续。
每一个数据都保存了下一个数据的内存地址,通过这个地址找到下一个数据。 第一个人知道第二个人的座位号,第二个人知道第三个人的座位号……
增加数据和删除数据很容易。 再来个人可以随便坐,比如来了个人要做到第三个位置,那他只需要把自己的位置告诉第二个人,然后问第二个人拿到原来第三个人的位置就行了。其他人都不用动。
查找数据时效率低,因为不具有随机访问性,所以访问某个位置的数据都要从第一个数据开始访问,然后根据第一个数据保存的下一个数据的地址找到第二个数据,以此类推。 要找到第三个人,必须从第一个人开始问起。
不指定大小,扩展方便。链表大小不用定义,数据随意增删。
链表中插入节点
考虑在链表头结点插入
中间插入
尾部插入
bug的生命周期
发现BUG–>提交BUG–>指派BUG–>研发确认BUG–>研发去修复BUG–>回归验证BUG–>是否通过验证–>关闭BUG
说一下GC()
可以从以下三点:
可达性分析判断对象已死
垃圾回收算法
垃圾回收器
多线程实现方式
如何实现线程同步
什么是线程同步:
线程同步:即当有一个线程在对内存进行操作时,其他线程都不可以对这个内存地址进行操作,直到该线程完成操作,其他线程才能对该内存地址进行操作,而其他线程又处于等待状态、
- synchronized(同步方法,同步代码块)
- volatile
- 使用重入锁实现线程同步。使用类ReentrantLock类来定义锁,其中lock()方法为打开锁,unlock()方法为关闭锁
- 参考