早春二月,研发倍忙,杂花生树,群鸥竟飞。为什么?因为春季招聘,无论是应届生,还是职场老鸟,都在摩拳擦掌,秣马厉兵,准备在面试场上一较身手,既分高下,也决Offer,本次我们打响春招第一炮,躬身入局,让2023年的第一个Offer来的比以往快那么一点点。
打开某垂直招聘平台,寻找2023年的第一个猎物:
投递简历之后,如约进行面试。
笔试题
正规公司的面试一般都是笔试先行,笔试题的作用非常务实,就是直接筛掉一批人,提高面试效率,需要注意的是,在这个环节中,往往无法用搜索引擎进行检索,所以,你的大脑就是Python解释器,你的笔将会代替程序的输出:
# 实现字符串反转,以逗号作为切割符,切割的子串以单词作为单元反转
# 输入:hello world, god bless you
# 输出:world hello, you bless god
这道题网上没有原题,但其实并不难,考点在于应聘者对于Python基础和复合数据类型内置方法的熟悉程度,题目中所谓的字符串反转并不是真正意义的字符串反转,而是以单词为单元的反转,同时加入了逗号分割逻辑,所以只要对字符串内置方法split,rstrip和列表内置方法join以及reverse的用法足够了解,就可以直接写出解法:
def reseverWords(s:str) -> str:
all_str = ""
s = s.split(',')
for x in s:
lis= x.split()
lis.reverse()
all_str += ' '.join(lis)+', '
all_str=all_str.rstrip(', ')
return all_str
print(reseverWords(str1))
第二题是SQL语句题目,请写一条sql,按照地区的分组聚合数据进行排序:
id name location
-- ----- --------
1 Mark US
2 Mike US
3 Paul Australia
4 Pranshu India
5 Pranav India
6 John Canada
7 Rishab India
排序后结果:
id name location
-- ----- --------
4 Pranshu India
5 Pranav India
7 Rishab India
1 Mark US
2 Mike US
3 Paul Australia
6 John Canada
这道题也无法在网上查证,一般的分组聚合只是查一个数,这个是按照数量进行排序,并且其实并不展示数量,也可以理解为展示的为分组数据的明细排行榜:
SELECT x.*
FROM my_table x
JOIN (SELECT location, COUNT(*) total FROM my_table GROUP BY location) y
ON y.location = x.location
ORDER
BY total DESC
, id;
思路是先分组,随后按照分组的聚合数据根据地区字段连表排序即可。
自我介绍
通过笔试题筛选后,进入自我介绍环节,一般介绍技术栈和简单的项目经历即可,参考示例:
进程、线程和协程的区别
进程、线程和协程,从来就是Python面试中聚讼不休的一个话题,只要我们还在使用Python,就一定逃离不了三程问题:
Python中的深拷贝和浅拷贝
仅次于三程问题的明星面试题,一般情况下,大家都会说浅拷贝修改复制对象会影响原对象,而深拷贝不会,但其实,浅拷贝会有三种细分的情况:
1.拷贝不可变对象:只是增加一个指向原对象的引用,改变会互相影响。
>>> a = (1, 2, [3, 4])
>>> b = copy.copy(a)
>>> b
... (1, 2, [3, 4])
# 改变一方,另一方也改变
>>> b[2].append(5)
>>> a
... (1, 2, [3, 4, 5])
2.拷贝可变对象(一层结构):产生新的对象,开辟新的内存空间,改变互不影响。
>>> import copy
>>> a = [1, 2, 3]
>>> b = copy.copy(a)
>>> b
... [1, 2, 3]
# 查看两者的内存地址,不同,开辟了新的内存空间
>>> id(b)
... 1833997595272
>>> id(a)
... 1833997595080
>>> a is b
... False
# 改变了一方,另一方不会改变
a = [1, 2, 3] b = [1, 2, 3]
>>> b.append(4)
>>> a
... [1, 2, 3]
>>> a.append(5)
>>> b
... [1, 2, 3, 4]
3.拷贝可变对象(多层结构):产生新的对象,开辟新的内存空间,不改变包含的子对象则互不影响、改变包含的子对象则互相影响。
>>> import copy
>>> a = [1, 2, [3, 4]]
>>> b = copy.copy(a)
>>> b
... [1, 2, [3, 4]]
# 查看两者的内存地址,不同,开辟了新的内存空间
>>> id(b)
1833997596488
>>> id(a)
1833997596424
>>> a is b
... False
# 1.没有对包含的子对象进行修改,另一方关我卵事
a = [1, 2, [3, 4]] b = [1, 2, [3, 4]]
>>> b.append(5)
>>> a
... [1, 2, [3, 4]]
>>> a.append(6)
>>> b
... [1, 2, [3, 4], 5]
# 2.对包含的子对象进行修改,另一方也随之改变
a = [1, 2, [3, 4]] b = [1, 2, [3, 4]]
>>> b[2].append(5)
>>> a
... [1, 2, [3, 4, 5]]
>>> a[2].append(6)
>>> b
... [1, 2, [3, 4, 5, 6]]
高并发如何进行处理的
既然JD(Job Describe)中提到了高并发,那么就一定会问高并发问题,一般情况下,涉及高并发场景的基本上都是外部系统,此时需要简单介绍一下系统的容量是多少,比如有注册用户数、日活、QPS等等。然后就是提供具体方案,一般的手段是加缓存,数据库读写分离,数据库 sharding 等等。高并发背景下,整个系统瓶颈一般都在数据库。
除了上述的一些常规方案,业内最常用的缓解高并发的手段是使用异步任务队列:
保持幂等性
如果面试中提到了异步任务队列(消息队列),那么幂等性操作几乎一定会在后续的问题中提及,所谓幂等性,简单来说就是对于同一个系统,在同样条件下,一次请求和重复多次请求对资源的影响是一致的,就称该操作为幂等的。比如说如果有一个接口是幂等的,当传入相同条件时,其效果必须是相同的。在RabbitMQ中消费幂等就是指给消费者发送多条同样的消息,消费者只会消费其中的一条。例如,在一次购物中提交订单进行支付时,当网络延迟等其他问题造成消费者重新支付,如果没有幂等性的支持,那么会对同一订单进行两次扣款,这是非常严重的,因此有了幂等性,当对同一个订单进行多次支付时,可以确保只对同一个订单扣款一次。
具体手段:
结语
技术面试虽然是一种信息不对等的较量,但是只要认真研究JD(Job Describe),做好相关的知识储备,基础常识不要翻车(包含但不限于Python基础/数据库基础),那么作为应聘者拿一个Offer也不是想象中的那么难,本次面试的实战录音可以在B站(Youtube)搜索刘悦的技术博客查阅,欢迎诸君品鉴。