文章目录














测试开发实习面经合集

腾讯系统测试岗

一面

1. 谈项目


  1. 自动化测试项目

  1. 你发现了什么bug?
  2. 发现bug你会怎么做?
  3. 怎么判断bug的优先级?(凡是不符合需求的就是bug)

  1. 接口测试项目

  1. 碰到过什么困难?

  1. 前后端连接时,后台控制器无法接受前端axios发送的参数。
  2. 用正则表达式,获取前台输入的正则表达式。

  1. 其余重复问题在​​测试开发面经(二)阿里​


2.HTTP和HTTPS?


  1. HTTP与HTTPS的区别?

  1. HTTP是超文本传输协议,信息是明文传输,HTTPS则是具有安全性的SSL加密传输协议。
  2. HTTP采用80端口连接,而HTTPS则是443端口。
  3. HTTPS需要CA颁发安全证书。

  1. HTTP长连接,短连接?
  2. 短连接
    ​ 客户端和服务器每进行一次HTTP操作,就建立一次连接,任务结束就中断连接。
  3. 长连接
    ​ 当网页打开完成后,TCP连接也不会关闭,客户端再次访问服务器时,会继续使用这条已经建立的连接。
    ​ 实现长连接需要客户端和服务器端都支持长连接。
  4. 实质上是TCP协议的长连接和短连接。

3. GET和POST区别?


  1. get使用URL或Cookie传参。而post将数据放在body中。
  2. get的url有长度限制,post的数据可以非常大。
  3. post比get安全,因为数据在地址栏上不可见。
  4. 在客户端,一般get请求用来获取数据,post请求用于发送数据。

4. 测试微信小程序?



如何设计测试用例?



常用设计方法:

等价类(有效数据、无效数据)

边界值(左边界和右边界)

流程图

场景法(正确流程、错误流程)

正交表(T\F组合)



用例设计思路

单模块

单模块的数据影响

模块和模块之间的数据流转

项目的整体功能





小程序的用例设计需要关注哪些点?


  1. 与微信的切换,当微信有新消息时,有微信电话时。
  2. 与对应的APP、web的数据互通。
  3. 小程序与手机的交互和兼容,通知管理,横竖屏显示。



小程序具体需要测试哪些内容?



功能测试


  1. 按功能模块测试
  2. 按业务流程测试 (把各个功能点串联起来形成完整的业务流 支付,下载,播放)
  3. 按数据流向测试
  4. 同一功能不同的入口有效性检查(普通用户和VIP用户)
  5. 交互性检查(前台前台,后台后台,后台前台)



界面测试

设计是否美观,设计是否符合要求、尺寸是否合理、横竖屏切换操作



兼容性


  1. 小程序和其他小程序一起运行
  2. 微信的版本
  3. 手机平台
  4. 不同网络状态
  5. 系统



和其他app的交互性


  1. 和支付APP的交互
  2. 和微信其他功能的交互



易用性



导航栏

  1. 导航标签是否易理解
    2. 定位到某个模块的所在的位置
    3. 快速的回到顶部


功能入口


  1. 重要的常用功能是否在比较显眼的位置。
  2. 业务操作过程是否便于大多数用户使用和查看。



上下层级进入和返回



字体、图片、动态交互结果



安全测试


  1. 数据传送是否保密
  2. 微信数据是否有泄漏风险。





5. 常用的linux命令

​测试开发面经(七)Linux常见题​

6. SQL命令

​测试开发面经(六)SQL增删改查​

7. CSRF原理和防御?


  1. 原理
    攻击性通过技术上手段去访问用户认证过的网站
    被访问的网站会认为是真正的用户操作而去运行的。
  2. 防御

  1. 验证 http referer 字段
  2. 二次输入验证码
  3. token认证
  4. cookie hashing


8.两个简单算法题。

​66. 加一​

输入[1,2,3,4]

输出[1,2,3,5]

class Solution {
public int[] plusOne(int[] digits) {
int len = digits.length;
boolean flag = false;
int last = len -1;
if(digits[last]!=9){
digits[last]++;
return digits;
}
for(int i =len-1;i>=0;i--){
if(i==0&&digits[i]==9){
flag =true;
}
if(digits[i]!=9){
digits[i]++;
break;
}

digits[i]=0;
}
//System.out.println(flag);
if(flag==true){
int[] res = new int[len+1];
res[0]=1;
return res;
}
return digits;
}
}

输入123455 输出21435;

public int test(int num){
String ns = num+"";
String[] strs = ns.split("");

for(int i=0;i<strs.length;i+=2){
if(i+1<=strs.length-1){
String temp = strs[i];
strs[i]=strs[i+1];
strs[i+1]=temp;
}
}
StringBuilder builder = new StringBuilder();
for(int i = 0;i<strs.length;i++){
builder.append(strs[i]);
}

return Integer.parseInt(builder.toString());
}
public static void main(String[] args) {
System.out.println(new Test().test(12345));
System.out.println(new Test().test(123456));
}

二面

1.聊项目

2. 什么是数据库索引和主键?

  1. 索引

建立索引是加快查询速度的有效手段,用户可以根据应用环境的需要建立一个或者多个索引,加快查找速度。但需要占据一定的存储空间,当基本表更新的时候索引要进行相应的维护,会增加数据库的负担。

create unique index stusno on student(sno)
create unique index scno on sc(sno asc,cno desc)
### 修改索引的名字
alter index stuson rename to studentsno
### 删除索引
drop index stuname;

B+树索引是将属性组织成B+树的形式,B+树的叶子节点为属性值和相应的元组指针。B+树具有动态平衡的优点。

散列索引是建立若干个桶,将索引属性按照散列函数值映射到相应的桶中,桶中存放索引属性值和相应的元组指针。具有查找速度快的特点。

位图索引是用位向量记录索引属性值中可能出现的值,每个位向量对应一个可能值。

  1. 主键。
    ​ 主关键字(primary key)是表中的一个或多个字段,它的值用于唯一的标识表中的某一条记录。在两个表的关系中,主关键字用来在一个表中引用来自于另一个表中的特定记录。主关键字是一种唯一关键字,表定义的一部分。一个表的主键可以由多个关键字共同组成,并且主关键字的列不能包含空值。

3.HTTP怎么实现的安全加密传输?

使用md5的加密方式对数据进行加密,虽然md5加密算法不可逆,但是可以通过大量正向运算进行破解,加密之前可以再混合一个时间字符串。服务器接收后,如果间隔大于1分钟判定为不合法。

4.点击提交表单,没有反应,进行诊断。


  1. 在浏览器中查看状态码,4**是前端的错误,500是后端的错误。
  2. 后台控制器接收数据的格式是否和前端数据接收的格式是否统一。
  3. 后台分层排查,Controller层,Service层,dao层,最后看业务层是不是有return null;

5. SQL注入的原理?

SQL注入时将页面的原URL、表单域或数据包输入的参数,修改拼接成SQL语句,传递给服务器,传给数据库服务器以执行数据库命令。

6.数组二分查找元素,如果没找到,返回应该插入的位置

package leetcode;

import java.util.Arrays;

public class Solution {
public int brinarySearch(int[] nums,int target){
if(nums.length==0) return 0;
Arrays.sort(nums);

int left = 0;
int right=nums.length-1;
while(left<=right){
int mid = (right+left)/2;
if(mid==target){
return mid;
}
if(mid>target){
right=mid-1;
}else {
left=left+1;
}

}

return left;
}

public static void main(String[] args) {
int[] nums={1,2,3,4,5,6,7,8,9};
System.out.println(new Solution().brinarySearch(nums,1));
}
}

7.反问

百度

二面

1. 聊项目

2.TCP三次握手,四次挥手?

三次握手


  1. 客户端发送带有SYN(j,请求建立连接)标志的数据包。
  2. 服务器发送带有SYN( k )/ACK(确认号是否有效,一般置为1,这里 j+1)标志的数据包。
  3. 客户端发送ACK (k+1) 标志的数据包。连接成功的状态。

四次挥手


  1. 客户端发送一个FIN,用来关闭客户端到服务器的数据传送。
  2. 服务器收到FIN,发回一个ACK确认序号为 收到的序号加1。
  3. 服务器关闭与客户端的连接,发送一个FIN给客户端
  4. 客户端发送ACK报文确认,并将确认序号设置为收到的序号加1;

拓展:为什么连接的时候是三次握手,关闭的时候却是四次握手?

连接时因为当服务器端收到客户端连接请求报文后,可以直接发送SYN+ACK报文。

但是关闭连接时,当服务器端收到fin报文时可能不会立即关闭socket,所以只能先回复一个ack报文,告诉客户端fin报文收到了,等服务器端所有报文都发送完了,才能发送fin报文,不能一起发送。所以需要四次握手。

拓展 :为什么不能两次握手进行连接?

三次握手完成两个重要的功能


  1. 双方知道彼此都准备好发送和接收数据。
  2. 初始的序列号在握手的过程中被发送和确认。

三次握手改成两次握手可能会发生死锁,接收端b不知道发送端a是否已经准备好,不知道a端是否接受到自己的请求。b认为未建立连接成功。

拓展:如果已经建立连接,客户端出现状况了怎么办?

服务器每接收到一次客户端的请求后重新复位计时器,时间通常设置为2小时,若两小时还没收到客户端的任何数据,服务器端发送探测报文段,以后每隔75秒发送一次。如果10个探测报文没有响应,服务器认为客户端出现故障,关闭连接。

3.HTTP和HTTPS?


  1. HTTP是超文本传输协议,信息是明文传输,HTTPS则是具有安全性的SSL加密传输协议。
  2. HTTP采用80端口连接,而HTTPS则是443端口。
  3. HTTPS协议需要到CA申请证书,HTTP协议不需要。

拓展:什么是HTTP协议?

超文本传输协议是互联网上应用最广泛的一种网络协议。所有的www文件都必须遵守的一个标准,是以ASCII码传输,建立在TCP/IP协议之上的应用层规范,简单点说就是一种固定的通讯规则。

拓展:HTTPS协议 数字证书

HTTPS协议是以安全为目标的HTTP通道,其实就是HTTP的升级版本。

数字证书:是由权威的CA机构给服务端进行颁发,CA机构通过服务端提供的相关信息生成证书,证书内容包含了持有人的相关信息,服务器公钥,签署者签名信息等。

4. 服务器接收到http请求后呢?

服务器处理请求,返回响应。

拓展:简述Http协议实现的原理机制?


  1. 域名解析
  2. 发起TCP三次握手
  3. 发起Http请求
  4. 服务器响应HTTP请求。
  5. 浏览器解析HTML代码,并请求HTML代码中的资源
  6. 浏览器对页面进行渲染,呈现给用户。

5. 针对百度网盘下载进行用例设计。

参考上面小程序的用例设计

6.判断链表有无环?

​141. 环形链表​

/**
* Definition for singly-linked list.
* class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public boolean hasCycle(ListNode head) {
if(head==null||head.next==null) return false;
ListNode slow = head;
ListNode fast = head.next;

while(slow!=fast){
if(fast==null||fast.next==null) break;
slow=slow.next;
fast=fast.next;
fast=fast.next;
}

if(slow==fast &&slow.next!=null){
return true;
}

return false;


}
}

7. 翻转二叉树

​226. 翻转二叉树​

/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
public TreeNode invertTree(TreeNode root) {
if(root == null) return root;
if(root.left==null&&root.right==null) return root;

TreeNode temp = root.left;
root.left=root.right;
root.right=temp;
invertTree(root.left);

invertTree(root.right);

return root;
}
}

8. 堆和栈

堆是具有以下性质的完全二叉树:


  1. 每个节点的值都大于或等于其左右孩子节点的值称为大根堆。
  2. 每个节点的值都小于或等于其左右孩子节点的值,称为小根堆。
    栈是一种运算受限的线性表,先进后出,后进先出。

内存中的堆和栈


  1. 栈内存在函数中定义的一些基本类型的遍历和对象的引用变量都在函数的栈内存中分配。存取速度比堆快,​栈的数据可以共享​,但是大小和生存周期是肯定的。
  2. 堆内存是允许程序在运行时动态地申请某个大小的内存空间。

内存中堆和栈的区别


  1. 栈内存空间由操作系统自动分配和释放,堆内存空间手动申请和释放。
  2. 栈内存空间优先有限,堆的空间是很大的自由区,几乎没有空间限制。

百度(用户质量效能部)

一面

1. 自我介绍

​测试开发面经(九)腾讯​

2.项目介绍

3.servlet生命周期?


  1. servlet初始化后调用init() 方法
  2. servlet调用service() 方法来处理客户端请求。
  3. servlet销毁前调用destory()方法。
  4. servlet由jvm的垃圾回收器进行垃圾回收的。

4.GC机制(垃圾回收机制)

4.1 垃圾回收算法分为四种


  1. 复制算法

  1. 标记复制算法简称,将可用内存按容量分为大小相等的两块,每次只使用其中的一块,当这块内存使用完了,就将存活的对象复制到另一块内存上,然后再把已使用过的内存空间一次清理掉。
  2. 优点:实现简单,解决了标记清除算法导致的内存碎片问题。
  3. 缺点:

  1. 空间浪费太多。
  2. 对象存活较多,复制操作较多,效率低。
  3. 一般虚拟机会采用该算法回收新生代,但JVM对复制算法进行了改进;8:1:1


  1. 标记-清除算法

  1. 标记出所有需要回收的对象,在标记完成后,统一回收掉所有被标记的对象;也可以标记存活的对象,标记完成后统一回收未被标记的对象。标记过程就是判定对象是否属于垃圾的过程,基于可达性分析算法判断对象是否可以回收。
  2. 清除:标记后,对所有被标记的对象进行回收。
  3. 优点:基于可达性分析算法,实现简单
  4. 缺点:

  1. 执行效率不稳定,当其中大部分需要回收,需要执行大量的标记和清除动作,导致执行效率随对象的增长而降低。
  2. 内存空间碎片化问题,不连续的内存碎片;


  1. 标记-整理算法

  1. 标记-整理算法是根据老年代的特点而产生的。
  2. 标记:与上面的标记一样,基于可达性分析算法。
  3. 整理:区别是根据存活对象进行整理,让存活对象向一端移动,然后直接清理掉边界以外的内存;
  4. 优点

  1. 不会像复制算法那样划分两个区域,提高了空间利用率。
  2. 不会产生不连续的内存碎片。

  1. 缺点:效率问题,除了像标记清除算法的标记过程外,还多了一步整理过程,效率变低。(Stop the world)

  1. 分代收集算法
  1. 新生代每次回收会发现大量对象死去,少量存活,因此采用赋值算法。
    老年代中,存活率高,采用标记-清理、标记-整理算法进行回收。

4.2 介绍一下JVM垃圾收集器?

新生代收集器:Serial、ParNew、Parallel Scavenge

老年代收集器:CMS、Serial Old、Parallel Old

整堆收集器:G1

5. Selenum的定位方式?

八种定位方式,他们都是位于By类中并且都是静态方法。


  1. By.id();
  2. By.name();
  3. By.tagName();
  4. By.className();
  5. By.linkText();
  6. By.partialLinkText();
  7. By.xpath();
  8. By.cssSelector();

6.排序知道哪些?

冒泡,快排,堆排序,选择排序,希尔排序,常用的是冒泡和快排

7.手写堆排序

package leetcode;

import java.util.Arrays;

public class Solution {
/**
* 大根堆,只要 根节点大于子节点就ok,每次去除根节点,即最大值。
* */
public static void main(String[] args) {
Solution solution=new Solution();
int[] nums ={2,4,3,6,9};
System.out.println(Arrays.toString(nums));
heapInsert(nums);
System.out.println(Arrays.toString(nums));
heapSort(nums);
System.out.println(Arrays.toString(nums));
}

//堆排序
public static void heapSort(int[] arr) {
//构造大根堆
heapInsert(arr);
int size = arr.length;
while (size > 1) {
//固定最大值
swap(arr, 0, size - 1);
size--;
//构造大根堆
heapify(arr, 0, size);
}
}
//构造大根堆(通过新插入的数上升)
public static void heapInsert(int[] arr) {
for (int i = 0; i < arr.length; i++) {
//当前插入的索引
int currentIndex = i;
//父结点索引
int fatherIndex = (currentIndex - 1) / 2;
//如果当前插入的值大于其父结点的值,则交换值,并且将索引指向父结点
//然后继续和上面的父结点值比较,直到不大于父结点,则退出循环
while (arr[currentIndex] > arr[fatherIndex]) {
//交换当前结点与父结点的值
swap(arr, currentIndex, fatherIndex);
//将当前索引指向父索引
currentIndex = fatherIndex;
//重新计算当前索引的父索引
fatherIndex = (currentIndex - 1) / 2;
}
}
}
//将剩余的数构造成大根堆(通过顶端的数下降)
public static void heapify(int[] arr, int index, int size) {
int left = 2 * index + 1;
int right = 2 * index + 2;
while (left < size) {
int largestIndex;
//判断孩子中较大的值的索引(要确保右孩子在size范围之内)
if (arr[left] < arr[right] && right < size) {
largestIndex = right;
} else {
largestIndex = left;
}
//比较父结点的值与孩子中较大的值,并确定最大值的索引
if (arr[index] > arr[largestIndex]) {
largestIndex = index;
}
//如果父结点索引是最大值的索引,那已经是大根堆了,则退出循环
if (index == largestIndex) {
break;
}
//父结点不是最大值,与孩子中较大的值交换
swap(arr, largestIndex, index);
//将索引指向孩子中较大的值的索引
index = largestIndex;
//重新计算交换之后的孩子的索引
left = 2 * index + 1;
right = 2 * index + 2;
}

}
//交换数组中两个元素的值
public static void swap(int[] arr, int i, int j) {
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}



}

8. 手写快排

package leetcode;

import java.util.Arrays;

public class QuickSort {

public static void main(String[] args) {
QuickSort sort =new QuickSort();

int[] nums={9,8,7,6,5,4,3,2,1};
sort.quickSort(nums,0,nums.length-1);
System.out.println(Arrays.toString(nums));
}

public void swap(int[] nums,int i,int j){
int temp = nums[i];
nums[i] = nums[j];
nums[j]= temp;

}

public int partion(int[] nums,int left,int right){
int privot = left;
int index =left+1;
for(int i = left+1;i<=right;i++){
if(nums[i]<nums[privot]){
swap(nums,index,i);
index++;
}
}
swap(nums,privot,index-1);
return index-1;
}
public void quickSort(int[] nums,int left,int right){
if(left<right){
int privot = partion(nums,left,right);
quickSort(nums,left,privot-1);
quickSort(nums,privot+1,right);
}
}
}

9.HTTP和HTTPS的区别?


  1. HTTP是超文本传输协议,HTTPS是具有安全性的SSL加密传输协议
  2. HTTP端口是80,HTTPS端口是443
  3. HTTPS需要CA机构颁发证书,HTTP不需要。

10.数据库的事务隔离级别?

不同等级可以解决的问题不一样:脏读(读取未提交的数据)、不可重复读(多次读取结果不同)、幻读(读取别的事务插入的数据导致读取前后不一致)


  1. 读取未提交内容。都不可以解决
  2. 读取提交内容。可以解决脏读
  3. 可重读。可以解决脏读和可重复读
  4. 可串行化。都可以解决

11.数据库的连接

等值连接、自身连接

左外连接列出左边关系中所有的元组。

select teacher.tno,teacher.tname,classroom from teacher 
left join teacher_course on teacher.tno = teacher_course.tno
where teacher_course.classroom='c305';

右外连接列出右边关系中所有的元组。

outer join(外连接、全连接)查询出左表和右表所有数据,但是去除两表的重复数据。

13.数据库什么时候用索引?


  1. 当某个字段频繁的作为查询参数是,可以在这个字段上建立索引。(建表时主键默认建立唯一索引)
  2. 经常需要排序的字段,比如日志表
  3. 需要数据汇总统计的字段
  4. 一个表的外键如果查询经常使用的话也可以建立索引

create unique index name_desc on student(sname desc);

14.Linux命令,查一下端口号?

losf -i:8080

15.常用的linux命令

top
vmstat -n 2 3
free
iostat -xdk 2 3
ifstat 1

16.输出一个指定文件的后10行?

tail a.txt
### 后3行
tail -n 3 a.txt

## 前5行
head -n 5 a.txt

17.朋友圈点赞的测试用例?


  1. 界面

  1. 界面是否简介美观
  2. 是否符合设计

  1. 功能

  1. 点赞人
  2. 被点赞人
  3. 点赞内容
  4. 消息提醒
  5. 人数限制、按时间点赞排序

  1. 并发

  1. 同时点赞
  2. 连续点赞
  3. 点赞是删除动态

  1. 兼容
  1. 不同版本系统
  1. 性能上

  1. 网络延时断网
  2. 压力测试,多个用户同时点赞。


18.反问

二面

1.聊项目

2.用java伪代码实现?id cost time对相同的id的cost进行排序输出?

// 使用springboot+mybatis查询
class logPage{
id;
cost;
time;
//get set
//toString

}

@Repository
@Mapper
public interface LogMapper{
@Select("
select * from log
group by id
order by cost asc")
public List<logePage> getlog();
}
@Autowired
private LogMapper dao;
main{
List<logePage> pages = dao.getlog();
for(int i =0;i<pages.size();i++){
sout(pages.get(i));
}
}
select * from log
group by id
order by cost asc;

3.OSI七层模型介绍?


  1. 应用层:通过应用进程间的交互完成特定网络应用。
  2. 表示层:数据的表示、安全、压缩。
  3. 会话层:建立管理终止会话。
  4. 运输层:两台主机进程之间的通信提供通用的数据传输服务。
  5. 网络层:选择交换路由和网间节点。
  6. 数据链路层:将网络层交下来的IP数据报组装成帧。
  7. 物理层:实现计算机节点之间比特透明传送,尽可能屏蔽掉具体传输介质和物理设备的差异。

4.http个TCP、IP协议分别在哪一层?

HTTP是应用层的

TCP是运输层的

IP是网络层的。

百度测开

一面

1.介绍自己

特长成就。社会经历,最重要的是自信!

2.写一下快排和冒泡

package leetcode;

import java.util.Arrays;

public class QuckSort2 {
public static void main(String[] args) {
QuckSort2 quckSort2 = new QuckSort2();
int[] nums={9,8,7,6,5,4,3,2,1};
quckSort2.quickSort(nums,0,nums.length-1);
System.out.println(Arrays.toString(nums));
}

public void quickSort(int[] nums,int left,int right){
if(left<right){
int privot = partion(nums,left,right);
quickSort(nums,left,privot-1);
quickSort(nums,privot+1,right);
}



}

public void swap(int[] nums,int i,int j){
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}

public int partion(int[] nums,int left,int right){
int privot =left;
int index = left+1;

for(int i=left+1;i<=right;i++){
if(nums[i]<nums[privot]){
swap(nums,index,i);
index++;
}
}
swap(nums,index-1,privot);

return index-1;
}
}
// 冒泡
public void easySort(int[] nums){
for(int i=0;i<nums.length-1;i++){
for(int j=i+1;j<nums.length;j++){
if(nums[i]>nums[j]){
swap(nums,i,j);
}
}
}
}

3.数据库索引的作用,你用过哪些索引。

作用:


  1. 通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。
  2. 可以大大加快检索速度(主要原因)
  3. 可以加速表与表之间的连接,实现数据的参考完整性
  4. 使用分组和排序字句时减少耗费的时间
  5. 通过索引,可在查询过程中,使用优化隐藏器,提高系统性能。

索引类型:


  1. 唯一索引:
    ​create unique index stusno on student(sno) ​
  2. 主键索引:primary key
  3. 聚簇索引:每个表可以建立一个聚簇索引,但需要120%额外空间,查找数据块。

4.常用的linux命令?

## 查找文件
find . -name "*.txt"
## 查看某个日志的前50行
head -n 50 abc.txt
## 查看当前进程
ps
## 查看进程的详细信息
ps -ef
## 查看路径下所有文件
ls
## 查看abc文件下的目录的详细信息和操作记录
ls -al abc
## 创建目录a
mkdir a

## 修改文件权限
## 为a.txt增加可执行权限
chmod +x a.txt
## 去掉写的权限
chmod -w a.txt

## 修改与用户有关的文件权限
## 修改文件属于mygroup组下的myuser
chown myuser:mygroup a.txt

## 文件重命名
mv a.txt b.txt
## 将文件a.txt移动到a文件夹下
mv a.txt a/
## 复制文件a.txt
cp a.txt ../
## 删除文件夹a
rm -r a


## 查看指定进程41836
ps -ef | grep 41836
## 查看命令操作的历史
history
## 查询a.txt包含关键字“2”的行数
grep -c "2" a.txt

## 目录下以.log结尾的文件中包含关键字2但不包含关键字1的行数
grep "2" a.txt | grep -cv "1"

5. 如果虚拟机根物理机之间的连接出现了问题怎么解决?


  1. 可能是虚拟机的网卡坏了。
  2. 重置虚拟机的网卡。
  3. 检查物理机防火墙配置
  4. 服务器的话检查安全组端口是不是放开。

6.git常用的命令。如果发生冲突怎么解决?本地仓库和远程仓库的区别?

## 初始化一个仓库
git init
## 查看状态
git status
## 把变更记录到暂存区
git add test.txt
## 记录这次操作
git commit -m "add txt"
## 创建分支
git branch testing
## 查看有几个分支
git branch
## 切换分支到testing
git checkout testing
## 将testing合并到主分支
git merge testing
## 然后修改有冲突的地方

如何解决冲突?

git status ## 查看冲突情况 并去修改

git merge ## 先合并再修改提交

本地仓库和远程仓库的区别?

远程仓库只是众多分布式电脑上本地仓库的一员,但充当这“中央服务器的作用”,团队在这里进行下载和推送。

远程仓库是托管在因特网或其他网络中的项目版本库。

7.介绍项目

8.移动端测试的时候是怎么启动app的,原理是什么呢?

(1)Appium 服务器。Appium 服务器是 Appium 框架的核心。它是一个基于 Node.js 实现的 HTTP服务器。Appium 服务器的主要功能是接受从 Appium客户端发起的连接, 监听从客户端发送来的命令,将命令发送给 bootstrap.jar(iOS 手机为 bootstrap.js)执 行,并将命令的执行结果通过 HTTP 应答反馈给 Appium 客户端。

(2)Bootstrap.jar。Bootstrap.jar 是在 Android 手机上运行的一个应用程序,它在手机 上扮演 TCP 服务器的角色。当 Appium 服务器需要运行命令时,Appium 服务器会与 Bootstrap.jar 建立 TCP 通信,并把命令发送给 Bootstrap.jar;Bootstrap.jar 负责运行测 试命令。

(3)Appium客户端。它主要是指实现了Appium功能的WebDriver协议的客户端Library, 它负责与 Appium 服务器建立连接,并将测试脚本的指令发送到 Appium 服务器。现 有的客户端 Library 有多种语言的实现,包括 Ruby、Python、Java、JavaScript(Node.js)、 Object C、PHP 和 C#。Appium 的测试是在这些 Library 的基础上进行开发的。

9.TCP的三次握手和四次挥手?

10.TCP/IP的四层模型?

二面

1.自我介绍?

2.介绍项目,负责的内容?

3.被测平台是做什么的?

4.项目中的测试流程?


  1. 立项

  1. 拿到需求说明书
  2. 原型图
  3. 接口文档
  4. 数据库字典

  1. 需求评审
  2. 用例编写
  3. 用例评审
  4. 测试执行
  5. 编写测试报告和操作手册

5.对加入购物车进行测试,要考虑哪些问题,哪些场景?


  1. 并发:抢购场景、卖家下架商品
  2. 功能界面性能网络环境测试

6.测试项目中测试出了哪些bug?

7.开发接口测试平台是为了做什么的?

8.moco过接口嘛?怎么实现的?

springBoot

9.UI测试功能有集成到平台嘛?

10.Linux查看进程、根据关键字查找日志内容?

##linux查看进程
ps -ef
## 根据关键字查看日志内容
cat app.log | grep "新增用户"
## 根据关键字查看前后10行日志,并显示行号
cat app.log | grep "新增用户" -C 10

11.谈谈对测试的理解?

测试是为了发现错误而执行程序的过程,对软件程序的质量起着促进的作用。

京东

​771. 宝石与石头​

class Solution {
public int numJewelsInStones(String jewels, String stones) {
Map<Character,Integer> jmap = new HashMap<>();
Map<Character,Integer> smap = new HashMap<>();

for(int i =0;i<jewels.length();i++){
jmap.put(jewels.charAt(i),jmap.getOrDefault(jewels.charAt(i),0)+1);
}

for(int i =0;i<stones.length();i++){
smap.put(stones.charAt(i),smap.getOrDefault(stones.charAt(i),0)+1);
}

int res =0;

for(char c:jmap.keySet()){
res+=smap.getOrDefault(c,0);
}

return res;


}
}

字符串,给一个化合物的表达式,计算原子质量。

first

1.自我介绍

2.在项目中哪些原因导致测试延迟?


  1. 项目的三个主要约束时 范围、时间和成本,测试时间延迟的话可能是
  2. 开发进度较慢
  3. 沟通有误
  4. 客户临时修改需求
  5. 技术瓶颈

3.当你发现一个bug,开发人员认为不是bug怎么办?


  1. 优先确认需求,不符合需求的就是BUG,如果开发认为需求有问题,让开发去找产品经理改需求。如果需求优先级比较低,则保持open状态,测试报告写明原因,抄送测试leader和开发leader。
  2. bug,重现。确定不是环境配置的问题。
  3. 说明导致的后果。

4.移动端自动化测试用的框架?

appnium

5.接口测试HttpClient,简单介绍下doGet和doPost的封装和传参?


  1. 域名存放在属性文件中。
  2. 常用get,post方法的封装

  1. doGet(String url)
  2. doGet(String url,String para)
  3. doGet(String url,Map para)
  4. doGetByCookie(String url,CookieStore cookie)
  5. doPost(String url,String para)
  6. doPost(String url,Map para) 针对 Content-type 是 Form
  7. doPost(String url,JSONObject para) 针对 Content-type 是 JSON
  8. doPostByCookie(String url,JSONObject para,CookieStore cookie)

  1. 断言的封装 Checker
  2. 数据驱动(把 1000 个商品遍历,做 submit 的操作;10 个用户的登录,下单)
  3. 数据库的访问(JDBC)
  4. 监听器的使用 ApiListener extends TestListenerAdapter 重写 onFinish()方法
  5. 发送邮件 JAVAmail

public static String doPost(String url, String body,CookieStore cookie) throws Exception {
RequestConfig gConfig =
RequestConfig.custom().setCookieSpec(CookieSpecs.STANDARD).build();
CloseableHttpClient client=HttpClients.custom().
setDefaultRequestConfig(gConfig).setDefaultCookieStore(cookie).build();
HttpPost post=new HttpPost(url);
post.setHeader("content-type","application/json");
HttpEntity request_entity=new StringEntity(body);
post.setEntity(request_entity);
CloseableHttpResponse response =client.execute(post);
HttpEntity result_entity=response.getEntity();
String result=EntityUtils.toString(result_entity,"utf-8");
EntityUtils.consume(result_entity);
response.close();
client.close();
return result;
}

京东

1.聊项目?

2.http和https区别?


  1. http是超文本传输协议,数据明文传输,https是具有安全性的基于SSL加密传输协议
  2. 端口号不同,http使用80端口,https使用的是443端口。
  3. https需要ca颁发安全证书。

3.http都有什么请求方法?


  1. get
  2. post
  3. options
  4. head
  5. put
  6. delete
  7. trace
  8. connect

京东物流测试开发

一面

1.自我介绍

2.有什么优势?


  1. 测试框架
  2. 主流java开发框架

3.项目被测网站?

4.在第一个测试项目中怎么确保测试进行,确保测试的质量的?

4.1 如何确保测试进度?


  1. 评估版本工作量,划分需求优先级
  2. 按优先级执行测试用例
  3. 提前协调测试相关资源
  4. 版本测试进度日报
  5. 测试范围变更管理

4.2如何确保质量?


  1. 不同的测试类型的结合,功能,性能,界面,兼容性,可用性,增加测试覆盖面
  2. 理解需求,设计测试用例
  3. 用例的质量。功能细分,用例覆盖所有需求
  4. 执行的质量,跟进测试进度,注意各模块的交叉关联。
  5. 缺陷管理。记录bug,跟踪缺陷,对遗留缺陷进行分析。
  6. 版本控制,建立主干分支,版本有问题可以随时恢复。
  7. 测试评估,对结果进行分析,讨论上线的风险。

5.怎么防止前端某个按钮多次点击导致出错 ?


  1. 定义标志位。按钮触发后置为false,再次点击不再发送请求。
  2. 点击触发请求后,卸载点击事件
  3. 替换按钮dom 或者移除。

6.给一个包含只包含字母和数字的字符串,怎么找出其中的数字 ?

7.UI测试中碰到了哪些问题 ?

8.元素找不到是因为什么?最后怎么解决

​xpath知识​

9.Java序列化了解吗 ?

9.1 定义


  1. 序列化:将对象转化为流的过程称为序列化。
  2. 反序列化:将流转化成对象的过程称为反序列化。

9.2 序列化作用


  1. 把内存中的对象保存到一个文件中或者数据库中;
  2. 用套接字再网络上传送对象;
  3. 通过RMI传输对象;

9.3 实现

实现Serializable接口

public class User implements Serializable{}

10. String类有哪些方法

String s = "abc";
s.charAt(1);
int b=s.compareTo(""); //等于返回0
System.out.println(b);// 3
s.concat("add");
char[] cs = s.toCharArray();
s.length();
s.split("");
s.substring(0,1);
s.toLowerCase();
s.toUpperCase();
s.trim();

11. 遇到过那些Java异常

ArrayIndexOutOfBoundsException 数组越界异常

NullPointerException 空指针异常

12、Java异常分几类


  1. IOException

  1. EOFException(文件已结束异常)
  2. FileNotFoundException(文件未找到异常)

  1. RuntimeException (运行异常)

  1. ArrithmeticException(算数异常)
  2. MissingResourceException
  3. ClassNotFoundException
  4. NullPointerException(空指针异常)
  5. illegalArgumentException
  6. ArrayIndexOutBoundsException(数组下标越界异常)
  7. UnknowTypeException


13、谈谈平台开发项目从最开始到结束是怎么做的,期间遇到的问题,如 何解决

14、谈谈项目有哪些不足

15、从开发和测试的角度谈谈提交一个表单应该注意到什么?

16、怎么确保后端不会向前端传输无用的错误信息?

京东

1.自我介绍

2.int和integer区别


  1. Integer是int的包装器类,int是java的一种基本数据类型。
  2. Integer变量必须实例化后才能使用,而int变量不需要
  3. Integer实际是对象的引用,当new一个Integer时,实际上是生成一个指针指向此对象;而int是直接存储数据值
  4. Integer的默认值是null,int的默认值是0;

3.String是否可被继承

不可以,因为String类有final修饰符,而final修饰的类是不能被继承的,实现细节不允许改变。

4.讲一下GC机制

5.接口测试中出现问题如排查 ?


  1. 先检查接口地址,端口拼写是否正确。
  2. ping下地址检查网络是否正常
  3. 检查端口号是否正确
  4. 检查项目是否启动,部署成功
  5. 检查服务器防火墙是否关闭
  6. 检查测试工具,是不是filter代理没关。
  7. 检查操作系统的host文件。

6.selenium元素定位方式


  1. By.id();
  2. By.name();
  3. By.tagName();
  4. By.className();
  5. By.linkText();
  6. By.partialLinkText();
  7. By.xpath();
  8. By.cssSelector();

7.实训中敏捷开发是怎么进行的 ?


  1. 产品负责人和开发团队对产品业务目标形成共识。
  2. 产品负责人家里和维护产品的需求列表,并进行优先级排序
  3. 产品负责人每轮迭代前,浏览需求列表,并筛选高优先级需求进行本轮迭代开发。
  4. 开发团对细化迭代需求,并按照需求列表的优先级,一次在本轮迭代完成
  5. 开发团队每日例会,特征开发,持续集成,使开发进度真正透明
  6. 产品经理对每轮迭代交付的可用的软件进行现场验收和反馈。
  7. 团队内部进行本轮冲刺的回顾,发现可改进的方面,指导下一轮的迭代。

8.设计充值话费的测试用例


  1. 界面
  2. 功能
  3. 并发
  4. 性能

京东

自我介绍

1.你的优势

2.测试流程


  1. 需求分析
  2. 测试计划
  3. 设计测试用例
  4. 执行测试用例
  5. 编写测试报告

3.测试计划的内容


  1. 测试范围
  2. 测试策略
  3. 资源安排
  4. 进度安排
  5. 发布标准
  6. 风险预防

4.测试报告的内容


  1. 测试背景说明。
  2. 测试范围说明。
  3. 测试环境说明。
  4. 测试方法说明。
  5. 测试结果与缺陷分析,主要从功能性能方面分析。
  6. 测试结论与建议。
  7. 质量或风险评估。

5.如何搭建一个本地测试环境


  1. 配置Linux系统
  2. 安装jdk
  3. 安装tomcat
  4. 安装mysql

6.安全测试可能出现的漏洞


  1. xss漏洞:在input标签输入js代码
  2. sql注入漏洞
  3. 文件包含漏洞:将文件设置为变量,禁止跳转目录。
  4. 点击劫持
  5. CSRF 冒充用户进行浏览器操作。

7.如何对一个需求进行分析


  1. 根据业务逻辑和业务流程画出流程图,分析需求以及业务走向。
  2. 挖掘每个需求点的产生原因
  3. 挖掘每个需求点的隐含需求
  4. 挖掘每个需求的必要性。

8.接口测试,移动端测试,安全测试更擅长哪一个

9.项目(如何分包,前后端怎么连接)

10.反问

11 .项目生命周期?


  1. 需求分析
  2. 需求定义
  3. 概要设计
  4. 详细设计
  5. 实现
  6. 系统测试
  7. 验收测试
  8. 维护

快手

一面:30min

1、自我介绍

2、说说项目过程中做了些什么(面试官根据回答情况进行进一步细节提 问)

3、细节提问:

(1)TestNG监听器怎么使用?


  1. 在testng.xml中使用使用监听器。
  2. ​<suite name="TestNGSample"> <listeners> <listener class-name="listeners.MyListener1" /> <listener class-name="listeners.MyListener2" /> </listeners> <test name="testDemo"> <classes> <class name="tests.MyTest" /> </classes> </test> </suite> ​​​​public class MyTest extends TestListenerAdapter ​

  1. 创建监听类,实现接口ITestListener,或者继承类TestListenerAdapter
  2. 重写三个方法


    1. onTestStart
    2. onTestSuccess
    3. onTestFailure


  3. 配置testng.xml文件在listeners和listener 标签中来添加监听器

  1. 用@Listeners注释
    ​@Listeners({ MyListener.class, MyListener2.class }) ​

(2) MySQL查看日志


  1. 查看默认日志文件/var/log/mysqld.log
  2. 利用查询
    ​set GLOBAL general_log=1; set global log_output='table'; select * from mysql.general_log; ​

(3) SpringBoot对数据库日志的查看


  1. springboot默认使用的是logback日志系统,需要引入maven依赖,日志框架是logback+slf4j;
  2. mybatis查询general_log表

(4)设计的平台后端怎么分层(项目骨架,有哪些包,作用是什么)

(5)怎么组织的小组成员进行测试,过程中遇到的问题、解决方式 Ps:主要还是详细了解项目内容以及过程

4、代码题:https://leetcode-cn.com/problems/er-wei-shu-zu-zhong-de-cha-zhao-lcof/

矩阵搜索值是否存在 排序规则为 左到右 上到下递增。

class Solution {
public boolean findNumberIn2DArray(int[][] matrix, int target) {

if(matrix==null||matrix.length==0||matrix[0].length==0){
return false;
}

int m = matrix.length;
int n = matrix[0].length;

int row = 0;
int col = n-1;

while(row<m&&col>=0){
if(matrix[row][col]>target){
col--;
}else if(matrix[row][col]<target){
row++;
}else{
return true;
}
}
return false;


}
}

5、针对代码题的输入进行测试

6、现在怎么优化当时做的项目

7、为什么想做测试工作,对测试工作的看法


  1. 我喜欢找BUG的快感
  2. 测试的技术要求更广泛,包括业务能力、设计和架构分析能力,测试手段和工具使用,用户模型分析和理解,编程能力。

我可以利用之前积累的测试用例的设计经验、以及逻辑分析能力,设计出比较完善的测试用例;我自己也比较细心,可以尽可能的找到软件中的各种潜藏的bug;我可以使用各种接口、UI自动化测试的技术来对项目进行自动化测试,同时具体一定的运维知识,可以进行自动化的环境搭建,自动化的项目部署等工作。可以充分发挥自己的技术特长来提升测试效率。另外,我沟通能力不错,能很好的在测试工作中同公司的UI、产品、开发、运维等各个岗位的同时进行互动,而我个人也非常喜欢与他们打交道,因为可以在工作中学习到各个领域的很多新知识,从不同的人身上学习到不同的东西。

从事软件测试工作是符合我长期的职业发展规划的,我会使用现有的所有技能、经验快速上手项目的测试工作,同时在项目过程中不断学习新知识,提高工作的测试效率和软件的质量。

8、反问

二面:30min

1、继续询问项目

2、对数据从前端到后端到数据库的过程进行测试

3、代码题:https://leetcode-cn.com/problems/median-of-two-sorted-arrays/

先合并两个数组然后合并中位数。

class Solution {
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
int[] nums = new int[nums1.length+nums2.length];

for(int i = 0;i<nums1.length;i++){
nums[i] = nums1[i];
}

for(int i=nums1.length,j=0;j<nums2.length;j++){

nums[i+j] = nums2[j];
}
int len = nums.length;

Arrays.sort(nums);

double res = 0;

if(nums.length%2==0){
res = nums[len/2-1]+nums[len/2];
return res/2.0;
}else {
res = nums[len/2];
return res;
}


}
}

4、为什么选择测试工作

5、反问。

6.testng的@Test注解需要那些包?

7.最大回文子串

​​

class Solution {
public String longestPalindrome(String s) {
int maxlen =1;
int begin = 0;

int len = s.length();
if(len<2) return s;

boolean[][] dp = new boolean[len][len];

for(int i = 0;i<len;i++){
dp[i][i] = true;
}

char cs[] = s.toCharArray();

for(int j = 1;j<len;j++){
for(int i =0;i<j;i++){
if(cs[i]!=cs[j]){
dp[i][j]=false;
}else{
if(j-i<3){
dp[i][j] = true;
}else{
dp[i][j] = dp[i+1][j-1];
}
}

if(dp[i][j]&&j-i+1>maxlen){
maxlen = j-i+1;
begin = i;
}
}


}

return s.substring(begin,begin+maxlen);


}

}

字节跳动

一面

1.两道sql题,一道多表联查,一道分组统计

多表联查

# 查询法政学院教师第一学期所带班级
select classno from student
where sno in (
select sno from student_course
where cno in(
select cno
from teacher_course
where tno in(
select tno
from teacher
where dno in(
select dno from department
where dname = '法政学院'
)
)
)and cno in(
select cno from course
where semester = 1
)
)

分组统计

## 查询计算机导论平均成绩最高的班级
select classno from student,student_course
where student.sno=student_course.sno
and cno in(
select cno from course
where cname='计算机导论'
)group by classno
having avg(score)>= all(
select avg(score)
from student,student_course
where student.sno=student_course.sno
and cno in(
select cno from course
where cname='计算机导论'
)group by classno
);

2.算法题,链表中环的入口节点(拓展:不利用额外空间),写完代码之后 提交运行,通过之后让你自己设计测试用例来验证。

​剑指 Offer II 022. 链表中环的入口节点​

快慢指针 ,相遇后释放慢指针和temp指针 相遇就是入口。

/**
* Definition for singly-linked list.
* class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
public ListNode detectCycle(ListNode head) {

if(head == null) return null;

ListNode slow = head;
ListNode fast = head;

while(fast!=null){

slow = slow.next;

if(fast.next!=null){
fast=fast.next.next;
}else{
return null;
}

if(fast==slow){
ListNode temp = head;
while(temp!=slow){
temp=temp.next;
slow=slow.next;
}

return temp;
}


}
return null;

}
}

3.从地址栏输入url到浏览器显示出内容,一系列过程描述。(其中涉及到 tcp三次握手,四次挥手,dns解析)


  1. DNS解析 获取对应域名的解析(DNS过程:浏览器缓存,路由器缓存,DNS缓存)。
  2. TCP连接。
  3. 发送HTTP请求。
  4. 服务器处理请求并返回HTTP报文。
  5. 浏览器解析渲染页面。
  6. 连接结束。

4.描述测试流程


  1. 进行需求分析
  2. 编写测试计划
  3. 设计测试用例
  4. 执行测试用例
  5. 编写测试报告

5.进程和线程的区别,在java中有哪些线程安全的例子,Java的锁机制 ?

5.1进程和线程的区别


  1. 线程是进程更小的运行单位,一个进程在其执行过程中可以产生多个线程
  2. 进程是独立的,线程不一定,同一进程中的线程可能会相互影响。
  3. 线程执行开销小,但不利于资源的管理和保护。

5.2 java中有哪些线程安全的例子?

购票软件,并发执行

5.3 java锁的机制?

  1. synchronized关键字 (独占锁)

  1. 解决了多个线程之间访问资源的同步性
  2. 可以保证被它修饰的方法或者代码块在任意时刻只能有一个线程执行。
  3. 可以修饰实例方法
  4. 修饰静态方法
  5. 修饰代码块

6.还问了问学校,问我为什么学软件工程的来应聘测试开 发

7.项目也问到了,问了问项目是干什么的,问的比较简单不深入,问了什么 我忘了

8.反问环节,然后一面完了之后马上约二面,30min后开始二面

二面

1.有序整数数组nums1和nums2,请你将nums2合并到nums1中,使nums1成为一个有序数组。

​88. 合并两个有序数组​

class Solution {
public void merge(int[] nums1, int m, int[] nums2, int n) {

for(int i = 0;i<n;i++){
nums1[m+i] = nums2[i];
}

quickSort(nums1,0,nums1.length-1);




}

public void swap(int[] nums,int i,int j){
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}

public int partion(int[] nums ,int left ,int right){
int privot = left;
int index = privot +1;

// 分治 { { 小于} privot {大于}}

for(int i = index;i<=right;i++){
if(nums[i]<nums[privot]){
swap(nums,index,i);
index++;
}
}

swap(nums,privot,index-1);


return index -1;
}

public void quickSort(int[] nums,int left,int right){
if(left < right){
int privot = partion(nums,left,right);
quickSort(nums,left,privot-1);
quickSort(nums,privot+1,right);
}
}
}

nums1足够大,时间复杂度O(n),不使用额外空间

class Solution {
public void merge(int[] nums1, int m, int[] nums2, int n) {
int p1 = 0, p2 = 0;
int[] sorted = new int[m + n];
int cur;
while (p1 < m || p2 < n) {
if (p1 == m) {
cur = nums2[p2++];
} else if (p2 == n) {
cur = nums1[p1++];
} else if (nums1[p1] < nums2[p2]) {
cur = nums1[p1++];
} else {
cur = nums2[p2++];
}
sorted[p1 + p2 - 1] = cur;
}
for (int i = 0; i != m + n; ++i) {
nums1[i] = sorted[i];
}
}
}

2.对微信朋友圈点赞设计测试用例

​微信朋友圈点赞测试​

3.Ui自动化测试是怎么进行的,遇到了哪些问题,是怎么解决的,面试官会根 据自己的回答来提问细节

4.一条接口测试用例包含什么,检查点有什么

5.接口自动化测试平台是怎么做的,前端后端数据库是怎么实现的,在做接口 自动化测试平台时,遇到了哪些问题,是怎么解决的,面试官会根据自己的回 答来提问细节

6.liunx系统,在搭建测试环境,部署项目的时候,用到了哪些命令,遇到了哪 些问题

## 安装jdk
mkdir java
cd /usr/local/java
tar -xzvf jdk-8u231-linux-x64.tar.gz

vim /etc/profile
export JAVA_HOME=/usr/local/java/jdk1.8.0_231
export CLASSPATH=.:$JAVA_HOME/jre/lib/rt.jar:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
export PATH=$JAVA_HOME/bin:$PATH
## 使配置文件生效
source /etc/profile

## 安装tomcat类似
cd /usr/local/tomcat/bin
## 启动
sh startup.sh

## 安装mysql
wget 下载地址

7.操作系统死锁的原因

两个或者多个线程同时阻塞,他们中的一个或者全部都在等待某个资源被释放,由于线程被无限期地阻塞,因此程序不可能正常终止。

9.反问环节

三面

1.ip地址的计算

10:10:10 1.1.1.1 xxxx

10:10:10 2.1.1.1 xxxx

这个日志文件里有多少个ip

2.针对抖音上滑推荐下一条视频,做测试设计

3.在连续上滑抖音的过程中,后端如何保证流畅性,你作为开发该怎么办 (我当时回答的是做缓存)

4.智力题,100个人做核酸检测(假设有一个人是阳性),在你看来,经过 多少次可以找出那个人来?(分组问题)

5.Webdriver的工作原理


  1. 工程师写的脚本运行,一个http请求就会被创建并且发送给浏览器驱动。
  2. 浏览器驱动里包含了一个http server,用来接收这些请求。
  3. HTTP server接收到这些请求后根据请求来操控对应的浏览器
  4. 浏览器会执行具体的测试步骤
  5. 浏览器将步骤执行的结果返回给httpserver
  6. http server又将结果返回给脚本

webdriver是基于 json wire protocol的,它是在http协议的基础上,对http请求及响应信息的body部分的数据进行进一步规范。

6.在大学里,你觉得你干过的最有成就感的事?

7.问项目,描述项目,然后提问,问了什么我忘了

8.反问环节。

字节·2

一面

1,自我介绍+项目描述(20min)

2.测试报告里该有哪些内容


  1. 测试背景说明。
  2. 测试范围说明。
  3. 测试环境说明。
  4. 测试方法说明。
  5. 测试结果与缺陷分析,主要从功能性能方面分析。
  6. 测试结论与建议。
  7. 质量或风险评估。

3,输入关键词后到指定页面,其中的过程

4,抖音点赞测试用例

5.http状态码

分类

分类描述

1**

指示信息。服务器收到请求,需要请求者继续执行操作

2**

请求发送成功

3**

重定向

4**

客户端发送的请求有语法错误

5**

服务器错误

6,手撕:合并两个有序链表

​剑指 Offer 25. 合并两个排序的链表​

/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {

ListNode head = new ListNode(0);
ListNode temp = head;

while(l1!=null||l2!=null){
if(l1!=null&&l2!=null&&l1.val<=l2.val){
temp.next = l1;
l1 = l1.next;
}else if(l1!=null&&l2!=null&&l1.val>l2.val){
temp.next = l2;
l2 = l2.next;
}else if(l1!=null&&l2==null){
temp.next = l1;
l1 = l1.next;
}else if(l1==null&&l2!=null){
temp.next = l2;
l2 = l2.next;
}

temp = temp.next;
}

return head.next;

}
}

二面

1.手撕:矩阵最短路径和

​剑指 Offer II 099. 最小路径之和​

class Solution {
public int minPathSum(int[][] grid) {
int m = grid.length;
int n = grid[0].length;
int dp = new int[m][n];
dp[0][0] = grid[0][0];

for(int i = 1;i<m;i++){
dp[i][0]=dp[i-1][0]+grid[i][0];
}

for(int i = 1;i<n;i++){
dp[0][i]=dp[0][i-1]+grid[0][i];
}

for(int i = 1;i<m;i++){
for(int j = 1;j<n;j++){
dp[i][j] = Math.min(dp[i-1][j],dp[i][j-1])+grid[i][j];
}
}


return dp[m-1][n-1];
}


}

2.手撕:字符串的字符串统计

​剑指 Offer II 015. 字符串中的所有变位词​

class Solution {
public List<Integer> findAnagrams(String s, String p) {
List<Integer> res = new ArrayList<>();
if(s.length()<p.length()) return res;
int[] dic = new int[128]; //asc码
for(int i = 0;i<p.length();i++){
dic[p.charAt(i)]++;
}
int left = 0;//窗口左端
for(int i = 0;i<s.length();){
// 有这个字符
if(dic[s.charAt(i)]>0){
dic[s.charAt(i)]--;
//如果相等的话右边界向右移动
i++;
if(i - left==p.length()) res.add(left);
}else{
//不相等的话 左边界 复原之前的字典 并向右移动
dic[s.charAt(left)]++;
left++;
}
}
return res;
}
}

3,对职业的规划

4,对微信搜索框进行测试用例设计

字节.3

笔试

选择

T1:最远座位问题(环状数组)easy题,10分钟就能ac。

T2:树的自底向上深搜找公共节点(树+深搜+memo),这个题不是二叉树,其 次找的多个节点的公共节点,这些节点之间还可能存在各种关系。

​剑指 Offer 68 - II. 二叉树的最近公共祖先​

/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
/***
1.一个左子树,一个右子树,
2.两个都在左
3.都在右
*/
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if(root== null) return null;

if(root == p|| root==q){
return root;
}
TreeNode left =lowestCommonAncestor(root.left,p,q);
TreeNode right = lowestCommonAncestor(root.right,p,q);

if(left!=null&&right!=null){
return root;
}

if(left==null){
return right;
}

if(right == null){
return left;
}

return null;

}


}

一面

1.java内存

2.mysql索引

3.数据库引擎

MyISAM是MySQL的默认数据库引擎(5.5版之前)。虽然性能极佳,⽽且提供了⼤量的特性,包括全⽂索 引、压缩、空间函数等,但MyISAM不⽀持事务和⾏级锁,⽽且最⼤的缺陷就是崩溃后⽆法安全恢复。不 过,5.5版本之后,MySQL引⼊了InnoDB(事务性数据库引擎),MySQL 5.5版本后默认的存储引擎为 InnoDB

1.是否⽀持⾏级锁 : MyISAM 只有表级锁(table-level locking),⽽InnoDB ⽀持⾏级锁(rowlevel locking)和表级锁,默认为⾏级锁。

2.是否⽀持事务和崩溃后的安全恢复: MyISAM 强调的是性能,每次查询具有原⼦性,其执⾏速度 ⽐InnoDB类型更快,但是不提供事务⽀持。但是InnoDB 提供事务⽀持事务,外部键等⾼级数据 库功能。 具有事务(commit)、回滚(rollback)和崩溃修复能⼒(crash recovery capabilities) 的事务安全(transaction-safe (ACID compliant))型表。

3.是否⽀持外键: MyISAM不⽀持,⽽InnoDB⽀持。

4.是否⽀持MVCC :仅 InnoDB ⽀持。应对⾼并发事务, MVCC⽐单纯的加锁更⾼效;MVCC只在 READ COMMITTED 和 REPEATABLE READ 两个隔离级别下⼯作;MVCC可以使⽤ 乐观 (optimistic)锁 和 悲观(pessimistic)锁来实现;各数据库中MVCC实现并不统⼀。

4.浏览器输入url

5.进程通信,并且比较这些方式。


  1. 管道/匿名管道​ :⽤于具有亲缘关系的⽗⼦进程间或者兄弟进程之间的通信。
  2. 有名管道​ : 匿名管道由于没有名字,只能​⽤于​亲缘关系的进程间通信。为了克服 这个缺点,提出了有名管道。有名管道严格遵循先进先出(first in first out)。有名管道以磁 盘⽂件的⽅式存在,​可以实现本机任意两个进程通信​。
  3. 信号​:信号是⼀种比较复杂的通信⽅式,⽤于通知接收进程某个事件已经发⽣;
  4. 消息队列​:消息队列是​消息的链表​,具有特定的格式,存放在内存中并由消息 队列标识符标识。管道和消息队列的通信数据都是先进先出的原则。与管道(⽆名管道:只存在 于内存中的⽂件;命名管道:存在于实际的磁盘介质或者⽂件系统)不同的是消息队列存放在内 核中,只有在内核重启(即,操作系统重启)或者显示地删除⼀个消息队列时,该消息队列才会被 真正的删除。消息队列可以实现消息的随机查询,消息不⼀定要以先进先出的次序读取,也可以按 消息的类型读取.⽐ FIFO 更有优势。消息队列​克服了信号承载信息量少​,​管道只能承载⽆格式 字 节流​以及​缓冲区⼤⼩受限等缺陷​。
  5. 信号量​:信号量是⼀个计数器,⽤于多进程对共享数据的访问,信号量的意图在 于进程间同步。这种通信⽅式主要⽤于​解决与同步相关的问题并避免竞争条件​。
  6. 共享内存​:使得多个进程可以访问同⼀块内存空间,不同进程可以及时看到对 ⽅进程中对共享内存中数据的更新。这种⽅式需要依靠某种同步操作,如互斥锁和信号量等。可 以说这是最有⽤的进程间通信⽅式。
  7. 套接字​ : 此⽅法主要⽤于在​客户端和服务器​之间通过⽹络进⾏通信。套接字是⽀持 TCP/IP 的⽹络通信的基本操作单元,可以看做是不同主机之间的进程进⾏双向通信的端点,简 单的说就是通信的两⽅的⼀种约定,⽤套接字中的相关函数来完成通信过程

5.1补充一个,tcp和udp的使用场景。


  1. 要求通信数据可靠用TCP。
  2. 要求通信速度高用UDP。

6.项目(没有深挖,就我一个人得得得

7.检验镜像二叉树(10min)

​剑指 Offer 28. 对称的二叉树​

/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public boolean isSymmetric(TreeNode root) {

if(root==null) return true;

return assertTree(root.right,root.left);



}

public boolean assertTree(TreeNode r,TreeNode l){
if(r == null&& l == null) return true;

if(r == null||l==null||r.val!=l.val) return false;

return assertTree(r.right,l.left)&&assertTree(r.left,l.right);
}
}

8.反问

二面

1.项目,挖了点,面试官估计是开发的。

2.操作系统,虚拟内存,物理内存,内存管理,LRU等

2.1虚拟内存

虚拟内存 使得应⽤程序认为它拥有连续的可⽤的内存(⼀个连续完整的地址空间),⽽实际上,它 通常是被分隔成多个物理内存碎⽚,还有部分暂时存储在外部磁盘存储器上,在需要时进⾏数据交 换。与没有使⽤虚拟内存技术的系统相⽐,使⽤这种技术的系统使得⼤型程序的编写变得更容易, 对真正的物理内存(例如 RAM)的使⽤也更有效率。

2.2 物理内存

物理内存指通过物理内存条而获得的内存空间,真实存在的插在主板内存槽上的内存条的容量的大小。

2.3 内存管理


  1. 内存管理主要是做什么的?
    ​ 操作系统的内存管理主要负责内存的分配与回收(malloc 函数:申请内存,free 函数:释 放内存),另外地址转换也就是将逻辑地址转换成相应的物理地址等功能也是操作系统内存管理做的事情。
  2. 常⻅的⼏种内存管理机制?

  1. 块式管理 :将内存分为⼏个固定⼤⼩的块,​每个块 中只包含⼀个进程​。如果程序运⾏需要内存的话,操作系统就分配给它⼀块,如果程序运⾏只需 要很⼩的空间的话,分配的这块内存很⼤⼀部分⼏乎被浪费了。这些在每个块中未被利⽤的空 间,我们称之为​碎⽚​。
  2. ⻚式管理 :把主存分为⼤⼩相等且固定的⼀⻚⼀⻚的形式,​⻚较⼩​,相对相⽐于块式管理的划 分⼒度更⼤,提⾼了内存利⽤率,减少了碎⽚。⻚式管理通过⻚表对应逻辑地址和物理地址。
  3. 段式管理 : ⻚式管理虽然提⾼了内存利⽤率,但是⻚式管理其中的⻚实际并⽆任何实际意义。 段式管理把主存分为⼀段段的,每⼀段的空间⼜要⽐⼀⻚的空间⼩很多 。但是,最重要的是段 是有实际意义的,​每个段定义了⼀组逻辑信息​,例如,有主程序段 MAIN、⼦程序段 X、数据段 D 及栈段 S 等。 段式管理通过段表对应逻辑地址和物理地址。

  1. ⻚⾯置换算法

  1. OPT ⻚⾯置换算法(最佳⻚⾯置换算法) :最佳(Optimal, OPT)置换算法所选择的被淘汰⻚⾯ 将是以后永不使⽤的,或者是在最⻓时间内不再被访问的⻚⾯,这样可以保证获得最低的缺⻚ 率。但由于⼈们⽬前⽆法预知进程在内存下的若千⻚⾯中哪个是未来最⻓时间内不再被访问的, 因⽽该算法⽆法实现。⼀般作为衡量其他置换算法的⽅法。
  2. FIFO先进先出⻚⾯置换算法 : 选择在内存中驻留时间最久的⻚⾯进⾏淘汰。
  3. LRU ⻚⾯置换算法(最近最久未使⽤⻚⾯置换算法) :LRU算法赋予 每个⻚⾯⼀个访问字段,⽤来记录⼀个⻚⾯⾃上次被访问以来所经历的时间 T,当须淘汰⼀个⻚ ⾯时,选择现有⻚⾯中其 T 值最⼤的,即最近最久未使⽤的⻚⾯予以淘汰。
  4. LFU ⻚⾯置换算法(最少使⽤⻚⾯置换算法) : 该置换算法选择在 之前时期使⽤最少的⻚⾯作为淘汰⻚。


3.网络,服务器怎么处理请求,容器等


  1. tcp连接
  2. 接收http请求
  3. 处理http请求
  4. 访问资源
  5. 构建响应
  6. 发送响应
  7. 记录日志

4.java语言基础,线程,syc关键字,作用范围,修饰啥,除了syc关键字呢, java还能怎么实现线程同步,java信号量。

4.1 java线程


  1. 线程创建之后它将处于**NEW(新建)**状态,调⽤ **start() **⽅法后开始运⾏,
  2. 线程这时候处于​READY(可运⾏)​ 状态。可运⾏状态的线程获得了 cpu 时间⽚(timeslice)后就处于 **RUNNING(运 ⾏) **状态。
  3. 当线程执⾏ ​wait()​ ⽅法之后,线程进⼊ **WAITING(等待)**状态。进⼊等待状态的线程需要依靠其他 线程的通知才能够返回到运⾏状态,⽽ TIME_WAITING(超时等待) 状态相当于在等待状态的基础上增加 了超时限制,⽐如通过 sleep(long millis) ⽅法或 wait(long millis) ⽅法可以将 Java 线程置于 TIMED WAITING 状态。当超时时间到达后 Java 线程将会返回到 RUNNABLE 状态。当线程调 ⽤同步⽅法时,在没有获取到锁的情况下,线程将会进⼊到 ​BLOCKED(阻塞)​ 状态。线程在执⾏ Runnable 的 ​run()​ ⽅法之后将会进⼊到 ​TERMINATED(终⽌​) 状态。

4.2 synchronized 关键字使用方式


  1. 修饰实例⽅法
  2. 修饰静态⽅法
  3. 修饰代码块

4.3 java还能怎么实现线程同步


  1. 使用同步代码块
  2. 使用同步方法
  3. 使用互斥锁ReetrantLock(更灵活的代码控制)

4.4 java信号量

信号量模型

信号量的模型很简单,有:一个计数器,一个等待队列,三个方法(init,down,up)。在该模型中,计数器与等待队列对外是透明的,只能去通过三个方法区访问。

三个方法详解:


  1. init():设置计数器的初始值(信号量是支持多个线程访问一个临界区的,所以可以通过设置计数器的初始值来控制线程访问临界资源的数量)
  2. down():计数器减一操作;如果此时计数器的值小于0,则当前线程被阻塞,否则当前线程可以继续执行。
  3. up():计数器加一操作;如果此时计数器的值小于或者等于 0,则唤醒等待队列中的一个线程,并将其从等待队列中移除。

5.二维数组的广搜。

6.微信发消息怎么测试。——然后追问群聊500人,发消息,怎么测试 ——其他499人怎么确定收到

自己实现一个线程,监听收到的消息,如果群里收到了新的消 息,打印时间和用户名到日志文件里,或者统计一下,最后打印多少个用户收 到了,延时怎么样。

相⽐,使⽤这种技术的系统使得⼤型程序的编写变得更容易, 对真正的物理内存(例如 RAM)的使⽤也更有效率。

2.2 物理内存

物理内存指通过物理内存条而获得的内存空间,真实存在的插在主板内存槽上的内存条的容量的大小。

2.3 内存管理


  1. 内存管理主要是做什么的?
    ​ 操作系统的内存管理主要负责内存的分配与回收(malloc 函数:申请内存,free 函数:释 放内存),另外地址转换也就是将逻辑地址转换成相应的物理地址等功能也是操作系统内存管理做的事情。
  2. 常⻅的⼏种内存管理机制?

  1. 块式管理 :将内存分为⼏个固定⼤⼩的块,​每个块 中只包含⼀个进程​。如果程序运⾏需要内存的话,操作系统就分配给它⼀块,如果程序运⾏只需 要很⼩的空间的话,分配的这块内存很⼤⼀部分⼏乎被浪费了。这些在每个块中未被利⽤的空 间,我们称之为​碎⽚​。
  2. ⻚式管理 :把主存分为⼤⼩相等且固定的⼀⻚⼀⻚的形式,​⻚较⼩​,相对相⽐于块式管理的划 分⼒度更⼤,提⾼了内存利⽤率,减少了碎⽚。⻚式管理通过⻚表对应逻辑地址和物理地址。
  3. 段式管理 : ⻚式管理虽然提⾼了内存利⽤率,但是⻚式管理其中的⻚实际并⽆任何实际意义。 段式管理把主存分为⼀段段的,每⼀段的空间⼜要⽐⼀⻚的空间⼩很多 。但是,最重要的是段 是有实际意义的,​每个段定义了⼀组逻辑信息​,例如,有主程序段 MAIN、⼦程序段 X、数据段 D 及栈段 S 等。 段式管理通过段表对应逻辑地址和物理地址。

  1. ⻚⾯置换算法

  1. OPT ⻚⾯置换算法(最佳⻚⾯置换算法) :最佳(Optimal, OPT)置换算法所选择的被淘汰⻚⾯ 将是以后永不使⽤的,或者是在最⻓时间内不再被访问的⻚⾯,这样可以保证获得最低的缺⻚ 率。但由于⼈们⽬前⽆法预知进程在内存下的若千⻚⾯中哪个是未来最⻓时间内不再被访问的, 因⽽该算法⽆法实现。⼀般作为衡量其他置换算法的⽅法。
  2. FIFO先进先出⻚⾯置换算法 : 选择在内存中驻留时间最久的⻚⾯进⾏淘汰。
  3. LRU ⻚⾯置换算法(最近最久未使⽤⻚⾯置换算法) :LRU算法赋予 每个⻚⾯⼀个访问字段,⽤来记录⼀个⻚⾯⾃上次被访问以来所经历的时间 T,当须淘汰⼀个⻚ ⾯时,选择现有⻚⾯中其 T 值最⼤的,即最近最久未使⽤的⻚⾯予以淘汰。
  4. LFU ⻚⾯置换算法(最少使⽤⻚⾯置换算法) : 该置换算法选择在 之前时期使⽤最少的⻚⾯作为淘汰⻚。


3.网络,服务器怎么处理请求,容器等


  1. tcp连接
  2. 接收http请求
  3. 处理http请求
  4. 访问资源
  5. 构建响应
  6. 发送响应
  7. 记录日志

4.java语言基础,线程,syc关键字,作用范围,修饰啥,除了syc关键字呢, java还能怎么实现线程同步,java信号量。

4.1 java线程


  1. 线程创建之后它将处于**NEW(新建)**状态,调⽤ **start() **⽅法后开始运⾏,
  2. 线程这时候处于​READY(可运⾏)​ 状态。可运⾏状态的线程获得了 cpu 时间⽚(timeslice)后就处于 **RUNNING(运 ⾏) **状态。
  3. 当线程执⾏ ​wait()​ ⽅法之后,线程进⼊ **WAITING(等待)**状态。进⼊等待状态的线程需要依靠其他 线程的通知才能够返回到运⾏状态,⽽ TIME_WAITING(超时等待) 状态相当于在等待状态的基础上增加 了超时限制,⽐如通过 sleep(long millis) ⽅法或 wait(long millis) ⽅法可以将 Java 线程置于 TIMED WAITING 状态。当超时时间到达后 Java 线程将会返回到 RUNNABLE 状态。当线程调 ⽤同步⽅法时,在没有获取到锁的情况下,线程将会进⼊到 ​BLOCKED(阻塞)​ 状态。线程在执⾏ Runnable 的 ​run()​ ⽅法之后将会进⼊到 ​TERMINATED(终⽌​) 状态。

4.2 synchronized 关键字使用方式


  1. 修饰实例⽅法
  2. 修饰静态⽅法
  3. 修饰代码块

4.3 java还能怎么实现线程同步


  1. 使用同步代码块
  2. 使用同步方法
  3. 使用互斥锁ReetrantLock(更灵活的代码控制)

4.4 java信号量

信号量模型

信号量的模型很简单,有:一个计数器,一个等待队列,三个方法(init,down,up)。在该模型中,计数器与等待队列对外是透明的,只能去通过三个方法区访问。

三个方法详解:


  1. init():设置计数器的初始值(信号量是支持多个线程访问一个临界区的,所以可以通过设置计数器的初始值来控制线程访问临界资源的数量)
  2. down():计数器减一操作;如果此时计数器的值小于0,则当前线程被阻塞,否则当前线程可以继续执行。
  3. up():计数器加一操作;如果此时计数器的值小于或者等于 0,则唤醒等待队列中的一个线程,并将其从等待队列中移除。

5.二维数组的广搜。

6.微信发消息怎么测试。——然后追问群聊500人,发消息,怎么测试 ——其他499人怎么确定收到

自己实现一个线程,监听收到的消息,如果群里收到了新的消 息,打印时间和用户名到日志文件里,或者统计一下,最后打印多少个用户收 到了,延时怎么样。