Anoyer - 三流痞子 - 默认分类
type: channel
link: http://193.112.96.159/index.php/category/default
description: 只是一个默认分类
items: 大模型Prompt技巧全解析
items: 20分钟聊聊clang-tidy那些事
items: Clang 新手教程
items: 单元测试的必要性？一文聊聊单元测试
items: Etcd 部署和基础操作
items: 【面试复习】C++基础
items: 【面试复习】数据库
items: 【面试复习】计算机网络
items: 【面试复习】操作系统
items: 第四次训练讲课视频

大模型Prompt技巧全解析
type: item
date: 2025-02-27T09:55:00+08:00
description: 第一节：Prompt定义及基本框架一、 什么是Prompt大模型 prompt 指在大语言模型应用中，用于 “提示” 模型唤起特定能力以解决实际问题的提问方式。早期它被称作 “输入形式” 或 “输入模板”，后来 “prompt”（提示）这一叫法因契合大语言模型语境，能准确体现其在调用模型能力方面的关键作用，成为公认术语。大模型多数核心能力在预训练阶段形成，prompt 就像钥匙，引导模型从预训练积累的海量信息中，精准唤起如理解复杂文本、总结信息、生成内容、逻辑推理等能力，满足用户实际需求。它并非把模型当作单纯知识库，而是高效调用其能力，实现类似人类运用智能解决复杂问题的效果，是 prompt 工程的核心，对用好大语言模型意义重大。二、 撰写Prompt的基本框架1、Prompt包含的要素● 指令：想要模型执行的特定任务或指令。● 上下文：包含外部信息或额外的上下文信息，引导语言模型更好地响应。● 输入数据：用户输入的内容或问题。● 输出指示：指定输出的类型或格式。2、Prompt五大框架2.1 RTF框架RTF(Role-Task-Format)框架是一个非常简单通用的Prompt提示框架，我们和任意大模型对话场景下都可以使用该规范进行改进输出。● R-Role(角色)：指定大模型担当固定角色(程序员、数据分析师、讲解员、记者等等)● T-Task(任务): 任务，告诉大模型需要为我们做的事情● F-Format(格式)：大模型最终结果的返回格式(比如：表格、Markdown、英文等等)主要优点：● 简单、方便。● 指定Role角色，可以让大模型在当前的角色范围内回答知识，这在一些特定的领域中非常有效。● 指定Role角色也能让工程上检索知识能够确定边界范围，配合元数据所发挥的威力会更强。● 如果结合RAG知识内容检索，那么上下文回答的内容会让用户感觉更加是顺畅。2.2 思考链模式通过这种模式来逐步改善大模型的推理能力，非常适合一些复杂的任务处理。例如：● 分析型或者逻辑推理型的任务● 决策● 解决问题(比如程序员根据错误日志找Bug)而要使用这种模式，只需要在末尾添加”让我们逐步思考”即可。例如：# 数据源（与指令区分） user_datasource = """XXX……""" prompt1 = """分析一下在人工客服服务场景下，'''{user_datasource}'''中客户有哪些诉求。用一句话概括。""" prompt2 = """分析一下在人工客服服务场景下，'''{user_datasource}'''中客户有哪些诉求。用一句话概括。让我们逐步思考。""" # 模型输出结果 output1：在人工客服服务场景下，客户主要诉求为：微信账号存在安全风险导致无法添加好友、单点拦截、下载安装微信出现问题等，寻求客服协助解决问题。 output2：在人工客服服务场景下，客户主要诉求为：微信账号存在安全风险导致无法添加好友，以及因违规行为被限制登录，客户希望客服能够尽快处理这些问题。 # 分析结果 output1中的”单点拦截”并不是用户的诉求，而output2显然更加正确2.3 RISEN框架● R-Role:大模型扮演的角色● I-Instructions: 指示命令，和Task-任务差不多● S-Steps: 步骤● E-End Goal: 最终目标● N-Narrowing(Constraints): 缩小范围(约束条件)，和RTF框架中的Format有异曲同工之妙，一个是格式的约束，而这里的约束可以是任意方面，比如回答的内容(特定领域)、字数限制等等方面该框架主要适合：● 撰写具有特定约束的任务(例如博客文章)● 有明确指导方针的任务（例如商业计划）2.4 RODES框架● R-Role: 角色● O - Objective: 目标● D - Details: 详细的细节● E - Examples: 示例● S - Sense Check: 感官检查2.5 密度链模式密度链模式Prompt是Salesforce、麻省理工学院和哥伦比亚大学的研究人员推出的一种新提示，它非常的高效，使用递归来创建越来越好的输出的提示，与普通提示生成的 GPT-4 摘要相比，它生成的摘要更加密集且更适合人们理解。适合：● 总结● 改进您最喜欢的提示● 通过递归生成可用的长格式内容(感兴趣的同学可以自己检索一下)第二节：打造高效Prompt的两大核心原则在Prompt工程领域，掌握精妙的撰写策略是释放语言模型强大潜力的关键。本节将深入探讨prompt撰写的两大核心策略，为您揭示如何通过优化指令，引导模型生成更贴合需求、更具质量的输出。一、原则一：编写明确和具体的指令为了让模型精准理解我们的意图，编写清晰、明确且具体的指令至关重要。…

20分钟聊聊clang-tidy那些事
type: item
date: 2023-04-06T11:26:56+08:00
description: 20分钟聊聊clang-tidy那些事在1月初凯新有过在各算法/公共模块引入 Clang-tidy 的提议 ，在3月初我向大家分享了一个关于完善算法/业务项目CI流程的静态代码检查的文档，其中都提到了一个工具，那就是clang-tidy，今天我便带大家聊一聊clang-tidy。Clang-tidy大家应该多少对clang-tidy这个工具有一定的了解，它是一个基于clang的静态代码分析框架。同时它是一个功能非常强大的lint工具。绝大部分lint工具只能在出现问题的地方给出提示，之后需要人为修改，而clang-tidy拥有自动修复功能（当然怎么修复需要相应 checker 作者提供）。并且clang-tidy采用模块化设计，非常容易扩展。如果用户想往clang-tidy添加一个新的检测功能，只需要编写一个clang-tidy checker实现（如何编写一个clang-tidy check以后将会有一章详细介绍），每一个checker检测一种问题，例如检测某个违反Code style的模式，检测某些API不正确使用的方法等等。那么提到了Code Style，我们不得说一说Google Code Style，这是目前使用最为广泛的一种代码规范。为此Google Code style也提供了一个cpplint脚本，用于检测代码中违反code style的地方。同时clang-tidy也支持检测代码中违反google code style的地方（google-*check）。那么可能会有人问他们之间有什么区别呢？cpplint是一个python的脚本，它是采用正则表达式匹配出违反code style的代码, 所以它能检测的功能会受限于正则表达式，它不能够检测所有的违反code style的地方，并且还会有False positive和True negative；而clang-tidy则是基于抽象语法树(AST)对源文件进行分析，相比之下，是在分析的结果更加准确，能检测的问题也更多。OK 到这里我们应该对clang-tidy 进行静态代码分析的原理有了一个大致的框架它基于clang，基于抽象语法树AST实现的。那clang和AST是什么？Clang众所周知clang是一个编译器，是一个以LLVM为后端的编译前端那么clang和llvm还有什么其他关系呢？这里我们可能需要说一下广义的llvm和狭义上的llvm了。在LLVM整体架构中，前端用的是clang，因此广义的LLVM是指整个LLVM架构，而狭义的LLVM指的是LLVM后端（包含代码优化和目标代码生成）。在LLVM架构中，源代码（c/c++）经过clang生成中间代码，之后中间代码通过优化器进行一系列的优化，最后通过后端生成机器码。而在经过前端生成中间代码过程中，前端会对代码进行词法分析、语法分析以及语义分析。而在语法分析过程中变为生成一棵语法树，也就是我们说的AST。int add(int a, int b){ typedef long long ll; return a + b; }// 我们可以使用-fsyntax-only -Xclang -ast-dump 打印出源码文件的ast // clang -fmodules -fsyntax-only -Xclang -ast-dump main.m `-FunctionDecl 0x1398df030 <test.cpp:1:1, line:4:1> line:1:5 add 'int (int, int)' |-ParmVarDecl 0x1398deed8 <col:9, col:13> col:13 used a 'int' |-ParmVarDecl 0x1398def58 <col:16, col:20> col:20 used b 'int' `-CompoundStmt 0x1398df250 <col:22, line:4:1> |-DeclStmt 0x1398df198 <line:2:5, col:25> | `-TypedefDecl 0x1398df140 <col:5, col:23> col:23 ll 'long long' | `-BuiltinType 0x139840750 'long long' `-ReturnStmt 0x1398df240 <line:3:5, col:16> `-BinaryOperator 0x1398df220 <col:12, col:16> 'int' '+' |-ImplicitCastExpr 0x1398df1f0 <col:12> 'int' <LValueToRValue> | `-DeclRefExpr 0x1398df1b0 <col:1…

Clang 新手教程
type: item
date: 2023-04-06T11:25:00+08:00
description: Clang 新手教程长话短说这个新手教程会让你弄清楚什么是clang，clang AST，clang plugins 和clang tools 等等。让你大概知道clang 可以解决什么问题，而且小白也是可以用clang libraries 来开发工具的 :)Clang 是什么？Clang 是一个以LLVM为后端的编译前端。编译前端主要负责parse 源码，检查错误，并生成Abstract Syntax Tree (AST)。Ref: Understanding the Clang AST什么时候会用到Clang？需要基于编译器的AST 对源码做精确的编辑需要引入自定义的编译错误和警告基于C/C++ 源码的代码生成(code generation)，比如生成数据结构的序列化，语言交互接（Foreign function interface）Clang AST 是什么？Clang AST 的节点是由几种没有共同基类的类来组成（建模）的Clang’s AST nodes are modeled on a class hierarchy that does not have a common ancestor.其中比较常用的四种class 是Type,Decl,DeclContext,Stmt每种节点都有专门的遍历函数来获取子节点ASTContext 里可以获取AST 的额外信息，比如源码的地址例子// test.cc int foo(int num) { int result = (num / 2); return result; } void test_f() { int i = 10; int b = foo(i); }clang -Xclang -ast-dump -fsyntax-only test.ccRef: Introduction to the Clang AST - Clang 15.0.0git documentationClang APIsClang 提供C 和C++ APIC API (libClang) 稳定但是不完整C++ API（LibTooling）完整但是不稳定LibTooling 主要用于开发standalone 工具，并且plugins 只能使用LibToolingRef: Choosing the Right Interface for Your Application - Clang 15.0.0git documentationClang plugins v.s. Clang toolsClang plugin 在编译时对AST 进行一些额外的操作。plugin是动态库（.so），在运行时由编译器加载，可以很容易集成到编译环境中。Clang tools 是由LibTooling 开发的可执行程序，比如clang-check，clang-format，clang-tidy 这些llvm project 提供的。有时候两种方式都能解决问题：# 1. As a loadable Clang plugin: clang -cc1 -load <BUILD_DIR>/lib/libLACommenter.so '\' -plugin LACPlugin test/LACInt.cpp # 2. As a standalone tool: <BUILD_DIR>/bin/ct-la-commenter test/LACInt.cpp考虑点：能不能控制用哪个编译器？clang / gcc?需不需要make 或者break buildClang 6.0 写的plugin Clang 7.0 不一定能用（API 不稳定！）CI 环境使用哪种工具用户接入成本更低？RecursiveASTVisitor v.s. ASTMatcherLibTooling 有两种framework: RecursiveASTVisitor 和ASTMatcherThe RecursiveASTVisitor provides hooks of the form bool VisitNodeType(NodeType *) for most AST nodesASTMatcher 是一套用来匹配和遍历AST 的DSL两种framework 可以一起使用来解决比较复杂的问题！https://github.com/banach-space/clang-tutor/blob/main/README.md#unusedforloopvar优先考虑用ASTMatcher，因为可以用clang-query 来验证DSL 是否正确clang-query test.cc# some useful commands to setup clang-…

单元测试的必要性？一文聊聊单元测试
type: item
date: 2022-04-08T16:50:00+08:00
description: 单元测试写的代码能一次正确执行是每个程序员的追求，但世事皆不能尽如人意，我们的代码经常会有 Bug，这就需要测试的存在。测试有黑盒和白盒之分。黑盒测试，测试时认为被测程序就像一个漆黑的盒子，虽然不明白其中的运行原理，但知道怎么输入有对应的输出。QA (Quality assurance)，也就是我们的测试部门一般负责对程序进行黑盒测试，调用接口时传确定的参数，再校验接口响应值符合某种预期。与黑盒测试对应的是白盒测试，白盒测试要求被测试人员了解被测程序的构造，从而构造测试用例校验程序各个分支逻辑。从这一方面来说，单元测试就是一种白盒测试。单元测试，又称为模块测试，是针对程序模块（软件设计的最小单位）来进行正确性检验的测试工作，一般对面向对象语言来说，这个最小单位是类或重要的类方法，它不仅可以用作功能测试，将单元测试集成到依赖集成工具之后，它们还可以在模块编译时执行，进行模块的回归测试。工作以来，我对单元测试的认知不断刷新，从拒绝到勉强接受，再到理解其中妙处，最近竟然有些理解我以前觉得不可思议的 TDD（测试驱动开发）了，我觉得有必要把其中心路历程整理一下，无论是之后回忆还是翻出来打脸，应该都很有意思。初遇单测不写单测刚开始工作时的公司是一个小型公司，项目小且业务简单，部门也没有要求，我是不写单元测试的。不接触就无法理解它，这时候我对单元测试的认识就是收益很低的”测试工具”，认为代码是自己写的，自己再编造一些数据去迎合这些代码，根本测试不出来什么，而且编造数据还要花费大量的尽力，收益和付出完全不成正比，程序的正确性靠 QA 就完全够了。可能跟我有类似想法的同事也有很多，后来我们干脆把所有的类方法都改成了静态方法，程序运行时不用再去创建服务对象了，这样，代码就变成了披着面向对象外衣的函数式程序。当然，这也进一步导致了单元测试不可能实行了，因为方法是层层调用的，想要构造出一组能正确运行的数据都非常困难，就更不用说再测试各种分支逻辑了。随波逐流后来换到了目前所在的岗位，部门强制要求每段逻辑都要有对应的单测 case，这样我才真正接触到了单元测试。刚开始写单元测试时内心是非常煎熬的，不认同还要被强制要求做，当然很不爽，更重要的是不习惯。原来功能开发完成后，自己改改参数调两遍接口测下就行，现在还要再写同样多甚至更多的代码来校验功能代码是否正确，花费的不仅是时间，还有心力。而且有些代码就没法写单测，费尽心思构造出数据，可能还没测出功能代码的问题，改单测 case 的 bug 就能让人崩溃了。这时我采用的策略就是仿着原来的单测 case 写，现在看来之前的很多单测 case 也没什么质量，又由于自己水平低，导致最终写出来的单测 case 基本没什么意义，要么是重要逻辑覆盖不到，要么是只能覆盖一些通用逻辑，就算有问题，调接口测一下也能测出来。收获也不能说完全没有，毕竟有非常明显的 bug 还是能够测出来的，而且有时候误改了之前的代码，也能够在 QA 反馈前及时解决，但总体来说，这样写单元测试是不划算的。单测的意义缘由后来 case 越写越多，在越来越熟练地满足单测覆盖的要求时，我也在不停思考这样的工作有什么意义，直到有一天被 leader review 代码，我感觉有些开悟了。被 review 代码的功能是将一个 json 字符串解析为服务里的配置模型，考虑到它只是一个解析字符串的功能，我把它定义为一个”工具类”，里面用静态方法实现，这样调用解析方法时不用注入 bean，使用类名.方法即可。我以为这个类虽然称不上完美无缺，但命名、日志、异常处理都很完善，至少算得上中规中矩，没想到被 leader 一顿狠批，因为他直接跳到这个工具类的上层类，发现这个类没有单测覆盖。为什么上层类没有写单元测试呢，不是因为上层的逻辑太过复杂，而且因为如果我想测这个上层类，就需要构造出一个能够解析为配置模型的大型字符串，还要传上一堆配置参数到这个解析工具类里，这个字符串不好构造不说，即使构造出来了，写在代码里这么一堆，也异常难看，如果之后要变更这个配置模型的结构，更是一场噩梦。思考被教育一顿后，我终于明白了，上层代码的单元测试难写，是因为这么一个工具类，工具类的静态方法无法 Mock 返回值，这就需要我构造大量的真实数据，费力也讨不了好，简而言之，是因为我的设计烂导致单测不好写。接着我观察了更多据说写不出单测的代码，反思了之前遇到的单测难写的代码，拿这些代码去对比代码设计原则，发现了这些代码的一个共同点：它们都严重违背了一种或更多设计原则，也就是说，它们都是烂代码。”不好写单测的代码都是烂代码”，我觉得我理解了单元测试的（部分）意义，单元测试不仅用来测试代码功能，还可以用来测试代码设计。从此之后，我开始更重视单元测试了，单元测试的名字不再用 “testMethodNam…

Etcd 部署和基础操作
type: item
date: 2021-10-28T15:21:00+08:00
description: docker部署方式（etcd可以单实例也可以集群）sudo docker run -d -it \ --name etcd_test \ -e ETCDCTL_API=3 \ -p 2379:2379 \ -p 2380:2380 \ quay.io/coreos/etcd:v3.3.9 \ etcd \ --advertise-client-urls http://0.0.0.0:2379 \ --listen-client-urls http://0.0.0.0:2379如果需要添加挂载目录，则追加属性--volume=etcd-data:/etcd-data以及--data-dir=/etcd-data；根据电脑架构选择合适的镜像（arm架构：e2eteam/etcd:3.4.13-0-linux-arm64）基本操作进入服务sudo docker exec -it etcd_test sh基本命令## 增加 / # etcdctl --endpoints="127.0.0.1:2379" put /test_key1/sub1 "key111" OK ## 查询 / # etcdctl --endpoints="127.0.0.1:2379" get /test_key1/sub1 /test_key1/sub1 key111 ## 删除 / # etcdctl --endpoints="127.0.0.1:2379" del /test_key1/sub1 1 ## watch监听某个key 被操作的记录 / # etcdctl --endpoints="127.0.0.1:2379" watch /test_key1/sub1 PUT /test_key1/sub1 123 PUT /test_key1/sub1 1234 DELETE /test_key1/sub1 ## 查看当前endpoint的状态 / # etcdctl endpoint --cluster=true status -w table +---------------------+------------------+---------+---------+-----------+-----------+------------+ | ENDPOINT | ID | VERSION | DB SIZE | IS LEADER | RAFT TERM | RAFT INDEX | +---------------------+------------------+---------+---------+-----------+-----------+------------+ | http://0.0.0.0:2379 | 8e9e05c52164694d | 3.3.9 | 20 kB | true | 4 | 18 | +---------------------+------------------+---------+-- ## 查看集群状态 / # etcdctl --endpoints="127.0.0.1:2379" endpoint status -w table +----------------+------------------+---------+---------+-----------+-----------+------------+ | ENDPOINT | ID | VERSION | DB SIZE | IS LEADER | RAFT TERM | RAFT INDEX | +----------------+------------------+---------+---------+-----------+-----------+------------+ | 127.0.0.1:2379 | 8e9e05c52164694d | 3.3.9 | 20 kB | true | 4 | 18 | +----------------+------------------+---------+---------+-----------+-----------+------------+本地命令配置配置etcd服务镜像开机启动 默认镜像并不会开机启动，但往往我们需要服务开机自启，所以通过在/etc/profile中添加以下内容来实现开机启动etcd容器# etcd docker start etcd_test为命令设置别名 因为etcdctl命令在容器内部，每次想要执行都要进到容器里面执行或者使用docker exec etcd_test etcdctl。这样太过于麻烦，我们可以通过别名，简化执行etcdc…

【面试复习】C++基础
type: item
date: 2020-09-27T11:04:00+08:00
description: 一、基础知识1、基本知识说一下C++和C的区别设计思想上：C++是面向对象的，C是面向过程的语法上：C++具有封装、继承和多态三种特性；C++相比C，增加了许多类型安全的功能，比如强制类型转换；C++支持范式编程，比如模板类、函数模板等C++11的新特性auto关键字、右值引用、初始化列表对类进行初始化、新增容器array和tuple、智能指针inline函数的作用加快函数的执行速度吧。因为内敛函数调用，是将调用表达式直接用内敛函数体来替换。虚函数和纯虚函数的区别声明不同：纯虚函数后面必须跟=0;虚函数必须实现，纯虚函数一定没有实现虚函数在子类里面可以不重载，但是纯虚函数必须重载虚函数在子类里面也可以不重载的；但纯虚必须在子类去实现说一下C++中static关键字的作用1、修饰局部变量：特点：有默认值0，只执行一次，运行一开始就开辟了内存，内存放在数据段2、修饰全局函数和全局变量：特点：只能在本源文件使用3、修饰类里面的成员变量：特点：和1差不多，定义多个类对象,但共用相同的静态成员变量,不进入类的大小计算，不依赖于类对象的存在而存在（可直接调用，要进行外置声明）（类名或对象直接访问）4、修饰类的成员函数：特点：f():括号里无this指针，只能调用他的本类静态函数和他的静态变量，即是用static修饰过的不依赖于类对象的存在而存在（可不进行外置声明，直接调用）（类名或对象直接访问）说一说C++中的四种cast转换C++中四种类型转换是：static_cast、dynamic_cast、const_cast、reinterpret_cast1、dynamic_cast 用于动态类型转换。只能用于含有虚函数的类，用于类层次间的向上和向下转化。只能转指针或引用。向下转化时，如果是非法的对于指针返回NULL，对于引用抛异常。要深入了解内部转换的原理。 向上转换：指的是子类向基类的转换 向下转换：指的是基类向子类的转换 它通过判断在执行到该语句的时候变量的运行类型和要转换的类型是否相同来判断是否能够进行向下转换。2、static_cast可以转换相关联的类，可以从子类转换成父类。也能从父类转向子类，但是如果转换的父类指针（或者父类引用）所指向的对象是完整的，那么是没有问题；但是如果所指向的对象并不完整，那么会出现runtime错误。 用于各种隐式转换，比如非const转const，void*转指针等，**static_cast**能用于多态向上转化，如果向下转能成功但是不安全，结果未知。 3、**reinterpret_cast**几乎什么都可以转，比如将int转指针，可能会出现问题，尽量少用3、reinterpret_cast该操作不会去进行动态类型或者静态类型的检测，它仅仅将值强行赋值过去。从某种意义上对编译器进行了一种欺骗，同时也带来了一定的不安全性4、const_cast常量转换，用于将const变量转为非const指针和引用的区别？1、指针是一个变量，引用是一个别名2、指针可以为空，引用不可以为空，创建时候必须初始化3、指针的值在初始化后可以改变，但是引用不可以改变4、指针可以多级，但是引用只能一级左值和右值引用的区别左值与变量绑定一次，而右值只能和表达式绑定一起，且右值引用只能绑定到一个即将销毁的对象上左值有持久性，右值一般是个临时变量或者字面常量为什么要使用智能指针智能指针的作用是管理一个指针，因为存在以下这种情况：申请的空间在函数结束时忘记释放，造成内存泄漏。使用智能指针可以很大程度上的避免这个问题，因为智能指针就是一个类，当超出了类的作用域是，类会自动调用析构函数，析构函数会自动释放资源。所以智能指针的作用原理就是在函数结束时自动释放内存空间，不需要手动释放内存空间。请你说一下你理解的c++中的smart pointer四个智能指针auto_ptr（C++11已抛弃）采用所有权模式，使用=将会给所有权传给对方。auto_ptr< string> p1 (new string ("I reigned lonely as a cloud.”)); auto_ptr<string> p2; p2 = p1; //auto_ptr不会报错.此时不会报错，p2剥夺了p1的所有权，但是当程序运行时访问p1将会报错。所以auto_ptr的缺点是：存在潜在的内存奔溃问题！unique_ptr（独占的智能指针）unique_ptr实现独占式拥有或严格拥有概念，保证同一时间内只有一个智能指针可以指向该对象。它对于避免资源泄露（例如“以new创建对象后因为发生异常而忘记调用delete”）特别有用。unique_ptr<string> p3 (new string ("auto")); //#4 unique_ptr<string> p4…

【面试复习】数据库
type: item
date: 2020-09-27T11:04:00+08:00
description: 数据库数据库事务及4个特性事务：由一系列对系统中数据进行访问与更新的操作所组成的一个程序执行逻辑单元。事务是DBMS中最基础的单位，事务不可分割。具有4个特性ACID原子性：事务是最小的执行单元，不允许分割一致性：执行事务后，数据保持一致，多个事务对同一个数据读取结果相同隔离性：并发访问数据库是，一个用户的事务不被其他事务所干扰。并发事务之间相互独立持久性：一个事务被提交后，他对数据库的改变是持久的。DB DBMS DBS DBADB(数据库)：按一定结构组织并长期存放在计算机内的、可共享的大量数据集合DBMS(数据库管理系统)：是管理和维护数据库的系统软件DBA(数据库管理员)：管理操作数据库人员DBS(数据库系统)：由数据库、数据库管理系统、数据库管理员、硬软件等组成的集合体数据库三大范式第一范式：所有属性不能再分解为更基本的数据单元第二范式：在第一范式基础上，所有非主属性完全依赖于每一个候选码第三范式：满足第一范式，非主属性不存在传递依赖数据库索引对数据库的一列或者多列进行排序的一种结构，使用索引可以快速访问数据库表中的特定信息

【面试复习】计算机网络
type: item
date: 2020-09-27T11:03:00+08:00
description: 计算机网络基础TCP可靠传输实现校验和序列号确认应答超时重传连接管理窗口控制拥塞控制：慢启动，拥塞避免，快重传，快恢复tcp本身通过ack确认机制来保证确认信息收到了，并通过重传机制对丢失信息进行重传，也就是说，应用端将数据交给TCP，自己啥都不用管了，他一定能传到，所以称之为可靠性TCP和UDP区别TCP面向字节流，UDP面向报文TCP面向连接的传输协议，传输前必须建立连接，UDP无连接TCP是可靠的，UDP不保证可靠TCP保证了数据顺序，UDP不保证TCP首部开销大于UDP，TCP需要20字节，UDP则是8字节TCP三次握手四次挥手三次握手：主机向服务器发送一个请求连接报文服务器收到报文后，向主机发送一个确认连接请求报文主机收到后，送一个检查ACK报文，服务器收到连接建立成功开始传输四次挥手：主机向服务器发送连接释放报文服务器收到后，向主机发送一个ACK报文当服务器无数据传输时，发送一个连接释放报文主机收到后，发送一个ACK报文，进入时间等待状态，等待两个报文段最大生存时间，然后关闭连接（保证最后一次报文能到B，2MSL后，这次连接的所有报文都会消失）不是2次握手：无法获取到对方的状态，无法知道主机是否收到服务器的确认连接，且不会超时重传，TCP不会为没有数据的ACK进行重传；为了防止 已失效的链接请求报文突然又传送到了服务端，因而产生错误。不是4次挥手：主动关闭方需要等待被动关闭方传送完数据，所以在收到主机连接释放报文时，不能直接回复一个连接释放报文，需要等服务器数据发送完https和http的区别HTTP是以明文的方式在网络中传输数据，而HTTPS协议传输的数据则是经过TLS加密后的，HTTPS具有更高的安全性HTTPS在TCP三次握手阶段之后，还需要进行SSL的握手，协商加密使用的对称加密密钥HTTPS协议需要服务端申请证书，浏览器端安装对应的根证书HTTP协议端口是80，HTTPS协议端口是443HTTPS的安全性更高，握手阶段延时较高HTTP三个缺点：被篡改、被监听、被伪装https的建立过程客户端发送请求到服务端服务端返回公钥和证书到客户端客户端接收后会验证证书的安全性,如果通过则会随机生成一个随机数,用公钥对其加密,发送到服务端服务端接受到这个加密后的随机数后会用私钥对其解密得到真正的随机数,随后用这个随机数当做私钥对需要发送的数据进行对称加密客户端在接收到加密后的数据使用私钥(即生成的随机值)对数据进行解密并且解析数据呈现结果给客户SSL加密建立对称加密和非对称加密对称加密：即加密的密钥和解密的密钥相同非对称加密：非对称加密将密钥分为公钥和私钥，公钥可以公开，私钥需要保密，客户端公钥加密的数据，服务端可以通过私钥来解密http1.0 http1.1和http2.0http1.0 是短连接 http1.1是长链接短连接每次请求都需要建立连接，长连接则允许传送多个HTTP请求响应http2.0增加了多路复用，也就是连接共享，一个连接可以有多个请求并行执行ipv4和ipv6的区别地址长度不同，iPv4为4字节32位，ipv6为16字节128位，因此他们的寻址空间不同IPv4使用了地址解析通讯协议，IPv6使用的是多点传播IPV6的安全性更高。在使用IPv6网络中，用户可以对网络层的数据进行加密并对IP报文进行校验，这极大地增强了网络安全post和get请求区别对于get方式，浏览器会把http 消息头和data 一并发送过去，服务器响应200（返回数据）；对于post方式，浏览器先发送消息头，服务器响应100 continue，浏览器再发送data，服务器响应200 ok（返回浏览器）区别：l、get参数通过url传递，post放在request body中。2、get 请求在url中传递的参数是有长度限制的，而post没有。3、get比post更不安全，因为参数直接暴露在url中，所以不能用来传递敏感信息。4、get 请求只能进行url编码，而post支持多种编码方式。5、get请求参数会被完整保留在浏览历史记录里，而post中的参数不会被保留。6、GET和POST本质上就是TCP链接，并无差别。但是由于HTTP的规定和浏览器/服务器的限制，导致他们在应用过程中体现出一些不同。7、GET产生一个TCP数据包:POST产生两个TCР数据包。session和cookie区别Cookie通过在客户端记录信息确定用户身份，Session通过在服务器端记录信息确定用户身份。1、cookie数据存放在客户的浏览器上，session数据放在服务器上。2、cookie不是很安全，别人可以分析存放在本地的cookie并进行cookie欺骗，考虑到安全应当使用session。3、session会在一定时间内保存在服务器上。当访问增…

【面试复习】操作系统
type: item
date: 2020-09-27T11:02:00+08:00
description: 操作系统线程池线程池就是首先创建一些线程，他们的集合称为线程池。使用线程池可以很好地提高性能，线程池在系统启动时即创建大量空闲的线程，程序将一个任务传给线程池，线程池就会启动一条线程来执行这个任务，执行结束以后，该线程并不会死亡，而是再次返回线程池中成为空闲状态，等待执行下一个任务。1、设置一个生产者消费者队列，作为临界资源2、初始化n个线程，并让其运行起来，加锁去队列取任务运行3、当任务队列为空的时候，线程阻塞4、当生产者队列来了一个任务后，先对队列加锁，把任务挂在队列上，然后使用条件变量去通知阻塞中一个线程进程和线程概念及区别进程：进程是对运行时程序的封装，是系统进行资源调度和分配的基本单位，实现了操作系统的并发；进程=程序+数据+PCB(进程控制块)线程：是进程的子任务，是CPU调度与分配的基本单位，用于保证程序的实时性，实现了线程内部的并发。区别：线程属于进程，一个线程只能属于一个进程，进程可以拥有多个线程，线程依赖于进程存在进程是资源分配的基本单位，线程是CPU调度的基本单位进程执行的过程中拥有独立内存单元，线程共享进程的内存进程切换资源开销大，线程小进程间不会相互影响，一个线程挂了整个进程就会挂掉进程的通信可以通过管道、系统IPC实现进程的通信管道是半双工的，具有固定的读端和写端，它可以用于具有亲缘关系的进程之间的通信。系统IPC：消息队列：消息的链接表，存放在内核中，一个消息队列由一个标识符来标记。面向记录信号量：就是一个计数器，可以用来控制多个进程对共享资源的访问。用于实现进程间的互斥与同步共享内存：他使得多个进程可以访问同一块内存空间，不同进程可以及时看到对方进程对共享内存数据的更新。进程调度策略先来先服务(FCFS)： 队列实现，非抢占的，先请求先分配CPU最短作业优先调度(SJF)： 平均等待时间最短，但难以知道下一个CPU区间长度优先级调度算法： 优先级高的先分配，相同优先级的先到先服务。容易出现饥饿时间片轮转调度： 每个进程执行只分配一个时间片的CPU时间，时间片结束，进程被抢占并放回就绪队列进程的五种基本状态创建状态：进程正在被创建就绪状态：进程被加入到就绪队列中等待CPU调度运行执行状态：进程正在被运行等待阻塞状态：进程因为某种原因，比如等待I/O，等待设备，而暂时不能运行终止状态：进程运行完毕就绪状态被调度变为执行状态，发生时间片到了或者高优先级则会从执行变为就绪执行状态因等待某事件而睡眠变为等待阻塞等待阻塞因等待事件发生而唤醒变为就绪上下文切换上下文切换(Context Switch)是一种将CPU资源从一个进程分配给另一个进程的机制 。在切换的过程中，操作系统需要先存储当前进程的状态(包括内存空间的指针，当前执行完的指令等等)，再读入下一个进程的状态，然后执行此进程。（ 程序计数器、CPU寄存器状态等数据 ）进程切换一般分两步：切换页目录以使用新的地址空间（只有进程需要做）切换内核栈和硬件上下文（线程与进程都要做）确实进程交换过程进程交换技术： 换出一部分进程到外存，腾出内存空间将内存暂时不能运行的进程，或者暂时不用的数据和程序，换出到外存，来腾出足够的内存空间，把已经具备运行条件的进程，或进程所需的数据和程序换入到内存。挂起状态： 进程被交换到外存，进程状态就成为了挂起状态活动阻塞：进程在内存中，但由于某种原因被阻塞了静止阻塞：进程在外存，同时被某种原因阻塞了活动就绪：进程在内存，处于就绪状态，只要给CPU和调度就可以运行静止就绪：进程在外存，处于就绪状态，只要调度到内存，给CPU和调度就可以运行活动就绪到静止就绪（内存不够，调到外存）活动阻塞到静止阻塞（内存不够，调到外存）执行到静止就绪（时间片用完）系统分配的资源处理器、存储器、I/O 设备以及信息线程的通信及同步线程通信主要通过：使用全局变量、使用消息实现通信、使用事件实现通信线程同步的方式：临界区：通过多线程的串行化来访问公共资源或一段代码、速度快、适合控制数据访问互斥量：采用互斥对象机制、只有拥有互斥对象的线程才有访问公共资源的权限。因为互斥对象只有一个、所以保证公共资源不会被多个线程同时访问信号量：为具有有限数量的用户资源而设计的，它允许多个线程在同一时刻去访问同一个资源（但一般需要限制同一时刻访问此资源的最大线程数目）事件：通过通知操作的方式来保持多线程同步，还可以方便实现多线程优先级的比较操作守护、僵尸、孤儿进程的概念守护进程：运行在后台的一种特殊进程，独立于控制终端并周期性地执行某些任务。僵尸进程：一个进程 fork 子进程，子进程退出，而父进程没有wait/waitpid子进程，那么子进程的进程描述符仍保存在系统中，这样的进程称为僵尸进程。孤儿进程：一个父进程退出，而它的一个或多个子进程还在运行，这些子进程称为孤儿进程。…

第四次训练讲课视频
type: item
date: 2020-04-19T22:52:00+08:00
description: [scode type="red"]非常抱歉！！因为视频的分段录制，在第一段录制时屏蔽了录制机麦克风声源，但在第二段录制时忘记打开麦克风声源了，导致第二段视频成了无声视频 ::aru:crying:: 。[/scode][scode type="yellow"]如果哪位同学有录制第二段视频，还请联系我，谢谢 ::aru:bigeye:: 。[/scode] var player = new DogePlayer({ container: document.getElementById('player'), userId: 575, vcode: '33f460ad2f9c49e0', autoPlay: false, plcode: 'ed4f9a8c16e35f57', plsort: 'name' });