软工面试准备资料
面试准备
本篇文章是我根据自身在大一上准备软工分流面试经验整理的一篇简单的资料,里面没有太多细节的描述,大概说明了我认为面试需要准备的几个方向,以及如何准备。内容比较杂,但是首先的建议是,如果是从暑假开始准备的,强烈建议学习UCB(美国加州大学伯克利分校)的CS61系列的公开课,分别是CS61A,CS61B,CS61C,对应编程入门,数据结构,计算机组成三大块基础知识,就从前往后学即可 注:这里给出的要求都是最低要求,准备是准备不完的(悲
0.个人推荐的学习路线
- 计算机速成课 科普性质的视频,有精良的翻译,没有学习难度,但是覆盖范围很广,讲的也通俗易懂,没必要一次性看完,可以看个几章找个感觉,后续课程学习中可以穿插着看
- CS61A 伯克利的计算机入门课程(需要翻墙,请自行找工具),理论上来说不需要任何计算机基础,讲的非常通俗易懂,但是覆盖了Python基础,函数式编程,SQL和编译原理基础等内容,注意一定要做lab和Project,这些才是课程的精华。但是如果你还是觉得英文授课有难度,你也可以看翁恺的C语言,这个视频可以帮你很好地应付C程序设计课的期末考试,但是在计算机入门的角度就完全不如CS61A了,并且计算机是注重实践的课,翁恺的课没有给出配套的练习,因此遇到视频中的代码最好跟着敲
- CS61B 伯克利的数据结构课程,覆盖了Java语法,oop和数据结构基础的内容,有点麻烦的是代码的框架好像最近都设置为伯克利的学生才能访问,但是这门课非常出名,在github上应该能找到相应的代码框架。
- CS61C 伯克利的计算机组成课,以C语言和RISCV为基础,面临和61B一样的问题,代码框架可能要到别处去找
最近伯克利把很多课程的内容设置为了私有,如果你觉得麻烦的话,可以考虑去csdiy上找一些课替换
1.一些无法给出准确准备范围的东西
前沿科技
这部分覆盖范围过于广泛,反正大家就都去了解涉猎一点,尤其是最近比较火的AI之类的
常见的智力问题
比如找次品的问题,砝码称重问题等等覆盖很广。
数学在计算机中的应用
面试中可能会问到你现在在学习的微积分,线性代数等在计算机中的应用。你可以去搜寻有关资料,比如数论在密码学上的应用,线性代数在图形处理的应用,微积分的应用(cordic算法)
专业选择问题
包括了那些问你为什么选择软工,讲讲你的未来规划,对行业的认识等等,这个反正也多多益善
2.数据结构与算法
如果有时间的话建议学习UCB的CS61B公开课,这门课会用Java带你学习和实现各种常见的数据结构,并且用这些数据结构做三个有趣的Project,前置条件是有一定的编程语言基础,基本上把翁恺的C语言看一遍写一遍就算有了。如果你实在不能接受纯英文的课程,也可以学习陈越老师的数据结构网课,在B站和MOOC都能找到
2.1 算法性能分析
首先要了解算法的定义,什么是算法
算法(英语:algorithm),在数学(算学)和计算机科学之中,指一个被定义好的、计算机可施行其指示的有限步骤或次序,常用于计算、数据处理和自动推理。算法是有效方法,包含一系列定义清晰的指令,并可于有限的时间及空间内清楚的表述出来^^。——维基百科
算法的性能分析主要分为时间复杂度和空间复杂度两部分,其主要描述了算法运行所花费的时间和所需要的内存空间
2.2 数据结构
这部分我当初是手写的笔记,所以就懒得在打一遍了,大家可以自行搜寻相关的定义,或者直接参看网课,
线性表
有顺式存储结构和链式存储结构两种,前者利于读取某一位的元素;后者利于插入和删除元素
栈
栈是线性表的一种特殊形式,是一种具有后进先出特点的数据结构
是一种特殊的线性表,只在表尾进行插入和删除操作
同样有顺序存储结构和链式存储结构两种
可以用于生成逆波兰表达式,来实现去括号的操作
队列
和栈一样,都是一种特殊的线性表,只允许在一段进行插入操作另一段进行删除操作
(我们的键盘有输入缓冲区,使用的就是对列的数据结构)
树
与最基本的线性表不同,树是一种一对多的数据结构
树的应用有很多,操作系统的文件管理,数据库系统常见的(用的是B+ Tree)的索引,编译系统有自己的语法树对我们写的程序进行语法分析
哈希表
建立一个搜索表,函数位置,冲突--指针
求余 字典,
根据关键值和值直接进行访问的数据结构
把元素的关键值根据哈希函数得到它的地址
2.3 一些你可能需要熟悉的算法
常见的查找算法和排序算法,例如
冒泡排序;快速排序;插入排序;堆排序
线性查找;二分查找(斐波那契查找);哈希;广度优先搜索,深度优先搜索(图)
3.体系结构
主要针对硬件层面的问题,具体入门学习可以阅读计算机系统概论这本书,或者有时间的话,依旧是建议学习UCB的CS61C公开课
如果应对面试的话,我认为 Crash Course Computer Science(b站上有)里面讲的应该够用了
你至少需要知道何为冯诺依曼架构,计算机中的一些典型硬件,以及计算机的运行速度的发展历程(例如缓存的出行,流水线CPU等等),64位系统和32位系统有什么区别等等
4.优秀的编程习惯
良好的代码规范
包括注释的书写,变量命名规范,提高代码的可维护性和可复用性
具体可以参看一些常用的代码规范 - LiZ的博客 (boilingfrog.github.io)
debug 和 测试
知道并且实践过如何设置断点,设置监视变量从而找到程序的bug,现代IDE也有更加高级的功能
例如进行对程序进行可视化(具体可以参照Python Tutor code visualizer: Visualize code in Python, JavaScript, C, C++, and Java 这个网站)或者设置条件断点等等
书写测试是编写大型程序必不可少的一部分,例如Java中有一个内置的库JUnit,里面提供了大量的函数便于程序员编写测试程序,测试主要针对程序的正确性和性能进行测试。如果你想了解测试的必要性,可以参看这篇文章
git and github
如果你需要对git的操作进行实践,你最好能够有一定的对shell的了解,可以参看whx学长的视频
Shell 基础及 CLI 工具推荐 | 实用技能拾遗第一讲 | 浙江大学计算机学院朋辈辅学【直播回放】_哔哩哔哩_bilibili
具体对git的学习可以参看the missing semester其中的一章,或者你不喜欢看视频也可以参看git的官方文档或者
Using Git | CS 61B Spring 2019 (datastructur.es) 这个文档里面描述了一个对git的小测试,你可以跟着做从而获得更好的理解(记得先下载git)
git是一个分布式版本控制系统,而不是集中式版本控制系统,git使每个开发人员的计算机都包含整个历史(git保存的代码版本,存放在本电脑中,而不是远程服务器)当你执行git init
命令时,你当前所在的文件夹会出现一个.git文件,里面用来存放你所迭代的版本(不止是代码也包括文件)
当你要进行不确定的操作或者和他人合作开发代码的时候,你需要时常保存当前的代码版本并进行迭代,git帮助你管理你的代码版本。
GitHub的其中一个作用是你可以使用你本地的git,把代码发送到GitHub上,便于你和你的朋友进行远程合作开发。
面向对象程序设计(oop)
把面向对象放到这一块来貌似有点问题,但是oop的思想确实是传统的设计模式的一部分
以C++为例,如果你需要深入学习C++,可以参看C++(0) 课程简介_哔哩哔哩_bilibili 也是一位学长的朋辈网课,如果你不喜欢看视频,也可以参看这位学长的博客C++ 学习 - 咸鱼暄的代码空间 (xuan-insr.github.io)
但是这位学长的C++网课属于是比较详细的一档,不只包括oop,浙江大学 C++ 翁恺老师_哔哩哔哩_bilibili 翁恺老师的这一版会稍微短一点。
如果你想学习Java的oop(更加oop的语言)可以学习CS61B
由于我精力有限,就不在这里详细讲述了
5.你自己的程序
面试的时候时常会问到你自己写过的最印象深刻的一个程序或者最大型的程序是什么,你最好能够提前准备一版。如果希望少花点精力,你可以
到b站找一个用c语言编写的小游戏,跟着对方敲代码敲下来就好。如果你有精力的话,请优先学习UCB的CS61系列,ABC中的任何一门课都有几个优质的Project,可以应付面试了
6.c语言基础
应当在面试之前学完c程的内容,一般看完翁恺老师的网课就差不多了
你需要至少了解:
- 程序是如何运行的 编译预处理,编译,汇编,链接各个阶段都在干什么
- 了解宏定义及其风险
- 计算机底层是如何处理浮点数的
- 什么是命令行参数
- 简单地了解递归
- 了解运算符的优先级
- 了解c语言的变量在内存中分配情况
7.人工智能
由于计院这几年开设了大量人工智能相关的课程,有可能在面试的时候也会涉及到相关的内容。但大家也没必要操之过急,在学习人工智能之前还是要打好前面的编程语言和数据结构的基础,如果你已经具备了这些基础的话(需要一定的Python基础,如果你没有Python基础的话,我还是推荐伯克利的CS61A),那么有一些人工智能的相关课程可以推荐给你
这两门课都是比较好的,吴恩达老师的机器学习相对基础,适合入门;李宏毅老师的机器学习覆盖范围更广,也包括了不少深度学习的内容,并且是中文授课。