MSC面试试题

0x00 背景

为加入MSC(中山大学互联网与开源技术协会)做的几个面试题

第一次开发这么多东西

社团意在传承我社团多年来的技术积淀,促进计算机学院培养具有互联网技术精神的人才,同时促进相关先进技术的交流并激发同学们的学习兴趣。开源技术与开源精神在当代计算机相关领域发展活动中有着举足轻重的作用,我们将结合自身实践,引导同学们基于开源平台进行协作和开源贡献,了解开源的意义和参与开源的方式并从中受益

0x01 个人卡片

1.1 题目

请根据以下HTML结构,实现一个简单的个人简介卡片页面。要求使用CSS进行样式设计,需包含以下几点:

  1. 卡片背景颜色设置为浅灰色
  2. 卡片的宽度为300px,高度为400px,且在页面居中显示
  3. 卡片顶部放置一个圆形头像(图像内容随意),头像直径100px,并居中显示
  4. 在头像下方,显示你的姓名,字体加粗,字号为20px
  5. 在姓名下方,显示用户简介(随便写),文字颜色为灰色,行高为1.5
  6. 使用CSS实现卡片的阴影效果

请在 styles.css 文件中编写相应的CSS样式,使上述HTML结构实现题目描述的效果

  • 使用CSS选择器来选择元素并应用样式
  • 使用marginpadding属性来调整元素之间的间距 ( 外边距 内边距 )
  • 使用box-shadow属性来实现阴影效果
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
# 1
background-color: #f7f7f7;

# 2
width: 300px;
height: 400px;
align-items: center;

# 3
border-radius: 50%;

width: 100px;
height: 100px;
border-radius: 50%;
object-fit: cover;

# 4
font-size: 20px;
font-weight: bold;

# 5
color: #666;
line-height: 1.5;
text-align: center;

# 6
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);

1.2 HTML

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>个人简介卡片</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<div class="card">
<img src="avatar.jpg" alt="头像" class="avatar">
<h1 class="name">CH0ico</h1>
<p class="description">这里是用户的简介,介绍用户的兴趣爱好和专业技能等信息。</p>
</div>
</body>
</html>

同级目录补充一张头像

1.3 外部样式表

1.3.1 插入

源码已给出

1
2
3
<head>
<link rel="stylesheet" type="text/css" href="mystyle.css">
</head>

1.3.2 CSS

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
/* styles.css */
body {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 10px;
background-color: #e0e0e0;
}

.card {
background-color: #f7f7f7;
width: 300px;
height: 400px;
display: flex;
flex-direction: column;
align-items: center;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
border-radius: 8px;
overflow: hidden;
}

.avatar {
width: 100px;
height: 100px;
border-radius: 50%;
object-fit: cover;
margin-top: 20px;
}

.name {
font-size: 20px;
font-weight: bold;
margin-top: 20px;
color: #333;
font-family: monospace;
}

.description {
color: #666;
line-height: 1.5;
text-align: center;
margin-top: 10px;
padding: 0 20px;
font-family: monospace;
}

0x02 计算器

2.1 题目

请根据以下提供的HTML结构和部分JavaScript代码,补全JavaScript部分,实现⼀个简单的计算器功能

计算器需要⽀持以下功能:

1
2
3
4
5
1. 数字键 0-9 的输⼊
2. 基本的四则运算 +, -, *, /
3. 清空 (C) 按钮,⽤于清空当前输⼊
4. 退格键,⽤于删除最后⼀个字符
5. 等于号 (=),⽤于计算当前表达式并显⽰结果
1
2
3
4
5
可以使⽤ eval函数来执⾏字符串形式的数学表达式

实际上计算我们⼈类看到的数学表达式需要使⽤中缀表达式

注意处理异常情况,如⾮法输⼊或除零错误

2.1 HTML

html需要为button加class

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
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>简单计算器</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<div class="calculator">
<input type="text" id="display" disabled>
<div class="keys">
<button class="key">7</button>
<button class="key">8</button>
<button class="key">9</button>
<button class="key">/</button>
<button class="key">4</button>
<button class="key">5</button>
<button class="key">6</button>
<button class="key">*</button>
<button class="key">1</button>
<button class="key">2</button>
<button class="key">3</button>
<button class="key">-</button>
<button class="key">C</button>
<button class="key">0</button>
<button class="key">=</button>
<button class="key">+</button>
<button class="key">CE</button>
</div>
</div>
<script src="script.js"></script>
</body>
</html>

2.2 JS

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
// 获取元素
const display = document.getElementById('display');
const keys = document.querySelectorAll('.key');

// 添加事件监听器到每个按钮
keys.forEach(key => {
key.addEventListener('click', () => {
const keyValue = key.textContent;

if (keyValue === 'C') {
// 清空输入
display.value = '';
} else if (keyValue === 'CE') {
// 退格
display.value = display.value.slice(0, -1);
} else if (keyValue === '=') {
try {
// 计算并显示结果
const result = eval(display.value);
if (result === Infinity) {
display.value = '除零错误喵';
} else {
display.value = result;
}
} catch (error) {
// 处理非法输入
display.value = '输入错误喵';
}
} else {
// 添加输入到显示框
display.value += keyValue;
}
});
});

2.3 CSS

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
53
body {
font-family: Arial, monospace;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
background-color: #f0f0f0;
}

.calculator {
background: white;
border-radius: 8px;
box-shadow: 0 0 20px rgba(0, 0, 0, 0.2);
padding: 20px;
width: 300px;
}

#display {
width: 100%;
height: 40px;
margin-bottom: 10px;
text-align: right;
font-size: 1.5em;
border: 1px solid #ccc;
border-radius: 4px;
padding: 5px;
}

.keys {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 10px;
}

.key {
padding: 20px;
font-size: 1.5em;
border: none;
border-radius: 4px;
background-color: #007BFF;
color: white;
cursor: pointer;
transition: background 0.3s;
}

.key:hover {
background-color: #0056b3;
}

.key:active {
background-color: #003f7f;
}

0x03 新闻展示

3.1 题目

请根据以下提供的HTML结构和JSON数据,实现⼀个简单的新闻展示页面

要求使⽤Bootstrap进⾏样式设计,并使用JavaScript解析JSON数据,将新闻标题、摘要和链接展示在页面上

1
2
3
4
5
6
7
1. 需要在js中访问news.json来读取,不能直接复制json内容到js内

2. 使⽤Bootstrap的⽹格系统将每个新闻项显⽰在单独的列中

3. 每个新闻项使⽤Bootstrap的卡⽚组件进⾏展⽰

4. 使⽤JavaScript解析提供的JSON数据,并将新闻标题、摘要和链接动态添加到HTML中

下载 Bootstrap · Bootstrap v5 中文文档 v5.3 | Bootstrap 中文网 (bootcss.com)

有几个库先下载到本地

3.2 HTML

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
<div class="col-md-4 mb-4">
<div class="card">
<div class="card-body">
<h5 class="card-title">Python(ML)面试资料</h5>
<p class="card-text">前言 我们面向大三及以上同学, 开设 Python (ML) 方向 本次考核将涉及机器学习、深度学习、强化学习、算子开发四个方面,考察四个方面的入门知识和基础实践能力</p>
<a href="https://www.sysumsc.cn/interviewMaterials/11.html" class="btn btn-primary">阅读更多</a>
</div>
</div>
</div>
<div class="col-md-4 mb-4">
<div class="card">
<div class="card-body">
<h5 class="card-title">如何正确使用AI大模型</h5>
<p class="card-text">介绍 往往新手使用ai时会遇到诸多问题,比如不知道一些好用的插件,提示写的比较烂模型不遵循指令等等 本篇文章从ai写文章,ai写代码两个方面科普大模型的使用方法</p>
<a href="https://www.sysumsc.cn/tech/10.html" class="btn btn-primary">阅读更多</a>
</div>
</div>
</div>
<div class="col-md-4 mb-4">
<div class="card">
<div class="card-body">
<h5 class="card-title">C++ 面试资料</h5>
<p class="card-text">前言 我们面向大一或大二同学,开设 C++ 编程方向 我们不希望考察课内已经学过的经典 C/C++,而是更注重考察大家接触较少的 Modern C++作为一门与时俱进的语言,除了课内学过的基础用法外,Modern C++ 还有很多新的特性,例如模板元编程可以在编译期就玩出很多花样</p>
<a href="https://www.sysumsc.cn/interviewMaterials/9.html" class="btn btn-primary">阅读更多</a>
</div>
</div>
</div>
<div class="col-md-4 mb-4">
<div class="card">
<div class="card-body">
<h5 class="card-title">Web编程面试资料</h5>
<p class="card-text">前言 我们面向各个年级同学,开设 Web 编程方向 致敬本社 Web 大神 xy3,整个 MSC 官网都由他搭建</p>
<a href="https://www.sysumsc.cn/interviewMaterials/7.html" class="btn btn-primary">阅读更多</a>
</div>
</div>
</div>

0x04 SQL

4.1 题目

1
2
3
使⽤SQLite作为数据库后端,实现⼀个简单的⽤⼾注册与登录系统

可以选择使⽤Python或PHP或者其他你熟悉的后端语⾔来完成
1
2
3
4
5
6
7
8
9
10
11
12
13
user表

id
username
email
password

CREATE TABLE users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
username TEXT UNIQUE,
email TEXT UNIQUE,
password TEXT
);
1
2
3
4
5
6
7
8
9
10
11
1. ⽤⼾注册⻚⾯:
提供⽤⼾名、邮箱、密码的输⼊框
验证输⼊的⽤⼾名和邮箱是否唯⼀
将注册信息存⼊数据库,并返回注册成功或失败的消息
2. ⽤⼾登录⻚⾯:
提供⽤⼾名和密码的输⼊框
验证输⼊的⽤⼾名和密码是否匹配数据库中的记录
成功登录后,显⽰欢迎信息;失败则显⽰错误消息
3. ⽤⼾主⻚
显⽰⽤⼾名字
未登录则不可以访问,会跳转到登录⻚⾯
1
2
3
4
数据库使⽤较为简单的slite3 users.db

如果选择使⽤PHP,请确保在 php.ini ⽂件中启⽤了SQLite3扩展:
extension=sqlite3

4.2 后端

1
2
3
4
5
6
/project_directory
├── db.php
├── register.php
├── login.php
├── dashboard.php
└── logout.php

4.3 创建数据库

1
2
3
4
5
6
CREATE TABLE user (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50) NOT NULL UNIQUE,
email VARCHAR(100) NOT NULL UNIQUE,
password VARCHAR(255) NOT NULL
);

4.4 后端开发

db.php — 数据库连接

创建一个名为 db.php 的文件,包含数据库连接代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
$host = 'localhost'; // 数据库主机
$db = 'users'; // 数据库名
$user = 'your_db_username'; // 数据库用户名
$pass = 'your_db_password'; // 数据库密码

try {
$pdo = new PDO("mysql:host=$host;dbname=$db;charset=utf8", $user, $pass);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
echo 'Connection failed: ' . $e->getMessage();
}
?>

register.php — 用户注册

创建一个名为 register.php 的文件,实现用户注册功能:

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
<?php
session_start();
require 'db.php';

if ($_SERVER["REQUEST_METHOD"] == "POST") {
$username = $_POST['username'];
$email = $_POST['email'];
$password = password_hash($_POST['password'], PASSWORD_DEFAULT);

// 检查用户名和邮箱是否唯一
$stmt = $pdo->prepare("SELECT * FROM user WHERE username = ? OR email = ?");
$stmt->execute([$username, $email]);
if ($stmt->rowCount() > 0) {
echo "用户名或邮箱已被使用";
} else {
// 插入用户信息
$stmt = $pdo->prepare("INSERT INTO user (username, email, password) VALUES (?, ?, ?)");
if ($stmt->execute([$username, $email, $password])) {
echo "注册成功!";
} else {
echo "注册失败,请重试";
}
}
}
?>

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>注册页面</title>
</head>
<body>
<h2>注册</h2>
<form method="POST">
<input type="text" name="username" placeholder="用户名" required>
<input type="email" name="email" placeholder="邮箱" required>
<input type="password" name="password" placeholder="密码" required>
<button type="submit">注册</button>
</form>
</body>
</html>

login.php — 用户登录

创建一个名为 login.php 的文件,实现用户登录功能:

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
<?php
session_start();
require 'db.php';

if ($_SERVER["REQUEST_METHOD"] == "POST") {
$username = $_POST['username'];
$password = $_POST['password'];

// 查询用户
$stmt = $pdo->prepare("SELECT * FROM user WHERE username = ?");
$stmt->execute([$username]);
$user = $stmt->fetch(PDO::FETCH_ASSOC);

if ($user && password_verify($password, $user['password'])) {
$_SESSION['user_id'] = $user['id'];
$_SESSION['username'] = $user['username'];
header("Location: dashboard.php");
exit();
} else {
echo "用户名或密码错误";
}
}
?>

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>登录页面</title>
</head>
<body>
<h2>登录</h2>
<form method="POST">
<input type="text" name="username" placeholder="用户名" required>
<input type="password" name="password" placeholder="密码" required>
<button type="submit">登录</button>
</form>
</body>
</html>

dashboard.php — 用户主页面

创建一个名为 dashboard.php 的文件,显示用户信息并确保用户已登录:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?php
session_start();

if (!isset($_SESSION['user_id'])) {
header("Location: login.php");
exit();
}

echo "欢迎," . htmlspecialchars($_SESSION['username']) . "!";
?>

<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>用户主页面</title>
</head>
<body>
<h2>用户主页面</h2>
<p>这是你的主页面,您已成功登录</p>
<a href="logout.php">退出</a>
</body>
</html>

logout.php — 用户登出

创建一个名为 logout.php 的文件,处理用户登出功能:

1
2
3
4
5
6
<?php
session_start();
session_destroy();
header("Location: login.php");
exit();
?>

0x05 Vue

5.1 题目

请使⽤Vue 3框架实现⼀个简单的购物⻋⻚⾯,要求能够动态添加商品、修改商品数量以及计算总价

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
商品列表:
⻚⾯上显⽰多个商品,包含商品名称、价格、购买数量输⼊框、以及添加到购物⻋的按钮
2.
购物⻋:
购物⻋显⽰已添加的商品列表,包括商品名称、价格、数量以及⼩计(商品价格 * 数量)
⽤⼾可以在购物⻋中直接修改商品数量
在购物⻋中添加⼀个删除按钮,⽤⼾可以将商品从购物⻋中移除
3.
总价计算:
⻚⾯底部显⽰购物⻋中所有商品的总价,并随购物⻋商品的数量或商品的删除⾃动更新
4.
表单验证:
购买数量需为正整数,且不能超过库存数量
5.
组件化设计:
使⽤Vue 3的组件化思想,将⻚⾯拆分为多个组件建议⾄少包含以下⼏个组件:
商品列表组件:负责展⽰商品和“添加到购物⻋”按钮
购物⻋组件:负责展⽰购物⻋中的商品、数量修改、删除和总价
单个商品组件:⽤于商品展⽰及功能

响应式系统:使⽤Vue 3的响应式系统处理商品数量、购物⻋内容的动态更新
⽗⼦组件通信:使⽤props和emit实现⽗组件与⼦组件之间的数据传递和事件触发
计算属性:使⽤Vue 3中的计算属性来处理总价的实时计算
使⽤Vue 3进⾏开发,尽量使⽤Composition API
保证代码的模块化、可读性以及复⽤性
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
商品列表⻚⾯:
商品名称 | 价格 | 库存 | 购买数量 | 操作----------------------------------------
商品 A | 100元 | 10 | 1
| [添加到购物车]
商品 B | 200元 | 5 | 1
购物⻋⻚⾯:
| [添加到购物车]
购物车:
商品名称 | 价格 | 数量 | 小计 | 操作----------------------------------------
商品 A | 100元 | 1 | 100元 | [删除]
商品 B | 200元 | 2 | 400元 | [删除]
总价:500元
提⽰:
你可以使⽤Vue CLI或Vite初始化项⽬。为了简单起⻅,商品数据可以硬编码在项⽬中,不需要从API获

5.2 VUE

5.2.1 App.vue

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
<!-- App.vue -->
<template>
<div id="app">
<h1>购物车示例</h1>
<ProductList @add-to-cart="addToCart" />
<ShoppingCart :cartItems="cartItems" @remove-from-cart="removeFromCart" />
</div>
</template>

<script>
import ProductList from './components/ProductList.vue';
import ShoppingCart from './components/ShoppingCart.vue';
import { ref } from 'vue';

export default {
components: {
ProductList,
ShoppingCart,
},
setup() {
const cartItems = ref([]);

const addToCart = (product) => {
const existingProduct = cartItems.value.find(item => item.id === product.id);
if (existingProduct) {
existingProduct.quantity += product.quantity;
} else {
cartItems.value.push({ ...product });
}
};

const removeFromCart = (id) => {
cartItems.value = cartItems.value.filter(item => item.id !== id);
};

return {
cartItems,
addToCart,
removeFromCart,
};
},
};
</script>

<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
padding: 20px;
}
</style>

5.2.2 ProductList.vue

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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
<!-- components/ProductList.vue -->
<template>
<div>
<h2>商品列表</h2>
<div v-for="product in products" :key="product.id" class="product">
<span>{{ product.name }}</span>
<span>{{ product.price }}元</span>
<span>库存: {{ product.stock }}</span>
<input
type="number"
v-model.number="product.quantity"
min="1"
:max="product.stock"
@input="validateQuantity(product)"
/>
<span v-if="product.errorMessage" class="error">{{ product.errorMessage }}</span>
<button @click="addToCart(product)">添加到购物车</button>
</div>
</div>
</template>

<script>
import { ref } from 'vue';

export default {
emits: ['add-to-cart'],
setup(props, { emit }) {
const products = ref([
{ id: 1, name: '商品 A', price: 100, stock: 10, quantity: 1, errorMessage: '' },
{ id: 2, name: '商品 B', price: 200, stock: 5, quantity: 1, errorMessage: '' },
]);

const validateQuantity = (product) => {
// Reset error message
product.errorMessage = '';

// Validate quantity
if (product.quantity <= 0) {
product.errorMessage = '购买数量必须为正整数!';
} else if (product.quantity > product.stock) {
product.errorMessage = '购买数量超过库存!';
}
};

const addToCart = (product) => {
// First, validate the quantity
validateQuantity(product);

// If there's an error message, do not proceed
if (product.errorMessage) {
return;
}

emit('add-to-cart', { ...product });
product.stock -= product.quantity; // 更新库存
product.quantity = 1; // 重置数量
};

return {
products,
addToCart,
validateQuantity,
};
},
};
</script>

<style scoped>
.product {
margin: 10px 0;
}
.error {
color: red;
font-size: 12px;
}
</style>

5.2.3 ShoppingCart.vue

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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
<!-- components/ShoppingCart.vue -->
<template>
<div>
<h2>购物车</h2>
<table>
<thead>
<tr>
<th>商品名称</th>
<th>价格</th>
<th>数量</th>
<th>小计</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr v-for="item in cartItems" :key="item.id">
<td>{{ item.name }}</td>
<td>{{ item.price }}元</td>
<td>
<input type="number" v-model.number="item.quantity" min="1" @change="updateQuantity(item)" />
</td>
<td>{{ item.price * item.quantity }}元</td>
<td>
<button @click="removeFromCart(item.id)">删除</button>
</td>
</tr>
</tbody>
</table>
<h3>总价:{{ totalPrice }}元</h3>
</div>
</template>

<script>
import { computed } from 'vue';

export default {
props: {
cartItems: {
type: Array,
required: true,
},
},
emits: ['remove-from-cart'],
setup(props, { emit }) {
const totalPrice = computed(() => {
return props.cartItems.reduce((total, item) => total + item.price * item.quantity, 0);
});

const updateQuantity = (item) => {
// 可以在这里进行库存检查
// 例如: item.quantity = Math.min(item.quantity, item.stock);
};

const removeFromCart = (id) => {
emit('remove-from-cart', id);
};

return {
totalPrice,
removeFromCart,
updateQuantity,
};
},
};
</script>

<style scoped>
table {
width: 100%;
border-collapse: collapse;
}
th, td {
border: 1px solid #ccc;
padding: 8px;
text-align: center;
}
</style>

5.3 npm

配置

package.json …\MSC\E5\e5\package.json

C run

T dev