AI时代,我们的价值在于:从程序员教练的角度审查AI的方案是否完善、AI的代码是否健壮。此专栏,将会和大家一起返璞归真,牢固计算机底层原理知识,让人人都能成为优秀程序员教练,以应对AI浪潮的到来,欢迎订阅,一起成长!
之所以说是最熟悉的陌生人,是因为我们每天的编码中都会和他打交道,比如读取文件、通过HTTP进行接口调用等。下面用一个生活中的例子来讲明白这俩概念。
一:你和你的零花钱
在这个没有公平、正义可言的世界,虽然你家的收入大部分来自于你的功劳,但是很抱歉,你和你的工资完全是隔离状态,你没有权限直接操作它!
1.1 工资入账操作
工资发放之后,第一时间要向媳妇执行入账操作,通常情况下这种操作不需要什么特别的权限,因此都会顺利的执行完毕,且该执行一般没有返回值。
1.2 零花钱使用操作
每逢周五,作为爷们的你,骚动的心总是难以按捺。这时候,哥们叫上你出去撸一把串子时,你就需要触发一下零花钱请求操作。因为这个操作会降低金库的价值,所以这个请求操作往往不能够被正常执行。
二:你们仨是什么关系?
在上图中,挣钱养家的你、貌美如花的她、你的工资 三者构成了一个运转的系统。在此系统中,你永远都没有任何权限直接操作你的工资,你对工资的操作永远都需要经过一个桥梁:你媳妇!
同样如此,在计算机系统中,硬件就类似于“工资”,我们编写的代码就像我们一样都是以“用户模式(低权限)”在运行,而媳妇就是操作系统(windows、linux、mac等)。
我们的代码如果想要操作cpu、硬盘等硬件时,是没有权限的,这时候需要通过高级语言标准库提供的API来请求操作系统对外提供的API,操作系统API执行的代码则是在“内核模式”下运行的。
挣钱养家的你:程序员编写的程序
貌美如花的他:操作系统
你的工资:计算机硬件/系统资源
三:代码举例
3.1 Java读取文件内容
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class ReadFileDemo {
public static void main(String[] args) {
String filePath = "path/to/your/file.txt"; // 替换为实际文件路径
BufferedReader reader = null;
try {
// 创建BufferedReader对象来读取文件
reader = new BufferedReader(new FileReader(filePath));
String line;
// 逐行读取文件内容
while ((line = reader.readLine()) != null) {
System.out.println(line); // 打印每一行
}
} catch (IOException e) {
e.printStackTrace(); // 异常处理
} finally {
// 关闭文件流
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
3.2 代码解释
1. 当执行new FileReader(filePath)时,Java应用程序(在用户模式下运行)发起一个打开文件的请求。
2. 这个请求通过Java的I/O库发给操作系统,由操作系统将请求转化为一个或多个系统调用。
3. 操作系统接收到系统调用后,会切换到内核模式,访问文件系统并且处理文件打开的操作。
4. 一旦文件被打开,操作系统会返回一个文件描述符(或句柄)给Java程序。
5. 当readLine()被调用时,Java程序再次通过系统调用请求操作系统从文件中读取数据。
6. 操作系统在内核模式下完成实际的文件读取操作,并将读取到的数据返回给Java应用程序。
7. Java程序接收到数据后,在用户模式下继续执行,例如打印这些数据到控制台。
8. 最后,当文件读取完成后,再次通过系统调用来关闭文件,操作系统在内核模式下关闭文件,并释放资源。
四:为什么要有这两种模式?
4.1 安全性
程序员的水平参差不齐,假如我们编写的程序可以直接操作硬件或者系统资源,这就有可能会破坏系统的稳定性和安全性,因为错误的操作会导致系统崩溃或安全漏洞。
操作系统的API是由系统研发团队内部设计出来的,他们的代码经过了充分的考虑和测试,所以能够提供安全的环境,确保对硬件的访问不会影响系统的稳定性和安全性。(当然,他们也会时不时的发布补丁来修复bug)
操作系统会在内核模式下管理所有硬件资源,对外提供API可供用户模式下的应用程序安全的来使用这些硬件资源。
4.2 便利性
假如允许用户模式访问硬件资源,那么这通常需要程序员编写复杂的低级代码来和硬件交互,而这在大多数使用高级语言编程的环境中是不现实的。
操作系统API通常易于使用,并隐藏了与硬件通信的复杂性。在C#、Java、Python等高级语言中,可以使用各种类库和框架,来轻松地进行文件操作、网络通信以及访问数据库和其他系统资源,而无需担心硬件层面的细节。
4.3 可移植性
与硬件通信的代码通常和操作系统平台和硬件本身有着极强的绑定关系,那么我们编写的与硬件交互的程序在不同的硬件和操作系统之间移植时会遇到各种各样的兼容性问题,但是操作系统提供的API通常是兼容了不同的硬件的。
五:思考题
你觉得Java能直接编写操作硬件的代码吗?欢迎在评论中发表您的观点,无关对错,旨在一起进步!