解决flutter集成sqlite3报错问题

在集成sqlite3的时候报如下错误: ======== Exception caught by widgets library ======================================================= The following ArgumentError was thrown building Builder: Invalid argument(s): Failed to load dynamic library '/data/data/cn.liginfo.kqjhq_app/lib/libsqlite3.so': dlopen failed: library "/data/data/cn.liginfo.kqjhq_app/lib/libsqlite3.so" not found 通过报错信息查看是找不到libsqlite3.so的文件,在全网搜索这个报错信息,关于flutter的app报这个错误的解决方案几乎没有。当我自己在csdn下载了libsqlite3.so文件 放到任何目录下都解决不了该问题。随后通过不屑的努力通过俩个地方可以找到答案,一个是给提供flutter的sqlite3包的仓库说明,一个是来至https://stackoverflow.com/的解决方案。 在flutter仓库中的Readme中其实有说明: 在支持的平台中有说明,如果是Android的平台的flutter用户需要依赖sqlite3_flutter_libs包,去装载最近的sqlite3版本。所以需要多依赖一个sqlite3_flutter_libs,所以我们在flutter库中添加了sqlite3_flutter_libs的库就可以正常使用sqlite3了。 另一个是在stackoverflow中有一个解答这个问题的。 他说经过长时间的搜索,他的问题得到了解决通过添加sqlite3_flutter_libs. 自此问题已经全部解决。

vue-quill-editor自定义工具栏,确定光标位置、插入内容,获取选中的内容。

文章目录 一、安装使用二、自定义工具栏三、自定义按钮四、获取富文本编辑器的光标位置,并插入内容或图片五、获取选中的内容六、官方文档 一、安装使用 下载 yarn add vue-quill-editor yarn add quill 导入 import { quillEditor } from "vue-quill-editor"; import 'quill/dist/quill.core.css'; import 'quill/dist/quill.snow.css'; import 'quill/dist/quill.bubble.css'; 注册 export default { components: { quillEditor }, } 使用 <quill-editor v-model="content" :options="editorOption" ref="QuillEditor"></quill-editor> 二、自定义工具栏 定义工具栏 const toolbarOptions = [ ['bold', 'italic', 'underline', 'strike'], // toggled buttons ['blockquote', 'code-block'], [{ 'header': 1 }, { 'header': 2 }], // custom button values [{ 'list': 'ordered'}, { 'list': 'bullet' }], [{ 'script': 'sub'}, { 'script': 'super' }], // superscript/subscript [{ 'indent': '-1'}, { 'indent': '+1' }], // outdent/indent [{ 'direction': 'rtl' }], // text direction [{ 'size': ['small', false, 'large', 'huge'] }], // custom dropdown [{ 'header': [1, 2, 3, 4, 5, 6, false] }], [{ 'color': [] }, { 'background': [] }], // dropdown with defaults from theme [{ 'font': [] }], [{ 'align': [] }], ['clean'] // remove formatting button ]; 配置 export default { placeholder: '', // 默认展示文字 theme: 'snow', // 主题 modules: { toolbar: { container: toolbarOptions , // 自定义工具栏选项 handlers: { // 事件添加 // handlers object will be merged with default handlers object 'link': function(value) { // 事件名和工具名一致 if (value) { var href = prompt('Enter the URL'); this.

目标检测数据集PASCAL VOC简介

简介 PASCAL VOC挑战赛 (The PASCAL Visual Object Classes )是一个世界级的计算机视觉挑战赛, PASCAL全称:Pattern Analysis, Statical Modeling and Computational Learning,是一个由欧盟资助的网络组织。 很多优秀的计算机视觉模型比如分类,定位,检测,分割,动作识别等模型都是基于PASCAL VOC挑战赛及其数据集上推出的,尤其是一些目标检测模型(比如大名鼎鼎的R CNN系列,以及后面的YOLO,SSD等)。 PASCAL VOC从2005年开始举办挑战赛,每年的内容都有所不同,从最开始的分类,到后面逐渐增加检测,分割,人体布局,动作识别(Object Classification 、Object Detection、Object Segmentation、Human Layout、Action Classification)等内容,数据集的容量以及种类也在不断的增加和改善。该项挑战赛催生出了一大批优秀的计算机视觉模型(尤其是以深度学习技术为主的)。 我们知道在 ImageNet挑战赛上涌现了一大批优秀的分类模型,而PASCAL挑战赛上则是涌现了一大批优秀的目标检测和分割模型,这项挑战赛已于2012年停止举办了,但是研究者仍然可以在其服务器上提交预测结果以评估模型的性能。 虽然近期的目标检测或分割模型更倾向于使用MS COCO数据集,但是这丝毫不影响 PASCAL VOC数据集的重要性,毕竟PASCAL对于目标检测或分割类型来说属于先驱者的地位。对于现在的研究者来说比较重要的两个年份的数据集是 PASCAL VOC 2007 与 PASCAL VOC 2012,这两个数据集频频在现在的一些检测或分割类的论文当中出现。 PASCAL主页 与 排行榜 (榜上已几乎看不到传统的视觉模型了,全是基于深度学习的) PASCAL VOC 2007 挑战赛主页 与 PASCAL VOC 2012 挑战赛主页 与 PASCAL VOC Evaluation Server. 以及在两个重要时间点对 PASCAL VOC挑战赛 成绩进行总结的两篇论文 The PASCAL Visual Object Classes Challenge: A Retrospective

安装Linux遇到的一点问题

按照网上的教程安装Liunx,成功后并没有出现期待的图形化界面,结果一步步排查发现自己在这个界面的时候忘记了点【软件选择】,结果默认安装的就是命令行窗口。 在软件选择安装我们的桌面,此处选择GNOME桌面 然后正常流程继续 后面就正常了。 此外,在命令行窗口,新手的疑问是输入密码的时候界面会没有反应,第一反应是键盘坏了,结果上网查查,原来Linux下输入密码就是看不到,正确输入密码即可。 localhost login:root Password: Password上面直接写root的密码,但屏幕上不显示。 如果出现 localhost login:root Password: login incorrect. login: 这种情况就是密码写错了。login:这里写root 会显示Password:,再填入root系统管理员的密码。

在 vim 中编辑时 突然卡死怎么办

问题描述 在 Linux 下中 vim 编辑会莫名其妙的卡死,按啥都动不了。 查资料是因为不小心按到了 ctrl + s,让 vim 阻塞了。 解决办法 按 ctrl + q 就可以退出卡死状态,就可以正常编辑了。

以太坊虚拟机( EVM )

以太坊虚拟机( EVM ) 以太坊虚拟机 EVM 是智能合约的运行环境作为区块验证协议的一部分,参与网络的每个节点都会运行 EVM 。他们会检查正在验证的块中列出的交易,并运行由 EVM 中的交易触发的代码EVM 不仅是沙盒封装的,而且是完全隔离的,也就是说在 EVM 中运行的代码是无法访问网络、文件系统和其他进程的,甚至智能合约之间的访问也是受限的合约以字节码的格式( EVM bytecode )存在于区块链上合约通常以高级语言( solidity )编写,通过 EVM 编译器编译为字节码,最终通过客户端上部署到区块链网络中 EVM 和 账户 以太坊中有两类账户:外部账户 和 合约账户,它们共用 EVM 中同一个地址空间无论账户是否存储代码,这两类账户对 EVM 来说处理方式是完全一样的每个账户在 EVM 中都有一个键值对形式的持久化存储。其中 key 和 value 的长度都是 256 位,称之为 存储空间( storage ) EVM 和交易 交易可以看作是从一个账户发送到另一个账户的消息,它可以包含二进制数据( payload )和 以太币如果目标账户含有代码,此代码会在 EVM 中执行,并从 payload 作为入参,这就是 合约的调用如果目标账户是零账户( 账户地址为 0 ),此交易就将创建一个 新合约,这个用来创建合约的交易的 payload 会被转换为 EVM 字节码并执行,执行的输出作为合约代码永久存储 EVM 和 gas 合约被交易触发调用时,指令会在全网的每个节点上执行:这需要消耗算例成本;每一个指令的执行都有特定的消耗,gas 就用了该量化表示这个成本消耗一经创建,每笔交易都按照一定数量的 gas 预付一笔费用,目的是限制执行交易所需要的工作量和为交易支付手续费EVM 执行交易时,gas 将按特定规则逐渐消耗gas price 时交易发送者设置的一个值,作为发送者预付手续费的单价。如果交易执行后还有剩余,gas 会被原路返还无论执行到什么位置,一旦 gas 被耗尽( 比如降为负值 ),将会触发一个 out-of-gas 异常。当前调用帧( call frame )所做的所有状态修改都将被回滚 EVM 数据存储 Storage 每个账户都有一块持久化的存储空间,称为 storage,这是一个将 256 为字映射到 256 位字的 key-value 存储区,可以理解为合约的数据库永久存储在区块链中,由于会永久保存合约状态变量,所以读写的 gas 开销也是最大的 Memory(内存) 每一个消息调用,合约会临时获取一块干净的内存空间生命周期仅为整个方法执行期间,函数调用后回收,因为仅保存临时变量,故读写 gas 开销较小 Stack(栈) EVM 不是基于寄存器的,而是基于栈的,因此所有的计算都在一个被称为栈( stack )的区域执行存放部分局部值类型变量,几乎免费使用的内存,但有数量限制 EVM 指令集 所有的指令都是针对 “256 位的字( word )” 这个基本的数据类型来进行操作具备常用的算数、位、逻辑和比较操作,也可以做到有条件和无条件跳转合约可以访问当前区块的相关属性,比如它的块高度和时间戳 消息调用( Message Calls ) 合约可以通过调用的方式来调用其它合约或者发送以太币到非合约账户合约可以决定在其内部的消息调用中,对于剩余的 gas ,应发送和保留多少如果在内部消息调用发生了 out-of-gas 异常(或其他任何异常),这将由一个被压入栈顶的错误值所指明;此时只有与该内部消息调用一起发送的 gas 会被消耗掉 委托调用(Delegatecall) 一种特殊类型的消息调用目的地址的代码将在发起调用的合约的上下文执行,并且 msg.

分布式事务CAP与Base理论以及2PC、3PC模式、XA模式、TCC模式、Saga模式、Seata框架介绍

一、分布式事务理论知识 1、CAP(强一致性) CAP定理,又被叫作布鲁尔定理。对于共享数据系统,最多只能同时拥有CAP其中的两个,任意两个都有其适应的场景。 2、BASE(最终一致性) BASE 是指基本可用(Basically Available)、软状态(Soft State)、最终一致性(Eventual Consistency)。它的核心思想是即使无法做到强一致性(CAP就是强一致性),但应用可以采用适合的方式达到最终一致性。 BA指的是基本业务可用性,支持分区失败;S表示柔性状态,也就是允许短时间内不同步;E表示最终一致性,数据最终是一致的,但是实时是不一致的。 原子性和持久性必须从根本上保障,为了可用性、性能和服务降级的需要,只有降低一致性和隔离性的要求。 BASE解决了CAP理论中没有考虑到的网络延迟问题,在BASE中用软状态和最终一致,保证了延迟后的一致性。 3、分布式事务模式 分布式解决方案: 2PC模式(强一致性) 2PC是Two-PhaseCommit缩写,即两阶段提交,就是将事务的提交过程分为两个阶段来进行处理。事务的发起者称协调者,事务的执行者称参与者。协调者统一协调参与者执行。 阶段1:准备阶段 协调者向所有参与者发送事务内容,询问是否可以提交事务,并等待所有参与者答复。各参与者执行事务操作,但不提交事务,将undo和redo信息记入事务日志中。 如参与者执行成功,给协调者反馈yes;如执行失败,给协调者反馈no。 阶段2:提交阶段 如果协调者收到了参与者的失败消息或者超时,直接给每个参与者发送回滚(rolback)消息;否则,发送提交(commit)消息。 2PC方案实现起来简单,实际项目中使用比较少,主要因为以下问题: 性能问题:所有参与者在事务提交阶段处于同步阻塞状态,占用系统资源,容易导致性能瓶颈。可靠性问题:如果协调者存在单点故障问题,如果协调者出现故障,参与者将一直处于锁定状态。数据一致性问题:在阶段2中,如果发生局部网络问题,一部分事务参与者收到了提交消息,另一部分事务参与者没收到提交消息,那么就导致了节点之间数据的不一致。 3PC模式(强一致性) PC三阶段提交,是两阶段提交的改进版本,与两阶段提交不同的是,引入超时机制。同时在协调者和参与者中都引入超时机制。三阶段提交将两阶段的准备阶段拆分为2个阶段,插入了一个preCommit阶段,解决了原先在两阶段提交中,参与者在准备之后,由于协调者或参与者发生崩溃或错误,而导致参与者无法知晓处于长时间等待的问题。如果在指定的时间内协调者没有收到参与者的消息则默认失败。 阶段1:canCommit协调者向参与者发送commit请求,参与者如果可以提交就返回yes响应,否则返回no响应。阶段2:preCommit协调者根据阶段1 canCommit参与者的反应情况执行预提交事务或中断事务操作。 参与者均反馈 yes:协调者向所有参与者发出preCommit请求,参与者收到preCommit请求后,执行事务操作,但不提交;将undo和redo信息记入事务日志中;各参与者向协调者反馈ack响应或no响应,并等待最终指令。 任何一个参与者反馈no或等待超时:协调者向所有参与者发出abort请求,无论收到协调者发出的abort请求,或者在等待协调者请求过程中出现超时,参与者均会中断事务。阶段3:do Commit该阶段进行真正的事务提交,根据阶段2 preCommit反馈的结果完成事务提交或中断操作。 相比2PC模式,3PC模式降低了阻塞范围,在等待超时后协调者或参与者会中断事务。避免了协调者单点问题,阶段3中协调者出现问题时(比如网络中断等),参与者会继续提交事务。 XA(强一致性) XA是由X/Open组织提出的分布式事务的规范,是基于两阶段提交协议。XA规范主要定义了全局事务管理器(TM)和局部资源管理器(RM)之间的接口。目前主流的关系型数据库产品都是实现了XA接口。 XA之所以需要引入事务管理器,是因为在分布式系统中,从理论上讲两台机器理论上无法达到一致的状态,需要引入一个单点进行协调。由全局事务管理器管理和协调的事务,可以跨越多个资源(数据库)和进程。 事务管理器用来保证所有的事务参与者都完成了准备工作(第一阶段)。如果事务管理器收到所有参与者都准备好的消息,就会通知所有的事务都可以提交了(第二阶段)。MySQL在这个XA事务中扮演的是参与者的角色,而不是事务管理器。 TCC模式(最终一致性) TCC(Try-Confirm-Cancel)的概念,最早是由Pat Helland于2007年发表的一篇名为《Life beyond Distributed Iransactions:an Apostate’s Opinion》的论文提出。TCC是服务化的两阶段编程模型,其Try、Confirm、Cancel3个方法均由业务编码实现: Try操作作为一阶段,负责资源的检查和预留;Confirm操作作为二阶段提交操作,执行真正的业务;Cancel是预留资源的取消; TCC事务模式相对于XA等传统模型如下图所示: TCC模式相比于XA,解决了如下几个缺点: 解决了协调者单点,由主业务方发起并完成这个业务活动。业务活动管理器可以变成多点,引入集群。同步阻塞:引入超时机制,超时后进行补偿,并且不会锁定整个资源,将资源转换为业务逻辑形式,粒度变小。数据一致性,有了补偿机制之后,由业务活动管理器控制一致性。 消息队列模式(最终一致性) 消息队列的方案最初是由eBay提出,基于TCC模式,消息中间件可以基于Kafka、RocketMQ等消息队列。 此方案的核心是将分布式事务拆分成本地事务进行处理,将需要分布式处理的任务通过消息日志的方式来异步执行。消息日志可以存储到本地文本、数据库或MQ中间件,再通过业务规则自动或人工发起重试。 事务的处理流程: 步骤1:事务主动方处理本地事务。 事务主动方在本地事务中处理业务更新操作和MQ写消息操作。步骤2:事务主动方通过消息中间件,通知事务被动方处理事务通知事务待消息。 事务主动方主动写消息到MQ,事务消费方接收并处理MQ中的消息。步骤3:事务被动方通过MQ中间件,通知事务主动方事务已处理的消息,事务主动方根据反馈结果提交或回滚事务。 为了数据的一致性,当流程中遇到错误需要重试,容错处理规则如下: 当步骤1处理出错,事务回滚,相当于什么都没发生。当步骤2处理出错,由于未处理的事务消息还是保存在事务发送方,可以重试或撤销本地业务操作。如果事务被动方消费消息异常,需要不断重试,业务处理逻辑需要保证幂等。如果是事务被动方业务上的处理失败,可以通过MQ通知事务主动方进行补偿或者事务回滚。如果多个事务被动方已经消费消息,事务主动方需要回滚事务时需要通知事务被动方回滚。 Saga模式(最终一致性) Saga这个概念源于1987年普林斯顿大学的Hecto和Kenneth发表的一篇数据库论文Sagas,一个Saga事务是一个有多个短时事务组成的长时的事务。在分布式事务场景下,我们把一个Saga分布式事务看做是一个由多个本地事务组成的事务,每个本地事务都有一个与之对应的补偿事务。在Saga事务的执行过程中,如果某一步执行出现异常,Saga事务会被终止,同时会调用对应的补偿事务完成相关的恢复操作,这样保证Saga相关的本地事务要么都是执行成功,要么通过补偿恢复成为事务执行之前的状态。(自动反向补偿机制)。 Saga事务基本协议: 每个Saga事务由一系列幂等的有序子事务(sub-transaction)Ti组成。每个Ti都有对应的幂等补偿动作Ci,补偿动作用于撤销Ti造成的结果。 Saga是一种补偿模式,它定义了两种补偿策略: 向前恢复(forward recovery):对应于上面第一种执行顺序,发生失败进行重试,适用于必须要成功的场景。向后恢复(backward recovery):对应于上面提到的第二种执行顺序,发生错误后撤销掉之前所有成功的子事务,使得整个Saga的执行结果撤销。 二、Seata框架介绍 Seata(Simple Extensible Autonomous Transaction Architecture)是一套一站式分布式事务解决方案,是阿里集团和蚂蚁金服联合打造的分布式事务框架。Seata目前的事务模式有AT、ICC、Saga三种模式,默认是AT模式,AT本质上是2PC协议的一种实现。

C++头文件 <algorithm>的 常用函数(详细)

1.sort( ) 用于排序,默认从小到大排。 2.max( ):两数最大 3.min():两数最小 4.abs():求一个数的绝对值 ( 与<cmath>中的fbs(),不同,因abs()只用于整型变量 ) 5.swap(): 交换 x 与 y 的值 6.reverse(): 反转数组函数 (1)翻转整个数组 例: #include <iostream> #include <algorithm> using namespace std; int main() { int a[5]={11,22,33,44,55}; reverse(a,a+5); for(int i =0;i<5;i++) { cout << a[i] << " "; } return 0; } 输出 55 44 33 22 11 (2)翻转部分数组 #include <iostream> #include <algorithm> using namespace std; int main() { int a[5]={11,22,33,44,55}; reverse(a+3,a+5); for(int i =0;i<5;i++) { cout << a[i] << "

在非构建工具下使用vue

通常项目开发进程中,使用工程化配置下开发项目,但在少数老项目下如jquery项目下也想使用vue.js,可以渐进式地来使用。下面介绍一个简单使用方法: 1、引入文件: <!-- element-ui 样式 --> <link rel="stylesheet" href="../../../lib/element-ui/lib/theme-chalk/index.css"> <!-- 处理 ie 浏览器兼容性 待后续验证后作调整 --> <!--<script src="../../../lib/babel-polyfill/browser.js"></script>--> <!--<script src="../../../lib/babel-polyfill/polyfill.js"></script>--> <!-- vue --> <script src="../../../lib/vue/vue.js"></script> <!-- element-ui js --> <script src="../../../lib/element-ui/lib/index.js"></script> <!-- 异步请求 --> <script src="../../../lib/axios/dist/axios.js"></script> <!-- 模块组件 --> <script src="./courseModal.js"></script> <style> html,body { padding: 0; margin: 0; height: 100%; } .container { height: 100%; background-color: #f5f5f5; } .query-container, .data-container { padding: 20px; margin-bottom: 10px; background-color: #fff; } .toolbar-container { margin-bottom: 10px; } .

京东联盟高级API - 高并发京东联盟转链接口 京东客转链接口 京粉转链接口 京东联盟接口,线报无广告接口

京东联盟高级API - 高并发京东联盟转链接口 京东客转链接口 京粉转链接口 京东联盟接口 京东接口,线报无广告接口 ##共京荣开放平台 接口支持商品链接,活动链接,店铺链接转链,获取普通推广链接和优惠券二合一推广链接,转链后下单佣金归自己所有,结算后可以在京东联盟提现。 1、注册共京荣开放平台账号 注册地址: http://interface.mkstone.club/ 2、获取接口秘钥apikey 登录个人中心 - 系统设置 - 接口管理 找到接秘钥apikey,apikey 接口秘钥是调用接口的唯一凭证,请妥善保管! 3、事先准备好京东联盟转链接口所需要的unionId参数,获取方式:打开并登录京东联盟(https://union.jd.com/index)=》账户管理 接口请求参数见下表: Body参数说明 (application/x-www-form-urlencoded) 参数名 示例值 是否必填 参数描述 material_id https%3a%2f%2fu.jd.com%2fI6wZkDm 必填 需要转链的链接 需要urlencode union_id 1002839984 必填 联盟id position_id 选填 推广位id 非pid appkey 你的appkey 必填 appkey ———————————————— 版权声明:本文为CSDN博主「共京荣开放平台」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/MkGjr/article/details/119237950

东线报接口 全网一手线报全网(京东,淘宝,天猫)最全优惠信息

1、注册共京荣开放平台账号 注册地址: http://interface.mkstone.club/#/ 2、京东共有4类线报接口可选 3.消息源参考: http://interface.mkstone.club/#/source 京东精品线报,只保留了精品,配有导购和作业图等 线报都是websocket接口 对接方式: 1.链接到线报接口 2.发送任意消息到接口 3.有消息就会给推送了 使用方式: 1.先正则取掉图片,把图片最后处理 (https?)😕/gchat.qpic.cn[-A-Za-z0-9+&@#/%?=|!:,.;]+[-A-Za-z0-9+&@#/%=|]?term=2 [emoji=F09F8DAF] [Face174.gif] 这两个是表情,如果匹配不上,也用正则干掉 3.把剩下的就是正常文本了。图片再显示出来就可以了。

vue处理getpost的http请求

一、使用Vue.http/this.$http 在发起请求的时候,为了减少作用域链的搜索,建议使用一个局部变量来接受this 1. GET请求 // 基于全局Vue对象使用http Vue.http.get('/someUrl', [options]).then(successCallback, errorCallback); // 在一个Vue实例内使用$http this.$http.get('/someUrl', [options]).then(successCallback, errorCallback); 示例 //不带参数的get请求 this.$http.get('/someUrl').then(function(res){ console.log('请求成功处理'); },function(res){ console.log('请求失败处理'); }); //需要传递数据的get请求 this.$http.get('/someUrl',{param:jsonData}).then(function(res){ console.log('请求成功处理'); },function(res){ console.log('请求失败处理'); }); //ES6的Lambda写法 this.$http.get('/someUrl', [options]).then((response) => { console.log('请求成功处理'); }, (response) => { console.log('请求失败处理'); }); 2.POST请求 post 发送数据到后端,需要第三个参数 {emulateJSON:true}。 emulateJSON 的作用: 如果Web服务器无法处理编码为 application/json 的请求,你可以启用 emulateJSON 选项。启用该选项后,请求会以application/x-www-form-urlencoded作为MIME type,就像普通的HTML表单一样。 // 基于全局Vue对象使用http Vue.http.post('/someUrl', [body], [options]).then(successCallback, errorCallback); // 在一个Vue实例内使用$http this.$http.post('/someUrl', [body], [options]).then(successCallback, errorCallback); 示例 this.$http.post('/try/ajax/demo_test_post.php',{name:"菜鸟教程",url:"http://www.runoob.com"},{emulateJSON:true}).then(function(res){ document.write(res.body); },function(res){ console.log(res.status); }); 二、使用Vue.

electron打包vue项目

创建项目 点击这里 添加electron-builder 1、在项目目录下运行命令:vue add electron-builder 2、electron-builder添加完成后会选择electron版本,直接选择最新版: electron下载失败 vue add electron-builder下载electron会下载失败,使用淘宝镜像下载:cnpm i electron 窗体运行 1、下载完成后尝试运行electron窗体:npm run electron:serve 2、窗体运行成功: 打包exe 1、运行打包命令:npm run electron:build 2、打包时由于会在github下载包,国内网络一般会失败,需要手动下载nsis与winCodeSign(网络允许的话你也可以自己到github下载,这里我下载分享出来了),点击这里下载,提取码:1uq8,解压后将nsis与winCodeSign复制(替换)到以下目录: 3、复制文件后再次运行打包命令即可打包成功: 4、打包完成后,项目目录下会多出一个dist_eletron,打包出的exe即在其中,此exe需安装后使用: 5、但在dist_eletron的win-unpacked下也会有与项目同名的exe,此exe无需安装即可运行,但依赖同级目录下的文件,不能直接单独使用: 白屏 1、到这里其实打包就已经成功完成了,但你打开exe后会发现与在项目中窗体运行不一样,或者直接白屏,这是由于vue与electron路由模式的原因,vue一般默认history模式。 2、需要在router的index.js中修改:从vue-router中引入createWebHashHistory,将createWebHistory(process.env.BASE_URL)改为createWebHashHistory(process.env.BASE_URL)。 若为vue2的项目则直接将mode的值从history改为hash: 3、删除项目中的dist_eletron目录,重新npm run electron:build打包: 4、打包成功:

CompletableFuture 使用及应用场景

JDK1.8 之前,我们会通过 Future 和 Callable 采用轮询来实现异步获取结果 //定义一个异步任务 Future<String> future = executor.submit(()->{ Thread.sleep(2000); return "hello world"; }); //轮询获取结果 while (true){ if(future.isDone()) { System.out.println(future.get()); break; } } JDK1.8 中提供的 CompletableFuture 提供了异步函数式编程。可以帮助我们简化异步编程的复杂性,通过回调的方式处理计算结果,并且提供了转换和组合的方法。 1 CompletableFuture 的使用 1.1 创建 CompletableFuture 对象 提供了四个静态方法来创建 public static CompletableFuture<Void> runAsync(Runnable runnable) public static CompletableFuture<Void> runAsync(Runnable runnable, Executor executor) public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier) public static <U> CompletableFuture<U> supplyAsync(Supplier<U> supplier, Executor executor) async 代表异步。 runAsync 和 supplyAsync 方法的区别在于,前者没有结果返回,后者会有结果返回

力扣LeetCode-贪心算法

贪心算法 基本知识 1.思想 基于局部最优的选择逐渐推导出全局最优解 2.一般步骤 将问题分解为若干个子问题; 找出合适的贪心策略; 求解每一个子问题的最优解; 将局部最优解合成为全局最优解; 典型例题 1. LeetCode 376. 摆动序列 题目 如果连续数字之间的差严格地在正数和负数之间交替,则数字序列称为 摆动序列 。第一个差(如果存在的话)可能是正数或负数。仅有一个元素或者含两个不等元素的序列也视作摆动序列。 例如, [1, 7, 4, 9, 2, 5] 是一个 摆动序列 ,因为差值 (6, -3, 5, -7, 3) 是正负交替出现的。 相反,[1, 4, 7, 2, 5] 和 [1, 7, 4, 5, 5] 不是摆动序列,第一个序列是因为它的前两个差值都是正数,第二个序列是因为它的最后一个差值为零。 子序列 可以通过从原始序列中删除一些(也可以不删除)元素来获得,剩下的元素保持其原始顺序。 给你一个整数数组 nums ,返回 nums 中作为 摆动序列 的 最长子序列的长度 。 来源:力扣(LeetCode) 链接:力扣 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 思路 求取摆动子序列元素个数,则与原数组峰值个数有关; 遍历原数组,记录相邻两个数的差值,若后面相邻两数差值与之前异号,则摆动子序列元素个数加1; 代码 class Solution { public: int wiggleMaxLength(vector<int>& nums) { if(nums.

Autoware 1.12学习整理--03--NDT点云定位

〇、前言 在得到点云地图后,接下来为点云定位,是汽车导航的前提,autoware中使用ndt_matching模块完成基于点云的定位,是一种scan-to-map的点云配准算法,本文将使用《Autoware 1.12学习整理–02–构建点云地图》中的点云地图和rosbag数据包完成ndt点云定位。 一、ndt点云定位 ndt点云定位时的tf树与建图时的稍有不同,从map到base_link的坐标系转换由autoware中的ndt_matching模块完成的,如下图所示: 1.1、加载bag文件 启动autoware,切换到Simulation页面,点击Ref按钮加载bag文件,Start Time设置为0,点击Play然后点击Pause暂停播放,如下图所示。为了保证autoware的正常运行,在启动autoware后首先要做的就是加载bag文件,否则会出现时间戳同步问题。 1.2、完成从base_link到velodyne的坐标系转换 切换到autoware的Setup页面下,确定Localizer选的是Velodyne,设置Baselink to Localizer的x、y、z、yaw、pitch、roll数值,其为雷达中心点与车身后轴中心点的相对位置关系,接着点击TF按钮,最后点击Vehicle Model按钮,如果其后为空,那么会加载一个默认模型。 1.3、完成从world到map的坐标系转换 切换到autoware的Map页面下,点击TF右侧的Ref按钮,加载如下路径的launch文件,其中是从/world坐标系转换到/map坐标系的tf变换,最后点击TF按钮。 autoware.ai/src/autoware/documentation/autoware_quickstart_examples/launch/tf_local.launch 1.4、加载点云地图 在Map页面下,点击Point Cloud右侧的Ref按钮,加载pcd点云地图,并点击Point Cloud按钮,进度条显示OK,则加载完毕,如下所示: 1.5、点云降采样 voxel_grid_filter,也就是体素滤波,PCL实现的体素滤波VoxelGrid类通过输入的点云数据创建三维体素栅格(可以将体素栅格想象为微小的空间三维立方体的集合),然后在每个体素内,用体素中的所有点的重心近似显示体素中的其他点,这样该体素内所有点就用一个重心点最终表示,然后将所有体素处理后得到过滤后的点云。(这种方法比用体素中心来逼近的方法更慢,但对于采样点对应曲面的表示更为准确。) 切换到autoware的Sensing页面下,点击Points Downsampler下voxel_grid_filter右侧的app按钮,设置点云话题名Points topic为/points_raw,下面两个参数默认即可,Voxel Leaf Size参数值为2,表示2米的立方体内的全部点近似用1个重心代替,Measurement Range的参数值为200,表示点云的有效的距离是200米。设置完参数后点击OK,最后勾选voxel_grid_filter。 1.6、完成map到base_link的坐标系转换 切换到autoware的Computing页面下,点击lidar_localizer下ndt_matching右侧的app按钮,在弹出的页面中topic:/config/ndt选择Initial Pos选项,x,y,z,roll,pitch,yaw的值表示激光数据的初始位姿,如果有GNSS设备可以选择GNSS进行初始定位。Method Type选择pcl_anh_gpu,即使用GPU进行点云匹配计算,然后点击OK,最后勾选ndt_matching。 1.7、播放bag数据 点击autoware界面的RViz按钮,打开rviz,依次点击file->open config加载配置文件: autoware.ai/src/autoware/documentation/autoware_quickstart_examples/launch/rosbag_demo/default.rviz 切回到autoware的Simulation界面,点击Pause按钮开始播放数据,Rviz界面显示如下: 整个运行过程如下: 在开始时,没有定位成功,汽车前进了一段距离后突然回到起始位置,此时才定位成功,后面汽车就能一直将点云与地图匹配起来,完成汽车在点云地图中的定位。开始时如果长时间没有定位成功,可以使用rviz中的2D Pose Estimate工具指定汽车的初始位姿。利用ndt_matching进行点云定位时的节点图如下: 最后可以看一下voxel_grid_filter降采样前后的对比: 文章不妥之处还望指正 参考文章: https://www.cnblogs.com/hgl0417/p/11143107.html https://zhuanlan.zhihu.com/p/64226544

编译原理 CS-143(更新至week4)

编译原理 CS-143 Pre-Course SurveyNavigation Your Course01-01: Introduction (8m20s)01-02: Structure of a Compiler (13m53s)【编译器结构】first step:recognize words句法分析句意分析optiimization(优化)finally code Gen 01-03: The Economy of Programming Languages (19m51s)【编译器性价比】why are there so many progamming languageswhy are there new programming languages?what is a good programming language?Summarize 02-01: Cool Overview (19m58s)【cool语言概述】02-02: Cool Example II (15m04s)【cool样例2】02-03: Cool Example III (18m05s)【cool样例3】 CS-143 Week2 Lexical Analysis&Finite Automata[词法分析和有限自动机]03-01: Lexical Analysis (12m06s)【词法分析】Token class(标记类)样例分析SummarizeQuiz 03-02: Lexical Analysis Examples (13m03s)【词法分析案例】为什么需要lookaheadPL/1 keywords are not reservedSummarize 03-03: Regular Languages Part 1 (11m48s)【正则语言part1】regular expressions 正则表达式基本表达式复合正则表达式 exampleQuizSummarize 03-04: Formal Languages (13m40s)【形式语言】03-05: Lexical Specifications (16m19s)【词法规则】keywordintegeridentifierwhitespace课外exampleSummarize 04-01: Lexical Specification (14m30s)【词法规则2】1.

LearnOpenGL笔记——四、高级OpenGL:“面剔除”与“帧缓冲”

四、高级OpenGL:“面剔除”与“帧缓冲” 4.4 面剔除 不绘制我们看不到的面如何只绘制面向观察者的面呢?OpenGL使用了一个很聪明的技巧,分析顶点数据的环绕顺序(Winding Order)!环绕顺序 简而言之,对于每个面,定义时面向观察者,顶点顺序为逆时针,这样在光栅化时任何顶点顺序为顺时针的面都是背向观察者的,可以剔除! 面剔除 确认在每个三角形中它们都是以逆时针定义的,这是一个很好的习惯。要想启用面剔除,我们只需要启用OpenGL的GL_CULL_FACE选项:glEnable(GL_CULL_FACE); 从这一句代码之后,所有背向面都将被丢弃(尝试飞进立方体内部,看看所有的内面是不是都被丢弃了)。目前我们在渲染片段的时候能够节省50%以上的性能,但注意这只对像立方体这样的封闭形状有效。当我们想要绘制上一节中的草时,我们必须要再次禁用面剔除,因为它们的正向面和背向面都应该是可见的。OpenGL允许我们改变需要剔除的面的类型。如果我们只想剔除正向面而不是背向面会怎么样?我们可以调用glCullFace来定义这一行为:glCullFace(GL_FRONT); glCullFace的初始值是GL_BACK。除了需要剔除的面之外,我们也可以通过调用glFrontFace,告诉OpenGL我们希望将顺时针的面(而不是逆时针的面)定义为正向面:glFrontFace(GL_CCW); 默认值是GL_CCW,它代表的是逆时针的环绕顺序,另一个选项是GL_CW,它(显然)代表的是顺时针顺序。我们可以来做一个实验,告诉OpenGL现在顺时针顺序代表的是正向面,这样的结果是只有背向面被渲染了:glEnable(GL_CULL_FACE); glCullFace(GL_BACK); glFrontFace(GL_CW); 注意你可以仍使用默认的逆时针环绕顺序,但剔除正向面,来达到相同的效果:glEnable(GL_CULL_FACE); glCullFace(GL_FRONT); 可以看到,面剔除是一个提高OpenGL程序性能的很棒的工具。但你需要记住哪些物体能够从面剔除中获益,而哪些物体不应该被剔除。 4.5 帧缓冲 到目前为止,我们已经使用了很多屏幕缓冲了:用于写入颜色值的颜色缓冲、用于写入深度信息的深度缓冲和允许我们根据一些条件丢弃特定片段的模板缓冲。这些缓冲结合起来叫做帧缓冲(Framebuffer),它被储存在内存中。OpenGL允许我们定义我们自己的帧缓冲,也就是说我们能够定义我们自己的颜色缓冲,甚至是深度缓冲和模板缓冲。我们目前所做的所有操作都是在默认帧缓冲的渲染缓冲上进行的。默认的帧缓冲是在你创建窗口的时候生成和配置的(GLFW帮我们做了这些)。有了我们自己的帧缓冲,我们就能够有更多方式来渲染了。你可能不能很快理解帧缓冲的应用,但渲染你的场景到不同的帧缓冲能够让我们在场景中加入类似镜子的东西,或者做出很酷的后期处理效果。 4.5.1 创建一个帧缓冲 和OpenGL中的其它对象一样,我们会使用一个叫做glGenFramebuffers的函数来创建一个帧缓冲对象(Framebuffer Object, FBO):unsigned int fbo; glGenFramebuffers(1, &fbo); 首先我们创建一个帧缓冲对象,将它绑定为激活的(Active)帧缓冲,做一些操作,之后解绑帧缓冲。我们使用glBindFramebuffer(GL_FRAMEBUFFER, fbo); 在绑定到GL_FRAMEBUFFER目标之后,所有的读取和写入帧缓冲的操作将会影响当前绑定的帧缓冲。我们也可以使用GL_READ_FRAMEBUFFER或GL_DRAW_FRAMEBUFFER,将一个帧缓冲分别绑定到读取目标或写入目标。绑定到GL_READ_FRAMEBUFFER的帧缓冲将会使用在所有像是glReadPixels的读取操作中,而绑定到GL_DRAW_FRAMEBUFFER的帧缓冲将会被用作渲染、清除等写入操作的目标。大部分情况你都不需要区分它们,通常都会使用GL_FRAMEBUFFER,绑定到两个上。不幸的是,我们现在还不能使用我们的帧缓冲,因为它还不完整(Complete),一个完整的帧缓冲需要满足以下的条件: 附加至少一个缓冲(颜色、深度或模板缓冲)。至少有一个颜色附件(Attachment)。所有的附件都必须是完整的(保留了内存)。每个缓冲都应该有相同的样本数。 在完成所有的条件之后,我们可以以GL_FRAMEBUFFER为参数调用glCheckFramebufferStatus,检查帧缓冲是否完整。它将会检测当前绑定的帧缓冲,并返回规范中这些值的其中之一。如果它返回的是GL_FRAMEBUFFER_COMPLETE,帧缓冲就是完整的了。if(glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE) // 执行胜利的舞蹈 之后所有的渲染操作将会渲染到当前绑定帧缓冲的附件中。由于我们的帧缓冲不是默认帧缓冲,渲染指令将不会对窗口的视觉输出有任何影响。出于这个原因,渲染到一个不同的帧缓冲被叫做离屏渲染(Off-screen Rendering)。要保证所有的渲染操作在主窗口中有视觉效果,我们需要再次激活默认帧缓冲,将它绑定到0。glBindFramebuffer(GL_FRAMEBUFFER, 0); 在完成所有的帧缓冲操作之后,不要忘记删除这个帧缓冲对象:glDeleteFramebuffers(1, &fbo); 在完整性检查执行之前,我们需要给帧缓冲附加一个附件。附件是一个内存位置,它能够作为帧缓冲的一个缓冲,可以将它想象为一个图像。当创建一个附件的时候我们有两个选项:纹理或渲染缓冲对象(Renderbuffer Object)。 4.5.1.1 纹理附件 当把一个纹理附加到帧缓冲的时候,所有的渲染指令将会写入到这个纹理中,就像它是一个普通的颜色/深度或模板缓冲一样。使用纹理的优点是,所有渲染操作的结果将会被储存在一个纹理图像中,我们之后可以在着色器中很方便地使用它。为帧缓冲创建一个纹理和创建一个普通的纹理差不多:unsigned int texture; glGenTextures(1, &texture); glBindTexture(GL_TEXTURE_2D, texture); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 800, 600, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 主要的区别就是,我们将维度设置为了屏幕大小(尽管这不是必须的),并且我们给纹理的data参数传递了NULL。对于这个纹理,我们仅仅分配了内存而没有填充它。填充这个纹理将会在我们渲染到帧缓冲之后来进行。同样注意我们并不关心环绕方式或多级渐远纹理,我们在大多数情况下都不会需要它们。现在我们已经创建好一个纹理了,要做的最后一件事就是将它附加到帧缓冲上了:

Ubuntu虚拟机中网络中没有网卡

由于实体机有2个网卡所以想在虚拟机中使用双网卡配置,结果按照网上的教程操作后不止没有实现双网卡,之前的网卡也找不到了(只有ubuntu20.4没有,ubuntu18.4正常。只是在Settings->network中找不到,使用ifconfig -a 还是能看到,不过设置IP地址也无法上网),找了很多教程最后使用如下方法才恢复: 图1:无网卡 图2:恢复后 sudo service network-manager stop sudo rm /var/lib/NetworkManager/NetworkManager.state sudo service network-manager start sudo gedit /etc/NetworkManager/NetworkManager.conf 把false改成true sudo service network-manager restart