为了满足人类的需求,提升人的体验。
以下是马斯洛需求层次表格:
需求层次 | 描述 | 相关IT技术举例 |
---|---|---|
生理需求 | 包括食物、水、空气、睡眠、性等基本的生存需求 | 空气净化器中的检测系统 |
安全需求 | 指个人生命、健康、财产以及安全感等方面的需求 | 银行系统 |
社交需求 | 需要社交互动、关爱、友情等情感需求 | 各种社交软件 |
尊重需求 | 指个人需要获得自尊、尊重、成就感以及得到他人的认可、赞赏等 | 高赞开源项目 |
自我实现需求 | 指个人追求个人成长、实现潜能、独立自主、自我表现等高层次需求 | 暂未想到 |
人类有自己的不同层次的需求,在大部分的层次里面,IT技术都可以协助满足一部分需求,提升人的体验。
举个例子:人想知道明天的天气怎么样。如果没有IT技术,那么人只能通过自己的经验来判断,但是IT技术可以通过收集大量的数据,来预测明天的天气,从而提升人的体验。
工业革命 | 大致时间范围 | 典型场景 |
---|---|---|
第一次工业革命(机械工业革命) | 1760年至1840年 | 用机器代替手工,比如纺纱机。 |
第二次工业革命(电气化工业革命) | 1860年至1920年 | 用电力驱动机器。发明电灯了,晚上也有光了。 |
第三次工业革命(数字革命) | 1950年至2010年 | 发明电脑了,开始用机器进行计算了。 |
第四次工业革命(智能革命) | 2010年至今 | 发明人工智能了,机器本身可以进行创造了。 |
其中第三次和第四次工业革命是IT技术的主要发展阶段。
硬件和软件两部分。
两者相辅相成,缺一不可。
本文的侧重点是软件部分。
图灵计算机 | 冯诺伊曼计算机 |
---|---|
以纸带为输入 | 以存储器为输入 |
没有存储器 | 有存储器 |
没有指令集 | 有指令集 |
以程序为中心 | 以数据为中心 |
专用型计算机 | 通用型计算机 |
现在基本不用了 | 依旧广泛应用于PC电脑、Mac电脑、手机、平板、服务器,几乎无处不在 |
图灵为了在战争期间破解德国的密码,发明了图灵计算机。他发明的机器是专用型的计算机(用于破译密码),而不是通用型的计算机。同时图灵在1936年发表了一篇论文:《论可计算数及其在判定问题中的应用》,这篇论文从数学理论上证明了通用型计算机的可行性。
冯诺伊曼在图灵的论文的基础之上,把理论变成了现实,造出了通用型的计算机。(EDVAC报告初稿(First Draft of a Report on the EDVAC))
因此图灵和冯诺伊曼被并称为计算机之父。
补充一点:冯诺伊曼是在EDVAC的后期才以顾问的身份进入这个项目的,他的主要贡献除了提出了现在的冯洛伊曼体系结构之外,还在于他拒绝了其他同事想通过这种结构申请专利的提议,使得这种结构成为了公有领域的知识,大家可以免费使用这种结构而不用交专利费用。
冯诺伊曼之前的计算机不是通用型计算机,它具体要怎么设计严重依赖于要完成的任务是什么,不同的任务需要设计不同的电路结构。比如在当时一个巨大的机房里,张三要做他的任务(比如计算导弹的轨迹),他需要把机房里的电线重新搭一遍,才能匹配张三的任务。张三的任务完成后,李四要做他的任务(比如计算根号2等于多少)时,还是要把机房里的电路重新搭一遍,才能匹配李四的任务。这样做的效率很低,切换一次任务的平均时间大约在1到2天。
冯诺伊曼之后的计算机是通用的计算机,它的电路结构是固定的,不会因为任务的不同而改变。张三要计算导弹的轨迹,他只需要把他的任务按照一定的规则(可以理解为cpu的指令集)输入到计算机的存储器里,计算机就会自动完成计算,并输出结果。李四要计算根号2等于多少,也只需要把他的任务按照相同的规则输入到计算机的存储器里,计算机也会自动完成计算。
组成部分 | 名称 | 作用 |
---|---|---|
运算器 | Arithmetic and Logic Unit (ALU) | 执行算术运算和逻辑运算 |
控制器 | Control Unit (CU) | 控制程序的执行 |
存储器 | Memory Unit (MU) | 存储数据和程序 |
输入设备 | Input Unit (IU) | 将数据输入计算机 |
输出设备 | Output Unit (OU) | 将计算机处理后的数据输出 |
以PC电脑为例:鼠标和键盘是输入设备,显示器是输出设备,cpu是运算器和控制器,内存是存储器。 注:硬盘也可以看作是输入设备,因为它可以把数据输入到内存里。
架构 | 描述 |
---|---|
冯诺伊曼结构 | 最常见的计算机架构。它是一种通用架构,非常适合许多任务。 |
哈佛结构 | 一种计算机架构类型,其中程序和数据存储在不同的存储器中。这使得CPU可以独立访问程序和数据,从而可以提高性能。 |
改进的哈佛结构 | 类似于哈佛结构,但它允许CPU同时访问程序和数据存储器。这可以进一步提高性能。 |
数据流架构 | 一种计算机架构类型,其中指令在其操作数可用时立即执行。这可以通过减少指令等待其操作数的时间来提高性能。 |
精简指令集计算(RISC)架构 | 一种计算机架构类型,使用少量简单指令。这可以通过使CPU更容易解码和执行指令来提高性能。 |
复杂指令集计算(CISC)架构 | 一种计算机架构类型,使用大量复杂指令。这可以通过允许CPU在单个指令中执行更多操作来提高性能。 |
量子计算机 | 一种使用量子力学原理进行计算的新型计算机。量子计算机使用与传统计算机不同的架构,使它们能够比传统计算机更快地执行某些类型的计算。 |
神经形态计算机 | 受人脑启发,旨在执行与大脑执行的任务类似的任务。神经形态计算机使用与传统计算机不同的架构,使它们能够比传统计算机更有效地执行某些类型的任务。 |
基于忆阻器的计算机 | 一种使用忆阻器(一种非易失性存储器)的新型计算机。基于忆阻器的计算机使用与传统计算机不同的架构,使它们能够比传统计算机更有效地执行某些类型的任务。 |
前三种结构(冯诺伊曼结构、哈佛结构、改进的哈佛结构)大体上比较类似。现在的计算机也并没有非常严格的按照冯诺伊曼的论文来设计,只能说是大方向上遵循了冯诺伊曼结构。比如说冯诺伊曼从来没有提到过cpu缓存的概念,但现在的计算机都有cpu缓存,而且在一级缓存里面还区分了指令缓存和数据缓存。
简单总结如下:
用于电脑:
x86 = i386 = IA32
amd64 = x86_64 = x64 != IA64 (不要管是Intel的CPU还是AMD的CPU,只要是64位的,都差不多)
用于手机:
arm = arm32
arm64 = AArch64
详细参考文章:【CPU】关于x86、x86_64/x64、amd64和arm64/aarch64
以一台早期使用 8086CPU 的电脑为例,启动过程是这样的:
- CPU 硬件初始化
- CPU 内部自测试(可选,有的 CPU 可能会有自测式,有的可能没有)
- 把寄存器内容初始到预置状态。8086CPU,除 CS 段寄存器外,其他都是
0
,CS 寄存器是FFFF
- 取指令并执行指令,8086CPU 第一个指令地址为
FFFF:0000
,即FFFF0
,位于内存地址的顶部区域,距离顶部只有 16 个字节,这里存放了一条占用 5 个字节的跳转指令:EA5BE000F0
,EA
表示跳转指令,E05B
表示偏移地址,F000
表示段地址,最终会跳到F000:E05B
地址处(即 BIOS 中的指令)。注:对 CPU 来说,内存是一个连续的范围,但是物理上不是,这里的FFFF0
就是在 BIOS 中的。 - 8086CPU 的地址如果在
F0000
~FFFFF
之间(共 64KB ),访问的是一个特殊的芯片,即 BIOS ,数据即使断电也不会消失,里面存储了开机时需要执行的指令,用来对计算机的基本模块进行诊断、检测、初始化,还提供了与常用硬件通信的接口,如操作键盘、硬盘、显示器。 - BIOS 的容量不大,为了做更多的事情,在 BIOS 中还固化了一些指令,用于从外部的辅助存储设备(如硬盘、U盘)读取程序指令放入内存,继续执行,一般来说这时最先加载的是操作系统的相关程序指令。
- 操作系统开始启动。
注:操作系统也只是一个运行在处理器上的软件。
参考youtube视频:Computer Boot Process animation
实模式是早期的 CPU 唯一支持的模式,它的主要特点是:没有内存保护机制,访问的都是实际的物理地址,程序 A 可以看到并修改程序 B 的内存。
『实模式』中的『实』就是『实际物理地址』的意思。
由于实模式中不同程序访问的都是实际的物理地址,因此程序 A 可以看到并修改程序 B 的物理内存,这样就会造成安全问题。 为了保护不同进程的内存不被其他程序篡改,CPU 提供了保护模式,利用虚拟地址的方式,来隔离不同程序的内存。 比如给程序 A 分配了 4G 虚拟内存,给程序 B 也分配了 4G 虚拟内存。程序 A 访问的是虚拟地址 0x1000,程序 B 访问的是虚拟地址也 0x1000,但是实际上,程序 A 访问的是物理地址 0x100000,程序 B 访问的是物理地址 0x200000,这样就实现了内存的隔离。
『保护模式』中的『保护』就是『保护内存不被其他程序篡改』的意思。
补充一些关于保护模式的知识点:
- 实模式和保护模式的分界是由一个32位的寄存器CR0实现的(CR:Control Register),第0位是
1
时,表示进入保护模式。 - 是否进入保护模式,是由操作系统决定的。
- 在 BIOS 进行自检的时候会进入保护模式。
- 现在的操作系统都是运行在保护模式下的,实模式仅在电脑启动的前一小段时间才会存在。
特征 | 实模式 | 保护模式 |
---|---|---|
内存保护 | 无 | 有 |
多任务处理 | 无 | 有 |
虚拟内存 | 无 | 有 |
安全性 | 低 | 高 |
性能 | 低 | 高 |
- 依赖操作系统才能运行的程序。大部分的程序都是这种,比如QQ、微信、浏览器等等。
- 不依赖操作系统就能运行的程序。它必须自己做所有的工作,比如创建描述符,安装描述符。比如Windows、Linux,它们自己本身就是操作系统程序。
不是的。
比如一个普通的微波炉,虽然它里面有软件程序来控制一些功能,但它并不依赖操作系统,因为它的操作比较简单,不涉及多用户管理、多进程切换等复杂的功能,因此不需要操作系统。
一个程序员更熟悉的例子是:BIOS(Basic Input/Output System)。如果我们把电脑的内存条和硬盘拔掉,我们还是可以启动电脑,并进入到 BIOS 设置界面。BIOS 作为软件,执行了相关的指令,操作了相关的硬件,最终在显示器上显示出了一个管理界面。这个过程里面并没有操作系统的参与。
来源:【机械键盘DIY】真正从零开始 设计制作一款多媒体机械键盘
注:本文的重点不是嵌入式方向,是软件开发架构方向,但是软件开发人员也可以对嵌入式有一些基础的了解,这个视频实现了嵌入式开发的一个比较完整的流程。
机械键盘的基本结构:电路板、定位板、键轴、键帽、外壳。
设计制作机械键盘的步骤:
- 【硬件】确定键盘的布局
- 【硬件】确定硬件方案,绘制原理图
- 【硬件】根据原理图画PCB
- 【硬件】制作定位板
- 【硬件】焊接组装
- 【软件】烧写 bootloader。这一步完成以后,把键盘插到电脑上,在设备管理器中就可以识别到了。 烧写 bootloader 是指将一个预先写入的程序代码写入到芯片中,以便在每次复位时芯片先加载 bootloader,实现一些设置和功能,再开始执行代码。来源
- 【软件】制作键盘固件,可理解为写代码来规定键盘上的哪个键对应了电脑上的哪个键,这一步还只有代码。
- 【软件】烧写固件,把上一步中的代码烧写到芯片中,这个时候键盘功能就完成了,就是外观还很原始。
- 【硬件】用 3D 打印机打印键盘外壳。
- 【硬件】 组装为成品键盘。
操作系统的目的是管理计算机的硬件和软件资源,并提供运行应用程序的平台。
如果没有操作系统,程序员就要直接和硬件打交道,比如需要学习磁盘的驱动操作相关的接口才能往磁盘上写文件,如果电脑上装的不是磁盘而是固态硬盘,又需要学习固态硬盘的驱动接口。
有了操作系统以后,有操作系统来跟各种不同的驱动打交道,然后提供一个统一的接口给程序员,不管电脑上装的是哪种硬盘,程序员都只需要调用同一个接口。
注:这里只是举了一个简单的例子。操作系统的功能还有很多。
操作系统 | 平台 | 用户界面 | 特点 |
---|---|---|---|
Windows | 个人电脑 | 图形用户界面 (GUI) | 提供各种软件,包括游戏、生产力软件和娱乐软件 |
macOS | 个人电脑 | 图形用户界面 (GUI) | 用户友好的界面,稳定且安全,被许多创意专业人士使用 |
Android | 智能手机、平板电脑 | 基于触摸屏的图形用户界面 (GUI) | 灵活且可定制,被广泛的用户使用 |
iOS | 智能手机、平板电脑 | 基于触摸屏的图形用户界面 (GUI) | 简单易用,被广泛的用户使用 |
Linux | 个人电脑、服务器、其他高端系统 | 文本或图形用户界面 (GUI) | 稳定且安全,被各种用户使用,包括家庭用户和企业 |
注:Android 是基于 Linux 的。
本文以后只聚焦于 Linux 操作系统。
unix家族 https://upload.wikimedia.org/wikipedia/commons/7/77/Unix_history-simple.svg
特征 | Linux内核 | Linux发行版 |
---|---|---|
目的 | 管理计算机的硬件和软件资源 | 提供一个完整的操作系统,可以直接使用 |
开发 | 由全球开发人员社区开发的开源软件项目 | 由开发团队或公司开发 |
许可证 | 免费和开源软件 | 根据发行版而异 |
可用性 | 可从各种网站下载 | 可从发行版网站下载 |
Linux发行版是基于Linux内核的一组软件集合。它包括内核以及各种其他软件,例如GNU工具、X Window系统和桌面环境。
Linux 发行版 | 市场份额 |
---|---|
Ubuntu | 33.9% |
Debian | 16% |
CentOS | 9.3% |
RedHat Linux | 0.8% |
Fedora | 0.5% |
SuSE | 0.2% |
功能 | 描述 |
---|---|
内存管理 | 管理计算机的内存,确保每个应用程序都可以访问其所需的内存。 |
进程管理 | 管理计算机的进程,确保它们按时和高效地执行。 |
文件管理 | 管理计算机的文件,为用户提供了一种存储、检索和组织文件的方式。 |
输入/输出 (I/O) 管理 | 管理计算机的 I/O 设备,如键盘、鼠标、打印机和硬盘。 |
安全性 | 提供安全功能,以保护计算机免受未经授权的访问和恶意软件的侵害。 |
网络 | 提供网络功能,允许用户连接到其他计算机和互联网。 |
硬件支持 | 提供对各种硬件设备的支持,包括打印机、扫描仪和网络摄像头。 |
用户界面 | 提供用户界面,允许用户与计算机交互。 |
管理员工具 | 提供了用于系统管理员管理计算机的工具。 |
部分 | 说明 |
---|---|
虚拟化 Virtualization | 操作系统将物理(physical)资源(如处理器、内存或磁盘)转换为更通用、更强大且更易于使用的虚拟形式。 |
并发 Concurrency | 指在同时(并发地)处理很多事情时出现且必须解决的问题。 |
持久性 Persistence | 通过硬件和软件来持久的保存数据(因为内存中的数据是容易丢失的)。 |
安全 Security |
来源:Operating Systems: Three Easy Pieces - intro
一个运行的程序只做了一件简单的事情:执行指令。
将单个 CPU(或其中一小部分)转换为看似无限数量的 CPU,从而让许多程序看似同时运行,这就是所谓的虚拟化 CPU(virtualizing the CPU)。
每个进程访问自己的私有虚拟地址空间,操作系统以某种方式映射到机器的物理内存上。两个进程同时修改对本进程而言是 0x200000 的虚拟地址,但是操作系统会将这些修改映射到不同的物理内存地址上,因此两个进程之间互相没有影响。
虚拟地址空间(virtual address space)(有时称为地址空间,address space)。
时期 | 说明 |
---|---|
早期操作系统:只是一些库 | 只是一组常用函数库。需要一个操作员,由操作员在大型机系统上一次运行一个程序。 |
超越库:保护 | 出现了系统调用,出现了用户态和内核态,通过内核态的特权来保护资源。此时还是一次只能执行一个程序。 |
多道程序时代 | 操作系统不是一一只运行一项作业,而是将大量作业加载到内存中甚在它们之间快速切换,从而提高 CPU 利用率。 |
摩登时代 | 想法不断发展,为用户和应用程序提供更多功能,让现现系统更加完善。 |
来源:Operating Systems: Three Easy Pieces - intro
进程是正在运行的程序。
在许多操作系统中,一个通用的设计范式是将高级策略与其低级机制分开。
你可以将机制看成为系统的“如何(how)”问题提供答案。例如,操作系统如何执行上下文切换?
策略为“哪个(which)”问题提供答案。例如,操作系统现在应该运行哪个进程?
将两者分开可以轻松地改变策略,而不必重新考虑机制,因此这是一种模块化(modularity)的形式,一种通用的软件设计原则。
举个例子(这是维基百科上的例子,基于我自己的理解,描述如下):
现在有一扇门,只允许一部分人通过,怎么实现这个功能?答案是上锁,然后给一部分人发钥匙。
假设现在有两种锁:一种是用普通钥匙进入的,我们叫它『钥匙锁』;另一种是用门禁卡进入的,我们叫它『门禁卡锁』。
在钥匙锁的情况下,假设我昨天把钥匙发给了张三和李四,张三和李四都拿着钥匙走了。今天我忽然发现张三是个法外狂徒,我又不想让张三进门了。这种情况下我只有一个办法,就是换锁,然后把新的钥匙发给李四。你可以把这里的锁理解为机制,进门规则(哪些人能进门)理解为策略。策略修改了(不让张三进门了)导致机制也要跟着修改(需要换锁),这就是机制与策略未分离的情况。
在门禁卡锁的情况下,假设系统是联网的,刷卡的时候会请求服务器,服务器判断这张卡有没有权限打开这扇门。当我想阻止张三进门的时候,只需要在服务器上把张三那张卡的权限禁用就可以了。策略修改了(不让张三进门了)但是机制不需要修改(不需要换锁),这就是机制与策略分离的情况。
维基百科:Separation_of_mechanism_and_policy
区别 | 栈内存 | 堆内存 |
---|---|---|
分配方式 | 编译器自动分配和释放 | 程序员手动申请和释放 |
存储内容 | 函数参数、局部变量、临时变量等等 | 程序运行中动态分配的内存空间,如new出来的对象和数组 |
存储速度 | 快,仅次于寄存器 | 慢 |
存储大小 | 小 | 大 |
碎片问题 | 不会出现碎片问题 | 容易出现碎片问题 |
只用一种内存区域也可以完成所有的功能,但是效率会相对低一些。 如果分成两块内存区域,不同的数据结构存在不同的地方,可以提高效率。
注:除了这两种内存区以外,还有: 只读段(包括代码和常量等) 数据段(包括全局变量等) 文件映射段(包括动态库、共享内存等)