站长信息
jeffery.xu
jeffery.xu

软件工程师

欢迎访问我的个人笔记网站!我是一名热爱技术的开发者,专注于Web开发和技术分享。

811495111@qq.com
18521510875
筛选

个人笔记

第1章 计算机系统知识
软考

1.1 计算机系统基础知识

1.1.1 计算机系统硬件基本组成

计算机系统是由硬件软件组成的,它们协同工作来运行程序。计算机的基本硬件系统由运算器、控制器、存储器、输入设备和输出设备5大部件组成。运算器、控制器等部件被集成在一起统称为中央处理单元(Central Processing Unit,CPU)。CPU 是硬件系统的核心,用于数据的加工处理,能完成各种算术、逻辑运算及控制功能。存储器是计算机系统中的记忆设备,分为内部存储器和外部存储器。前者速度高、容量小,一般用于临时存放程序、数据及中间结果。而后者容量大、速度慢,可以长期保存程序和数据。输入设备和输出设备合称为外部设备(简称外设),输入设备用于输入原始数据及各种命令,而输出设备则用于输出计算机运行的结果。

Note: CPU包含运算器和控制器,存储器分为内存和外存,输入输出顾名思义。

1.1.2 中央处理单元

中央处理单元(CPU)是计算机系统的核心部件,它负责获取程序指令、对指令进行译码

并加以执行。



  1. CPU 的功能



    (1)程序控制。CPU 通过执行指令来控制程序的执行顺序,这是 CPU 的重要功能。


    (2)操作控制。一条指令功能的实现需要若干操作信号配合来完成,CPU产生每条指令的

操作信号并将操作信号送往对应的部件,控制相应的部件按指令的功能要求进行操作。



    (3)时间控制。CPU对各种操作进行时间上的控制,即指令执行过程中操作信号的出现时

间、持续时间及出现的时间顺序都需要进行严格控制。



    (4)数据处理。CPU 通过对数据进行算术运算及逻辑运算等方式进行加工处理,数据加工

处理的结果被人们所利用。所以,对数据的加工处理也是 CPU 最根本的任务。



    此外,CPU还需要对系统内部和外部的中断(异常)做出响应,进行相应的处理。

  2. CPU的组成

    CPU 主要由运算器、控制器、寄存器组和内部总线等部件组成,如图 1-1 所示。


1)运算器

运算器由算术逻辑单元(Arithmetic and Logic Unit,ALU)、累加寄存器、数据缓冲寄存

器和状态条件寄存器等组成,它是数据加工处理部件,用于完成计算机的各种算术和逻辑运算。

相对控制器而言,运算器接受控制器的命令而进行动作,即运算器所进行的全部操作都是由控

制器发出的控制信号来指挥的,所以它是执行部件。运算器有如下两个主要功能。

(1)执行所有的算术运算,例如加、减、乘、除等基本运算及附加运算。

(2)执行所有的逻辑运算并进行逻辑测试,例如与、或、非、零值测试或两个值的比较等。

下面简要介绍运算器中各组成部件的功能。

(1)算术逻辑单元(ALU)。ALU 是运算器的重要组成部件,负责处理数据,实现对数据的算术运算和逻辑运算。

(2)累加寄存器(AC)。AC通常简称为累加器,它是一个通用寄存器,其功能是当运算器的算术逻辑单元执行算术或逻辑运算时,为 ALU 提供一个工作区。例如,在执行一个减法运算前,先将被减数取出暂存在 AC 中,再从内存储器中取出减数,然后同 AC 的内容相减,将所得的结果送回 AC 中。运算的结果是放在累加器中的,运算器中至少要有一个累加寄存器

(3)数据缓冲寄存器(DR)。在对内存储器进行读/写操作时,用 DR 暂时存放由内存储器读/写的一条指令或一个数据字,将不同时间段内读/写的数据隔离开来。DR 的主要作用为:作为 CPU 和内存、外部设备之间数据传送的中转站;作为 CPU 和内存、外围设备之间在操作速度上的缓冲;在单累加器结构的运算器中,数据缓冲寄存器还可兼作为操作数寄存器。

(4)状态条件寄存器(PSW)。PSW 保存由算术指令和逻辑指令运行或测试的结果建立的各种条件码内容,主要分为状态标志和控制标志,例如运算结果进位标志(C)、运算结果溢出标志(V)、运算结果为0标志(Z)、运算结果为负标志(N)、中断标志(I)、方向标志(D)和单步标志等。这些标志通常分别由1位触发器保存,保存了当前指令执行完成之后的状态。通常,一个算术操作产生一个运算结果,而一个逻辑操作产生一个判决。

2)控制器

运算器只能完成运算,而控制器用于控制整个 CPU 的工作,它决定了计算机运行过程的自动化。它不仅要保证程序的正确执行,而且要能够处理异常事件。控制器一般包括指令控制逻辑、时序控制逻辑、总线控制逻辑和中断控制逻辑等几个部分。

指令控制逻辑要完成取指令、分析指令和执行指令的操作,其过程分为取指令、指令译码、按指令操作码执行、形成下一条指令地址等步骤。

(1)指令寄存器(IR)。当CPU执行一条指令时,先把它从内存储器取到缓冲寄存器中,再送入 I 暂存,指令译码器根据 I 的内容产生各种微操作指令,控制其他的组成部件工作,完成所需的功能。

(2)程序计数器(PC)。PC 具有寄存信息和计数两种功能,又称为指令计数器。程序的执行分两种情况,一是顺序执行,二是转移执行。在程序开始执行前,将程序的起始地址送入PC,该地址在程序加载到内存时确定,因此PC的内容即是程序第一条指令的地址。执行指令时,CPU 自动修改 PC的内容,以便使其保持的总是将要执行的下一条指令的地址。由于大多数指令都是按顺序来执行的,所以修改的过程通常只是简单地对 PC加1。当遇到转移指令时,后继指令的地址根据当前指令的地址加上一个向前或向后转移的位移量得到,或者根据转移指令给出的直接转移的地址得到。

(3)地址寄存器(AR)。AR 保存当前 CPU 所访问的内存单元的地址。由于内存和 CPU存在着操作速度上的差异,所以需要使用 AR 保持地址信息,直到内存的读/写操作完成为止。

(4)指令译码器(ID)。指令包含操作码和地址码两部分,为了能执行任何给定的指令,必须对操作码进行分析,以便识别所完成的操作。指令译码器就是对指令中的操作码字段进行分析解释,识别该指令规定的操作,向操作控制器发出具体的控制信号,控制各部件工作,完成所需的功能。

时序控制逻辑要为每条指令按时间顺序提供应有的控制信号。总线逻辑是为多个功能部件服务的信息通路的控制电路。中断控制逻辑用于控制各种中断请求,并根据优先级的高低对中断请求进行排队,逐个交给 CPU 处理。

3)寄存器组

寄存器组可分为专用寄存器和通用寄存器。运算器和控制器中的寄存器是专用寄存器,其作用是固定的。通用寄存器用途广泛并可由程序员规定其用途,其数目因处理器不同有所差异。

  1. 多核 CPU

核心又称为内核,是 CPU 最重要的组成部分。CPU 中心那块降起的芯片就是核心,是由单品硅以一定的生产工艺制造出来的,CPU 所有的计算、接收/存储命令、处理数据都由核心执行。各种 CPU 核心都具有固定的逻辑结构,一级缓存、二级缓存、执行单元、指令级单元和总线接口等逻辑单元都会有合理的布局。

多核即在一个单芯片上面集成两个甚至更多个处理器内核,其中,每个内核都有自己的逻辑单元、控制单元、中断处理器、运算单元,一级 Cache、二级 Cache 共享或独有,其部件的完整性和单核处理器内核相比完全一致。

CPU 的主要厂商 AMD 和 Intel 的双核技术在物理结构上有所不同。AMD 将两个内核做在一个 Die(晶元)上,通过直连架构连接起来,集成度更高。Intel 则是将放在不同核心上的两个内核封装在一起,因此将 Intel 的方案称为“双芯”,将 AMD 的方案称为“双核”。从用户端的角度来看,AMD 的方案能够使双核 CPU 的管脚、功耗等指标跟单核 CPU 保持一致,从单核升级到双核,不需要更换电源、芯片组、散热系统和主板,只需要刷新 BIOS 软件即可。

多核 CPU 系统最大的优点(也是开发的最主要目的)是可满足用户同时进行多任务处理的要求。

单核多线程 CPU 是交替地转换执行多个任务,只不过交替转换的时间很短,用户一般感觉不出来。如果同时执行的任务太多,就会感觉到“慢”或者“卡”。而多核在理论上则是在任何时间内每个核执行各自的任务,不存在交替问题。因此,单核多线程和多核(一般每核也是多线程的)虽然都可以执行多任务,但多核的速度更快。

虽然采用了 Intel 超线程技术的单核可以视为是双核,4 核可以视为是8核。然而,视为是8 核一般比不上实际是8核的 CPU 性能。

要发挥 CPU的多核性能,就需要操作系统能够及时、合理地给各个核分配任务和资源(如缓存、总线、内存等),也需要应用软件在运行时可以把并行的线程同时交付给多个核心分别处理。

批量删除功能
java学习

前端

// 批量删除权限
async deletePermissions(ids: number[]): Promise<void> {
const response = await request.post<ApiResponse<void>>('/permissionAction/batch_delete', {
ids
})
if (response.code !== 200) {
throw new Error(response.message || '批量删除权限失败')
}
},

后端
controller
@PostMapping("/batch_delete")
public R<String> batchDeleteMenus(@RequestBody BatchDeleteDTO dto) {
try {
boolean success = permissionActionService.batchDelete(dto.getIds());
if (success) {
return R.ok("批量删除菜单成功");
} else {
return R.error("批量删除菜单失败");
}
} catch (Exception e) {
return R.error("批量删除菜单失败:" + e.getMessage());
}
}

Service
boolean batchDelete(List<Long> ids);

@Override
public boolean batchDelete(List<Long> ids) {
return permissionActionMapper.deleteBatchIds(ids)>0;
}

mapper
int deleteBatchIds(@Param("ids") List<Long> ids);

XML
<delete id="deleteBatchIds" parameterType="java.util.List">
DELETE FROM permission_action
WHERE id IN
<foreach collection="ids" item="id" open="(" separator="," close=")">
#{id}
</foreach>
</delete>







Promise
java学习

Promise 是 JavaScript 中用于处理异步操作的对象。它代表一个可能还未完成但最终会完成的操作,并返回结果。Promise 有三种状态:等待(pending)、已完成(fulfilled)、已拒绝(rejected)。你可以用 .then() 处理成功结果,用 .catch() 处理失败结果。这样可以避免回调地狱,让异步代码更清晰易读。

emit
java学习

emit 是 Vue 组件中用于触发自定义事件的方法。它可以让子组件向父组件发送消息或数据。

const emit = defineEmits(['update:currentPage'])
emit('update:currentPage', page) // 触发事件并传递参数

父组件可以通过 @update:currentPage="方法" 监听这个事件,实现子传父

vue与angular之间的区别
java学习
Vue.js与Angular的应用场景

1)何时选择使用Vue.js前端框架

(1)如果开发的时候希望以最简单的方式来制作Web应用程序,那么应该选择Vue.js。如果对JavaScript的知识基础掌握不太好,或者有严格的开发截止日期,短时间内不能完成,Vue.js将是一个很好的选择。

(2)如果使用的前端是Laravel,那么可以选择使用Vue.js进行开发。Laravel社区的开发者认为,Vue.js是比较适用的框架,使用Vue.js会将总处理时间缩短50%左右,并释放服务器上的空间。

(3)如果是开发小规模应用系统或者开发时不喜欢受到开发的约束,请选择Vue.js。

(4)如果开发者很熟悉使用ES 5 JavaScript和HTML,那么可以完全使用Vue.js完成开发项目。

(5)如果想要在浏览器中编译模板且使用其简单性,使用独立版本的Vue.js会比较好。

(6)如果打算构建性能关键型SPA或需要功能范围的CSS,使用Vue.js开发的单文件组件会非常完美。

2)何时选择使用Angular前端框架

(1)如果需要构建大型复杂的应用程序,那么应该选择Angular,因为Angular为客户端应用程序开发提供了一个完整而全面的解决方案。

(2)对于希望处理客户端和服务器端模式的开发者来说,Angular是一个不错的选择。开发者喜欢Angular的主要原因是,它能够使他们专注于任何类型的设计(无论是jQuery调用还是DOM配置干扰)。

(3)对于创建具有多个组件和复杂需求的Web应用程序来说,Angular也同样适用。当选择Angular时,本地开发者会更容易理解应用程序功能和编码结构。

(4)如果想在新项目中选择现有组件,也可以选择Angular,因为只需复制和粘贴代码即可。

(5)Angular可以使用双向数据绑定功能来管理DOM和模型之间的同步。这使得Angular成了Web应用程序开发的强有力工具。对于希望制作更轻更快Web应用程序的开发者来说,可以选择使用Angular中的MVC结构和独立的逻辑及数据组件,这有助于加速开发过程。

5.Vue.js和Angular的代码比较

分析Vue.js和Angular的代码、包含标记、样式和行为的代码可以帮助开发者构建高效且可重用的接口。在Angular中,控制器和指令等实体包含在模块中,而在Vue.js中的模块中包含组件逻辑。

Vue.js组件,代码如下:

    Vue.extend({
       data: function(){ return{…} },
       created: function(){…},
       ready: function(){…},
       components:{…},
       methods:{…},
       watch:{…}
    });

Angular模块,代码如下:

    angular.module('myModule', […]);

相比Vue.js,Angular中的directive更加强大。

Vue.js指令,代码如下:

    Vue.directive('my-directive', {
       bind: function(){…},
       update: function(newValue, oldValue){…},
       unbind: function(){…}
    });

Angular指令,代码如下:

由于Vue.js受到Angular的启发借用了其模板语法,因此这两个框架的循环、插值和条件的语法都非常相似。例如,下面给出的代码片段。

    //Vue插值
    {{myVariable}}
    //Angular插值
    {{myVariable}}
    //Vue循环
    <li v-repeat="items" class="item-{{$index}}">
    {{myProperty}}</li>
    //Angular循环
    <li ng-repeat="item in items" class="item-{{$index}}">
    {{item.myProperty}}</li>
    //Vue条件
    <div v-if="myVar"></div>
    <div v-show="myVar"></div>
    //Angular条件
    <div ng-if="myVar"></div>
    <div ng-show="myVar"></div>

Vue.js的编码使页面渲染变得非常简单。事实上,Vue.js更像是一个库,而不是框架,因为它不提供Angular的所有功能。开发者不得不使用Vue.js的第三方代码,而Angular提供了HTTP请求服务或路由器等功能。

总之,Vue.js是轻量级的开发框架,很适合开发小规模的Web应用程序;而Angular尽管学习曲线较为陡峭,但却是构建完整复杂应用程序的好工具。

MVP模式介绍
java学习

MVP的英文全称为Model View Presenter,它是从经典的MVC模式演变而来的。它们的基本思想有相通的地方:Controller/Presenter负责逻辑的处理,Model提供数据,View负责显示。MVP从MVC演变而来,通过表示器将视图与模型巧妙地分开。在该模式中,视图通常由表示器初始化,它负责呈现用户界面(UI),并接收用户所发出的命令,但不对用户的输入做任何逻辑处理,而仅仅是将用户输入转发给表示器。通常每一个视图对应一个表示器,但是也可能一个拥有较复杂业务逻辑的视图会对应多个表示器,每个表示器完成该视图的一部分业务处理工作,降低了单个表示器的复杂程度;一个表示器也能被多个有着相同业务需求的视图复用,增加单个表示器的复用度。表示器包含大多数表示逻辑,用以处理视图,与模型交互以获取或更新数据等。模型描述了系统的处理逻辑,但对于表示器和视图一无所知。

1.MVP模式的优点

MVP模式的优点体现在以下三个方面。

(1)View与Model完全隔离。Model和View之间具有良好解耦性的设计,这就意味着,如果Model或View中的一方发生变化,只要交互接口不发生变化,另一方就无须对上述变化做出相应的变化,这使得Model层的业务逻辑具有很好的灵活性和可重用性。

(2)Presenter与View的具体实现技术无关。也就是说,采用诸如Windows表单、WPF(Windows Presentation Foundation)框架、Web表单等用户界面构建技术中的任意一种来实现View层,都无须改变系统的其他部分。甚至为了使B/S、C/S部署架构能够被同时支持,应用程序可以用同一个Model层适配多种技术构建的View层。

(3)可以进行View的模拟测试。由于View和Model之间的紧耦合,在Model和View同时开发完成前对其中一方进行测试是不可能的。出于同样的原因,对View或Model进行单元测试很困难。MVP模式解决了上述所有的问题。在MVP模式中,View和Model之间没有直接依赖,开发者能够借助模拟对象注入测试两者中的任意一方。

2.MVP模式与MVC模式的区别

MVP模式示意图如图1-1所示。作为一种新的模式,MVP与MVC有着一个重大的区别:在MVP中View并不直接使用Model,它们之间的通信是通过Controller来进行的,所有的交互都发生在Controller内部;而在MVC中View会直接从Model中读取数据,而不是通过Controller。在MVC中,View是可以直接访问Model的。View中会包含Model信息,不可避免地还要包括一些业务逻辑。在MVC模式中,更关注Model的不变,而同时有多个对Model的不同显示及View。所以在MVC模式中,Model不依赖于View,但View是依赖于Model的。不仅如此,因为有一些业务逻辑在View中实现,导致要更改View也是比较困难的,至少那些业务逻辑是无法重用的,代码复用率低。

图1-1 MVP模式

Boolean boolean的区别
java学习

Boolean 是 Java 的包装类,boolean 是基本类型。


boolean:基本类型,占 1 位,默认值是 false,不能为 null。
Boolean:包装类,可以为 null,有更多方法(如 toString()、parseBoolean()),常用于对象、泛型、集合等场景。
举例:

boolean a = false;      // 只能 true/false
Boolean b = null;       // 可以为 null

node装完 npm没法运行
java学习

Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy Bypass

注意:放宽执行策略有安全风险,仅在信任的环境下操作。

npm --install 出错
java学习

一定要在package.json下运行

 

配置Spring Boot 调试
java学习

在 IntelliJ IDEA 中配置调试 Spring Boot 项目步骤如下:


打开项目,点击右上角的“运行/调试配置”按钮(或菜单栏 Run -> Edit Configurations)。
点击左上角“+”,选择“Spring Boot”或“Application”。
填写主类(如 com.mobizone.kb.YourApplication),确保 VM options、Program arguments、Working directory 等参数正确。
点击“确定”保存配置。
点击绿色虫子图标(Debug)启动调试模式。
这样就可以在代码中设置断点,调试 Spring Boot 项目了。