韩源-末日生存手册 - 函数
type: channel
link: https://kerryhan.cn/index.php/tag/函数/
items: MySQL自定义排序
items: 【数据结构】绪论
items: 【C++】概述
items: 《深入理解计算机系统》之计算机系统漫游
items: vue挂载流程和模板编译
items: springboot+mybatisPlus代码层级梳理

MySQL自定义排序
type: item
date: 2023-11-23T09:24:35+00:00
description: 使用CASE语句进行自定义排序SELECT column_name(s) FROM table_name ORDER BY CASE column_name WHEN 'value1' THEN ... WHEN 'value2' THEN ... ELSE ... END; 使用FIELD函数进行自定义排序SELECT column_name(s) FROM table_name ORDER BY FIELD(column_name, value1, value2, ...) mybatis-plus中querywrapper使用 //设置是否置顶、截至日期优先展示 queryWrapper.orderByDesc("is_top", "deadline"); //设置任务未完成的优先展示，FIELD是数据库函数 queryWrapper.orderByAsc(" FIELD(state,'unfinish','finish') ");

【数据结构】绪论
type: item
date: 2022-03-14T03:48:05+00:00
description: 【数据结构】绪论定义数据项：具有独立含义的数据最小单位，也称为字段或域数据对象：性质相同的数据元素的集合，是数据的一个子集数据结构：所有数据以及数据元素之间的关系，可以看成是相互之间存在着某种特定关系的数据元素的集合逻辑结构集合数据元素同属一个集合线性结构数据元素之间存在一对一关系树形结构数据元素之间存在一对多关系存储结构顺序存储结构采用一组连续的存储单元存放所有的数据元素链式存储结构每个元素用一个内存结点存储，结点和结点之间通过指针域进行联系索引存储结构存储数据元素时，同时建立附加的索引表存储所有数据元素信息的表称为主数据表，其中每个数据元素有一个关键字和对应的存储地址。索引表中的每一项称为索引项，索引项一般形式为“关键字，地址”。关键字可以唯一标识一个元素，地址对应元素的存储位置。所有的索引项一般按照关键字进行有序排列。哈希（或散列）存储结构根据元素的关键字通过哈希（或散列）函数直接计算出一个值，并将这个值作为该元素的存储地址算法算法是对特定问题求解步骤的一种描述，是指令的有限序列。具备有穷性、确定性、可行性、有输入（零个或多个）、有输出时间复杂度程序语句执行的最多次数，省略常系数，保留幂次。备注数据结构包括数据的逻辑结构和其存储结构

【C++】概述
type: item
date: 2021-09-10T14:18:29+00:00
description: 请根据你的了解，叙述C++的特点。C++对C有那些发展？C语言是一个结构化开发的语言，它主要思想是面向过程进行开发，重点在于设计算法和数据结构，而C++是在C语言的基础上构造了对象模型，更加适合用于工程化开发，主要思想是面向对象进行开发，但是又不完全等同于当下的面向对象的语言如Java，C++保留了C语言操作内存等的特性，同时检错机制要弱一点，而Java是更加简化了开发过程，降低了开发门槛。从时间维度上和实际功能效果上而言，C++是处于C语言过渡到Java语言的一个中间产物，既然是中间产物，就从不同程度上具备了其上级和下级的多种优势点。目前经常见到的C++特性其本质也就是面向对象的特性，继承、多态、封装。所谓继承，就是新类从已有类那里得到已有的特性。类的派生指的是从已有类产生新类的过程。原有的类成为基类或父类，产生的心类称为派生类或子类。所谓多态，简单概括未“一个几口，多种方法”，即使用的是同一个接口，但是效果却各不相同，多态有两种形式的多态，一种是静态多态，一种是动态多态。所谓封装，就是指将抽象得到的数据和行为相结合，形成一个有机的整体，也就是将数据和操作数据进行有机的结合，形成类，其中数据和函数都是类的成员，目的在于将对象的使用者和设计者分开。一个C++程序由哪几部分构成？其中的每一部分分别起什么作用？C++程序的基本组成主要有注释、预编译代码、名字空间、主程序、函数。从接受以恶搞任务到获得最终结果，一般要经过几个步骤？C++中从拿到一个任务到最终结果有比编辑、预处理、编译、连接、装入、运行六步。请说明编辑、编译、连接的作用。在编辑后得到的目标文件为什么不能直接运行？简言之，编辑就是编写程序，编译是将源代码翻译成为目标代码，连接就是将目标文件连接生成可执行文件。C++从程序编辑完成到执行成功都会经过5个步骤，分别是预处理、编译、汇编、连接和执行。预处理过程主要处理那些源代码文件以#开始的预编译指令，预处理时可将所有的宏定义展开并且替换掉#include。编译过程是把预处理完的文件进行一系列的此法分析、语法分析以及优化后产生响应的汇编代码文件，这个过程是整体程序构建的核心部分，也是最复杂的部分。汇编过程实际是指将汇编语言代码翻译成目标机器代码的过程，它没有复杂的语法，也没有语义，也不需要做指令优化，只是根据汇编指令和及其指令的对照表一一翻译。连接过程是指前面提到的汇编过程生成的目标文件属于分离状态，并不能立即被执行，因为各个源文件之间可能是有相互联系的。连接就是将源程序产生的多个目标文件连接未一个整体。运行过程就是指执行前面连接过程产生的二进制文件（.exe文件）。

《深入理解计算机系统》之计算机系统漫游
type: item
date: 2021-01-31T14:42:00+00:00
description: 计算机系统漫游信息就是位+上下文源程序设计上就是一个由值0和1组成的位（又称比特）序列，8个位被组织成一组，称为字节。每个字节表示程序中的某些文本字符。大部分的现代计算机系统都实用ASCII来表示每个文本字符，这种方式实际上就是用一个唯一的单字节大小的整数值来表示每个字符。基本思想：系统中所有的信息——包括磁盘文件、内存中的程序、内存中存放的用户数据以及网络上传送的数据，都是由一串比特进行表示的。区分不同的数据对象的唯一方法是我们读到这些数据对象时的上下文。比如，在不同的上下文中，一个同样的字节序列可能表示一个整数、浮点数、字符串或者机器指令。源文件到目标文件的转化从源文件到目标文件的转化是由编译器驱动程序完成的从源文件到目标文件的翻译一共需要分为四个阶段，执行这四个阶段的程序（预处理器、编译器、汇编器和链接器）一起构成了编译系统预处理阶段预处理器（cpp）根据以字符#开头的命令，修改原始的C语言程序。（相当于完成所有宏命令的引入）编译阶段将C语言编译成为汇编语言汇编阶段汇编器将汇编语言翻译成为机器语言指令链接阶段链接阶段时将系统函数库进行引入，链接器就负责处理这种合并。结果将生成一个可执行部目标文件，可以被加载到内存中，由系统进行执行。知道编译系统工作有哪些好处优化程序性能理解链接时出现的错误避免安全漏洞系统的硬件组成总线贯穿整个系统的是一组电子管道，称作总线，它携带信息字节并负责在各个部件间进行传递。通常总线被设计成传送定长的字节块，也就是字。字中的字节数（即字长）是一个基本的系统参数，各个系统中都不尽相同。现在大多数机器字长要么是4个字节（32位），要么是8个字节（64位）I/O设备I/O（输入/输出）设备是系统和外部世界的联系通道。每个I/O设备都通过一个控制器或/适配器与I/O总线相连。控制器和适配器之间的区别主要是在于它们的封装方式。控制器是I/O设备本身或者系统的主印制电路板（通常称作主板）上的芯片组。而适配器则是一块插在主板插槽上的卡。无论如何，它们的功能都是在I/O总线和I/O设备之间进行传递信息。主存主存是一个临时存储设备，在处理器执行程序时，用来存放程序和程序处理的数据。从物理上来说，主存是由一组动态随机存取存储器（DRAM）芯片组成的。从逻辑上来说，存储器是一个相信的字节数组，每个字节都有其唯一的地址（数组索引），这些地址都是从零开始的。处理器中央处理器单元（CPU），简称处理器，是解释（或执行）存储在主存中指令的引擎。处理器的核心是一个大小为一个字的存储设备（或寄存器），成为程序计数器（PC）。在任何时候，PC都指向主存中的某条机器语言指令（即含有该指令的地址）。高速缓存针对处理器和主存在速度方面的差异，系统设计者采用了更小更快的存储设备，称为高速缓存存储器，作为暂时的集结区域，存放处理器近期可能会需要的信息。L1和L2高速缓存是用一种叫做静态随机访问存储器的硬件技术实现的。比较新的、处理能力更强大的系统甚至用三级高速缓存：L1、L2、L3。系统可以获得一个很大存储器，同时访问速度也很快，原因是利用了高速缓存的局部性原理，即程序具有访问局部区域里的数据和代码的趋势。通过让高速缓存里存放可能经常访问的数据，大部分内存操作都能在快速的高速缓存中完成。存储器的层次结构寄存器L1高速缓存（SRAM）L2高速缓存（SRAM）L3高速缓存（SRAM）主存（DRAM）本地二级存储（本地磁盘）远程二级存储（分布式文件系统，Web服务器）操作系统管理硬件文件是对I/O设备的抽象表示虚拟内存是对主存和磁盘I/O设别的抽象表示进程是对处理器、主存和I/O设备的抽象表示进程上下文：操作系统保持跟踪进程运行所需的所有状态信息。这种状态，也就是上下文，包括许多信息，比如PC和寄存器文件的当前值，以及主存的内容。上下文切换：在任何一个时刻，单处理器的系统都只能执行一个进程的代码。当操作系统决定要把控制权从当前进程转移到某个新进程时，就会进行上下文切换，即保存当前进程的上下文、恢复新进程的上下文，然后将控制权传递到新进程。新进程就会从它上次停止的地方继续开始。从一个进程到另一个进程的转换是由操作系统内核管理的，内核是操作系统代码常驻内存的部分。注意：内核并不是一个独立的进程，相反，它是系统管理全部进程所用代码和数据结构的集合。线程一个进程实际上可以由多个成为线程的执行单元组成，每个线程都运行在进程的上下文中，并共享同样的代码和全局数据。虚拟内存虚拟内存是一个抽象概念，它为每一个进程提供了一个假象，即每个进程都在独占地使用主存。每个进程看到的内存都是一致的，称为虚拟地址空间。（此处暂不赘述）文件文件就是字节序列，仅此而已。每一I/O设备，包括磁盘、键盘、显示器，甚至网络，都可以看成是文件。Amdahl定律主要思想：当我们对系统的某个部…

vue挂载流程和模板编译
type: item
date: 2020-05-10T13:05:00+00:00
description: vue挂载流程和模板编译基于源码构建的两种版本先了解一下vue基于源码构建的两个版本，一个是runtime only(一个只包含运行时的版本)，另一个是runtime + compiler(一个同时包含编译器和运行时的版本)。而两个版本的区别仅在于后者包含了一个编译器。那么什么叫做编译器：编译器就是将“一种语言（通常为高级语言）”翻译为“另一种语言（通常为低级语言）”的程序Runtime + Compiler一个完整的Vue版本是包含编译器的，我们可以使用template进行模板编写。编译器会自动将模板字符串编译成渲染函数的代码,源码中就是render函数。 如果需要在客户端编译模板 (比如传入一个字符串给 template 选项，或挂载到一个元素上并以其 DOM 内部的 HTML 作为模板)，就需要一个包含编译器的版本Runtime Only只包含运行时的代码拥有创建Vue实例、渲染并处理Virtual DOM等功能，基本上就是除去编译器外的完整代码。Runtime Only的适用场景有两种： 1.我们在选项中通过手写render函数去定义渲染过程，这个时候并不需要包含编译器的版本便可完整执行实例挂载大致流程：确认挂载节点编译模板为render函数渲染函数转换Virtual DOM创建真实节点详细流程：确定挂载的DOM元素,这个DOM需要保证不能为html，body这类根节点。渲染有两种方式，一种是通过template模板字符串，另一种是手写render函数，template模板需要运行时进行编译，而后一个可以直接用render选项作为渲染函数。因此挂载阶段会有两条分支，template模板会先经过模板的解析，最终编译成render渲染函数参与实例挂载，而手写render函数可以绕过编译阶段，直接调用挂载的$mount方法。针对template而言，它会利用Vue内部的编译器进行模板的编译，字符串模板会转换为抽象的语法树，即AST树，并最终转化为一个类似function(){with(){}}的渲染函数。无论是template模板还是手写render函数，最终都将进入mountComponent过程,这个阶段会实例化一个渲染watcher，渲染watcher的回调函数有两个执行时机，一个是在初始化时执行，另一个是当vm实例检测到数据发生变化时会再次执行回调函数。回调函数是执行updateComponent的过程，这个方法有两个阶段，一个是vm._render,另一个是vm._update。 vm._render会执行前面生成的render渲染函数，并生成一个Virtual Dom tree,而vm._update会将这个Virtual Dom tree转化为真实的DOM节点。template模块书写方式编译流程图小结当我们传入选项进行实例化时，最终的目的是将选项渲染成页面真实的可视节点。这个选项有两种形式，一个是以template模板字符串传入，另一个是手写render函数形式传入，不论哪种，最终会以render函数的形式参与挂载，render是一个用函数封装好的with语句。渲染真实节点前需要将render函数解析成虚拟DOM,虚拟DOM是js和真实DOM之间的桥梁。最终的_update过程让将虚拟DOM渲染成真实节点

springboot+mybatisPlus代码层级梳理
type: item
date: 2020-04-30T14:40:00+00:00
description: 代码层级梳理代码层级annotation层ExcelVoAttribut主要用于写@ExcelVoAttribute注解，可以更灵活的配置Excel数据表导出的一些基本配置LogDirection主要用于写@LogDirection注解，注解里包含一个字段（接口描述），通过接口添加这个注解，填写上接口的功能，当用户在访问接口时候，可以利用aop技术，把用户的操作记到日志里aspect层LogDrectionAspect主要定义了aop切点的位置和增强的方法/** * @Author Johnny * @Date 2020/4/16 * @Version 1.0 */ @Aspect @Component @Slf4j public class LogDirectionAspect { @Pointcut("@annotation(logDirection)") public void doLogDirection(LogDirection logDirection){ } @Around(value = "doLogDirection(logDirection)",argNames = "pjp,logDirection") public Object doBefore(ProceedingJoinPoint pjp,LogDirection logDirection) throws Throwable{ if (!"".equals(logDirection.direction())) { log.info(logDirection.direction()+"接口被调用"); return pjp.proceed(); } return "接口信息不规范"; } }@Pointcut定义切点，此处定义切点为使用@LogDirection的方法@Around定义增强的方法，通过around的参数ProceedingJoinPoint可以很好的控制程序能不能继续执行下一步，在权限判定发挥着比较重要的作用拓展：利用下面的这种方法，需要在xml文件中配置bean实例，当然也可以在方法中通过手动扫包的方法获得bean实例进行操作/** * @Author Johnny * @Date 2020/4/16 * @Version 1.0 */ @Aspect public class MyAdvice { /** * 配置切点 */ @Pointcut("execution(* com.soft1851.spring.web.dao..*.insert*(..))") public void pointCut() { } /** * 配置前置增强 */ @Before("MyAdvice.pointCut()") public void beforeMethod() { System.out.println("等待数据插入"); } /** * 配置后置增强 */ @AfterReturning("execution(* com.soft1851.spring.web.dao..*.*(..))") public void afterMethod(){ System.out.println("关闭数据库"); } }xml配置实例 <bean name="forumDao" class="com.soft1851.spring.web.dao.impl.ForumDaoImpl"/> <bean name="myAdvice" class="com.soft1851.spring.web.interceptor.MyAdvice"/> <aop:aspectj-autoproxy/>common层ResponseResult和ResultCode这两个类可以将响应体统一进行封装，将接口的响应体规范化，使前端获取数据也更加友好贴下代码，防止以后找不到ResponseResult类package com.soft1851.music.admin.common; import lombok.Data; import java.io.Serializable; /** * @author Johnny * @Date: 2020/4/21 19:52 * @Description: */ @Data public class ResponseResult implements Serializable { private static final long serialVersionUID = -3948389268046368059L; private Integer code; private String msg; private Obje…