【模拟面试】计算机考研复试集训(第五天)
文章目录
- 前言
- 一、专业面试
- 1、如何理解同步通信和异步通信?
- 2、进程的调度算法有哪些?
- 3、简述三级封锁协议
- 4、你了解transformer吗?
- 5、准备一下中文介绍
- 6、你为什么选择我们学校?
- 二、英文口语
- 1、Introduce youself
- 2、How do you plan to apply your undergraduate knowledge to your graduate studies in computer science?
- 三、算法上机
- 1、因数分解
- 2、拆分链表
前言
今天是模拟面试系列第五天,为大家精心准备了 4 道专业课面试题,2 道综合面试题,2 道英语口语题,2 道算法上机题。
涵盖复试中常见的考察点,助你从容应对考官提问!
一、专业面试
1、如何理解同步通信和异步通信?
同步通信 :
- 定义 :发送方发出请求后,必须等待接收方响应才能继续执行(阻塞式)。
- 特点 :逻辑简单,但效率低,可能因等待导致资源浪费。
- 示例 :HTTP 同步请求、数据库事务的 ACID 操作。
异步通信 :
- 定义 :发送方发出请求后,无需等待响应即可继续执行(非阻塞式)。
- 特点 :高并发、高效率,但需通过回调、事件或消息队列处理结果。
- 示例 :AJAX 异步请求、消息队列(如 Kafka、RabbitMQ)。
2、进程的调度算法有哪些?
常见调度算法包括:
- 先来先服务(FCFS) :按到达顺序分配CPU,简单但可能造成“护航效应”。
- 短作业优先(SJF) :优先调度预计运行时间短的进程,减少平均等待时间。
- 时间片轮转(RR) :每个进程分配固定时间片,时间到则切换,适用于分时系统。
- 优先级调度 :为进程分配优先级,优先级高的先执行(可能导致饥饿)。
- 多级反馈队列(MFQ) :设置多个优先级队列,进程根据行为动态调整队列。
3、简述三级封锁协议
三级封锁协议用于数据库事务并发控制,解决数据不一致问题。
一级封锁协议 :
- 措施 :事务对数据加写锁(X锁),直到事务结束才释放。
- 解决 :丢失修改(Lost Update)问题。
二级封锁协议 :
- 措施 :在一级基础上,读操作前加读锁(S锁),读完立即释放。
- 解决 :读脏数据(Dirty Read)问题。
三级封锁协议 :
- 措施 :读操作加S锁,直到事务结束才释放。
- 解决 :不可重复读(Non-Repeatable Read)问题。
4、你了解transformer吗?
我对 Transformer 有一定的了解。Transformer是一种基于自注意力机制(Self-Attention)的深度学习模型。它的核心思想是通过注意力机制捕捉输入序列中不同位置之间的依赖关系,从而替代传统的循环神经网络(RNN)和卷积神经网络(CNN)。
Transformer的主要特点包括:
- 自注意力机制 :通过计算每个词与其他词的相关性(注意力权重),动态地关注全局信息,尤其擅长处理长距离依赖问题。
- 并行计算 :与RNN的串行计算不同,Transformer可以并行处理序列数据,显著提升训练效率。
- 位置编码 :由于模型本身不具备序列顺序信息,通过添加位置编码(Positional Encoding)引入位置特征。
在应用方面,Transformer 是当前自然语言处理(NLP)领域的核心技术,例如 BERT、GPT 等预训练模型均基于 Transformer 架构。此外,它也被扩展到计算机视觉领域(如Vision Transformer)。
5、准备一下中文介绍
无模板,自己按照简历来说!
6、你为什么选择我们学校?
选择贵校主要有三方面原因:
- 第一,贵校在人工智能的学术声誉和科研实力深深吸引了我 。
- 第二,贵校的培养模式与资源平台非常符合我的发展需求 。
- 第三,贵校的学术氛围和校园文化让我感到亲切 。
二、英文口语
1、Introduce youself
无模板,根据自己的中文部分转一下,建议中英文自我介绍都准备一下。
2、How do you plan to apply your undergraduate knowledge to your graduate studies in computer science?
您打算如何将您本科阶段所学的知识运用到计算机科学的研究生学习当中呢?
During my undergraduate studies, I gained a solid foundation in programming, algorithms, and data structures, which I plan to build upon in my graduate studies. I aim to apply this knowledge to explore advanced topics like machine learning and distributed systems, focusing on solving real-world problems through innovative research and practical projects.
在本科阶段,我在编程、算法和数据结构方面打下了坚实的基础,我计划在研究生阶段以此为基础,进一步探索机器学习和分布式系统等高级领域,专注于通过创新研究和实际项目解决现实问题。
三、算法上机
1、因数分解
从键盘输入任意一个大于等于 2 的自然数 m
,将 m
写成所有数因子乘积的形式。
例如:
- 若输入:13,则你的输出应该是:13 = 13,
- 若输入:420,则你的输出应该是:420 = 22357
代码实现
#include <bits/stdc++.h>
using namespace std;
// 将 m 表示为质因数的乘积
void func(int m) {
// 从最小的质数2开始分解
for (int i = 2; i * i <= m; i++) {
while (m % i == 0) { // 如果 i 是 m 的因子
printf("%d", i); // 输出当前因子
m /= i; // 将 m 除以当前因子
}
}
// 如果 m 本身是质数,直接输出
if (m > 1)
printf("%d", m);
}
int main() {
int m;
scanf("%d", &m);
func(m);
return 0;
}
2、拆分链表
编写一个算法将一个带头结点的单链表 A 分解成两个单链表 A 和 B,使得 A 链表中含有原链表 A 中序号
为奇数的元素,而 B 链表中含有原链表 A 中序号为偶数的元素,且保持原来的相对顺序。
代码实现
#include <bits/stdc++.h>
using namespace std;
typedef struct Node {
int data;
struct Node *next;
}LNode, *LinkList;
// 创建链表
LinkList createList(int arr[], int n) {
LinkList head = (LinkList)malloc(sizeof(LNode));
head->next = NULL;
LNode* tail = head;
// 尾插法创链表
for (int i = 0; i < n; i++) {
LNode* newNode = (LNode*)malloc(sizeof(LNode));
newNode->data = arr[i];
newNode->next = NULL;
tail->next = newNode;
tail = newNode;
}
return head;
}
// 打印链表
void PrintList(LinkList head) {
LNode* cur = head->next;
while (cur) {
printf("%d->", cur->data);
cur = cur->next;
}
printf("NULL");
}
// 拆分链表
void func(LinkList head, LinkList *a, LinkList* b) {
// 为 A 申请头结点
LNode* A = (LNode*)malloc(sizeof(LNode));
A->next = NULL;
// 为 B 申请头结点
LNode* B = (LNode*)malloc(sizeof(LNode));
B->next = NULL;
LNode *curP = head->next,
*auxP; // 工作指针
int oe = 1; // 控制奇偶的变量
while (curP != NULL) {
auxP = curP->next;
if (oe % 2 == 0) { // 偶数放到 B 中
curP->next = B->next;
B->next = curP;
}
else { // 奇数放到 A 中
curP->next = A->next;
A->next = curP;
}
curP = auxP;
oe++;
}
*a = A;
*b = B;
}
void freeList(LinkList head) {
while (head != NULL) {
LNode* curP = head;
head = head->next;
free(curP);
}
}
int main() {
int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
int n = sizeof(arr) / sizeof(arr[0]);
// 创建原链表
LinkList head = createList(arr, n);
PrintList(head);
// 拆分链表
LinkList a, b;
func(head, &a, &b);
cout << endl;
// 打印
PrintList(a);
cout << endl;
PrintList(b);
// 释放资源
freeList(head);
return 0;
}