上海柏楚笔试题

上海柏楚感知算法实习生 笔试题

考试总共100分钟,17题,还是挺紧张的。

后续联系HR,得到可能同学方向和我们业务方向不够匹配,没法继续推进流程的回复,已凉凉。

1. 论述题 (14*3)

  1. 一个数组 [4, 8, 6, 2, 5, 9, 1, 7, 3, 10],用一个 1*5 的中值滤波器滤波后的结果(边界补0)。

我的答案:[4, 4, 5, 6, 5, 5, 5, 7, 7, 7]
gemini答案:[4, 4, 5, 6, 5, 5, 5, 7, 3, 3]
补0后的数组:[0, 0, 4, 8, 6, 2, 5, 9, 1, 7, 3, 10, 0, 0]

  1. 相机手眼标定

相机安装在机械臂末端,在机械臂移动过程中随着机械臂一起运动。
eye_in_hand
有以下几种坐标系:

  • B:机械臂基座坐标系
  • E:机械臂末端执行器坐标系
  • C:相机坐标系
  • M:标定板坐标系
    有已下几种变换矩阵:
  • $T_{BE}$:机械臂基座坐标系到机械臂末端执行器坐标系的变换矩阵(可以通过正运动学求解得到)
  • $T_{BM}$:机械臂基座坐标系到标定板坐标系的变换矩阵(这两个都不会动)
  • $T_{CM}$:相机坐标系到标定板坐标系的变换矩阵

求:

  • $X$:机械臂末端执行器坐标系到相机坐标系的变换矩阵(4分)
  • 求解 $AX = BX$,并给出 A 和 B 的计算方法(10分)

我的答案(只知道要用上这三个变换):

1
2
1. $T_{CE} = T_{BE} * T_{BM}^{-1} * T_{CM}$
2. 没写

标准答案直接参考解析:
相关解析:https://develop.realman-robotics.com/AI/developerGuide/hand/

  1. resnet 的残差连接 和 ViT 的位置编码的作用? 训练效率和数据需求方面有哪些差异?
    我的答案(大概):
1
2
3
4
1. 残差连接可以解决多层非线性模型难以学习线性关系的问题,残差连接公式 $ x = x + res(x)$ (这里当时想成代码实现逻辑了,不是数学公式)。
ViT 的位置编码来源于transformer模型,通过把embedding后的词向量加上不同频率的正余弦编码,使得不同位置信息流动路径复杂度 `O(1)`。(只回答了transformer的位置编码的作用,ViT不会捏)

2. resnet 一般层数与参数量比ViT少,较容易训练,收敛速度更快,数据需求相对较少。

gemini 答案:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
**1. ResNet 残差连接 (Residual Connection)**

* **作用**
* **解决梯度消失/爆炸**:在深层网络中,梯度反向传播时容易变得非常小(消失)或非常大(爆炸)。残差连接 $y = F(x) + x$ 允许梯度直接通过恒等映射(Identity Mapping)传导到浅层,相当于搭建了“高速公路”,使得训练深层网络(如上百甚至上千层)成为可能。
* **打破网络退化**:理论上深层网络不应比浅层差(至少可以学成恒等映射),但实际中深层网络往往更难优化。残差结构让模型更容易学习到恒等映射(只需让 $F(x) \rightarrow 0$),从而保证加深网络层数时性能不会下降。
* **集成学习视角**:残差网络可以看作是许多不同深度路径的浅层网络的集成(Ensemble),增强了模型的鲁棒性。

**2. ViT 位置编码 (Position Encoding)**

* **作用**
* **注入序列顺序信息**:Transformer 的核心 Self-Attention 机制具有排列不变性(Permutation Invariant),即打乱输入 token 的顺序,输出结果(除了顺序变化)数值上是一样的。对于图像 Patch 序列来说,空间位置关系至关重要。位置编码通过将位置信息(绝对位置或相对位置)加到(或拼接到)输入 Embedding 上,让模型能够区分不同 Patch 的空间位置。
* **保持空间结构**:帮助模型理解图像的 2D 结构(如左上角、右下角、相邻关系等),弥补了 CNN 固有的归纳偏置(Inductive Bias,如平移不变性和局部性)在 Transformer 中的缺失。

**3. 训练效率与数据需求的差异**

* **训练效率**
* **ResNet**:由于引入了归纳偏置(卷积核的局部感受野和权值共享),ResNet 收敛速度通常较快,优化难度相对较低,在中小规模数据集上也能快速达到较好的效果。
* **ViT**:由于缺乏归纳偏置,ViT 需要从头学习像素间的长距离依赖和空间关系,训练初期收敛较慢,且对优化器(如 AdamW)和超参数(如 Learning Rate Warmup)更敏感。
* **数据需求**
* **ResNet**:对数据量的依赖相对较小,在 ImageNet-1k(128万张图)甚至更小的数据集上就能训练得很好。
* **ViT**:通常被认为是“数据饥渴”的(Data Hungry)。在中小数据集上容易过拟合,性能往往不如 ResNet。只有在超大规模数据集(如 JFT-300M, ImageNet-21k)上预训练后,ViT 的性能优势才能充分体现,超越 ResNet。

2. 选择题 (4*2 + 2*10)

  1. 下列关于数据结构的说法中,正确的是( )多选
    A. 数组随机访问复杂度 O(1)
    B. 二叉搜索树中序遍历的时间复杂度为 O(n)
    C. 忘了
    D. 哈希表的查找复杂度为 O(log n)
    我的答案:ABC(应该是对的)
    gemini答案:AB

  2. RANSAC 算法的说法中,正确的是( )单选
    A. 采样的次数越多,模型越准确
    B. 阈值
    C. 每次迭代都使用最小点集来拟合模型
    D. 单次拟合可以拟合出多个平面
    我的答案:A
    gemini答案:C

  3. 88 正方体 由若干11 正方体构成 表面涂色的块数( )单选
    A. 296
    剩下忘了都是300+
    我的答案:A
    gemini答案:A

  4. 仓库运来含水量为90%的一种水果100千克.一星期后再测,发现含水量降低到80%.现在这批水果的质量是__千克 单选
    A. 40kg
    B. 50kg
    C. 80kg
    D. 90kg
    我的答案:B
    gemini答案:B
    相关解析:https://qb.zuoyebang.com/xfe-question/question/a78e2d0d714e35752ef11d225e11166f.html

  5. 1000瓶饮料,3个瓶子可以再换一瓶,一共可以喝多少瓶?(不能另外再借瓶子) 单选
    A. 1333
    B. 1494
    C. 1499
    D. 1500
    我的答案:C
    gemini答案:C
    相关解析:https://www.nowcoder.com/questionTerminal/2569018b80044c4fab95b4d6752fbccf

  6. 12*5 = 61 在几进制下成立( )单选
    A. 7进制
    B. 8进制
    C. 9进制
    D. 10进制
    我的答案:C
    gemini答案:C

  7. 200个数冒泡排序200ms, 800ms 能排多少数?单选
    A. 200
    B. 400
    C. 600
    D. 800
    我的答案:B
    gemini答案:B

  8. 4对(), 能组成多少对字符串() 单选
    A. 5
    B. 10
    C. 12
    D. 14
    我的答案:B(简单枚举了一下)
    gemini答案:D

  9. 一个圆随机画两条弦,求两条弦相交的概率 单选
    A. 1/2
    B. 1/3
    C. 1/4
    D. 1/6
    我的答案:A(随便选了,来不及算)
    gemini答案:B
    https://blog.csdn.net/wwxy1995/article/details/108206111

  10. 彼此痛恨的甲、乙、丙三个枪手准备决斗。甲枪法最好,十发八中;乙枪法次之,十发六中;丙枪法最差,十发四中。如果三人同时开枪,并且每人只发一枪;谁活下来的机会大一些? 单选
    A. 甲
    B. 乙
    C. 丙
    D. 三人机会相等
    我的答案:D
    gemini答案:C
    https://blog.csdn.net/raojunyang/article/details/82291975

  11. 某家饭店中,一桌人边用餐边谈生意其中,一个人是哈尔滨人,两个人是北方人,一 个人是广东人,两个人只做电脑生意,三个人只做服装生意。如果以上介绍涉及餐桌上所有 的人,那么这一桌最少可能是几个人?最多可能是几个人?
    A.最少可能是 3 人;最多可能是 8 人。
    B.最少可能是 5 人,最多可能是 8 人。
    C.最少可能是 5 人,最多可能是 9 人。
    D.最少可能是 3 人,最多能是 9 人。
    我的答案:B
    gemini答案:B
    相关解析:https://wenku.baidu.com/view/7e6a22d60d22590102020740be1e650e52eacfd1.html?_wkts_=1766941582650

  12. 给甲、乙、丙三人各发一个正整数,并告诉他们他们三人的数字之和为14。
    甲对乙和丙说:我知道你们两人的数字一定不相等。
    乙想了想,对甲说:我们两人的数字之差一定比丙大。
    丙听完甲和乙的话后,依旧沉默不语。
    若甲乙丙三人都很聪明,且只要他们能推断出三人的数字分别是什么,那个人会在第一时间说出。(不考虑甲、乙见到丙沉默之后是否知晓)
    那么,丙的数字是多少? () 单选
    A. 1
    B. 2
    C. 3
    D. 4
    我的答案:A
    gemini答案:A
    相关解析:https://www.33iq.com/question/92507.html

gemini解析:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
*正确答案应该是 A。**

以下是详细的逻辑推导过程:

**1. 分析甲(A)的话:**
* **条件**:$a + b + c = 14$,且 $a, b, c$ 都是正整数。
* **甲说**:“我知道你们两人的数字一定不相等。” ($b \neq c$)
* **推断**:甲知道 $a$,也就知道 $b+c = 14-a$。如果 $14-a$ 是偶数,那么 $b$ 和 $c$ 有可能相等(例如 $14-a=12$,则可能 $b=c=6$)。甲既然**敢肯定** $b \neq c$,说明 $b=c$ 的情况根本不可能发生。这意味着 $b+c$ 必须是奇数。
* **结论 1**:$14-a$ 是奇数 $\Rightarrow$ **$a$ 必须是奇数** ($1, 3, 5, 7, 9, 11$)。

**2. 分析乙(B)的话:**
* **乙说**:“我们两人的数字之差一定比丙大。” ($|a - b| > c$)
* **推断**:乙听了甲的话,知道 $a$ 是奇数。乙知道自己的数 $b$。乙敢肯定 $|a-b| > c$,说明对于**所有**满足条件的奇数 $a$,这个不等式都成立。
* 代入 $c = 14 - a - b$,不等式变为 $|a - b| > 14 - a - b$。
* 我们来测试 $b$ 的可能值(已知 $a$ 为奇数):
* 若 $b=7$:$a=1 \Rightarrow c=6, |1-7|=6 \ngtr 6$ (不成立)。
* 若 $b=8$:
* $a=1 \Rightarrow c=5, |1-8|=7 > 5$ (成立)
* $a=3 \Rightarrow c=3, |3-8|=5 > 3$ (成立)
* $a=5 \Rightarrow c=1, |5-8|=3 > 1$ (成立)
* (注意 $a$ 不能是 7,因为 $a$ 是奇数且 $a+b<14$)。
* 所以 $b=8$ 是可能的。
* 同理验证,$b=9, 10$ 也是可能的。
* 若 $b=11$:$a$ 只能是 1 ($c=2$)。此时乙能直接推断出 $a=1, c=2$。根据题目“只要他们能推断出...会在第一时间说出”,乙应该直接说“我知道了”,而不是说“差比丙大”。所以 $b \neq 11$。同理 $b \neq 12$。
* **结论 2****$b$ 的值只能是 8, 9, 10**

**3. 分析丙(C)的沉默:**
* **现象**:丙听完后依旧沉默。
* **推断**:丙知道 $c$,也知道 $a$ 是奇数,$b \in \{8, 9, 10\}$。如果丙能根据自己的 $c$ 唯一确定一组 $(a, b)$,他就会说话。**丙沉默说明对于他的 $c$,至少有两组 $(a, b)$ 符合条件。**

**4. 验证选项:**

* **选项 B ($c=2$):**
* 已知 $a+b = 12$。
* 限制条件:$a$ 是奇数,$b \in \{8, 9, 10\}$。
* 可能的组合:
* 若 $b=8 \Rightarrow a=4$ (偶数,不符)
* 若 $b=9 \Rightarrow a=3$ (奇数,符合) $\rightarrow$ 组合 $(3, 9, 2)$
* 若 $b=10 \Rightarrow a=2$ (偶数,不符)
* **结果**:如果 $c=2$,只有唯一解 $(3, 9, 2)$。丙会立即知道答案并说出来。**但这与“丙沉默”矛盾。所以 $c \neq 2$。**

* **选项 A ($c=1$):**
* 已知 $a+b = 13$。
* 限制条件:$a$ 是奇数,$b \in \{8, 9, 10\}$。
* 可能的组合:
* 若 $b=8 \Rightarrow a=5$ (奇数,符合) $\rightarrow$ 组合 $(5, 8, 1)$
* 若 $b=9 \Rightarrow a=4$ (偶数,不符)
* 若 $b=10 \Rightarrow a=3$ (奇数,符合) $\rightarrow$ 组合 $(3, 10, 1)$
* **结果**:如果 $c=1$,存在两组解 $(5, 8, 1)$ 和 $(3, 10, 1)$。丙无法区分是哪一组,所以会保持沉默。**这与题目描述相符。**

**结论:**
根据严格的逻辑推理,**正确答案应该是 A (1)**

3. lc算法题(15*2)

  1. 压缩字符串
    参数给的是字符串类型的,返回也要求字符串类型。
    题目要求返回压缩后的字符串,没法压缩的返回原字符串。但没给数据量的范围。。。
    面试官要求必须用cpp解决,不能自行添加测试样例,但允许调试代码
    (测试框架用的googleTest,cout的输出在终端好像也看不见。。)

case1 input:

1
aaacbb

output:

1
a3c1b2

赛场代码 感觉加一个特判就能解决?也是傻逼了,过了2/3个hidden case:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
class Solution {
public:
string compressString(string arg1)
{
string ans = "";
char x = arg1[0];
int cnt = 1;
bool hasCompressed = false;
for(int i = 1; i < arg1.size(); i++)
{
if(arg1[i] == x)
{
cnt++;
}
else
{
ans += x;
// 这里当时写了一个while循环处理了多位数,不知道测评是什么环境不敢用to_string
// string num = "";
// while(cnt > 0)
// {
// num = (char)(cnt % 10 + '0') + num;
// cnt /= 10;
// }
// ans = ans + num;
ans += to_string(cnt);

x = arg1[i];
cnt = 1;
}
}
if(cnt > 0)
{
ans += x;
ans += to_string(cnt);
}
return ans;
}
};

标准答案:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Solution {
public:
string compressString(string arg1) {
string compressed = "";
int count = 1;
bool hasCompression = false;
for (int i = 1; i <= arg1.size(); ++i) {
if (i < arg1.size() && arg1[i] == arg1[i - 1]) {
count++;
hasCompression = true;
} else {
compressed += arg1[i - 1];
compressed += to_string(count);
count = 1;
}
}
return hasCompression ? compressed : arg1;
}
};
  1. 稀疏向量的点积

需要写完整的程序,包括输入输出。输入都给cpp了,肯定就得写cpp了。
只给了一个案例的输入:

1
2
vector<pair<int, double> > v1 = {{0, 1.0}, {2, 2.0}, {4, 3.0}};
vector<pair<int, double> > v2 = {{1, 4.0}, {2, 3.0}, {4, 4.0}};

需要实现的函数:

1
double sparseVectorDotProduct(vector<pair<int, double>> v1, vector<pair<int, double>>v2);

初始框架:

1
2
3
4
5
6
7
8
9
#include <iostream>
#include <vector>
#include <utility>
using namespace std;

int main()
{
return 0;
}

赛场代码(双指针,写的复杂了点):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#include <iostream>
#include <vector>
#include <utility>
using namespace std;

typedef vector<pair<int, double>> vpid;

double sparseVectorDotProduct(vpid v1, vpid v2) {
double result = 0.0;
if (v1.empty() || v2.empty())
return result;
int v1_ptr = 0, v2_ptr = 0;
int pos1, pos2;
while (v1_ptr < v1.size() && v2_ptr < v2.size()) {
if(pos1 == v1.size())
pos1 = -1;
else
pos1 = v1[v1_ptr].first;
if(pos2 == v2.size())
pos2 = -1;
else
pos2 = v2[v2_ptr].first;

if (pos1 == pos2) {
result += v1[v1_ptr].second * v2[v2_ptr].second;
v1_ptr++; // 这里之前差点忘记加了,导致程序一直卡在这
// v2_ptr++; // 这里赛场上没有加,其实可以加
} else if (pos1 < pos2) {
v1_ptr++;
} else {
v2_ptr++;
}
}
return result;
}

int main()
{
frepoen("input.txt", "r", stdin);
int n, m;
cin >> n >> m;
// 提前初始化,防止segmentation fault
vector<pair<int, double> > v1(n), v2(m);
for(int i = 0; i < n; i++)
cin >> v1[i].first >> v1[i].second;
for(int i = 0; i < m; i++)
cin >> v2[i].first >> v2[i].second;
double result = sparseVectorDotProduct(v1, v2);
cout << result << endl;
return 0;
}

双指针精简版:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
double sparseVectorDotProduct(vpid v1, vpid v2) {
double result = 0.0;
int i = 0, j = 0;
while (i < v1.size() && j < v2.size()) {
if (v1[i].first == v2[j].first) {
result += v1[i].second * v2[j].second;
i++;
j++;
} else if (v1[i].first < v2[j].first) {
i++;
} else {
j++;
}
}
return result;
}
  • Copyright: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.
  • Copyrights © 2022-2026 CPY
  • Visitors: | Views:

请我喝杯咖啡吧~

支付宝
微信