一面 1.18
自我介绍
算法题:最长不重复子串(取尺or直接暴力)
class Solution {
private final static int SIZE = 256;
public int lengthOfLongestSubstring(String s) {
final int n = s.length();
int start = 0;
boolean[] have = new boolean[SIZE];
int res = 0;
for (int i = 0; i < n; i++) {
int index = s.charAt(i);
if (!have[index]) {
have[index] = true;
continue;
}
res = Math.max(res, i - start);
while (s.charAt(start) != s.charAt(i)) {
have[s.charAt(start)] = false;
start++;
}
start++;
}
res = Math.max(res, n - start);
return res;
}
}
测试用例设计(微信发图片)
6大常见的测试用例设计面试题
Q:
一、登录功能,设计测试用例。
A:
功能测试:
1.输入正确的账号和密码,点击提交按钮,验证是否能正常登录;
2.输入错误的账号或错误的密码,登录失败,是否有相应的提示信息;
3.登录成功后能否跳转到正确的页面;
4.账号和密码,如果太短或者太长,应该怎么处理,密码太短时是否有提示;
5.账号和密码中有特殊字符(如空格),和其他非英文的情况,是否做了过滤;
6.是否可以记住登录成功的账号;
7.登录失败后,不能记住密码;
8.账号和密码前后有空格是否正常处理;
9.密码是否加密显示(星号、圆点等);
10.验证码文字是否扭曲过度导致辨认难度大,刷新是否正常;
11.登录页面中的注册、忘记密码链接是否正确跳转;
12.输入密码的时候,大写键盘开启时是否有提示信息;
13.不输入任何内容,点击提交按钮,提示信息是否正确(非空校验);
UI测试:
1.布局是否合理,文字和按钮是否正确排列;
2.文本输入框和按钮的长度,高度是否符合要求;
3.界面的设计风格是否与Ul的设计风格统一;
4.界面中的文字是否简洁易懂,没有错别字;
性能测试:
1.打开登录页面,需要几秒;
2.输入正确的账号和密码后,登录成功跳转到新页面,不超过5秒;
安全性测试:
1.登录成功后生成的Cookie是否有HttpOnly(降低脚本盗取风险);
2.账号和密码是否通过加密的方式,发送给Web服务器;
3.账号和密码的验证,应该是用服务器端验证,而不能单单是在客户端用javaScript验证;
4.账号和密码的输入框,应该屏蔽SQL注入攻击;
5.账号和密码的输入框,应该禁止输入脚本(防止XSS攻击);
6.错误登录的次数限制(防止暴力破解);
7.考虑是否支持多用户在同一机器上登录;
8.考虑一用户在多台机器上是否允许登录;
可用性测试:
1.是否可以全用键盘操作,是否有快捷键;
2.输入账号,密码后按回车,是否可以登录;
3.输入框是否可以以Tab键切换;
4.高对比度下能否显示正常(视力不好的人使用);
兼容性测试:
1.主流的浏览器下能否显示正常(IE,FireFox.Chrome,Safari等);
2.不同的平台是否能正常工作,比如Windows,Mac;
3.移动设备上是否正常工作,比如iPhone,Android;
4.不同的分辨率下是否显示正常;
Q:
二、怎么测试购物车模块,设计测试用例。
A:
功能测试:
1.将商品加入购物车>选择购物车中所有的商品>确认购买>生成订单>查看订单详情,显示商品信息,购物车商品是否被清空;
2.将商品加入购物车、从购物车删除,查看购物车该商品是否相应增减;
3.将商品加入购物车、增加/减少商品数量,查看购物车该商品是否相应增加/删除;
4.购物车商品默认全选/部分勾选/不勾选>,点击购买>生成订单显示全部商品/生成订单显示部分商品/提示未添加商品;
5.所有页面链接功能正常,可以跳转到正确页面;
6.卖家在线的时候,旺旺icon高亮,反之,灰色;
7.购物车页面打开的同时,在其他页面添加了商品,购物车页面刷新后,新的商品能显示;
8.若未登录,点击购物车,则提示用户先进行登录;
9.商品未勾选的状态下,结算按钮是置灰无法点击的;
10.勾选商品后,已选商品的总价会显示,结算按钮变高亮可点击工作;
11.购物车有商品降价或者库存告急的,那么点击对应的tab,降价或者告急商品会归类后显示;
12.购物车能添加的商品种类有数量上限;
13.若商品已经失效,购物车的商品不可以继续结算;
14.已进入支付界面但支付未成功,重新进入购物车,又重新添加了一些物品,则原有的物品是否能正确保留;
界面测试:
1.打开页面后,页面的布局是否合理,显示是否完整;
2.鼠标浮动在购物车按钮,购物车界面显示是否正常;
3.不同卖家的商品在不同的table区域显示,区分明显;
性能测试:
打开购物车页面要多久;
可用性测试:
快捷键功能是否支持;
兼容测试:
1.不同浏览器上的功能是否正常;
2.不同浏览器上的页面显示是否正常;
Q:
三、QQ收藏表情功能,设计测试用例。
A:
正常功能:
表情包支持的图片格式包括jpg、jpeg、bmp、gif、png,不支持doc、xls、flv、txt等;
1.表情包符合格式要求,且图片大小在范围内,收藏成功;
2.表情包不符合格式要求,图片大小在范围内,收藏失败;
3.表情包符合格式要求,图片大小不在范围内,收藏失败;
4.收藏时支持对符合格式要求,图片大小范围内的表情包进行单个收藏和批量收藏;
5.表情包收藏成功后,可以正常使用;
6.表情包收藏后支持删除后再次删除;
7.点击文字进行收藏,不支持收藏到表情;
8.选择聊天记录中系统时间进行收藏,不支持收藏到表情;
9.VIP用户退回到普通用户,原收藏的表情可用;
10.收藏表情有效时间内可使用,过期不可使用;
11.电脑和手机QQ收藏的表情可共用;
12.不支持收藏系统自带的表情;
13.支持收藏好友发送的、自己发送的未收藏过的表情;
异常功能:
1.空间不足时,点击收藏,是否正常处理;
2.达到收藏上限时点击收藏,是否正常处理;
3.弱网络、断网离线时,点击收藏,是否正常处理;
4.收到表情超过一定时限点击收藏,是否正常处理;
5.本地修改不支持的格式为支持的格式,点击收藏,是否正常处理;
易用性测试:
1.收藏操作是否方便、简单、易上手;
2.收藏后是否便于使用;
3.收藏后删除是否不再占用内存;
性能测试:
1.单个用户对单个表情收藏和批量收藏时,响应时间是否符合要求;
2.多个用户对单个表情收藏和批量收藏时,响应时间是否符合要求;
3.用户收藏表情数量达到最大限度时,用户使用表情时响应时间是否符合要求;
安全性测试:
1.添加感染病毒的图片进行收藏,是否可以收藏;
2.图片及内容涉及违规时,是否可以收藏;
兼容性测试:
1.不同Windows操作系统是否可以正常收藏;
2.QQ更新版本后,原收藏的表情可以正常使用;
3.在Windows/Mac/IOS/Android设备上可以正常浏览和使用收藏的表情;
Q:
四、网上银行转账是怎么测的,设计功能测试用例。
A:
功能测试:
1 .验证同行转账、跨行转账,绑定的银行卡的互转;
2..校验验证码的有效性(一般小额只需手机验证码,大额需要手机验证码+动态口令,转给绑定的银行卡无需验证);
3. 验证转账手续费收取情况(比如小于一定金额同行转账免费,跨行收费等等,具体收费标准以需求书描述为准);
4. 验证即时转账和普通转账情况;
5.验证6位数交易密码正确与否的情况;
6. 验证账户余额不足的情况;
7 .验证转账金额超过限额情况;
8.验证转账超时情况(一般交易都有超时控制,服务器超过一定时间(一般30s)没有响应,服务器就会发出超时报错给客户端,超时场景测试需要临时联系开发,让开发设置一下,测试员工就可以在客户端模拟出超时场景);
9.验证收款人姓名和收款账号不一致的情况或者两者都有误的情况;
10. 验证转出方或者转入方属于非法账户(挂失,冻结,锁定,销户的账户)情况;
11. 验证信用卡、定期存折不能转出。(一般会在账号选择的时候,进行屏蔽);
12.验证在ios、安卓,wap,web端的转账场景;
Q:
五、支付宝充值的测试,设计功能测试用例。
A:
功能测试:
1. 验证绑定的主流银行卡的充值情况;
2 .验证正常充值情况;
3. 验证充值金额大于限额情况;
4. 验证支付密码输入正确与否的情况;
5. 验证银行卡余额不足情况;
6 .验证银行卡挂失,冻结,锁定,销户的充值情况;
7.验证充值超时情况(一般交易都有超时控制,服务器超过一定时间(一般30s)没有响应,服务器就会发出超时报错给客户端,超时场景测试需要临时;
联系开发,让开发设置一下,测试员工就可以在客户端模拟出超时场景);
8 .验证在ios、安卓,wap,web端的充值场景;
Q:
六、支付宝提现的测试,设计功能测试用例。
A:
功能测试:
1 .验证提现到绑定的主流银行卡;
2. 验证提现两小时内到账情况;
3 .验证手续费收取情况(0.1%,2016年起每人只有20000的免费提现及转账额度);
4 .验证提现时,临时添加银行卡,并且选择该银行卡;
5. 验证提现时输入交易密码正确与否的情况;
6 .验证提现超时情况;
7.验证提现金额大于余额的情况;
8.验证提现金额小于等于余额的情况;
9 .验证在ios、安卓,wap,web端的提现场景;
以上
That‘s all
反问
二面 1.19
自我介绍
项目
-
C和C++的区别
-
C是一个结构化语言,它的重点在于算法和数据结构。C程序的设计首要考虑的是如何通过一个过程,对输入(或环境条件)进行运算处理得到输出(或实现过程(事务)控制)。
-
C++,首要考虑的是如何构造一个对象模型,让这个模型能够契合与之对应的问题域,这样就可以通过获取对象的状态信息得到输出或实现过程(事务)控制。 所以C与C++的最大区别在于它们的用于解决问题的思想方法不一样。之所以说C++比C更先进,是因为“ 设计这个概念已经被融入到C++之中 ”。
-
-
malloc/free 和new/delet
void *malloc(long NumBytes):该函数分配了NumBytes个字节,并返回了指向这块内存的指针。如果分配失败,则返回一个空指针(NULL)。void free(void *FirstByte): 该函数是将之前用malloc分配的空间还给程序或者是操作系统,也就是释放了这块内存,让它重新得到自由。
1.malloc/free是C/C++语言的标准库函数,new/delete是C++的运算符。它们都可用于申请动态内存和释放内存。但是new能够自动分配空间大小,而malloc需要计算字节数。
-
内存泄漏和内存溢出
-
内存溢出 out of memory,是指程序在申请内存时,没有足够的内存空间供其使用,出现out of memory;比如申请了一个integer,但给它存了long才能存下的数,那就是内存溢出。
-
内存泄漏是指你向系统申请分配内存进行使用(new),可是使用完了以后却不归还(delete),结果你申请到的那块内存你自己也不能再访问(也许你把它的地址给弄丢了),而系统也不能再次将它分配给需要的程序。就是分配的内存不足以放下数据项序列,称为内存溢出.
-
memory leak会最终会导致out of memory!
-
内存溢出的原因以及解决方法
-
引起内存溢出的原因有很多种,小编列举一下常见的有以下几种:
-
1.内存中加载的数据量过于庞大,如一次从数据库取出过多数据;
-
2.集合类中有对对象的引用,使用完后未清空,使得JVM不能回收;
-
3.代码中存在死循环或循环产生过多重复的对象实体;
-
4.使用的第三方软件中的BUG;
-
5.启动参数内存值设定的过小
-
内存溢出的解决方案:
-
第一步,修改JVM启动参数,直接增加内存。(-Xms,-Xmx参数一定不要忘记加。)
-
第二步,检查错误日志,查看“OutOfMemory”错误前是否有其它异常或错误。
-
第三步,对代码进行走查和分析,找出可能发生内存溢出的位置。
-
重点排查以下几点:
-
1.检查对数据库查询中,是否有一次获得全部数据的查询。一般来说,如果一次取十万条记录到内存,就可能引起内存溢出。这个问题比较隐蔽,在上线前,数据库中数据较少,不容易出问题,上线后,数据库中数据多了,一次查询就有可能引起内存溢出。因此对于数据库查询尽量采用分页的方式查询。
-
2.检查代码中是否有死循环或递归调用。
-
3.检查是否有大循环重复产生新对象实体。
-
4.检查对数据库查询中,是否有一次获得全部数据的查询。一般来说,如果一次取十万条记录到内存,就可能引起内存溢出。这个问题比较隐蔽,在上线前,数据库中数据较少,不容易出问题,上线后,数据库中数据多了,一次查询就有可能引起内存溢出。因此对于数据库查询尽量采用分页的方式查询。
-
5.检查List、MAP等集合对象是否有使用完后,未清除的问题。List、MAP等集合对象会始终存有对对象的引用,使得这些对象不能被GC回收。
-
第四步,使用内存查看工具动态查看内存使用情况
-
-
堆和栈的区别
-
栈(操作系统):由操作系统自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。
-
堆(操作系统): 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收,分配方式倒是类似于链表。
-
栈内存
-
在函数中定义的基本类型的变量和对象的引用变量都是在函数的栈内存中分配。
-
当在一段代码块中声明了一个变量时,java就会在栈内存中为这个变量分配内存空间,当超过变量的作用域之后,java也会自动释放为该变量分配的空间,而这个回收的空间可以即刻用作他用。
-
堆内存
-
堆内存用于存放由new创建的对象和数组。
-
在堆内存中分配的内存空间,由java虚拟机自动垃圾回收器来管理。在堆中产生了一个数组或者对象后,还可以在栈中定义一个特殊的变量,变量的值就等于数组或对象在堆内存中的首地址,而这个栈中的特殊变量,也就成为数组或对象的引用变量。以后可以在程序中使用栈内存中的引用变量访问堆内存中的数组或对象了。引用变量相当于是为数组或对象起的一个别名,或者是代号。
-
数组和对象在没有引用变量指向它的时候,才变成垃圾,不能被继续使用,但是仍然会占用堆内存空间,而后在一个不确定的时间内,由java虚拟机自动垃圾回收器回收,这也是java程序为什么会占用很大内存的原因。
-
-
代码题:模拟一个栈
1 public class ArrayStack {
2 private int maxSize;//栈的大小
3 private int top = -1;//栈顶指针
4 private int[] arr;//模拟栈的数组
5
6 public ArrayStack(int maxSize) {
7 this.maxSize = maxSize;
8 arr = new int[maxSize];
9 }
10
11 //判断当前栈是否已经满了
12 public boolean isFull(){
13 return top == maxSize - 1;
14 }
15 //判断栈是否为空
16 public boolean isEmpty(){
17 return top == -1;
18 }
19
20 //入栈
21 public void push(int val){
22 if(isFull()){
23 System.out.println("栈满,无法添加数据");
24 return;
25 }
26 top++;
27 arr[top] = val;
28 }
29 //出栈
30
31
32 //展示
33 public void show(){
34 if(isEmpty()){
35 System.out.println("栈空,无法展示");
36 return;
37 }
38 for (int i = 0; i <= top; i++) {
39 System.out.printf("arr[%d]=%d",i,arr[i]);
40 System.out.println();
41 }
42 }
43 }
-
测试用例设计(验证码)
三面 1.22
-
自我介绍
-
竞赛经历
-
代码题:判断一棵树是否是完全二叉树(bfs)
-
public static boolean check(Node head) {
-
boolean leaf = false; // 是否开启了状态
-
Queue<Node> q = new LinkedList<Node>();
-
q.add(head);
-
while (!q.isEmpty()) {
-
Node cur = q.poll();
-
Node l = cur.lchild;
-
Node r = cur.rchild;
-
if ((leaf && (l != null && r != null)) || (l == null && r != null))
-
return false;
-
if (l != null)
-
q.add(l);
-
if (r != null)
-
q.add(r);
-
else
-
leaf = true;
-
}
-
return true;
-
}
-
-
有序数组查找某个数是否出现(二分)
-
int BinarySearch(int array[], int n, int value)
-
{
-
int left = 0;
-
int right = n - 1;
-
//如果这里是int right = n 的话,那么下面有两处地方需要修改,以保证一一对应:
-
//1、下面循环的条件则是while(left < right)
-
//2、循环内当 array[middle] > value 的时候,right = mid
-
while (left <= right) //循环条件,适时而变
-
{
-
int middle = left + ((right - left) >> 1); //防止溢出,移位也更高效。同时,每次循环都需要更新。
-
if (array[middle] > value)
-
{
-
right = middle - 1; //right赋值,适时而变
-
}
-
else if(array[middle] < value)
-
{
-
left = middle + 1;
-
}
-
else
-
return middle;
-
//可能会有读者认为刚开始时就要判断相等,但毕竟数组中不相等的情况更多
-
//如果每次循环都判断一下是否相等,将耗费时间
-
}
-
return -1;
-
}
-
-
osi7层协议
-
第7层 应用层(Application Layer)
-
提供为应用软件而设的界面,以设置与另一应用软件之间的通信。例如:HTTP,HTTPS,FTP,TELNET,SSH,SMTP,POP3等。
-
-
第6层 表示层(Presentation Layer)
-
把数据转换为能与接收者的系统格式兼容并适合传输的格式。
-
-
第5层 会话层(Session Layer)
-
负责在数据传输中设置和维护电脑网络中两台电脑之间的通信连接
-
-
第4层 传输层(Transport Layer)
-
把传输表头(TH)加至数据以形成数据报。传输表头包含了所使用的协议等发送信息。例如:传输控制协议义(TCP)等
-
-
第3层 网络层(Network Layer)
-
决定数据的路径选择和转寄,它网络表头(NH)加至数据报,以形成数据包。网络表头包含了网络数据。例如:互联网协议(IP)等,网关,多口网关(路由器)
-
-
第2层 数据链路层(Data link Layer)
-
负责网络寻址、错误侦测和改错。当表头和表尾被加至数据包时,会形成了帧。数据链表头(DLH)是包含了物理地址和错误侦测及改错的方法。数据链表尾(DLT)是一串指示数据包末端的字符串。例如以太网、无线兼容认证券市场(Wi-Fi)和通用分组无线服务(GPRS)等。
-
-
第1层 物理层(Physical Layer)
-
在局部局域网络上传送帧,它负责管理电脑通信设备和网络媒体之间的互通。包括了针脚、电压、线缆规范、集线器、中继器、网卡、主机适配器等。
-
-
TCP/IP协议分为4层,由上至下为应用层、传输层、网络层和网络接口层。
-
应用层:定义上层应用可以直接使用的高级协议,如http、ftp等。
-
传输层:定义控制数据传输的协议,用以保证数据的可靠性和顺序到达性等,如tcp、udp协议。
-
网络层:定义不同网络类型间通信的协议,如IP协议用于实现网际路由,ICMP协议用于检测网络的畅通性,ARP协议用于获取设备MAC地址等。
-
网络接口层:定义网络介质上的传输协议,和电气相关,如Ethernet协议、802.3协议等,主要由操作系统的网卡驱动程序实现。
-
-
网页输入http地址后的过程
-
DNS解析(层层向上,找到ip地址)
-
找到了ip地址后,建立TCP连接
-
发送HTTP请求
-
服务器处理请求并返回HTTP报文
-
浏览器解析渲染页面
-
连接结束
-
-
tcp和udp的区别
-
TCP 是面向连接的,UDP 是面向无连接的
-
UDP程序结构较简单
-
TCP 是面向字节流的,UDP 是基于数据报的
-
TCP 保证数据正确性,UDP 可能丢包
-
TCP 保证数据顺序,UDP 不保证
-
-
tcp如何实现可靠传输
-
自动重传请求(ARQ、平均往返时间)
-
流量控制 (滑动窗口,计时器)
-
拥塞控制(慢启动,拥塞避免)
-
慢启动,每次double,直到门限
-
拥塞避免,每次加一,直到拥塞,然后门限/2,开始慢启动
-
-
-
流量控制和拥塞控制
-
反问
一面
1. 自我介绍
2. 项目和实习经验 ,根据我的回答提了不少问题
3. 微信上线一个新的好友推荐功能功能如何测试
4. 输入url到网页显示出来中间的过程
-
DNS解析(层层向上,找到ip地址)
-
找到了ip地址后,建立TCP连接
-
发送HTTP请求
-
应用层 (客户端发送http请求报文)
-
传输层 (建立TCP连接,三次握手,)
-
网络层 (加入IP)
-
数据链路层 (形成了帧,传输数据)
-
物理层 (物理传输bit)
-
-
服务器处理请求并返回HTTP报文
-
关闭TCP连接,四次挥手
-
浏览器解析渲染页面
-
连接结束
5. dict的底层结构,tuple和list的底层结构的区别(没答上来)
6. C/Python/Java的垃圾回收的机制(没答上来)
JAVA垃圾回收:采用停止-复制、标记-清扫的自适应方法
首先使用停止-复制方法,停止程序,然后将存活的对象,从当前堆复制到另外一个堆,并且是一个一个紧密排列;但是复制过程是两个堆之间来回进行,导致开销极大,并且,可能在程序稳定后,只有少部分垃圾,但是依旧进行停止-复制的话,产生浪费;
因此,标记-清扫方法派上了用场,该方法首先从堆栈和静态区出发,遍历所有引用,找出所有活引用,进行标记;该过程不进行清理,当标记完所有对象之后,开始清理工作,没有标记的对象(垃圾)就会被释放,所以剩下的是不连续的堆空间,如果希望堆连续,垃圾回收器将重新整理堆空间(Python 用的是计数引用回收,每次引用,计数器+1,当计数为0的时候,该变量会被回收)
8. 反问环节,这位面试官人还蛮好的,聊了很多比如测试岗位前途啊或者其他方向比如算法或者软件开发的前途一类的,还问了公司工作环境工作时间一类的
二面
1. 自我介绍(这次居然没有问项目经验)
3. 编程题,鸡兔同笼,一半的兔子伸起一半的脚,输入地上有几只脚,列出所有的可能性(兔子是基数则整除2)
4. 问有没有抓包经历(答用过wireshark),问包的头部有什么,多大(答错了)
1、端口号:用来标识同一台计算机的不同的应用进程。
1)源端口:源端口和IP地址的作用是标识报文的返回地址。
2)目的端口:端口指明接收方计算机上的应用程序接口。
TCP报头中的源端口号和目的端口号同IP数据报中的源IP与目的IP唯一确定一条TCP连接。
2、序号和确认号:是TCP可靠传输的关键部分。序号是本报文段发送的数据组的第一个字节的序号。在TCP传送的流中,每一个字节一个序号。e.g.一个报文段的序号为300,此报文段数据部分共有100字节,则下一个报文段的序号为400。所以序号确保了TCP传输的有序性。确认号,即ACK,指明下一个期待收到的字节序号,表明该序号之前的所有数据已经正确无误的收到。确认号只有当ACK标志为1时才有效。比如建立连接时,SYN报文的ACK标志位为0。
3、数据偏移/首部长度:4bits。由于首部可能含有可选项内容,因此TCP报头的长度是不确定的,报头不包含任何任选字段则长度为20字节,4位首部长度字段所能表示的最大值为1111,转化为10进制为15,15*32/8 = 60,故报头最大长度为60字节。首部长度也叫数据偏移,是因为首部长度实际上指示了数据区在报文段中的起始偏移值。
4、保留:为将来定义新的用途保留,现在一般置0。
5、控制位:URG ACK PSH RST SYN FIN,共6个,每一个标志位表示一个控制功能。
1)URG:紧急指针标志,为1时表示紧急指针有效,为0则忽略紧急指针。
2)ACK:确认序号标志,为1时表示确认号有效,为0表示报文中不含确认信息,忽略确认号字段。
3)PSH:push标志,为1表示是带有push标志的数据,指示接收方在接收到该报文段以后,应尽快将这个报文段交给应用程序,而不是在缓冲区排队。
4)RST:重置连接标志,用于重置由于主机崩溃或其他原因而出现错误的连接。或者用于拒绝非法的报文段和拒绝连接请求。
5)SYN:同步序号,用于建立连接过程,在连接请求中,SYN=1和ACK=0表示该数据段没有使用捎带的确认域,而连接应答捎带一个确认,即SYN=1和ACK=1。
6)FIN:finish标志,用于释放连接,为1时表示发送方已经没有数据发送了,即关闭本方数据流。
6、窗口:滑动窗口大小,用来告知发送端接受端的缓存大小,以此控制发送端发送数据的速率,从而达到流量控制。窗口大小时一个16bit字段,因而窗口大小最大为65535。
7、校验和:奇偶校验,此校验和是对整个的 TCP 报文段,包括 TCP 头部和 TCP 数据,以 16 位字进行计算所得。由发送端计算和存储,并由接收端进行验证。
8、紧急指针:只有当 URG 标志置 1 时紧急指针才有效。紧急指针是一个正的偏移量,和顺序号字段中的值相加表示紧急数据最后一个字节的序号。 TCP 的紧急方式是发送端向另一端发送紧急数据的一种方式。
9、选项和填充:最常见的可选字段是最长报文大小,又称为MSS(Maximum Segment Size),每个连接方通常都在通信的第一个报文段(为建立连接而设置SYN标志为1的那个段)中指明这个选项,它表示本端所能接受的最大报文段的长度。选项长度不一定是32位的整数倍,所以要加填充位,即在这个字段中加入额外的零,以保证TCP头是32的整数倍。
10、数据部分: TCP 报文段中的数据部分是可选的。在一个连接建立和一个连接终止时,双方交换的报文段仅有 TCP 首部。如果一方没有数据要发送,也使用没有任何数据的首部来确认收到的数据。在处理超时的许多情况中,也会发送不带任何数据的报文段。
一面(70min)
sql题:
学生表:id student_id class
成绩表:id student_id score
查询平均成绩大于八十分的同学的姓名和平均成绩
# where 写法
select
student_id,student.sname,avg(num) (要找的东西)
from
score,student(表)
where
score.student_id = student.sid (两个表的交集)
group by
student_id (顺序)
having
avg(num) > 80(条件)
# inner join
select
student_id,student.sname,avg(num)
from
score inner join student on score.student_id = student.sid
group by
student_id
having
avg(num) > 80
查询3班学生的平均成绩(join)
查询所有班的平均成绩
数据库隔离等级及解决了什么问题
-
linux的命令有哪些
-
cat cat 用于在标准输出(监控器或屏幕)上查看文件内容
-
grep grep 在给定的文件中搜寻指定的字符串。grep -i “” 在搜寻时会忽略字符串的大小写,而grep -r “” 则会在当前工作目录的文件中递归搜寻指定的字符串
-
find 这个命令会在给定位置搜寻与条件匹配的文件。你可以使用find -name 的-name选项来进行区分大小写的搜寻,find -iname 来进行不区分大小写的搜寻。
-
tar tar命令能创建、查看和提取tar压缩文件。tar -cvf 是创建对应压缩文件,tar -tvf 来查看对应压缩文件,tar -xvf 来提取对应压缩文件。
-
gzip gzip 命令创建和提取gzip压缩文件,还可以用gzip -d 来提取压缩文件。
-
ps — ProcesseS ps显示系统的运行进程。
-
-
jps和ps的区别
-
jps类似linux的ps命令,不同的是ps是用来显示进程,而jps只显示java进程,准确的说是当前用户已启动的部分java进程信息,信息包括进程号和简短的进程command
-
-
输入cd回车会跳转到哪个目录
-
linux进程的状态
引起进程状态转换的具体原因如下:
NULL—→新建态:执行一个程序,创建一个子进程。
新建态—→就绪态:当操作系统完成了进程创建的必要操作,并且当前系统的性能和虚拟内存的容量均允许。
运行态—→终止态:当一个进程到达了自然结束点,或是出现了无法克服的错误,或是被操作系统所终结,或是被其他有终止权的进程所终结。
终止态—→NULL:完成善后操作。
就绪态—→终止态:未在状态转换图中显示,但某些操作系统允许父进程终结子进程。
等待态(拥塞)—→终止态:未在状态转换图中显示,但某些操作系统允许父进程终结子进程
-
linux进程如何从阻塞跳转到运行
-
1)就绪状态(Ready):
-
进程已获得除处理器外的所需资源,等待分配处理器资源;只要分配了处理器进程就可执行。就绪进程可以按多个优先级来划分队列。例如,当一个进程由于时间片用完而进入就绪状态时,排入低优先级队列;当进程由I/O操作完成而进入就绪状态时,排入高优先级队列。
-
2)运行状态(Running):
-
进程占用处理器资源;处于此状态的进程的数目小于等于处理器的数目。在没有其他进程可以执行时(如所有进程都在阻塞状态),通常会自动执行系统的空闲进程。
-
3)阻塞状态(Blocked): 由于进程等待某种条件(如I/O操作或进程同步),在条件满足之前无法继续执行。该事件发生前即使把处理机分配给该进程,也无法运行。
-
-
说一个你了解的网络分层模型
-
应用层有什么协议
-
http和https的区别
-
Hypertext Transfer Protocol Secure
-
它是从WEB服务器传输超文本标记语言(HTML)到本地浏览器的传送协议。
-
设计HTTP最初的目的是为了提供一种发布和接收HTML页面的方法。
-
-
ssl握手原理,发生在什么时候
-
类似于 TCP 建立连接时的三次握手。 在 TLS 握手的过程中,通信双方交换消息以相互验证,相互确认,并确立它们所要使用的加密算法以及会话密钥 (用于对称加密的密钥)。可以说,TLS 握手是 HTTPS 通信的基础部分。
-
-
Java ArrayList和Linkedlist的区别
-
1.ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。
-
1.ArrayList使用数组存储元素,因此在查询时速度较快,直接返回该位置的元素即可,时间复杂度为O(1);而LinkedList使用双向链表存储元素,在查询时需要从头或者尾遍历至查询元素,时间复杂度为O(n/2);
-
2.还是因为存储方式的问题,ArrayList在插入或者删除时,需要移动插入位置之后的所有元素,因此速度较慢,时间复杂度为O(n)。而LinkedList只需要找到该位置,移动”指针”即可,时间复杂度为O(1)。
-
当你对列表更多的进行查询,即获取某个位置的元素时,应当优先使用ArrayList;当你对列表需要进行频繁的删除和增加,而很少使用查询时,优先使用LinkedList;
-
-
代码题:查询数组中没有重复的数字
-
扫一遍数组,用一个map统计每个元素出现的次数,2)再扫一遍数组,返回第一个计数值为1的
-
-
反问
二面(50min)
自我介绍
项目
问了怎么设计数据库表、怎么进行前后端交互、自己负责的部分提供了什么接口
了解什么数据结构
说一下二叉搜索树
怎么实现二叉搜索树
数组和链表的区别
都有什么链表
单向链表,双向链表以及循环链表
判断链表是否为循环链表
Java基本数据类型
用的最多类是什么
String有什么特性
1、该类不可被继承;2、不可变性(immutable),是线程安全的;
String、StringBuffer、StringBuilder的区别
如果我们的程序是在单线程下运行,或者是不必考虑到线程同步问题,我们应该优先使用StringBuilder类;如果要保证线程安全,自然是StringBuffer。
tcp、udp的区别
输入url到显示页面的过程
介绍一下了解的设计模式
如何实现单例模式
为什么选测开不选开发
职业规划
代码题
最长不重复子串
给写的代码设计测试用例
反问
三面(30min)
自我介绍
项目
为什么选择测开
抖音下滑到下个视频进行测试设计
get、post的区别
-
GET在浏览器回退时是无害的,而POST会再次提交请求。
-
GET产生的URL地址可以被Bookmark,而POST不可以。
-
GET请求会被浏览器主动cache,而POST不会,除非手动设置。
-
GET请求只能进行url编码,而POST支持多种编码方式。
-
GET请求参数会被完整保留在浏览器历史记录里,而POST中的参数不会被保留。
-
GET请求在URL中传送的参数是有长度限制的,而POST么有。
-
对参数的数据类型,GET只接受ASCII字符,而POST没有限制。
-
GET比POST更不安全,因为参数直接暴露在URL上,所以不能用来传递敏感信息。
-
GET参数通过URL传递,POST放在Request body中。
-
GET产生一个TCP数据包;POST产生两个TCP数据包。
-
长的说:
-
对于GET方式的请求,浏览器会把http header和data一并发送出去,服务器响应200(返回数据);
-
而对于POST,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据)。
3、PUT
put请求与post一样都会改变服务器的数据,但是put的侧重点在于对于数据的修改操作,但是post侧重于对于数据的增加。
4、DELETE
delete请求用来删除服务器的资源。
飞机有100个人,下飞机要在机场进行核酸检测,如何缓解机场的压力
飞机有100个人,有一个患有新冠,如何用最少的检测试剂找到这个病人
大学做过最有成就感的事
作者:我就是菠萝屋
链接:https://www.nowcoder/discuss/449981?type=all&order=time&pos=&page=1&channel=-1&source_id=search_all_nctrack
来源:牛客网
1.自我介绍
2.项目
3.TCP和UDP的区别
4.TCP的三次握手,为什么握手是三次,挥手是四次
第一次握手🤝: 客户端向服务器发出连接请求报文,这时报文首部中的同部位SYN=1,同时随机生成初始序列号 seq=x,此时,客户端进程进入了 SYN-SENT状态,等待服务器的确认。
第二次握手🤝: 服务器收到请求报文后,如果同意连接,则发出确认报文。确认报文中应该 ACK=1,SYN=1,确认号是ack=x+1,同时也要为自己随机初始化一个序列号 seq=y,此时,服务器进程进入了SYN-RCVD状态,询问客户端是否做好准备。
第三次握手🤝: 客户端进程收到确认后,还要向服务器给出确认。确认报文的ACK=1,ack=y+1,此时,连接建立,客户端进入ESTABLISHED状态,服务器端也进入ESTABLISHED状态。
它发送了第一个连接的请求报文,但是由于网络信号差或者服务器负载过多,这个请求没有立即到达服务端,而是在某个网络节点中长时间的滞留了,以至于滞留到客户端连接释放以后的某个时间点才到达服务端,那么这就是一个失效的报文,但是服务端接收到这个失效的请求报文后,就误认为客户端又发了一次连接请求,服务端就会想向客户端发出确认的报文,表示同意建立连接。
假如不采用三次握手,那么只要服务端发出确认,表示新的建立就连接了。但是现在客户端并没有发出建立连接的请求,其实这个请求是失效的请求,一切都是服务端在自相情愿
当服务端接收到FIN报文,并返回ACK报文,表示服务端已经知道了客户端要断开连接,客户端已经没有数据要发送了,但是这个时候服务端可能依然有数据要传输给客户端。
当服务端的数据传输完之后,服务端会发送FIN报文给客户端,表示服务端也没有数据要传输了,服务端同意关闭连接,之后,客户端收到FIN报文,立即发送给客户端一个ACK报文,确定关闭连接。在之后,客户端和服务端彼此就愉快的断开了这次的TCP连接。
5.学的什么语言,讲一下java里的jc
根搜索算法(Tracing Collector)
首先了解一个概念:根集(Root Set)
所谓根集(Root Set)就是正在执行的Java程序可以访问的引用变量(注意:不是对象)的集合(包括局部变量、参数、类变量),程序可以使用引用变量访问对象的属性和调用对象的方法。
这种算法的基本思路:
(1)通过一系列名为“GC Roots”的对象作为起始点,寻找对应的引用节点。
(2)找到这些引用节点后,从这些节点开始向下继续寻找它们的引用节点。
(3)重复(2)。
(4)搜索所走过的路径称为引用链,当一个对象到GC Roots没有任何引用链相连时,就证明此对象是不可用的。
Java和C#中都是采用根搜索算法来判定对象是否存活的。
6.Linux了解多少,创建文件夹用什么命令,创建文件用什么命令
7.从数据量很大的数据中如何选取top100,用什么算法
针对top K类问题,通常比较好的方案是分治+Trie树/hash+小顶堆(就是上面提到的最小堆),即先将数据集按照Hash方法分解成多个小数据集,然后使用Trie树活着Hash统计每个小数据集中的query词频,之后用小顶堆求出每个数据集中出现频率最高的前K个数,最后在所有top K中求出最终的top K。
8.如何去测试电梯(这个是在算法问题后面紧跟着问的,我以为是要问我电梯算法)😂
9.最喜欢用的APP,我说的是抖音,然后如果在刷抖音的时候显示连接中断你会怎么去测试是什么原因
10.代码:链表的逆序输出
11.代码:判断回文
一面(2020/4/28 下午):
1h17min
-
自我介绍
-
为什么选择测开?(我回答的有发展前景)
(那你觉得研发和产品设计这些岗位有前景吗?) -
看你实习做的是商业化测试,大概介绍一下做了哪些工作?
(广告投放平台具体有哪些工作和功能?具体介绍一下做过哪个模块的功能测试?投放广告经过了哪些步骤,哪几个步骤是跟你业务这边密切相关的?) -
自动化测试一般在哪些场景?
-
charles抓包的过程?如何实现maplocal的?
-
怼项目(一个低仿微信的社交类安卓app和一个web点餐系统)
(头像如何获取的,怎么传给后端?数据库如何设计的?有几张表、包括哪些属性?web页面在什么时候初始化建立数据库的连接?如何判断数据库中已经有添加的菜名?项目有什么难点?) -
Linux用过哪些命令?说一些。
-
写过shell脚本吗?
-
MySQL用过吗?MySQL和PostgreSQL数据库的区别。
-
简单写一道SQL的题吧:给了两张表,使用连接查询多表;实现一个分组统计。
-
编写测试case:测试微信朋友圈
-
http有哪些请求方法?除了get、post、head还有吗?说一下get和post的区别。
-
浏览器输入www.baidu后发生了什么?
-
反问环节:就完了吗,不用做题吗?(面试官笑了,说后面会有) ;然后还问了一下部门主要做啥的。
(一面完面试官说十分钟后二面。)
二面(2020/4/28 下午):
(二面没来得及录音,凭记忆尽量写一些,时间也是差不多1h+)
-
自我介绍
-
问实习(感觉很久。。)
-
问项目(感觉也很久。。)
-
撕代码:链表成环(leetcode原题)
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){
return false;
}
fast = fast.next.next;
slow = slow.next;
}
return true;
}
}
-
撕代码:给一个rand5,用它来实现rand7(leetcode原题)
-
正确的方法是利用rand5()函数生成1-25之间的数字,然后将其中的1-21映射成1-7,丢弃22-25。例如生成(1,1),(1,2),(1,3),则看成rand7()中的1,如果出现剩下的4种,则丢弃重新生成。
-
public class Test {
-
public int rand7() {
-
int x = 22;
-
while(x > 21) {
-
x = rand5() + (rand5() - 1)*5;
-
}
-
return 1 + x%7;
-
} }
-
-
多态是什么?写一个多态。
-
继承关系中,子类如果定义了一个与父类方法签名完全相同的方法,被称为覆写(Override)。
-
class Person {
-
public void run() {
-
System.out.println("Person.run");
-
}
-
}
-
class Student extends Person {
-
@Override
-
public void run() {
-
System.out.println("Student.run");
-
}
-
}
-
重载 (Overload) 表示同一个类中可以有多个名称相同的方法,但这些方法的参数列表各不相同(即参数个数、类型或顺序不同)。
-
-
写一个多线程,分别用Thread和Runnable实现。
在程序开发中只要是多线程肯定永远以实现Runnable接口为主,因为实现Runnable接口相比继承Thread类有如下好处:
-
避免点继承的局限,一个类可以继承多个接口。
-
适合于资源的共享
-
说一下Runnable和Callable的区别。
-
Linux命令写10个。修改文件权限的命令。
-
– rw- r– r–
-
普通文件 文件主 组用户 其他用户
-
chmod [who] [+ | – | =] [mode] 文件名¼
-
-
测试场景:微信传文件
-
同时收到百度阿里的offer你怎么选?(我哭了,我当然说选字节啊,先不说百度阿里早就已经挂了。。)
-
什么时候能来实习?目前正在进行的实习多久结束?
-
反问环节。(我忘了问的啥了。。)
貌似应该没写全,我记得不太清,因为一面完在等待的时间看了会手机,就退出录音了。。。
(二面之后半个小时左右吧,接到电话说过了,约三面,定在第二天早上10:00。)
三面(2020/4/29 上午):
59min
-
自我介绍
-
问一下你后续的实习安排是如何的?
-
问实习和项目(10min左右)
-
如何对一个表单进行测试?
-
现实场景1:如果一架飞机上面有100个人,下飞机后需要对每个人进行核酸和体温检测,有什么好的办法缓解这种机场的滞留呢?(我说的前置检测过程,利用乘客的自助能力,他说再打开脑洞)
-
现实场景2:飞机上下来100个旅客,最多可能一个人检测成阳性,你觉得最少用多少个试剂盒可以把这个可能是阳性的人找出来?(用二分查找)
-
现实场景3:飞机上下来100个旅客,有10个人是阳性,如何把这10个人找出来?
-
你在大学期间做过最有成就感的事情是什么?(我作死答了微积分满分,然后他问什么窍门什么经验。。)
-
同龄人中你最佩服的是谁?为什么?你觉得自己比他做得好的地方在哪?
-
个人的职业发展是怎么考虑的?
-
反问环节:问了下部门主要工作内容,面试官讲了大概五分钟左右吧。
(三面结束十分钟左右接到电话说三面过了,然后约在下午3:00进行hr面。)
hr面(2020/4/29 下午):
19min
-
自我介绍
-
确认了一下部门和岗位
-
对三位面试官的评价如何?对哪位印象最深刻?(说真的字节的面试体验不要太好!面试官十分亲切,不时还微笑,很多紧张和尴尬的时刻都被化解了,赞👍!)
-
为什么选择测开?
-
说说你的优势和劣势
-
别人对你的负面评价是什么?你觉得客观吗?
-
大学期间遇到的最艰难的时光是什么?如何渡过的?
-
最后口头答应offer,说最快在五一前审批下来(楼主听到时都要激动得哭了呜呜呜)
字节跳动测试开发复盘
11月15一面 58分钟
自我介绍
项目(说不足、说架构)
数据结构、稳定性、复杂度、细讲其中一个排序算法
计算机网络八股文(Url请求流程、TCP与UCP、OSI七层模型)
操作系统(忘了问啥了)
手撕算法(判断是否为有效的连续数组 Leetcode改编)
反问
11月19日 二面 58分钟
自我介绍
项目(大概说一下自己做了哪些)
数据库(B+树及其优势、索引)
create index id_name_subject on teacher(name, subject);
(1)B+树空间利用率更高,可减少I/O次数,
一般来说,索引本身也很大,不可能全部存储在内存中,因此索引往往以索引文件的形式存储的磁盘上。这样的话,索引查找过程中就要产生磁盘I/O消耗。而因为B+树的内部节点只是作为索引使用,而不像B-树那样每个节点都需要存储硬盘指针。
也就是说:B+树中每个非叶节点没有指向某个关键字具体信息的指针,所以每一个节点可以存放更多的关键字数量,即一次性读入内存所需要查找的关键字也就越多,减少了I/O操作。
e.g.假设磁盘中的一个盘块容纳16bytes,而一个关键字2bytes,一个关键字具体信息指针2bytes。一棵9阶B-tree(一个结点最多8个关键字)的内 部结点需要2个盘快。而B+ 树内部结点只需要1个盘快。当需要把内部结点读入内存中的时候,B 树就比B+ 树多一次盘块查找时间(在磁盘中就 是 盘片旋转的时间)。
(2)增删文件(节点)时,效率更高,
因为B+树的叶子节点包含所有关键字,并以有序的链表结构存储,这样可很好提高增删效率。
(3)B+树的查询效率更加稳定,
因为B+树的每次查询过程中,都需要遍历从根节点到叶子节点的某条路径。所有关键字的查询路径长度相同,导致每一次查询的效率相当。
更多推荐
字节跳动 测试开发面经
发布评论