ChatGPT背后的模型

InstructGPT语言模型,是一个比 GPT-3 更善于遵循用户意图,同时使用通过我们的对齐研究开发的技术使它们更真实、毒性更小。InstructGPT 模型循环迭代的过程当中,加入了人类反馈进行训练。

比如下面的例子:几句话向6岁的孩子解析登月

可以看到,GPT-3模型的回答需要分开多个句子进行解析,这样的回答并不像人类。而InstructGPT模型的回答,在逻辑和语义通顺上,更加偏向于人类的回答。

实际上,GPT-3 模型未接受过遵循用户说明的训练。InstructGPT 模型(上面蓝色的字体)生成更有用的输出以响应用户指令。

在GPT-3模型中,可以使用精心设计好的文本提示词语引导该模型执行自然语言任务。但是这些模型在生成文本时,会输出不真实、有毒或反映有害情绪的文本。这是因为,在训练GPT-3模型的时候,利用了大量的互联网文本数据来预测下一个单词,而不是在安全情况下执行用户想要的语言文本。总结来说,GPT-3模型与用户的需求不太一致。

为了让模型生成更安全,有用,对其用户需求的文本,OpenAI使用了一个称为RLHF(Reinforcement Learning from Human Feedback)的方法,它是一种根据人类反馈从而进行学习的强化学习方法。在实际过程中,用户提交文本提示词语,标注者针对模型给出的几个回答进行排序,这样就可以对GPT-3模型进行fine-tune,这样就可以得到InstructGPT模型。

InstructGPT模型比GPT-3模型更擅长遵循用户的指令。这个模型很少会编造事实,同时在有毒输出产生方面表现出小幅下降。InstructGPT模型参数量比GPT少100倍,只达到了1.3B,但其效果和GPT-3模型差不多。

1.RLHF方法

接下来详细讲一下InstructGPT中用到的RLHF方法。

构建一个安全的AI模型,首先需要的就是摆脱直接编写目标函数的需求。因为如果对复杂的目标任务使用简单的函数进行表征,或者使用错误的函数进行表征,就可能导致模型学习到不良的甚至时危险的行为。简单来说,就是让模型生成多种输出,然后人工标注哪种输出更好,来指导模型训练。

这里以“训练AI进行后空翻操作”为例子,讲述RLHF的原理

在算法中,仅仅需要900位人类的反馈,就可以完成AI后空翻的训练效果。其包含了3个训练循环步骤:

  • 奖励预测:根据人类的反馈
  • RL算法训练
  • agent理解目标行为

AI agent首先在环境中随机行动。定期将其行为的两个视频片段提供给人工审核,标注者决定两个片段中的哪一个最接近实现其目标——在本例中为后空翻。人工智能通过找到最能解释人类判断的奖励函数,逐步建立任务目标模型。然后它使用 RL 来学习如何实现该目标。随着其行为的改进,它会继续询问人类对轨迹行为的反馈,并进一步完善其对目标的理解。

后空翻视频需要不到 1000 位的人类反馈。它花费了人类评估者不到一个小时的时间。下面就是人工在看视频标注的过程:

作为对比,研究者重新编写了奖励函数也训练了一个模型。从实验上看,使用RLHF方法要更优雅得多。(左图为RLHF,右图为正常利用奖励函数进行训练)

OpenAI进一步把RLHF方法,试验到多个领域中,包括模拟机器人和 雅利达游戏上。在这些游戏中,没有利用后台的分数作为奖励函数,而仅仅利用标注进行奖励。

Agent可以从人类反馈中学习,有时甚至是超人的表现。在下面的动画中,可以看到训练好的智能体玩各种雅利达游戏。

2.ChatGPT中的RLHF方法

在实际应用上训练ChatGPT中,其包含了几个以下的三个主要步骤:

  • 收集人工标记的数据,用来微调预训练模型GPT-3
  • 训练奖励模型
  • 利用强化学习进一步微调语言模型

1

微调模型GPT-3

第一步比较简单,ChatGPT直接使用GPT-3作为预训练模型。在人工标注的数据微调后,可以得到一个初始化LM模型:Initial Language Model。

2

训练奖励模型

从Prompts数据集中,抽样出多个prompts,然后输入到上面微调过的LM模型中,这样会得到多个输出文本,即:[prompt, generated text]。

接下来利用人工方法对这些输出的文本进行排序,人为确认哪些文本较为满意。

为什么要使用排序方法,而不是直接打分数呢?这是因为不同的研究人员对同一个句子可能有不一样的评分,这样会导致大量的噪声出现,如果改成排序,则会大大降低噪声。

得到排序结果后,就可以用来训练奖励模型。奖励模型可以利用预训练模型进行初始化,或者也可以进行随机初始化。然后把人工标注的排序结果输入到奖励模型中。这里可以使用类似推荐系统中的“pair-wise”,把两个句子输入进行,奖励模型判别哪个句子较好。

最后,我们就有了两个模型,一个是第一步得到的LM模型,另一个是现在得到的奖励模型(RM)。

3

利用强化学习进一步微调语言模型

利用强化学习方法,不断强化Tuned Language Model。让这个模型生成的文本越来越符合人类的语言认知。这样最终得到的模型在文本生成上,更加语义通顺和安全。

这其中用到的强化学习方法主要是PPO算法,感兴趣的同学可以了解一下。

3.效果

为了衡量模型的安全性,OpenAI主要在公开可用的数据集上进行验证。与 GPT-3 相比,InstructGPT 产生的模仿性错误更少并且毒性更小。同时发现 InstructGPT 更少地编造事实(“幻觉”),并生成更合适的输出。

4.面临挑战

RLHF算法的性能最高只能达到与人类评估的行为,因此如果人类没有很好地掌握任务,他们不会提供很多有用的反馈,这进一步限制了模型的效果。

同时,AI系统的安全性不仅取决于底层模型的行为,还取决于这些模型的部署方式。需要更多的过滤器来检测不安全行为的生成。

InstructGPT更多的还是偏向于英语的文化价值观,针对少数群体的差异和分歧,该模型很难对齐。这更需要加入人工知识,来进一步平衡模型的价值观。

5.参考

1.https://zhuanlan.zhihu.com/p/591474085

2.https://huggingface.co/blog/rlhf

3.https://openai.com/blog/deep-reinforcement-learning-from-human-preferences/

4.https://mp.weixin.qq.com/s?__biz=MzI4MDYzNzg4Mw==&mid=2247554744&idx=3&sn=58d27263f499a939cba817522840a9cb&chksm=ebb72e6cdcc0a77a135c55c297c3c8c5ee106780c92f072bbf821ea0f8a1e143a47034e69680&scene=27

5.https://openai.com/blog/instruction-following/

好了,以上就是本期的全部内容了,我是leo,欢迎关的公众号/知乎"算法一只狗",我们下期再见~

本文转载于网络 如有侵权请联系删除

相关文章

  • VBA小技巧10:删除工作表中的错误值

    这里将编写VBA代码,用来删除工作表指定区域中的错误值,这在很多情况下都很有用。如下图1所示,有一组数据,但其中有一些错误值,我们想要自动删除这些错误值。图1删除错误值的数据表如下图2所示。图2如果不使用VBA,可以使用Excel的“定位”功能来实现。如下图3所示,单击功能区“开始”的“编辑”组中的“查找和选择——定位条件”,弹出“定位条件”对话框。在该对话框中,选取“公式”中“错误”前的复选框,如下图3所示。图3单击“确定”后,工作表中的错误数据单元格会被选择,单击“Delete”键,删除错误值,结果如上图2所示。也可以使用下面的VBA代码实现:SubDeleteError1()Range("B2:E8").SpecialCells(xlCellTypeFormulas,16).ClearContentsEndSub一句代码,即可实现!还可以使用下面的VBA代码:SubDeleteError2() DimrngDataAsRange DimcellAsRange SetrngData=Range("B2:E8") ForEachcellInrn

  • 仅仅是改变了统计学显著性呢?还是说改变了其本性

    前面我们分享过:学徒数据挖掘之谁说生存分析一定要按照表达量中位值或者平均值分组呢?,可以很容易对一个基因,根据表达量分组,然后进行生存分析,判断它是风险因子或者是保护因子,当然了前提是具有统计学显著性啦。然后很多粉丝留言说,如果并不是按照表达量中位值或者平均值分组,而是取巧使用了surv_cutpoint这样的函数,得到的结果并不好解释,认为这样的的数据处理方式简直是黑白颠倒!我看到了这样的留言,确实思考了一下,使用了surv_cutpoint这样的函数是仅仅是改变了统计学显著性指标呢?还是说,确实有可能造成黑白颠倒呢?风险因子会变成保护因子???布置它为学徒作业吧前面自己把表达量矩阵和临床信息准备好,得到exprSet这个表达量矩阵,以及meta这个临床信息,然后就可以使用了surv_cutpoint这样的函数对指定基因做生存分析啦,代码如下所示:library(survival) library(survminer) gs=c('BCL2','BCL2L1','MCL1') splots<-lapply(gs,f

  • 【LeetCode】一文详解二叉树的三大遍历:前序、中序和后序(python和C++实现)

    本文主要包括利用递归和栈的方法实现二叉树的前序、中序、后序遍历!144.二叉树的前序遍历给定一个二叉树,返回它的前序遍历。示例:输入:[1,null,2,3]1 \ 2 / 3 复制输出:[1,2,3]解题思路1.1树的前序遍历--非递归方法(栈)因为先访问根节点,所以直接将root的val放入答案(ans)容器利用stack来储存root。当左子树遍历完后,取出root接着遍历右子树。C++实现:/** *Definitionforabinarytreenode. *structTreeNode{ *intval; *TreeNode*left; *TreeNode*right; *TreeNode(intx):val(x),left(NULL),right(NULL){} *}; */ classSolution{ public: vector<int>preorderTraversal(TreeNode*root){ std::stack<TreeNode*>stack; vector<int>ans; while(root!=NULL||!s

  • 腾讯云 Elasticsearch 实战篇(二十二) ES6.8权限使用配置

    前言|在前面的章节中我们讲了开源架构ELK、腾讯云Elasticsearch产品系列。我们也知道了,在构建腾讯云ES集群的时候,我们选择的6.8.2白金版具备充分的安全的机制来保证数据和访问的安全。那么,它到底是如何实现的呢?我们今天就来简单聊聊这个问题:一、在ElasticSearch6.8及以上版本开启安全认证功能ElasticSearch的商业插件X-pack在ES6.x版本以前一直都是收费,不对外免费开放的。在ES6以后陆续放开了一些功能,比如前面讲到的Monitor集群监控功能。在ES6.8及以后版本ES又将部分安全性功能免费开放了,包含安全认证功能,之后版本又开放一些基础认证功能,对于普通用户来说是够用的。这里要提一下的是kibana的登录和权限是与ES紧密相关的,其实真正起作用的是Elasticsearch,因为kibana只是一个视图页面,真正工作的是Elasticsearch。现在我们就6.8版本的【基于角色的访问控制】进行操作、验证。步骤如下:第一步:下载、安装ES、Kibana6.8.2版本(此处省略,可参考本博客前面的教程)第二步:修改ES配置文件 elasti

  • python打印数组的全部元素

    Python打印数组的全部元素学习Python的人都知道数组是最常用的的数据类型,为了保证程序的正确性,需要调试程序。因此,需要在程序中控制台中打印数组的全部元素,如果数组的容量较小,例如只含有10个元素,采用print命令或print函数可以答应出数组中的每个元素;如果数组的容量过大,只能打印出数组的部分元素,打印结果只包含开始部分元素和结尾部分元素,中间元素省略。省略的部分不利于程序的调试,因此,为了方便调试程序,需要将数组中的元素全部打印出来。1.少量元素情况__author__='cmwqq2008' #coding=gbk #打印数组中的元素 fromnumpyimport* a=arange(6) printa 程序结果为:[012345] 2.大量元素情况可以采用set_printoptions(threshold='nan')set_printoptions(threshold='nan') printarange(100) printarange(100).reshape(10,10) 结果为:[0 1 2

  • 在Java中如何理解面向接口编程,荐读篇

    引言--面向接口所处的设计模式中的位置。 其实,我认为Java/C#比C++高级的其中一个原因是,它对面向接口编程的支持。不要误解,并不是说C++不支持面向接口编程,而是说C++的语法中没有这种天然的机制。面向对象之于面向过程,面向接口之于面向实现。但基本上,面向接口和面向实现都基于面向对象的模式,也就是说面向接口并不能称为比面向对象的更高的一种编程模式。而是在面向对象中大的背景下的一种更加合理的软件设计模式,它增强了类与类之间,模块与模块的之间的低耦合性,是软件系统更容易维护、扩展。不管是面向什么,都是一种软件设计模式,与具体的语言有没多大关系。就像之前介绍C语言一样,并不是说C语言这种面向过程的语言不能做面向对象编程,而是说,C语言当初设计的并没有针对面向对象软件系统的风格而进行设计的。由于后来的面向对象软件设计风格的流行,后来者语言C++/java/C#都在语言设计上充分考虑了支持面向对象的方便性,所以这些语言称为面向对象编程语言。根据语言之间没有能力大小的理论,C是可以进行面向对象编程的(实践上也是可行的)。上面理论同样适合讨论——C++之于面向接口编程。面向接口软件设计,并不

  • 左手Python,右手Go

    左手Python,右手Go0.说在前面最近Go很火!!!所以我也来学习了,一起来嗨GO!1.HelloWorld程序packagemain import"fmt" funcmain(){ fmt.Println("Hello,World!") //单行注释 /* 我是多行注释 */ } 复制注意一点,main()后面的大括号不能放在下面,会有语法错误哦~2.基本语法注释单行注释//单行注释 复制多行注释/*我是多行注释*/ 复制数据类型布尔型数字类型字符串类型派生类型区别:Go的字符串是单个字节连接!数字类型有整型int,浮点型float32,float64等!派生类型主要包含:指针类型(Pointer)数组类型结构化类型(struct)Channel类型函数类型切片类型接口类型(interface)Map类型变量【形式】声明变量的一般形式是使用var关键字:var变量名type 复制变量名也跟其他语言一样,起始不能为数字,由下划线,数组,字母组成!【单变量声明】例如:packagemain varname="光城" vara

  • Python 获取被调用函数名称,所处模块,被调用代码行

    module2.py:#!/usr/bin/envpython#-*-coding:utf-8-*-__author__='shouke'importsysdefget_cur_info():#获取被调用函数名称print(sys._getframe().f_code.co_name)#获取被调用函数在被调用时所处代码行数print(sys._getframe().f_back.f_lineno)#获取被调用函数所在模块文件名print(sys._getframe().f_code.co_filename)module1.py结果:

  • 如何在UFW、FirewallD、IPTable为Docker Swarm集群配置防火墙

    介绍DockerSwarm是Docker官方三剑客项目之一,提供Docker容器集群服务,是Docker官方对容器云生态进行支持的核心方案。使用它,用户可以将多个Docker主机封装为单个大型的虚拟Docker主机,快速打造一套容器云平台。DockerSwarm正常运行所需的网络端口是:用于保障Docker客户端通信安全机制的TCP2376端口。DockerMachine需要此端口才能工作。DockerMachine用于编排Docker主机。TCP端口。此端口2377用于DockerSwarm或集群的节点之间的通信。TCP和UDP端口7946用于节点之间的通信。用于覆盖网络流量的UDP端口4789。注意:除了这些端口之外,还必须打开端口22(用于SSH流量)以及任何在群集上运行特定服务所需的其他端口。腾讯云相关端口配置详见:腾讯云CVM安全组配置文档在本文中,您将学习如何使用防火墙管理应用程序在Ubuntu16.04上配置Linux防火墙。防火墙管理应用程序包括FirewallD,IPTables工具和UFW(简单防火墙)。UFW是Ubuntu发行版上的默认防火墙应用程序。本教程涵盖三

  • Lombok介绍、使用方法和总结

    1Lombok背景介绍官方介绍如下:ProjectLombokmakesjavaaspicierlanguagebyadding'handlers'thatknowhowtobuildandcompilesimple,boilerplate-free,not-quite-javacode.复制大致意思是Lombok通过增加一些“处理程序”,可以让java变得简洁、快速。2Lombok使用方法Lombok能以简单的注解形式来简化java代码,提高开发人员的开发效率。例如开发中经常需要写的javabean,都需要花时间去添加相应的getter/setter,也许还要去写构造器、equals等方法,而且需要维护,当属性多时会出现大量的getter/setter方法,这些显得很冗长也没有太多技术含量,一旦修改属性,就容易出现忘记修改对应方法的失误。Lombok能通过注解的方式,在编译时自动为属性生成构造器、getter/setter、equals、hashcode、toString方法。出现的神奇就是在源码中没有getter和setter方法,但是在编译生成的字节码文件中有

  • 程序员需要多个显示器来提高工作效率

    程序员需要多个显示器来提高工作效率我发现了一篇很有意思的关于研究多个显示器与生产力的博客文章。去年一些开发人员,包括我自己,开始使用多个显示器设置。基于我的经验,我完全同意这项研究调查的结果: 平均而言,人们宁愿要两个小一点的显示器也不要一个大一点的。没有人会回答说,他们更喜欢一个大屏的显示器。当应用程序有调色板或需要同时打开两三个窗口用于编程/调试等的时候,是多显示器最有用的时候。最大的抱怨是桌面空间太小,这是因为给我们配备的显示器都是CRT(而非LCD)。 上面这些结论对于重视时间的开发人员而言是明摆着的事实。而且现在比以往任何时候都更有这个趋向,这是因为: 最主流的廉价显卡都往往会配备两个VGA端口(又名“双头”)标准。不那么笨重的17″和19″液晶显示器的价格非常公道。WindowsXP中有成熟的多显示器支持:自从Windows98之后,开箱即用的win32功已经成为了一个标准。两台显示器需要更多的插头和一个现代化的“双头”显卡,但三台显示器就比较少见了——它的要求更多。 我最近刚进化到三台显示器的阶段,我觉得这是值得的。所有我认为不适合放在第一个和第二个显示器上的“额外的东西

  • Go语言 context包源码学习

    你必须非常努力,才能看起来毫不费力! 微信搜索公众号[漫漫Coding路],一起FromZeroToHero! 前言 日常Go开发中,Context包是用的最多的一个了,几乎所有函数的第一个参数都是ctx,那么我们为什么要传递Context呢,Context又有哪些用法,底层实现是如何呢?相信你也一定会有探索的欲望,那么就跟着本篇文章,一起来学习吧! 需求一 开发中肯定会调用别的函数,比如A调用B,在调用过程中经常会设置超时时间,比如超过2s就不等待B的结果了,直接返回,那么我们需要怎么做呢? //睡眠5s,模拟长时间操作 funcFuncB()(interface{},error){ time.Sleep(5*time.Second) returnstruct{}{},nil } funcFuncA()(interface{},error){ varresinterface{} varerrerror ch:=make(chaninterface{}) //调用FuncB(),将结果保存至channel中 gofunc(){ res,err=FuncB()

  • 聊聊vue组件开发的“边界把握”和“状态驱动”

    vue有着完整的组件化开发机制,但是官网只给了开发的方式,对于开发规范以及组件化开发的最佳实践,还需要我们来摸索。本文就平时开发中的经验来谈谈“把握边界”和“状态驱动”这两个话题。 边界把握 边界把握其实很好理解。在模块化编程中,我们通常要定义好一个模块的功能边界,做什么,不做什么,从外部接收什么,向外部提供什么。在vue的组件化系统之下,这些问题又更具体一些,需要我们细细把握。 划分业务逻辑 这个原则适用于任何模块化开发,一个组件要负责哪些业务,在开始写之初就应该非常明确,否则边界就容易模糊了。举个例子,页面上有个弹出层,里面会显示用户名。那么在弹出层组件中,需要有username这样一个数据吗? 很显然是不需要的。弹出层的任务就是:弹出、关闭、显示内容。至于是什么内容,组件并不需要关心。所以我们顶多会定义一个通用的content字段,或者干脆用slot。 组件简单了尚且容易把握,当业务较复杂的时候就需要好好斟酌了,这是个基本思维。 父子通信的注意点 这个话题想必大家不陌生,你甚至可以朗朗上口的背出来:父通过props传递数据给子,子通过emit发送消息给父。这有什么好说的呢? pr

  • 【BZOJ-4261】建设游乐场 最大费用最大流

    4261:建设游乐场 TimeLimit: 50Sec  MemoryLimit: 256MBSubmit: 21  Solved: 8[Submit][Status][Discuss] Description 现在有一大块土地,可以看成N*M的方格。在这块土地上,有些格子内是崎岖的山地,无法建造任何东西;其他格子都是平原。现在打算在这块土地上建设一个游乐园。游乐园由若干条闭合的过山车轨道组成,每个平原格子都要铺一截轨道,为下列6种类型中的一种: (每张图表示一块平原格子,图内网格线为辅助线,无实际意义。)   其中前2种为直轨道,后4种为弯轨道。显然对游客来说,弯轨道更加刺激。   由于每块格子风景各不相同,经过一番研究,现给了N*M个方格中的每个格子一个评估值,意义为:如果该格子修建弯轨道,会给游客们带来多少的愉悦值。现需要一名设计师,帮他设计一种最优的轨道建设方案,使所有格子给游客们带来的愉悦值之和尽量大。(如果没有合法方案,输出-1) Input 第一行两个正整数n,

  • 将Medium中的博客导出成markdown

    Medium(https://medium.com)(需要FQ访问)是国外非常知名的一个博客平台。上面经常有很多知名的技术大牛在上面发布博客,现在一般国内的搬运的技术文章大多数都是来自于这个平台。 Medium文章格式显示地非常优雅,但是存在一个问题。众所周知,markdown已经是最受程序猿欢迎的文本编辑格式之一。但是Medium仅仅支持markdown格式导入,不支持markdown格式的导出。这也正是我当初开发这个插件export-medium的原因,现在这个项目是放在github上面的,欢迎大家多多star,或者pr。自己也花了5美金,注册了开发者账号,因为现在chrome对于不是商店的插件限制很严格,如果没上商店,一直有提醒,很麻烦。商店访问地址在这,需要FQ访问。不过你可以手动安装: *将export-mediumclone或者下载到本地。 *在Chrome浏览中打开chrome://extensions,加载已解压的拓展程序,选择项目文件夹 这两种方法都是可以支持安装的。目前这个插件的功能主要是把Medium上面的文章解析成markdown格式的文本,用了一个

  • 分析仙剑4物理攻击的时候遇到一段代码

    PAL4.exe+139EF0-8B442404-moveax,[esp+04]PAL4.exe+139EF4-83F80A-cmpeax,0A{10}PAL4.exe+139EF7-7D0B-jnlPAL4.exe+139F04PAL4.exe+139EF9-85C0-testeax,eaxPAL4.exe+139EFB-7C07-jlPAL4.exe+139F04PAL4.exe+139EFD-8B8481CC000000-moveax,[ecx+eax*4+000000CC]PAL4.exe+139F04-C20400-ret0004{4}   贴出来的目的就是想记录一下,我以前看汇编代码不是很流利,最近看了一点儿之后,感觉有了感觉了。 观察一下上面代码。 只调用了一个栈中的变量,可以认为这个函数只有一个参数。 先从栈中取得这个参数,然后和10比较。如果大于等于10则返回,小于10则判断这个参数是否小于0,小于则返回。   intfunc(intindex) {   if(index<10)   {     if(index<0)     {ret

  • oracle与mysql创建表时的区别

    oracle创建表时,不支持在建表时同时增加字段注释。故采用以下方式: #创建表CREATETABLEpredict_dataas( idintegerNOTNULL,uidvarchar2(80), midvarchar2(80), timedate, contentvarchar2(300), constraintpredict_dataprimarykey(id) );#字段注释commentontablepredict_datais'预测表';commentoncolumnpredict_data.idis'主键';commentoncolumnpredict_data.uidis'用户名';commentoncolumnpredict_data.midis'博文id';commentoncolumnpredict_data.timeis'发文时间';commentoncolumnpredict_data.contentis'发文内容';复制 mysql创建表时,支持在建表时同时增加字段注释。故采用以下方式: CREATETABLEpredict_data( idintN

  • MySQL【锁】

    一、锁概述 锁是计算机协调多个进程或线程并发访问某一资源的机制(避免争抢)。 在数据库中,除传统的计算资源(如CPU、RAM、I/O等)的争用以外,数据也是一种供许多用户共享的资源。如何保证数据并发访问的一致性、有效性是所有数据库必须解决的一个问题,锁冲突也是影响数据库并发访问性能的一个重要因素。从这个角度来说,锁对数据库而言显得尤其重要,也更加复杂。 二、锁分类 (一)按操作粒度分 1)表锁:操作时,会锁定整个表 2)行锁:操作时,会锁定当前操作行 (二)按操作类型分 1)读锁(共享锁):针对同一份数据,多个读操作可以同时进行而不会互相影响 2)写锁(排它锁):当前操作没有完成之前,它会阻断其他写锁和读锁 三、MySQL中的锁 相对其他数据库而言,MySQL的锁机制比较简单,其最显著的特点是不同的存储引擎支持不同的锁机制。 下表中罗列出了各存储引擎对锁的支持情况: 存储引擎 表级锁 行级锁 页面锁 MyISAM 支持 不支持 不支持 InnoDB 支持 支持 不支持 MEMORY 支持 不支持 不支持 BDB 支持 不支持 支持 MySQL这3

  • GmSSL开发环境搭建及双证书生成

    目录国密开发总结国密开发环境搭建及双证书生成GMSSL 国密开发总结 国密开发环境搭建及双证书生成 GMSSL GmSSL是一个开放源代码加密工具包,它提供对GM/T串行标准中指定的中国国家加密算法和协议的第一级支持。作为OpenSSL项目的一个分支,GmSSL提供与OpenSSL的API级别兼容性并维护所有功能。在此感谢贡献,该项目地址:(https://github.com/guanzhi/GmSSL) 1.代码下载及配置变量 #通过git下载 $gitclonehttps://github.com/guanzhi/GmSSLgmssl #如果嫌下载速度慢,也可下载代码压缩包 $wgethttps://github.com/guanzhi/GmSSL/archive/master.zip $unzipmaster.zip 复制 GmSSL工具箱相关项目文档 2.编译与安装 $cd你解压的目录 $./config--prefix=/usr/local/gmssl $make $makeinstall $cd/usr/local/gmssl #tree:显示目录树-d:只显示目录-L:

  • VituralBox无法桥接问题解决办法

    我在使用VitualBox创建虚拟机后,一般需要设置桥接网卡的方式来模拟一个比较真实的服务器环境。但是有时候会发现VitualBox将从因为找不到宿主主机的网卡而无法设置桥接,如下图所示: 经过查找资料发现这是因为没有安装桥接驱动的原因,只要按照下列步骤再安装上即可。 打开物理网卡适配器的属性界面,点击安装: 然后,选择服务,点击添加: 从磁盘安装,浏览VitualBox的安装目录,找到文件VBoxNetLwf.inf,一般路径是VirtualBox\drivers\network\netlwf\VBoxNetLwf.inf 确定安装,等待一会儿即可,然后返回网卡属性界面就会看见一个VirtualBox的桥接驱动显示在列表中 最后重新打开VirtualBox之后,再次设置网卡桥接,已经可以找到网卡了,问题解决!

  • C++单例模式

    https://blog.csdn.net/unonoi/article/details/121138176 https://zhuanlan.zhihu.com/p/37469260

相关推荐

推荐阅读