面试复盘 | 华为软测一二主管面
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; } }#华为##笔经##面经#