2024.9.2东软面试记录

算法篇

(正常应该用Java做,Python代码比较短,直接写Python版本的)

题目一

input一个列表,内容是成绩,output一个列表,结果是对应的排名

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# input: [90, 85, 90, 95]
# output: [2, 3, 2, 1]

data = [90, 85, 90, 95]

# 1. 排序并去重
sorted_unique_data = sorted(set(data), reverse=True)

# 2. 构造mapping
mapping = {value: rank + 1 for rank, value in enumerate(sorted_unique_data)}

# 3. 根据mapping构造结果
result = [mapping[score] for score in data]

print(result)
# [2, 3, 2, 1]

题目二

给定一个dto list,里面包含年级、成绩、姓名,求出每个年级的平均成绩

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
dto_list = [
{"grade": 10, "score": 85, "name": "Alice"},
{"grade": 10, "score": 90, "name": "Bob"},
{"grade": 11, "score": 75, "name": "Charlie"},
{"grade": 11, "score": 80, "name": "David"},
{"grade": 12, "score": 95, "name": "Eve"}
]

grade_scores: dict[int, dict[str, int]] = {}
for dto in dto_list:
grade = dto["grade"]
score = dto["score"]
if grade not in grade_scores:
grade_scores[grade] = {"total_score": 0, "count": 0}
grade_scores[grade]["total_score"] += score
grade_scores[grade]["count"] += 1

for grade in grade_scores:
avg_score = grade_scores[grade]["total_score"] / grade_scores[grade]["count"]
print(f"年级 {grade} 的平均成绩是: {avg_score:.2f}")

SQL 篇

算法篇题目二的内容构成一张表,取出各年级平均成绩

1
2
3
4
5
6
7
SELECT 
grade,
AVG(score) AS average_score
FROM
students
GROUP BY
grade;

很简单,但是我忘记 SQL 语法了。。。没答上来,确实太久没写了😭

Java篇

题目一 值引用的问题。

基本数据类型会被改变,引用类型只会改变地址,不会改变对象。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class Main {
public static void main(String[] args) {
String s = "123";
int a = 1;
changeString(s);
changeInt(a);
System.out.println(s); // 123
System.out.println(a); // 1
}
public static void changeString(String tmp) {
tmp = "234";
}
public static void changeInt(int tmp) {
tmp = 3;
}
}

想要改变值只能 return 改变。

题目二 final 作用在类、方法、常量上分别有什么作用

答案

1
2
3
4
1. 修饰常量,值不可变 
2. 修饰对象,值可变,引用不变
3. 修饰方法,方法不可重写
4. 修饰类,无子类不可以被继承,更不可能被重写

之前确实没想过修饰对象的问题,记录一下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Test {
void print() {
System.out.println("test");
}
}
public class Main {

public static void main(String[] args) {
final Test a = new Test();
a = new Test();
}
}
// Main.java:10: error: cannot assign a value to final variable a
// a = new Test();
// ^
// 1 error

测试篇

问题一

以 UT 为例,怎么保证测试分支全部覆盖?

1
利用 True/False 标注以及 Jacoco 等测试工具综合判断。

问题二

IT 的 Case 是自己写的吗?根据什么写的?

1
根据画面 シナリオ 编写。

问题三

A && B || C,这种条件下,如果 A 是 True、B 是 False、C 是 True,最终结果是什么?

1
2
True
先看 True && False 是 False,False || True 是True。

日语篇

提 QA 的时候,像客户反映问题。指定场景回答对应的日文。

问题一

A 条件和 B 条件的顺序应该反过来,并不是先判断 A 再判断 B。

1
2
答案来自 ChatGPT
A 条件と B 条件の順序は逆であるべきです。A を先に判断するのではなく、B を先に判断すべきです。

问题二

变量 X 只被使用过一次,应该放在方法内作为局部变量。

1
2
答案来自 ChatGPT
変数 X は一度しか使用されていないため、メソッド内のローカル変数として定義するべきです。

OpenPyXL爬坑_第二弹

这是一段平平无奇的代码,用于获取冻结单元格

1
2
3
4
5
6
7
8
9
import shutil
import openpyxl

path = "/Users/xxx/Documents/tmp/openPyXLTest.xlsx"

wb = openpyxl.load_workbook(path)
sheet = wb["Sheet"]
print(sheet.freeze_panes)
wb.close()

文件内容如下

执行效果如下

看上去一切正常

但是当文件滚动条变更之后,如图

它的执行结果就变成了

没错,只要滚动条滚动了,取出来的值就是不正确的。如同源码展示的,它只会取 topLeftCell ,而这个值只会在加载的时候初始化,所以冻结的单元格行数,并不能准确取到。

已提交issue,期待回复

https://foss.heptapod.net/openpyxl/openpyxl/-/issues/2119

回复结果:

应该使用sheet.sheet_view.pane.ySplit获取冻结行数

输出结果 3.0

OpenPyXL爬坑

背景

接到需求,批量修改式样书的表纸页和履历页。本以为是简单的改动,但是深深踩了OpenPyXL的坑。

测试代码

1
2
3
4
5
6
7
8
9
10
11
import shutil
from openpyxl import load_workbook

path = "/Users/xxx/Documents/tmp/openPyXLTest.xlsx"
copyFile = "/Users/xxx/Documents/tmp/openPyXLTest2.xlsx"

shutil.copy(path, copyFile)

wb = load_workbook(copyFile)
wb.save(copyFile)
wb.close()

运行结果

图形问题解决

根据运行结果可以看出,只是简单的打开、关闭一个 excel 文件,会导致图片以及图形的丢失。

针对图形丢失在网上有很明确的说明,openpyxl 使用 Pillow 处理图片,所以需要安装 Pillow

pip install Pillow

安装 Pillow 之后,运行结果如下

图形依然丢失

去 OpenPyXL 仓库上翻了翻,这居然是一个陈年老bug https://foss.heptapod.net/openpyxl/openpyxl/-/issues/1268

彻底解决

使用 xlwings 库或者直接使用 VBA

xlwings: https://docs.xlwings.org/en/latest/quickstart.html#

xlwings示例

1
2
3
4
5
6
7
8
9
10
11
import shutil
import xlwings as xw

path = "/Users/xxx/Documents/tmp/openPyXLTest.xlsx"
copyFile = "/Users/xxx/Documents/tmp/openPyXLTest3.xlsx"

shutil.copy(path, copyFile)
wb = xw.Book(copyFile)
wb.save(copyFile)
wb.close()
print("done")

时间戳四舍五入

因为项目原因,api返回的结果是6位毫秒(2023-04-12 20:56:31.589183),而存储到db然后导出是3位数毫秒(2023-04-12 20:56:31.589)。

这里牵扯到四舍五入,所以不能单纯截取,需要加500毫秒。

1
2
3
4
5
6
from datetime import datetime, timedelta
time_str = "2023-04-07 18:14:45.589183"
dt = datetime.strptime(time_str, "%Y-%m-%d %H:%M:%S.%f")
new_dt = dt + timedelta(microseconds=500)
new_time_str = new_dt.strftime("%Y-%m-%d %H:%M:%S.%f")[:-3]
print(new_time_str)

ConfigParser读取properties

ConfigParser读取properties文件时,properties文件必须有默认的头,例如[default],如果没有会报错。

因为ConfigParser默认是读取ini格式文件,ini文件必须有section header。properties虽然也是key=value格式,但是不强制section header。

解决方式是读取内容后手动加上header,然后交给ConfigParser解析。

1
2
3
4
content = "[default]\n" + open(bathPath + "\\" + file).read()
config = ConfigParser(allow_no_value=True)
config.read_string(content)
value = config.get('default', key)

Python报错UnicodeDecodeError

背景

Python IO读取文件时报错UnicodeDecodeError: ‘gbk’ codec can’t decode byte...

错误原因

如同报错信息,Unicode解码失败。根本原因是文件中有汉字/日文等其他文字不能用gbk打开。

解决方法

利用utf-8格式打开

1
file = open(filename, encoding="utf8")

Python3-enum枚举类使用示例

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
from enum import Enum

# 声明枚举类
class Branch(Enum):
MAIN = "main branch"
DEV = "develop branch"


print(Branch.MAIN.name) # MAIN
print(Branch.MAIN.value) # main branch
print(Branch["MAIN"]) # Branch.MAIN
print(Branch("main branch")) # Branch.MAIN
print(Branch.MAIN) # Branch.MAIN

print(Branch.MAIN == Branch.MAIN) # True
print(Branch.MAIN == Branch.DEV) # False

print(Branch.MAIN is Branch.MAIN) # True

for branch in Branch:
print(branch)
# Branch.MAIN
# Branch.DEV

for branch in Branch.__members__:
print(branch)
# MAIN
# DEV

词云图生成

代码段

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import jieba
from wordcloud import WordCloud
from matplotlib.pyplot import imread

text = open("2020政府报告.txt").read()
font = "simhei.ttf"

# 背景图片
mask = imread("background.jpg")

cut = jieba.cut(text) # text为你需要分词的字符串/句子
result = ' '.join(cut) # 将分开的词用空格连接

# 剔除掉的关键词
exclude = {'我们', '今年', '同志', '我国'}

wc = WordCloud(collocations=False, # 避免重复单词
font_path=font, # 设置字体
mask=mask, # 设置背景
background_color="white",
# width=1400, height=1400, margin=2, # 图像宽高,字间距
stopwords=exclude)
wc.generate(result)
wc.to_file('2020政府报告.png')

引用模块

import jieba:中文词解析。
from wordcloud import WordCloud:词云图模块,用于生成词云图。
from matplotlib.pyplot import imread:图片加载。

数据源

background
2020政府报告

运行结果

设置背景版本

默认版本