我眼中的计算机:硬件、操作系统、应用程序

1.计算机 = 硬件 + 操作系统 + 应用程序

 

有人说过,计算机世界的绝大部分问题都可以通过分层的方法来解决。从一个程序员的角度,我比较喜欢将计算机分为三层,自底向上分别为:

1) 硬件(Hardware),按照冯氏的结构定义,一个处理器由5个部分构成,分别为:存储器;控制器;运算器;输入设备;输出设备。对于常见的计算机而言,存储器如常见的外存储设备;CPU则包含运算器、控制器和内存储;输入输出(I/O)很好理解,这里就不写了。

2) 操作系统:Operation System,操作系统主要负责管理计算机硬件资源,控制其他程序运行并为用户提供交互操作界面的系统软件的集合。讲的具体一点如进程、线程管理;内存管理;信号量机制;IO管理等。最常见OS的如Windows,又如HP-UX、SUSE、VxWorks(嵌入式)。

3) 应用程序层:Application,应用层,指使用各种不同的编程语言(C、C++、JAVA、Ruby、Python,太多了,写不完)、通过各种开发工具并基于各种操作系统开发的——软件。该部分是大部分程序员工作的一层,也是构成我们丰富多彩的生活最直接的一部分。常见的如Word是软件,QQ亦是软件。

 

2.那些围绕在我们身边的“计算机”

 

根据上面的分层,对应一下常见的计算机:

最常见的计算机莫过于个人PC,其硬件部分(主要讲CPU)当前最主流的当属Intel和AMD的产品,操作系统对应的如Windows(现在应该是Windows8了,当然如果自己装Linux也有可能),对于基于Windows的应用程序开发,其IDE如微软提供的Virual Studio, VC 6.0等。APP如Word,还有当前用来写文章的Maxthon。

再如华为公司的ATAE,其CPU主要采用Intel的x84_64,操作系统采用SUSE10 Linux,编译器为gcc/g++,其应用程序如FTP。

在服务器世界里,还有惠普公司的HP-UX、IBM的工作站,其对应的操作系统分别为HP Unix、AIX,编译器分别为aCC与xLC。还有那个曾经的SUN也有对应的产品,这里就不提了。

 

3.程序员在做什么?

 

对于一个程序员而言,主要在从事APP层的开发工作,如果主要从事C/C++,最直接接触的当属OS层。所以要写好程序,必须去了解操作系统的机制,不同的操作系统都有着不同的限制和调度机制。首当其冲的编译器的机制必须要去了解,比如gcc和g++,其常用的参数有哪些,每个参数代表什么含义,有什么限制?Makefile如何编写?基于该OS开发的程序如何进行调试?操作系统的信号量机制有哪些?同理,对于JAVA的开发而言,最直接的打交道的应该是JVM,可以理解为一个简单的操作系统,所以必须去了解JVM的调度机制,如内存管理、GC机制如何运作?调试工具如jvisualVM、jMap如何使用?

再深一层,就要了解到硬件的限制,如CPU的调度机制、汇编指令、IO等。比如代码a = a+1和a++转变成汇编指令有什么区别,怎样写才是高效的?HP Unix的aCC编译器,“+u1”参数后对生成的汇编指令有何影响?大尾端和小尾端有什么区别,与网络字节序又有何关系?再如,为什么要使用多线程编程,在编码时引入多线程的目的是什么?

上面主要简单描述了一个程序员眼中的计算机分层,那么对于我们的产品——APP或者叫做“软件”,内部又是怎样构成的呢?

 

4.软件/程序 是什么?

 

从技术角度而言,软件在运行态可以理解为一个个的进程,其内部可能有几个线程构成。上过操作系统课的同学应该有两句话印象深刻(上课睡觉,作业抄袭的除外):“进程是拥有资源的最小单位,线程是CPU调度的最小单位。”

画个图吧:

每个运行态的应用程序,可以称其为Process,每个Process对应有一个身份标识(PID)。其内部包含1到N个线程,每个线程也有自己的线程句柄。CPU以线程为单位进行调度,资源如MEMORY, CPU, IO等统一由进程拥有,换句话讲Thread1至Thread N均可以直接访问进程所拥有的资源。因此对于多线程程序而言,其资源存在并发访问的可能性,比如对于同一个变量a,Thread1在进行a = 1的时候,Thread 2可能“同时”在进行a = 2的操作,这个操作的结果就是a的赋值结果不可预知。如果Thread1在前,Thread 2在后,那么a最终等于2,反之a最终等于1。对于类似于a这类资源,我们可以定义其为“临界资源”,对于临界资源的保护,成为多线程编程必须面临而又必须解决的问题。

由于进程拥有着计算机的资源,因而其内部线程可以方便的访问其内部的各种资源。比如对于内存而言,Thread1可以通过地址访问到Process内部相应的内存块,Thread2也可以访问到Process内部的对应地址。

 

5.程序世界

 

每个计算机上面都不可能仅仅存在一个Process,运行期间,必然是有各种各样的Process构成,如下图:

但问题来了,如果Process1想访问Process2内部的数据,该如何处理呢?进程与进程间的数据访问,通过进程间通信(IPC)来解决,Linux下常见的进程间通信方式如共享内存、管道、Socket等(参见《Linux环境高级编程》,这里不多写了,后面再详细写)。

进程的构造弄清楚了,那进程/程序究竟在做什么?我理解的,程序无非是对于输入的信息/数据进行一定的处理,然后提供一定的输出。

 

对于输入的数据,可能是数据库的数据存储、可能是网络上的一串码流、抑或是我们单击了一下鼠标。逻辑处理即是对这些输入进行了一系列的数学运算,比如点击了12306上面的“订票”按钮,后台就要计算当前的余票信息,提交的订票信息,最终告诉你有没有票。“有没有票”即是程序的输出。更广泛意义的讲,输出可能是一个网络消息或修改数据库的某个字段的值(软件的所有输出均限制于计算机世界中,记得当年还曾怀疑过究竟人会不会被计算机病毒感染)。所以有人说了:“程序其实很简单,无非是找个编程语言,写串逻辑,处理下数据,偶尔连下数据库,或跟其它进程通通信”。


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
学生管理系统是一个典型的基于Web的信息系统,它可以帮助学校或教育机构管理学生的个人信息、学习记录、成绩等数据。下面是一个简单的学生管理系统的示例,使用HTML、CSS和JavaScript实现前端页面,使用PHP和MySQL实现后端的数据处理和管理。 1. 创建数据库 首先,需要创建一个MySQL数据库,用于存储学生信息、成绩和课程等数据。可以使用以下SQL语句创建一个名为`student`的数据库: ```sql CREATE DATABASE student; ``` 然后,创建一个名为`students`的学生表,用于存储学生的个人信息: ```sql USE student; CREATE TABLE students ( id INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY, name VARCHAR(50) NOT NULL, gender VARCHAR(10) NOT NULL, birthday DATE NOT NULL, major VARCHAR(50) NOT NULL, grade VARCHAR(20) NOT NULL ); ``` 2. 创建前端页面 接下来,使用HTML、CSS和JavaScript创建一个基本的学生管理系统前端页面。可以使用以下代码作为参考: ```html <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>学生管理系统</title> <link rel="stylesheet" href="style.css"> </head> <body> <h1>学生管理系统</h1> <div class="form"> <h2>添加学生</h2> <form> <label>姓名:</label> <input type="text" id="name" name="name"><br> <label>性别:</label> <input type="radio" id="male" name="gender" value="男"><label for="male">男</label> <input type="radio" id="female" name="gender" value="女"><label for="female">女</label><br> <label>出生日期:</label> <input type="date" id="birthday" name="birthday"><br> <label>专业:</label> <input type="text" id="major" name="major"><br> <label>年级:</label> <input type="text" id="grade" name="grade"><br> <input type="button" value="添加" onclick="addStudent()"> <input type="reset" value="重置"> </form> </div> <div class="table"> <h2>学生列表</h2> <table> <thead> <tr> <th>ID</th> <th>姓名</th> <th>性别</th> <th>出生日期</th> <th>专业</th> <th>年级</th> <th>操作</th> </tr> </thead> <tbody id="student-list"> </tbody> </table> </div> <script src="main.js"></script> </body> </html> ``` 该页面包含一个表单用于添加学生,以及一个表格用于显示学生列表。在`<head>`标签中引入了一个样式文件`style.css`和一个JavaScript文件`main.js`。 3. 创建后端接口 接着,需要创建后端接口,用于处理前端页面提交的数据,并将数据存储到MySQL数据库中。可以使用PHP编写后端接口,以下是一个简单的示例: ```php <?php // 连接数据库 $conn = mysqli_connect("localhost", "root", "password", "student"); // 处理添加学生请求 if ($_SERVER["REQUEST_METHOD"] == "POST") { $name = $_POST["name"]; $gender = $_POST["gender"]; $birthday = $_POST["birthday"]; $major = $_POST["major"]; $grade = $_POST["grade"]; // 插入学生数据到数据库 $sql = "INSERT INTO students (name, gender, birthday, major, grade) VALUES ('$name', '$gender', '$birthday', '$major', '$grade')"; mysqli_query($conn, $sql); } // 处理获取学生列表请求 if ($_SERVER["REQUEST_METHOD"] == "GET") { $sql = "SELECT * FROM students"; $result = mysqli_query($conn, $sql); // 将学生数据转换为JSON格式返回给前端 $students = array(); while ($row = mysqli_fetch_assoc($result)) { $students[] = $row; } echo json_encode($students); } // 关闭数据库连接 mysqli_close($conn); ?> ``` 该接口处理前端页面提交的添加学生请求和获取学生列表请求,将数据存储到MySQL数据库中或从数据库中获取数据,并将学生数据转换为JSON格式返回给前端。 4. 创建JavaScript文件 最后,需要创建一个JavaScript文件,用于调用后端接口,并将学生数据显示在前端页面上。可以使用以下代码作为参考: ```javascript // 获取学生列表 function getStudentList() { fetch("api.php") .then(response => response.json()) .then(data => { // 清空列表 const studentList = document.getElementById("student-list"); studentList.innerHTML = ""; // 遍历学生数据,添加到列表中 data.forEach(student => { const tr = document.createElement("tr"); tr.innerHTML = ` <td>${student.id}</td> <td>${student.name}</td> <td>${student.gender}</td> <td>${student.birthday}</td> <td>${student.major}</td> <td>${student.grade}</td> <td><button onclick="deleteStudent(${student.id})">删除</button></td> `; studentList.appendChild(tr); }); }); } // 添加学生 function addStudent() { const form = document.querySelector("form"); const name = form.elements["name"].value; const gender = form.elements["gender"].value; const birthday = form.elements["birthday"].value; const major = form.elements["major"].value; const grade = form.elements["grade"].value; // 提交数据到后端接口 fetch("api.php", { method: "POST", headers: { "Content-Type": "application/x-www-form-urlencoded" }, body: `name=${name}&gender=${gender}&birthday=${birthday}&major=${major}&grade=${grade}` }) .then(() => { // 添加成功后刷新学生列表 getStudentList(); form.reset(); }); } // 删除学生 function deleteStudent(id) { // 向后端接口发送删除请求 fetch(`api.php?id=${id}`, { method: "DELETE" }) .then(() => { // 删除成功后刷新学生列表 getStudentList(); }); } // 页面加载完成后获取学生列表 document.addEventListener("DOMContentLoaded", () => { getStudentList(); }); ``` 该JavaScript文件包含了三个函数,分别用于获取学生列表、添加学生和删除学生。其中,`getStudentList()`函数使用`fetch()`函数向后端接口发送获取学生列表请求,并将学生数据显示在前端页面的表格中;`addStudent()`函数从表单中获取学生数据,使用`fetch()`函数向后端接口发送添加学生请求,并在成功添加后刷新学生列表;`deleteStudent()`函数向后端接口发送删除学生请求,并在成功删除后刷新学生列表。最后,页面加载完成后调用`getStudentList()`函数获取学生列表并显示在表格中。 综上所述,以上示例是一个简单的学生管理系统的实现,使用HTML、CSS和JavaScript实现前端页面,使用PHP和MySQL实现后端的数据处理和管理。但是需要注意的是,该示例仅作为学习参考,实际的学生管理系统需要更加复杂的功能和数据处理能力,需要更加完善的前后端技术和架构支持。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值