阿里云弹性计算ECS暑期实习
一面--2.6
1.介绍你所知道的常用的时间复杂度
2.解释每一个数据结构的意义,在什么场景中使用?
3.每个数据结构查找与插入的时间复杂度
4.讲一个你所熟知的技术?
5.kv存储项目中初始化的耗时?
6.怎么确定每一个桶的最后一个数据?
7.编程题:
//5 个 1 - 100 的整数
// 输出前面 4 个数通过加法的 1 个或者多个等于第 5 个数的组合
// 例如 1,1,1,1,3 ===> 1,1,1
// 1,2,3,4,10 ====> 1,2,3,4
// 如果没有,输出空。
提问:时间复杂度能优化到2^n-1以下吗
思路:深度优先搜索遍历每一种情况,可以通过剪枝进行优化
import java.util.Deque;
import java.util.LinkedList;
import java.util.List;
import java.util.Scanner;
public class test02_2 {
public static List<List<Integer>> res;
public static int currretnSum;
public static Deque<Integer> path;
public static int cnt;
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int[] nums = new int[5];
for(int i = 0;i<5;i++){
nums[i] = in.nextInt();
}
List<List<Integer>> res = targetSum(nums);
for(List<Integer> temp : res){
for(int t : temp){
System.out.print(t + " ");
}
System.out.println();
}
System.out.println("时间复杂度为:"+cnt);
}
public static List<List<Integer>> targetSum(int[] nums){
res = new LinkedList<>();
currretnSum = 0;
path = new LinkedList<>();
cnt = 0;
int target = nums[4];
dfs(0,target,nums);
return res;
}
public static void dfs(int k, int target,int[] nums){
for(int i = k;i<4;i++){
cnt++;
currretnSum += nums[i];
path.addLast(nums[i]);
if(currretnSum == target){
res.add(new LinkedList<>(path));
}
//剪枝优化
if(currretnSum>target){
currretnSum -= nums[i];
path.removeLast();
return;
}
dfs(i+1,target,nums);
currretnSum -= nums[i];
path.removeLast();
}
}
}
二面--2.8
1.聊一下研究生的研究方向?
2.讲一下秒杀项目
3.redis如何mysql保证一致
注:这里应该指的是缓存的读写策略
- 读策略:在读取是先读取缓存,如果命中则直接返回,如果未命中,则访问数据库然后回填到数据库中
- 写策略:先更新数据库,然后输出缓存中的数据。
4.如何压测,压测的结果,了解Jmter的原理吗?
5.如何体现该系统的高并发?
6.限流适用什么做的?
7.手写令牌桶算法的介绍?
8.滑动时间窗口算法如何设计,谈下你的实现思路?
9.数据库:id,age,性别三个字短,查出age>20性别是男的记录,sql是应该怎么写?
10.数据表的索引应该怎么设计?
11.联合索引中age与性别的先后顺序?
这个应该回答有误,正确答案应该是联合索引讲性别字段放前面,因为联合索引要符合最左匹配原则,最左匹配原则遇到范围查找会失效,原因是接下来的第二个字段不是局部有序的,无法利用二分查找继续优化,所以会将满足第一个条件的所有情况进行回表(但有索引下伸优化,会以o(n)的时间复杂度比较第二个字段),如果将性别放在前面,则查到性别为男的所有索引,第二个字段age是有序排列的。
重点:联合索引遇到范围查找失效,范围查找后的字段无法继续匹配。
12.你最近看的书?
13.一门新语言比如rust应该怎么学?
14.未来的规划?
最近面试遇到的算法题;
1.设计一个运算器
力扣227--基本计算器2
2.
如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值,那么中位数就是所有数值排序之后位于中间的数值。如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。我们使用Insert()方法读取数据流,使用GetMedian()方法获取当前读取数据的中位数。
堆排序,大顶堆和小顶堆才是最优算法
(堆排序)
让数组的前半部分为大顶堆,需要最大值。后半部分为小顶堆,需要最小值
偶数是两边数目一样,取大顶堆的最大值和小顶堆的最小值的平均
奇数时,使右边边数目多一个,直接取小顶堆的最小值即可
由于左边的所有值都小于右边的。所以想往左边插入,则需先插入到右边的小顶堆,之后再弹出个最小的加到左边。反之亦然
import java.util.PriorityQueue;
import java.util.Comparator;
public class Solution {
PriorityQueue<Integer> min_heap=new PriorityQueue<>();
PriorityQueue<Integer> max_heap=new PriorityQueue<>(new Comparator<Integer>(){
@Override
public int compare(Integer o1,Integer o2){
return o2-o1;//默认是小顶堆,o1-o2
}
});
int count=0;//记录已获取数字的个数
public void Insert(Integer num) {
if(count%2==0){
max_heap.offer(num);
int tmp=max_heap.poll();
min_heap.offer(tmp);
}
else{
min_heap.offer(num);
int tmp=min_heap.poll();
max_heap.offer(tmp);
}
count++;
}
public Double GetMedian() {
if(count%2==0){
return new Double(min_heap.peek()+max_heap.peek())/2;
}
else{
return new Double(min_heap.peek());
}
}
}

浙公网安备 33010602011771号