面试复盘 | 华为软测一二主管面
timeline
笔试 7.28
专业面两面 9.14
主管面 9.15
一面 65min
- 自我介绍
- 项目
- 为什么采用分层架构
- 面向对象还是面向过程
- 了解Spring cloud吗?
- 撕题给20min:leetcode 1702
- 怎么理解测试工程师?
- 职业规划
- 怎么测试登录功能
- 测试知识了解哪些
- 有看书吗?(建议买纸质书。。
直接说等下一轮面试,5min后发短信开始二面
二面 50min
- 自我介绍
- 做题可以选代码题也可以选测试知识,给20min。选了代码题leetcode 1091变形
- 怎么理解测试工程师
- 测试知道哪些
- 怎么测试一个杯子
(有没说全的面试官还进行了补充,态度很好,一直说我们讨论一下这个blabla - 反问
直接说等下一轮面试,10min后发短信通知通过。晚上收到第二天主管面邀请。
三面 15min
最无语的一次面试。。没有问研究课题也没有问论文
- 自我介绍
- 通信专业为什么想做测试?
(回答涉及到对软件测试的理解,面试官直接打断说华为的测试不是这样的blabla,那明明上两面就能反驳我了为啥没有呢
然后面试官就开始了diss环节,非科班,代码能力不足,不懂微服务。。。(因为没有很强烈的意愿去华为所以一直微笑面对)
以为无了10min后收到通过短信,所以不知道是前两面面评很糟糕还是三面是个压力面,又或者泡池子了泡到捞不起来吧。。anyway
整个面试无复盘笔试无八股,准备了的复盘就放在这里吧。。
笔试复盘
第一题
M台服务器包含属性:
编号、CPU核数、内存、CPU架构、是否支持NP加速
根据资源分配要求分配N台满足要求的服务器。资源分配要求为:CPU核数 ≥ cpuCount,内存 ≥ memSize,CPU架构 = cpuArch,是否支持显卡=supportNP。
分配时同时会指定优选级策略strategy,策略如下:
策略1:CPU优先。最接近分配要求的cpuCount,memSize其次。
策略2:内存优先。最接近分配要求的memSize,cpuCount其次。
输入
第一行为服务器数量M台
接下来M行为M台服务器属性的数组
紧接下一行为分配要求:最大分配数量N,分配策略strategy,cpuCount,memSize,cpuArch,supportNP
需要注意的是cpuArch使用9表示所有CPU架构都满足分配要求,supportNP为2时表示不论是否支持NP卡都满足分配要求。
输出
先输出实际分配数量,后按分配的服务器编号从小到大依次输出
样例
请在这里输入引用内容
输入:
2
0,2,200,1,0
1,3,400,2,1
2 2 3 300 3 2
输出:
0
思路
基于面向对象的思想,将服务器建为一个类,属性包含主要的id,cpuCount,memSize。
对于不同的分配策略建立两种堆,分别为CPU优先和内存优先。基于资源分配要求将输入的服务器加入堆中,输出先确定结果,再将堆中的sid输出。
代码
import java.util.*;
public class Main0728 {
static PriorityQueue<Server> queue;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int M = sc.nextInt();
sc.nextLine();
int[][] CPU = new int[M][5];
for(int i = 0; i < M; i++){
String[] str = sc.nextLine().split(",");
CPU[i][0] = Integer.parseInt(str[0]);
CPU[i][1] = Integer.parseInt(str[1]);
CPU[i][2] = Integer.parseInt(str[2]);
CPU[i][3] = Integer.parseInt(str[3]);
CPU[i][4] = Integer.parseInt(str[4]);
}
int[] target = new int[6];
for(int i = 0; i < 6; i++){
target[i] = sc.nextInt();
}
//建立最小堆,分为策略1和2来建立。
if(target[1] == 1){
queue = new PriorityQueue<>((o1, o2)->{
if(o1.cpuCnt == o2.cpuCnt){
if(o1.memSize == o2.memSize){
return o1.sid - o2.sid;
}
else return o1.memSize - o2.memSize;
}else{
return o1.cpuCnt - o2.cpuCnt;
}
});
}
else if(target[1] == 2){
queue = new PriorityQueue<>((o1, o2)->{
if(o1.memSize == o2.memSize){
if(o1.cpuCnt == o2.cpuCnt){
return o1.sid - o2.sid;
}
else return o1.cpuCnt - o2.cpuCnt;
}else{
return o1.memSize - o2.memSize;
}
});
}
//将符合规定的入堆
for(int i = 0; i < M; i++){
if(CPU[i][1] >= target[2] && CPU[i][2] >= target[3] && (target[4] == 9 ||
CPU[i][3] == target[4]) && (target[5] == 2 || CPU[i][4] == target[5])){
queue.add(new Server(CPU[i][0], CPU[i][1], CPU[i][2]));
}
}
//合格的结果
int n = Math.min(queue.size(), target[0]);
int[] res = new int[n];
for(int i = 0; i < n; i++){
res[i] = queue.poll().sid;
}
Arrays.sort(res);
System.out.print(n);
for(int i = 0; i < n; i++){
System.out.print(" " + res[i]);
}
}
public static class Server{
public int sid;
public int cpuCnt;
public int memSize;
public Server(int sid, int cpuCnt, int memSize){
this.sid = sid;
this.cpuCnt = cpuCnt;
this.memSize = memSize;
}
}
} 第二题
陈大侠服药,m个药方需要全部服用完才能治愈,但一天内不能同时服用超过n种药方。药方之间有依赖关系,二维数组[1,3],[2,3],[3,4]表示3必须在1、2之后服用,4必须在3之后服用。药方编号从1到m,有依赖关系的药方不能在同一天服用,不然有副作用。不存在药方循环依赖。
最短需要多少天服完药?
输入
总药方m
每天最大喝药数量n
依赖组数z
依赖项1
…
依赖项z
输出
最短天数
样例
请在这里输入引用内容
输入:
8
2
6
2 1
3 1
4 2
1 5
6 7
7 8
输出:
4
解释:
第一天吃3、4号,第二天吃2、6号,第三天吃1、7号,第四天吃5、8号,最快需要4天。
思路
拓扑排序。用map存储依赖的指向关系,int数组存储被依赖数(入度)。
建立一个队列,把没有依赖点的节点放入队列。
在队列中还有顶点的条件下while循环,将弹出节点的依赖次数-1,如果为0,入队列。
for循环的次数即是吃药的次数,也就是循环多少次使队列为空。
代码
import java.util.*;
public class Main08292 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in),
int m = sc.nextInt();
int n = sc.nextInt();
int z = sc.nextInt();
int[][] input = new int[z][2];
//记录指向关系
Map<Integer, List<Integer>> map = new HashMap<>();
//记录被依赖数,入度数组
int[] count = new int[m];
for(int i = 0; i < z; i++){
input[i][0] = sc.nextInt();
input[i][1] = sc.nextInt();
int key = input[i][0];
int val = input[i][1];
count[val - 1]++;
if(map.containsKey(key - 1)){
map.get(key - 1).add(val - 1);
}else {
List<Integer> list = new ArrayList<>();
list.add(val - 1);
map.put(key - 1, list);
}
}
int res = 0;
Queue<Integer> queue = new LinkedList<>();
for (int i = 0; i < m; i++){
//没有依赖点的放入堆中
if(count[i] == 0)
queue.add(i);
}
while(!queue.isEmpty()){
//每次取出的节点数
int min = Math.min(queue.size(), n);
for(int i = 0; i < min; i++){
int t = queue.poll();
if(map.containsKey(t)){
List<Integer> l = map.get(t);
for (int j = 0; j < l.size(); j++){
count[l.get(j)]--;
if(count[l.get(j)] == 0)
queue.add(l.get(j));
}
}
}
res++;
}
System.out.println(res);
}
} 第三题
同leetcode980
思路
回溯。
代码
class Solution {
int pathLen = 2;
int res = 0;
public int uniquePathsIII(int[][] grid) {
int r = grid.length;
int c = grid[0].length;
int x = 0, y = 0;//起始位置
for(int i = 0; i < r; i++){
for(int j = 0; j < c; j++){
if(grid[i][j] == 1){
x = i;
y = j;
}
else if(grid[i][j] == 0) pathLen++;
}
}
boolean[][] visited = new boolean[r][c];
backtracking(grid, x, y, visited, 1);
return res;
}
public void backtracking(int[][] grid, int x, int y, boolean[][] visited, int len){
if(isValid(x, grid.length, y, grid[0].length) || grid[x][y] == -1 || visited[x][y]) return;
//结束条件
if(grid[x][y] == 2){
if(len == pathLen){
res++;
}
return;
}
visited[x][y] = true;
backtracking(grid, x + 1, y, visited, len + 1);
backtracking(grid, x, y + 1, visited, len + 1);
backtracking(grid, x - 1, y, visited, len + 1);
backtracking(grid, x, y - 1, visited, len + 1);
visited[x][y] = false;
}
public boolean isValid(int x, int r, int y, int c){
if(x < 0 || x >= r || y < 0 || y >= c)
return true;
return false;
}
} #华为##笔经##面经#
