【Java校招面试】实战面经(十一)


前言

“实战面经”是本专栏的第二个部分,本篇博文是第十一篇博文,是博主本人在某度公司的实战面经,如有需要,可:

  1. 点击这里,返回本专栏的索引文章
  2. 点击这里,返回上一篇《【Java校招面试】实战面经(十)》
  3. 点击这里,前往下一篇《【Java校招面试】面试中常考的手撸算法题》

一、编程语言部分

1. 讲一下Java的HashMap
包括的点有:
  1) HashMap的底层数据结构: Node数组,初始长度16,在初始化延迟到put中,调用resize实现。
  2) 怎么找对应的桶: 取hash值然后对cap取模
  3) 三种情况如何应对: 桶里没Node、桶里有普通Node、桶里有TreeNode
  4) 链表长度达到8之后调用TreeifyBin变成红黑树;
  5) 如果发现了Key已存在,用新Value替换老的Value;
  6) 如果长度到达临界值,需要resize,resize会调用rehash,把过程说清,还有临界值等于factory * cap,factory默认是0.75。

2. 如何将Key和Value插入到红黑树,即HashMap只要求键是一个Hashable就可以了,红黑树插入的时候要进行比较,拿什么比较?

先对Key求其哈希值hash,然后用hash值去比较。

3. 平时用过什么Java的内部类?Java中有哪些种类的内部类?
  1) 我答了一个ScheduledThreadPoolExecutor类中的内部类DelayedWorkQueue,当时想通过自定义线程池,调用这个类,发现它不是公有的,就调用失败了。

  2) 内部类有:
    a) 匿名内部类
    b) 具名内部类:
      i) 成员内部类
      ii) 静态内部类
      iii) 局部内部类。

4. 你刚刚说调用非公有的内部类失败了,有什么方法可以调用它?反射是怎么实现的?Class.forName做了什么?
  1) 调用非公有的内部类失败了可以使用反射,可以通过setAccessable(true)来修改访问权限,就可以调用它了。
  2) 通过ClassLoader类加载器实现的。
  3) 通过传入的类完全限定名,去寻找类的.class文件,然后将类的字节码加载进JVM供调用。


二、数据库部分

1. MySQL中可以实现索引的数据结构?说说B树和B+树的区别?B树和B+树一定是平衡的吗?
  1) 哈希表和B+树;
  2) B+树的非叶子节点只包含索引信息不包含记录,索引的记录更加密集。所有的叶子节点通过链表相连,便于范围查询。
  3) B树和B+树都是自平衡的,所以是一定平衡的。

2. 数据库都有哪些范式?分别都有什么约束
  有1NF、2NF、3NF和BCNF,一般情况下达到3NF即可

  1) 1NF: 字段不可再分,即不允许出现组合字段,如身高和体重的拼接字符串
  2) 2NF: 非主属性必须完全依赖于候选键,如一个表的主键是字段A和B的组合键,而字段C通过字段B就可以唯一标识。
  3) 3NF: 消除传递依赖,即任何非主属性不依赖于非主属性。

3. 数据库有哪些隔离级别,分别解决了什么问题?
  1) READ_UNCOMMITED: 什么都解决不了
  2) READ_COMMITED: 解决了脏读问题
  3) REPEATABLE_READ: MySQL通过MVCC多版本并发控制解决了不可重复读和幻象读的问题。

4. 有了上述的隔离级别,还要SERIALIZABLE干什么?
  原因: REPEATABLE_READ下仍有可能发生幻读

  举例: A事务读取了表,没提交,然后B事务插入了一条记录X,A事务对X进行了Update,它就可以看到新插入的记录X了,还是会幻读。

  SERIALIZABLE线性化,解决一切并发问题。


三、算法部分

题目: 给你一个数组base表示一年中第几天会出差(如{1, 20, 21, 23, 40, 355}),以及一个定长为3的数组cost,表示买1天票、7天票和30天票的价格(如{2, 7, 15},注意,不一定天数越短,票价越便宜),求最优买票策略下的最少花费。

动态规划,状态转移方程:
f(n) = min(f(n - 1) + cost[0], f(n - 7) + cost[1], f(n - 30) + cost[2]);

代码如下:
  1) 解题函数

    public static int solve(int[] travelDaysOfYear, int[] costOfTickets){
        int[] dp = new int[365];
        int minCost = 0, lastDay = 0;
        for (int travelDayOfYear: travelDaysOfYear){
            Arrays.fill(dp, lastDay, travelDayOfYear, minCost);
            lastDay = travelDayOfYear;
            minCost = getMinCost(dp, costOfTickets, travelDayOfYear);
        }
        return minCost;
    }

  2) 求加上第n天之后最小票价的函数

    private static int getMinCost(int[] dp, int[] costOfTickets, int day){
        int oneDayTicket = (day - 1 >= 0? dp[day - 1] : 0) + costOfTickets[0];
        int SevenDayTicket = (day - 7 >= 0? dp[day - 7] : 0) + costOfTickets[1];
        int ThirtyDayTicket = (day - 30 >= 0? dp[day - 30] : 0) + costOfTickets[2];
        return oneDayTicket < SevenDayTicket? (oneDayTicket < ThirtyDayTicket?
                oneDayTicket: ThirtyDayTicket):(SevenDayTicket < ThirtyDayTicket?
                SevenDayTicket:ThirtyDayTicket);
    }

四、简历中的项目

1. Transformer和RNN、LSTM的区别是什么?

Transformer 和 RNN(循环神经网络,包括 LSTM 和 GRU 等变体)都是用于处理序列数据的深度学习模型。尽管它们都可以处理一些类似的任务,但它们的架构和工作原理有很大差异,下面概述了这些主要区别:

RNN (循环神经网络):

  1) RNN 通过一个内部循环单元自然地处理序列数据,可以捕获输入序列中的顺序依赖关系。

  2) RNN 是串行(顺序)计算的。在处理序列时,先计算当前时间步的状态,然后将其作为输入传递给下一个时间步。因此,长序列上的训练和推理过程可能会相对较慢。

  3) RNN 通常在处理长时依赖关系方面会遇到困难,尤其是在训练过程中可能出现梯度消失的问题。LSTMGRU 通过引入特殊的门结构来减轻这个问题,使得它们能够捕获长序列中的依赖关系。

Transformer:

  1) Transformer 架构完全摒弃了循环和卷积结构,依赖于自注意力(self-attention)机制来捕获序列中的依赖关系。

  2) Transformer 的计算过程是并行的,而非顺序的。自注意力机制可以同时计算序列中所有成对的词之间的关系,因此在处理长序列时具有更高的计算效率。

  3) Transformer 的缺点在于其难以捕捉序列中的局部结构,因为它将所有位置看作是等距的。为了弥补这个缺陷,Transformer 引入了位置编码(position encoding),它将位置信息添加到输入序列中,以解决模型捕捉序列顺序方面的问题。

总结起来,RNN(包括 LSTM 和 GRU)和 Transformer 都能处理序列数据,但 Transformer 具有更高的计算效率,并能有效地捕捉长序列中的依赖关系。在处理诸如翻译、文本生成、摘要等任务时,Transformer 通常优于 RNN。但是,在某些任务(如需要对时间步进行建模的时序预测任务)上,RNN 可能是更自然的模型选择。

2. 语料库处理都做什么?用户自定义的变量名会破坏词嵌入,如何处理?
  1) 语料库做去除注释、函数抽取、语法过滤等操作。
  2) 使用Sentence Piece就不需要做变量名替换了。

3. 词嵌入用的是字符还是Token?为什么不用抽象语法树?
  1) 我们用的切词方法既不是字符级别也不是Token级别,使用的工具是谷歌的Sentence Piece,使用它之前需要先用语料库进行训练,然后根据训练出的模型来分词。它的训练过程实际上做了类似于统计词频的工作。

  2) 因为Tansformer词语词之间是平级的,每两个词之间的距离都是1,都会计算他们的关联度,但是抽象语法树这种树形结构具有父子上下级关系不适合放在Transformer中,使用图网络的时候可以使用抽象语法树进行词嵌入。

4. RNN和Transformer在Encoder和Decoder上的区别?

TransformerEncoderDecoderRNN的多了多头注意力,每一个头都能学到不同的权重,权重叠加起来会比单头注意力或者没有注意力的Transformer学习到的此相关信息更加准确。

5. GPT与Transformer的区别和联系
  1) GPT使用Transformer作为特征提取器。
  2) GPT采用的是单向的语言模型,只采用单词的上文来进行预测,而抛开了下文。这也是GPT的缺点。

6. GPT-2和GPT的区别
  1) 把第二阶段的Fine Tune做有监督地下游NLP任务,换成了无监督地做下游任务,即不做Fine Tune。
  2) 扩大了Transformer的规模。


后记

这是一份我自己的实战面经。题目虽然不多,八股部分常规回答即可,但是动态规划这种编程题,如果不是很熟练,十分钟想不出算法怎么写,基本就会挂掉。所以平时有机会,有时间还是要多练习。不过考算法考到这种题的企业不算多数。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IMplementist

你的鼓励,是我继续写文章的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值