某厂后端研发实习(可转正)面试

0.简述

​ 面试流程,大概如下:先是40分钟的笔试编程题,面试官给出3个编程题,让我现场进行编程,至少完成其中一道,无IDE,用的是视频对话的网页自带的检查器(貌似只能检查出基本类型拼写错误及补全括号等基础书写问题)。编程题目如下图

在这里插入图片描述

编程题时间到之后面试官会提醒(我太菜了,一题没做出来),问我要再继续做,还是讲下我的思路。我选择讲下我的思路(毕竟还差不少才能写出一题来QAQ),面试官听完我的思路后也没再说什么。

​ 然后就是开始正式的面试,首先做个简短自我介绍,之后面试官让我简单介绍一下我的项目情况,再轻描淡写地问了我的团队项目的实现原理。再后来开始问我一些基础核心知识。

​ 首先,问的是数组和链表的优缺点,这个我答的还可以,然后问我 Java 里面有哪些容器是用链表实现的,这个我没答上来。再来就是问了我 Java 里面的Map是怎样的结构,其查询效率又如何。之后又问了我排序算法都知道哪些(我说了冒泡、归并、快排、桶排序、基数排序等),再问了我这些算法时间复杂度比较低的是哪些(快排和归并),分别是多少(都是 nlogn ),再让我仔细讲一下快排是怎么实现的(我忘记了 orz ),再然后,问了我二叉搜索树是怎么样的数据结构(每个结点的值大于左子节点的值,小于或等于右子结点的值),二叉搜索树的查询效率是多少(这个我忘了 orz ,我懵了个 nlogn )。

​ 再来就问了一下数据库的知识,问我学的什么数据库(MySQL),然后又问我引擎用的是什么(这个我也答不上 orz ,我甚至到没听过这个概念,后来听面试官说 InooDB ,我才想起一点)。然后让我讲一下什么是ACID属性(我答得踉踉跄跄,并不好, orz ),然后举例问我,假如数据库里存有某商品的库存,现在查询到这个数据,并执行减一的操作,这整个操作过程有什么问题吗?(我答得不是太好,大概说了一下事务的一致性原理)面试官又问我怎么解决这个问题(我回答加锁),面试官继续追问,怎么加锁,技术上具体如何实现(我就被问倒了,后来面试官说直接加线程锁是不行,因为它不是内存里的东西,我后知后觉才明白是数据库的存储过程,果然我数据库还菜比 orz )。

​ 大概整个面试过程就这么多,后面面试官提问结束后,会询问我还有什么问题,我就再跟面试官简单聊了几句(毕竟太菜了,没脸接着聊了),然后就结束了。整个过程大概85分钟左右。

1.笔试(1)

​ 第一道笔试题应该采用动态规划来解决比较合适。
在这里插入图片描述
d [ i ] [ j ] d[i][j] d[i][j]为使用 arr 中(arr已按从小到大的顺序排列)前 i 种零钱,找的零钱为 j 的组合方式的种数。

d [ i ] [ j ] = ∑ k = 0 j / d [ i ] d [ i − 1 ] [ j − k ∗ d [ i ] ] d[i][j] = \sum_{k=0}^{j/d[i]} d[i-1][j-k*d[i]] d[i][j]=k=0j/d[i]d[i1][jkd[i]],即第 i 种有以下选择:可以不用、可以用1个、可以用2个、…、可以用 j / d[ i ] 个。

初始化则为: d [ i ] [ 0 ] = 1 ; d [ 0 ] [ j ] = 0 ; d[i][0] = 1; d[0][j] = 0; d[i][0]=1;d[0][j]=0; 即 凑成0元只有一种方法,也就是不用任何一种零钱;用前0种零钱凑成 j( j ≠ 0) 元的方法,为0种,因为前0种零钱即没有零钱。

    public static void dynamic_prommgram(int[] arr,int n){
   
        int[][] d = new int[arr.length+1][n+1];//length+1表示不适用任何币种、只使用1、只使用1 2 只使用1 2 3......等等,共length+1种情况,且n+1表示总计0、1.....至n元共n+1种情况
        for(int i = 0;i<=arr.length;i++) d[i][0] = 1;
        for(int i = 1 ;i<=arr.length;i++){
   //因为d[0][i]是0,所以i从1开始
            for(int j = 1;j<=n;j++){
   //由于d[i][0]==1,所以j从1开始
                for(int k=0;k<=j/arr[i-1];k++){
   //例如,使用面值为1时,对应的coins[]下标是i-1,逻辑上和实际上不是一致的
                    d[i][j] +=d[i-1][j-k*arr[i-1]];
                }
            }
        }
        System.out.println(d[arr.length][n]);
    }

再将这段代码中的二元数组简化为一元数组即可。

    public int solution(int[] arr, int n){
   
        int[] d = new int[n+1];
        d[0] = 1;
        for (int i = 0; i < arr.length ;i++) {
   
            for (int j = arr[i]; j <= n; j++) {
   
                d[j] += d[j - arr[i]];
            }
        }
        int result = d[n];
        return result;
    }

2.笔试(2)

​ 第二道题是股票最大利润问题。
在这里插入图片描述
首先是只买一次的情况。

只要记录前面的最小价格,将这个最小价格作为买入价格,然后将当前的价格作为出售价格,查看当前收益是不是最大利益。

    public int solution(int[] prices){
   
        if (prices.length == 0)
            return 0;
        int min = prices[0];
        int max = 0;
        for (int i = 1; i < prices.length; i++) {
   
            if (prices[i] < min)
                min = prices[i];
            else
                max = Math.max(max, prices[i] - min);
        }
        return max;
    }

然后是在日期不重叠的情况下卖买多次的最大利润。

对于prices[ i ] > prices[ i-1 ], 那么就可以进行一次卖买,即把prices[ i ] - prices[ i-1 ] 加入到收益当中,因为我们可以昨天买入,今天卖出,若明天价更高的话,还可以今天买入,明天卖出。以此类推,遍历完整个数组后即可求得最大利润。

    public int solution2(int[] prices){
   
        int profit = 0;
        for (int i = 1; i < prices.length; i++) {
   
            if (prices[i] - prices[i-1] > 0)
                profit += prices[i] - prices[i-1];
        }
        return  profit;
    }

3.笔试(3)

​ 第三道题是36进制求和。
在这里插入图片描述
​ 这道题相对来说简单点,可以考虑将‘0’ - ‘9’,‘a’ - ‘z’存储到List中,index是0-35为其对应的数字。定义一个StringBuilder,将每一位的计算 结果利用append方法加入其中,最后再用reverse方法倒转过来即可,注意最后要先检查进位temp是否为0,如果不为0,则需要再append字符‘1’,再倒转。

import java.util.Arrays;
import java.util.List;

public class Main {
   
    static Character[] nums = {
   '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};
    static List<Character> list = Arrays.asList(nums);

    public String solution(String num_a,String num_b){
   
        String result = new String();
        char[] n1 = num_a.toCharArray();
        char[] n2 = num_b.toCharArray();
        int i = num_a.length()-1;
        int j = num_b.length()-1;
        int temp = 0;
        StringBuilder stringBuilder = new StringBuilder();
        while(i >= 0 || j >=0){
   
            if (i >=0 && j >= 0){
   
                char c1 = n1[i];
                char c2 = n2[j];
                int index1 = list.indexOf(c1);
                int index2 = list.indexOf(c2);
                int sum = index1 +index2 + temp;
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值