面试经验 vol1 | 计算机基础知识
总结常见的诞生于 计算机组成原理,操作系统、 计算机网络、算法设计基础中的常见的知识,在这个过程中回顾快速入门计算机知识中,从纸条到硬盘、从继电器到二极管;这门学科的目的是实现自动化的操作,帮助我们高效的完成既定任务。在这个过程要克服死记硬背的指令,来解决盲目寻找答案的过程。
操作系统相关
1.1 Shell和脚本
使用字符串和计算机内核进行交互。其核心功能是允许执行程序,输入并获取某种结构化的输出。shell和所有的编程语言,同样包括变量、函数、条件、循环等一些系列操作,同时会询问环境变量 $PATH
Shell 中常见的函数有哪些?
常见的函数:
1 |
|
Shell文本处理三巨头grep、sed、awk的案例
1 |
|
Shell 中函数的常见参数
1 |
|
管道的使用方式Pipeline
1 |
|
从shell命令到脚本
从shell到脚本,可以实现变量、控制流和语法,同时加强了pipelines、保存到文件、标准输入输出原生操作的优势。
- $Var 是变量,$0 脚本名、$1~9 参数名、$@所有参数、$# 参数个数、$? 前一个命令的饭绘制、$$ 当前脚本的进程识别码、!! 上一次命令、$_ 上一条命令最后一层参数
- ‘ 和 “” 是不一样的
- 同样支持 if case while for的控制流关键字的操作
- 命令替换(command substitution)、进程替换(process substitution)
常用的正则表达式
必须要熟悉正则表达式:
- . 除去换行符之外的任意单个字符
- *匹配前面字符零次或者多次
- ‘+’ 匹配前面字符一次或者多次
- [abc]匹配abc其中的任何一个
- (rx1|rx2)任何能够匹配Rx1或者rx2的结果
- ^ 行首
- $ 行尾
RegexOne - Learn Regular Expressions - Lesson 1: An Introduction, and the ABCs
配置文件的格式 dotfile
相关程序的配置问价 DOTFILE 是通过这类隐藏的配置文件实现的
1 |
|
SSH 使用教程
ssh 使用过程,只需要向服务器证明客户端的私钥即可,等效于密码。
- ssh-keygen可以生成密钥
- 查询 .ssh/authorized_keys
- ssh-copy-id -i **pub username@ip
1.2 构建系统
调试器是什么以及其对应的作用?
是一种可以允许我们和正在执行的程序进行交互的程序,可以做到一条一条执行并且在程序崩溃之后查看变量的值;对于python的调试器包括:
- l 显示当前行附近11行或继续执行之前的提示
- s 执行当前行
- n 继续执行到下一个条遇见
- b 设置断点
- p 打印,pprint对于表达式求值并输出结果
- r继续执行
- q推出
除了代码调试之外,通常还包括专门工具、静态分析、性能分析、事件分析等等
元编程 (meta programming)是什么?
不是关于代码、高效工作,而是如何在大型工程中提升代码的鲁棒性,这些包括构建系统、持续集成、代码测试、依赖管理等等内容
构建系统 (Make system)
构建系统在多次可以见到,包括嵌入式中将语言烧录成为hex格式并传送至小车、包括latex中构建pdf的过程等等了这个步骤包括不同的分支。通常这些工具需要 定义 依赖(dependence)、目标(target)和规则(rule)
- 依赖:系统的任务是找到构建这些目标所需要的依赖
- 目标:告诉构建系统的具体目标
- 规则:构建规则
常见的make是最常用的构建系统之一,包括makefile
依赖管理(Dependency management)
对于项目来说,依赖于其他的项目、其他的程序、系统包、语言库。这些依赖往往需要特定的方式来进行管理。每一种仓库、每一种工具的运行机制都不太一样,也就是版本控制(Version control)方法的不同,常见的规则包括
- 如果新的版本没有改变API,则补丁递增
- 如果添加api,且向后兼容,则次版本号递增
- 如果修改api,但并不兼容,则主版本好递增
持续集成(Continuous integration)
随着项目规模的扩大,往往除了修改代码本身还需要有额外的操作。包括但不限于 代码风格检查、上传文档、编译文件、发不到pypi、执行测试套件等等。持续集成通常指的是“当您的代码变动的时候、自动运行的东西”,这些工具包括GitHub actions、Azure pipelines等等。工作原理为
您需要在代码仓库中添加一个文件,描述当前仓库发生任何修改时,应该如何应对。目前为止,最常见的规则是:如果有人提交代码,执行测试套件。当这个事件被触发时,CI 提供方会启动一个(或多个)虚拟机,执行您制定的规则,并且通常会记录下相关的执行结果。您可以进行某些设置,这样当测试套件失败时您能够收到通知或者当测试全部通过时,您的仓库主页会显示一个徽标。
测试简介(Code test)
测试套件:所有测试的统称
单元测试:一种微型测试
集成测试:针对系统的某个部分进行测试来观察是否可以协同工作
回归测试:特定模式测试、用于保证之前引起问题的bug不会出现
模拟:使用一个假的实现来替换函数、模块或类型,匹配那些和测试不相关的内容
Linux文件管理
/bin
- 基本命令二进制文件/sbin
- 基本的系统二进制文件,通常是root运行的/dev
- 设备文件,通常是硬件设备接口文件/etc
- 主机特定的系统配置文件/home
- 系统用户的主目录/lib
- 系统软件通用库/opt
- 可选的应用软件/sys
- 包含系统的信息和配置(第一堂课介绍的)/tmp
- 临时文件(/var/tmp
) 通常重启时删除/usr/
- 只读的用户数据
/usr/bin
- 非必须的命令二进制文件/usr/sbin
- 非必须的系统二进制文件,通常是由root运行的/usr/local/bin
- 用户编译程序的二进制文件
/var
-变量文件 像日志或缓存
1.3 操作系统相关
什么是操作系统(Operation system)
用于管理计算机硬件和软件资源,对下屏蔽硬件的复杂性、对上屏蔽资源调度的复杂性。所处于的内核(kernel)用用户提供应用(Application)、对下管理各种设备(device)
操作系统的主要功能
- 进程和线程的管理,包括增、删、阻塞、唤醒、通信等等
- 存储管理
- 文件管理:读写删除等
- 设备管理:输入输出设备的请求和释放
- 网络管理
- 安全管理等等
用户态和内核态切换到额方式
- 系统调用
- 中断 interrupt
- 异常 exception
堆和栈原理
栈:栈是一种后进先出(Last In, First Out,LIFO)的数据结构,它只允许在一端(栈顶)进行数据的添加和删除操作。栈通常用于管理方法调用的执行顺序、局部变量的存储等。应用包括函数调用、表达式求值
堆:堆是一种动态分配的内存区域,程序在运行时可以从堆中分配或释放内存。不同于栈,堆的内存分配和释放是不连续的,因此它更灵活,但管理成本更高。应用包括动态数据结构、大对象存储
进程和线程的区别(Process和thread)
进程是APP、线程是APP中的一个功能。具体来说进程是操作系统进行资源分配和调度的独立单位,是程序执行的实体,每个进程都有自己独立的地址空间、内存、数据站和辅助数据;线程是进程执行的最小单位,可以利用进程中的资源,在同一个进程内多个线程共享其地址空间和资源
进程之间的通信方式(Inter- process communicating)
- 管道(Pipes),允许一个进程和另一个进程之间的单向数据流。管道可以是匿名的,也可以是具名的(也称为命名管道或FIFO)。
- 信号(Signals),种用于进程间通信的有限制的方式,允许进程给另一个进程发送简单的消息。信号是一种异步的通信方式,用于处理诸如终止请求(SIGTERM)、中断请求(SIGINT)等事件。
- 消息队列(Message queues),允许不同的进程读写一个消息队列,这是一种比管道更灵活的通信方式,因为它允许消息的随机访问,不仅仅是FIFO(先进先出)。
- 共享内存(Shared memory),允许多个进程访问同一块内存空间。这是一种非常高效的通信方式,因为数据不需要在进程间复制,但它需要同步机制来防止并发访问问题。
- 信号量(Semaphore),主要用于同步多个进程对共享资源的访问,虽然它们本身不传递数据,但信号量可以用来同步数据访问,因此是进程间通信的重要部分。
- 套接字(Sockets),提供了在不同主机上运行的进程之间通信的能力。套接字可以是基于流的(TCP),也可以是基于数据报的(UDP)。
- 文件映射(Memory- mapped files),通过将文件或设备映射到内存,实现进程间的共享数据。这种方式允许文件或设备的内容直接加载到进程的地址空间,从而实现快速访问和修改。
为什么需要线程和多线程?
进程切换开销大,线程开销小。同时一个进程可以创建多个线程,线程可以并发处理不同的任务,有效的利用多处理器和多核计算机。而进程只能在一个时间内干一件事情
线程同步方式有哪些?
- **互斥锁(Mutex)**:采用互斥对象机制,只有拥有互斥对象的线程才有访问公共资源的权限。因为互斥对象只有一个,所以可以保证公共资源不会被多个线程同时访问。比如 Java 中的
synchronized
关键词和各种Lock
都是这种机制。 - 读写锁(Read-Write Lock):允许多个线程同时读取共享资源,但只有一个线程可以对共享资源进行写操作。
- **信号量(Semaphore)**:它允许同一时刻多个线程访问同一资源,但是需要控制同一时刻访问此资源的最大线程数量。
- 屏障(Barrier):屏障是一种同步原语,用于等待多个线程到达某个点再一起继续执行。当一个线程到达屏障时,它会停止执行并等待其他线程到达屏障,直到所有线程都到达屏障后,它们才会一起继续执行。比如 Java 中的
CyclicBarrier
是这种机制。 - 事件(Event) :Wait/Notify:通过通知操作的方式来保持多线程同步,还可以方便的实现多线程优先级的比较操作。
进程有哪些状态?
- 创建进程 new
- 就绪状态 ready
- 运行
- 阻塞 或者等待
- 结束
如何实现多线程?
计算机组成相关
如何实现高性能
- CDN
- 负载均衡
- 数据库优化
- 消息队列
如何实现高可用
- 冗余设计
- 服务限流
- 降级
- 超时
- 性能测试入门
计算机网络相关
OSI 七层模型
- 物理层:RS232、RS485、RJ45、SDH、DSL、SPI、CAN、802.11,考虑的 是如何传输比特
- 数据链路层:Ethernet、PPP、ATM、MAC,考虑如何纠错,实现局域网的实现
- 网络层:IP、ARP、ICMP 实现网络之间传输NAT
- 传输层:TCP、UDP、SSL、TLS 实现进程和进程之间的通信
- 会话层、表示层、应用层:DNS、HTTP、P2P、EMAIL、Telnet、FTP、SSH
从输入URL到页面展示的过程
- 利用DNS查询(浏览器缓存、系统缓存、路由器缓存、DNS缓存)找到IP
- 浏览器向服务器发送http请求
- 建立TCP、IP连接
- OPSF 在路由器之间使用
- ARP 转换成为mac
- HTTP 连接之后使用访问网页
- 服务器处理需求
HTTP 和 HTTPS的区别(pass)
- 端口号:HTTP 默认是 80,HTTPS 默认是 443。
- URL 前缀:HTTP 的 URL 前缀是
http://
,HTTPS 的 URL 前缀是https://
。 - 安全性和资源消耗:HTTP 协议运行在 TCP 之上,所有传输的内容都是明文,客户端和服务器端都无法验证对方的身份。HTTPS 是运行在 SSL/TLS 之上的 HTTP 协议,SSL/TLS 运行在 TCP 之上。所有传输的内容都经过加密,加密采用对称加密,但对称加密的密钥用服务器方的证书进行了非对称加密。所以说,HTTP 安全性没有 HTTPS 高,但是 HTTPS 比 HTTP 耗费更多服务器资源。
- SEO(搜索引擎优化):搜索引擎通常会更青睐使用 HTTPS 协议的网站,因为 HTTPS 能够提供更高的安全性和用户隐私保护。使用 HTTPS 协议的网站在搜索结果中可能会被优先显示,从而对 SEO 产生影响。
关于 HTTP 和 HTTPS 更详细的对比总结,可以看我写的这篇文章:HTTP vs HTTPS(应用层) 。
HTTP 1.0 和HTTP1.1 的区别(pass)
- 连接方式 : HTTP/1.0 为短连接,HTTP/1.1 支持长连接。HTTP 协议的长连接和短连接,实质上是 TCP 协议的长连接和短连接。
- 状态响应码 : HTTP/1.1 中新加入了大量的状态码,光是错误响应状态码就新增了 24 种。比如说,
100 (Continue)
——在请求大资源前的预热请求,206 (Partial Content)
——范围请求的标识码,409 (Conflict)
——请求与当前资源的规定冲突,410 (Gone)
——资源已被永久转移,而且没有任何已知的转发地址。 - 缓存机制 : 在 HTTP/1.0 中主要使用 Header 里的 If-Modified-Since,Expires 来做为缓存判断的标准,HTTP/1.1 则引入了更多的缓存控制策略例如 Entity tag,If-Unmodified-Since, If-Match, If-None-Match 等更多可供选择的缓存头来控制缓存策略。
- 带宽:HTTP/1.0 中,存在一些浪费带宽的现象,例如客户端只是需要某个对象的一部分,而服务器却将整个对象送过来了,并且不支持断点续传功能,HTTP/1.1 则在请求头引入了 range 头域,它允许只请求资源的某个部分,即返回码是 206(Partial Content),这样就方便了开发者自由的选择以便于充分利用带宽和连接。
- Host 头(Host Header)处理 :HTTP/1.1 引入了 Host 头字段,允许在同一 IP 地址上托管多个域名,从而支持虚拟主机的功能。而 HTTP/1.0 没有 Host 头字段,无法实现虚拟主机
HTTP1.1 和HTTP2的区别
- 多路复用(Multiplexing):HTTP/2.0 在同一连接上可以同时传输多个请求和响应(可以看作是 HTTP/1.1 中长链接的升级版本),互不干扰。HTTP/1.1 则使用串行方式,每个请求和响应都需要独立的连接,而浏览器为了控制资源会有 6-8 个 TCP 连接都限制。。这使得 HTTP/2.0 在处理多个请求时更加高效,减少了网络延迟和提高了性能。
- 二进制帧(Binary Frames):HTTP/2.0 使用二进制帧进行数据传输,而 HTTP/1.1 则使用文本格式的报文。二进制帧更加紧凑和高效,减少了传输的数据量和带宽消耗。
- 头部压缩(Header Compression):HTTP/1.1 支持
Body
压缩,Header
不支持压缩。HTTP/2.0 支持对Header
压缩,使用了专门为Header
压缩而设计的 HPACK 算法,减少了网络开销。 - 服务器推送(Server Push):HTTP/2.0 支持服务器推送,可以在客户端请求一个资源时,将其他相关资源一并推送给客户端,从而减少了客户端的请求次数和延迟。而 HTTP/1.1 需要客户端自己发送请求来获取相关资源。
HTTP2和HTTP3区别(Pass)
TCP三次握手
- 客户端发送syn数据给服务端
- 服务端发送 syn ack给客户端
- 客户端发送ack给服务端
TCP四次回收
数据结构相关
面向象中的继承、多态、封装
封装(Encapsulation):封装是面向对象编程的基本特征之一,它隐藏了对象的内部状态,并且只通过对象的方法来访问和修改。这样可以使代码更加安全和易于管理。
继承(Inheritance):继承是从已有的类派生出新的类,新的类继承了原有类的属性和方法,并且可以添加新的属性和方法。继承可以提高代码的重用性,并且使代码更加清晰和易于维护。
多态(Polymorphism):多态是指一个接口可以有多种实现方式,或者一个对象可以表现出多种形态。多态可以提高代码的灵活性和可扩展性,并且使代码更加易于理解和维护。