【MySQL 第18章_主从复制】

第18章_主从复制 1. 主从复制概述 1.1 如何提升数据库并发能力1.2 主从复制的作用 第1个作用:读写分离。第2个作用就是数据备份第3个作用是具有高可用性 2. 主从复制的原理 2.1 原理剖析 二进制日志转储线程 (Binlog dump thread)从库 I/O 线程从库 SQL 线程复制三步骤 2.2 复制的基本原则 3. 一主一从架构搭建 3.1 准备工作3.2 主机配置文件3.3 从机配置文件3.4 主机:建立账户并授权3.5 从机:配置需要复制的主机3.6 测试3.7 停止主从同步3.8 后续 4. 同步数据一致性问题 4.1 理解主从延迟问题4.4 如何解决一致性问题 方法 1:异步复制方法 2:半同步复制方法 3:组复制 5. 知识延伸 说明:本内容整理自尚硅谷B站MySQL视频>>尚硅谷B站MySQL视频 1. 主从复制概述 1.1 如何提升数据库并发能力 在实际工作中常常将Redis作为缓存与MySQL配合来使用,当有请求的时候,首先会从缓存中进行查找,如果存在就直接取出。如果不存在再访问数据库,这样就提升了读取的效率,也减少了对后端数据库的访问压力。Redis的缓存架构是高并发架构中非常重要的一环。 此外,一般应用对数据库而言都是“ 读多写少 ”,也就说对数据库读取数据的压力比较大,有一个思路就是采用数据库集群的方案,做主从架构 、进行读写分离 ,这样同样可以提升数据库的并发处理能力。但并不是所有的应用都需要对数据库进行主从架构的设置,毕竟设置架构本身是有成本的。 如果我们的目的在于提升数据库高并发访问的效率,那么首先考虑的是如何 优化SQL和索引 ,这种方式简单有效;其次才是采用 缓存的策略 ,比如使用 Redis将热点数据保存在内存数据库中,提升读取的效率;最后才是对数据库采用主从架构 ,进行读写分离。 按照上面的方式进行优化,使用和维护的成本是由低到高的。 1.2 主从复制的作用 主从同步设计不仅可以提高数据库的吞吐量,还有以下 3 个方面的作用。 第1个作用:读写分离。 我们可以通过主从复制的方式来同步数据,然后通过读写分离提高数据库并发处理能力

pip源的配置和方法

根据pip的官方文档: pip配置源是可以用命令直接添加的: 第一个在全局添加的是清华大学的源。 sudo pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple 第二个是备用的源也是清华大学的源: sudo pip config set install.index-url https://pypi.tuna.tsinghua.edu.cn 写这些命令行是有实例的: pip config set global.index-url https://example.org pip config set global.index-url https://example.org 仿着写就行。 我们再看看有关这个文件的位置: 我用的sudo位置是/root/.config/pip/pip.conf Configuration keys should be dot separated command and option name, with the special prefix “global” affecting any command. For example, “pip config set global.index-url https://example.org/” would configure the index url for all commands, but “pip config set download.timeout 10” would configure a 10 second timeout only for “pip download” commands.

Windows网络共享方式

熟悉 手机热点 的朋友,都知道,我们可以打开手机热点将手机的网络分享给其他设备(手机、pad、电脑等)。 那么我们的电脑网络能否分享给其他设备呢? 当然是可以的。现在我们就来看看如何将 Windows电脑的网络分享给其他设备。 不同于手机将手机网络转为wifi信号这种比较单一的场景。我们在使用电脑时的网络情况是有多种的。如:我们的笔记本连接网络就即可通过有线,又可以通过无线,所以,我们用笔记本分享网络同样可以通过有线和无线两种方式。 所以,我们用Windows分享网络的场景也就有4种,如图: 第1种和第3种 与我们日常用的无线路由器和路由器是不是很像,其实,这就是个路由器,只是我们这个路由器功能可强大太多了。生活中或数据中心用的路由器大家可以看作简化的只有网络功能的计算机。不过,这些计算机也针对网络功能做了很多定制化的开发。 第2种和第4种 可能会很少见到,不过未来应该会遇到较多,毕竟无线最大的好处就是不用走线。 下面我们就来看下如何设置。 首先,我们可以发现每个场景都是需要两个网卡的,一个用作连接Internet,一个用作分享网络。 不过第4种情况并不一定,我们放到最后说。 共享网络 先来说下如何共享网络: 1、打开网络适配器选项 2、打开要共享的网卡属性 3、选择共享 4、选择允许,选择需要网络的设备连接的网卡,点击“确定” 会有个重置网络地址为192.168.137.1的提示,点击“确定”即可 5、其他连接这个被共享网络网卡的设备,网络地址设置为DHCP模式,就可以通过这个共享的网络访问Internet了。 分享热点 下面我们来了解下如何分享热点,以及需要注意的事项,这也第1种和第4种场景都需要的。 分享热点功能需要网卡支持,不过目前一般网卡设备都是支持的。 win10 系统网络功能提供了直接开启热点的开关: 也提供了管理界面: 这里我们也可以看到这个网络是共享了电脑的哪个Internet连接。 win7 系统没有提供可视化的管理功能,所以需要通过命令形式来开启热点。 管理员模式运行CMD或Powershell,输入 netsh wlan set hostednetwork mode=allow ssid=test key=test1234 ssid是无线网络名称、key就是密码(密码长度不小于8位) 然后,回到共享网络的步骤,将Internet网络共享给这个网络就可以了。 还有一种可视化管理共享热点的方式,就是用安装wifi热点管理软件,需要的自行搜索,这里就不多说了 Q&A: 1、前面说一般需要两个网卡,电脑没有两个网卡怎么办? 答:笔记本都是有的,台式电脑可以加装网卡,也可以用USB无线网卡(包括插手机卡的),USB转有线网卡,市场上都是有的,可以实现以上所有场景。 2、无线网卡可以一个网卡实现网络连接和热点分享么? 答:是可以的,需要网卡支持,如何知道?试下就知道了、、、有些网卡说明里面也有写。

rc.exe not found.(完美解决,亲测有效)

完美解决rc.exe not found. 报错出错原因解决方法完美解决 报错 这两天安装了vs2015和IVF2016,安装完之后在运行程序的时候一直会出现rc.exe not found,重新生成解决方案后还是一样的问题. 出错原因 rc.exe是visual C 编译库中的内容 而IVF在编译fortran程序时需要C 编译库 通常来说老版本的visual studio完整安装时携带的SDK都是包含rc.exe的 但是visual studio community 2015安装时抛弃了这个文件。 解决方法 1、打开控制面板,去修改visual studio 2、点击visual studio,修改配置(打开需要几分钟,慢慢等待) 3、在编程语言中勾选Visual C++ ,点击更新即可 完美解决

高频面试题6:实现1个圣杯布局

一、实现1个圣杯布局 HTML <div class="bottom" >header</div> <div class="main"> <div class="left">left</div> <div class="center">center</div> <div class="right">right</div> </div> <div class="bottom">bottom</div> CSS .bottom { background: #eee; text-align: center; line-height: 100px; } .main { display: flex; } .left, .center, .right { text-align: center; line-height: 500px; } .left, .right { width: 200px; background: #ddd; } .center { flex: 1; background: white; } Tips:【小程序云开发】中高级前端面试题库(源码:小程序中联系我哟)。 ---------- 创作不易,感谢大家,请多多支持!

MybatisPlus中removeById删除数据库未变

removeById(Serializable id)传入的是id:Integer Long等,不是实体对象,就是对应你表的主键 由于我刚开始建表时未设置主键mybatisplus自动生成未在实体类表中标注主键。后加了主键 所以需在实体类主键添加上@TableId就成功了 @TableId(value = "product_id", type = IdType.AUTO) @TableId注解是专门用在主键上的注解,如果数据库中的主键字段名和实体中的属性名,不一样且不是驼峰之类的对应关系,可以在实体中表示主键的属性上加@Tableid注解,并指定@Tableid注解的value属性值为表中主键的字段名既可以对应上。 比如数据中的表中的字段是vote_id,但是实体类是voteId。那么就需要在voteId上打上这个注解,如下: /** 主键 */ @TableId("vote_id") @TableId(value = "vote_id") private Long voteId; 总结:removeById根据你数据库表中的主键来删除,就算数据库中有设置主键实体类上未标注也是不行的,所以需要在实体类中注@TableId注解来标注主键

图解:为什么非公平锁的性能更高?

在 Java 中 synchronized 和 ReentrantLock 默认使用的都是非公平锁,而它们采用非公平锁的原因都是一致的,都是为了提升程序的性能。那为什么非公平锁就能提升性能呢?接下来我们一起来看。 非公平锁 非公平锁:每个线程获取锁的顺序是随机的,并不会遵循先来先得的规则,任何线程在某时刻都有可能直接获取并拥有锁。 这就好比磊哥去加油,到了加油站之后发现前面有人在加,于是我就在车里刷起了抖音,过了一会,前面的车加完油走了,但磊哥没注意到,还在车里愉快的刷着抖音。然而此时加油站又来了一辆车,发现有空闲的油枪,于是就抢先在磊哥之前把油加了。这里的油枪就是锁,没有按照到达的先后顺序得到油枪,这就是非公平锁。 公平锁 公平锁:每个线程获取锁的顺序是按照线程访问锁的先后顺序获取的,最前面的线程总是最先获取到锁。 这就好像上高速排队过收费站一样,所有的车要排队等待通行,最先来的车最先通过收费站。 性能对比 公平锁和非公平锁的性能测试结果如下,以下测试数据来自于《Java并发编程实战》: 从上述结果可以看出,使用非公平锁的吞吐率(单位时间内成功获取锁的平均速率)要比公平锁高很多。 性能分析 以上测试数据虽然说明了结果,但并不能说明为什么非公平锁的性能会更高?所以,接下来,我们通过分析公平锁和非公平的执行流程,来得到这个问题的答案。 公平锁执行流程 获取锁时,先将线程自己添加到等待队列的队尾并休眠,当某线程用完锁之后,会去唤醒等待队列中队首的线程尝试去获取锁,锁的使用顺序也就是队列中的先后顺序,在整个过程中,线程会从运行状态切换到休眠状态,再从休眠状态恢复成运行状态,但线程每次休眠和恢复都需要从用户态转换成内核态,而这个状态的转换是比较慢的,所以公平锁的执行速度会比较慢。 用户态 & 内核态 用户态(User Mode):当进程在执行用户自己的代码时,则称其处于用户运行态。内核态(Kernel Mode):当一个任务(进程)执行系统调用而陷入内核代码中执行时,我们就称进程处于内核运行态,此时处理器处于特权级最高的内核代码中执行。 为什么分内核态和用户态? 假设没有内核态和用户态之分,程序就可以随意读写硬件资源了,比如随意读写和分配内存,这样如果程序员一不小心将不适当的内容写到了不该写的地方,很可能就会导致系统崩溃。 而有了用户态和内核态的区分之后,程序在执行某个操作时会进行一系列的验证和检验之后,确认没问题之后才可以正常的操作资源,这样就不会担心一不小心就把系统搞坏的情况了,也就是有了内核态和用户态的区分之后可以让程序更加安全的运行,但同时两种形态的切换会导致一定的性能开销。 非公平锁执行流程 当线程获取锁时,会先通过 CAS 尝试获取锁,如果获取成功就直接拥有锁,如果获取锁失败才会进入等待队列,等待下次尝试获取锁。这样做的好处是,获取锁不用遵循先到先得的规则,从而避免了线程休眠和恢复的操作,这样就加速了程序的执行效率。 比如前几天磊哥去一个小营业厅办理网络移机的业务,去了之后发现前面有人在办业务,于是磊哥就告诉前面(办理业务)的小姐姐,“我门口休息一下,您等会办理完业务,麻烦去门口叫一下我”,小姐姐人也比较好,一口就答应下来了。 但在小姐姐办完业务之后叫我,和我回到柜台办理业务之间,是有一段空闲时间的,这和等待队列中的线程被唤醒和恢复执行之间是有一段空闲时间是一样的,而在这个空闲的时间中,营业厅又来了一个老李头来交话费,等老李交完话费,我恰好也刚回来可以直接办理业务了,这样就是一个“三赢”的局面。 老李头不用排在我后面等着缴话费,我也不用等老李头交完话费再办理移机,而且在单位时间内提高了营业员办理业务的效率,她也能早早的回家,这就是所谓的“三赢”。在更短的时间内执行更多的任务,这就是非公平锁的优势。 总结 本文我们介绍了公平锁和非公平锁的定义以及执行流程,从二者执行流程的细节可以看出,非公平锁因为不用按(顺)序执行,所以后来的锁也可以直接尝试获得锁,没有了阻塞和恢复执行的步骤,所以它的性能会更高。 如果本文对你有帮助,别忘记给我个3连 ,点赞,转发,评论, 学习更多JAVA知识与技巧,关注与私信博主(222)学习JAVA 课件,源码,安装包,还有最新大厂面试资料等等等 咱们下期见。 收藏 等于白嫖,点赞才是真情。

[oh-my-zsh] Can‘t update: not a git repository. 错误解决

问题 MacOS打开iTerm总是出现[oh-my-zsh] Can't update: not a git repository. 解决方法 # 网上的解决方法 # 不推荐 sudo rm -rf /Library/Developer/CommandLineTools xcode-select --install 也就是卸载CLT再重装,但耗时太长且并没有解决问题,无奈只能到Apple官网再重新下载CLT,这样速度快一点 https://developer.apple.com/download/all/?q=Command%20Line%20Tools 之后运行(如果你没有卸载CLT,可直接跳到这一步) cd $ZSH git remote set-url origin "https://github.com/ohmyzsh/ohmyzsh.git" 如果出现错误:error: No such remote 'origin' 再运行: git init git remote add origin "https://github.com/ohmyzsh/ohmyzsh.git" git config --global url."https://github.com/".insteadOf git://github.com/ 之后如果每次打开iTerm总是提醒你要不要更新,则运行 sudo vim ~/.zshrc 按 i 进入编辑模式,在末尾添加 DISABLE_AUTO_UPDATE="true" DISABLE_UPDATE_PROMPT="true" 按 esc 退出编辑模式,键入 :wq 保存退出,最后运行 source ~/.zshrc

刘奇:能否掌控复杂性,决定着分布式数据库的生死存亡

本文回顾了 PingCAP 创始人兼 CEO 刘奇在 9 月 22 日的 用户峰 会 上以《现在决定未来》为主题的演讲, 分享了 PingCAP 在技术演进、用户价值、数据库技术趋势、国际化、社会价值等方面的思考, 同时也记录了建信金科、百胜中国、传音控股、老虎国际等用户在刘奇的演讲中分享的最佳实践。全文字数约 8,800,预计阅读时间 20 分钟。 [图片] PingCAP 到今天已经成立 7 年了,在全球拥有 3,000 多家大中型用户,其中很多还参与到 TiDB 开源社区的建设中,这些情况如果放到创业之初很难想象。 今天,我们认识到做一个真正广泛应用的数据库,是一个需要以十年为时间单位进行投入的基础工程。 这一路走来离不开关心和支持 PingCAP、喜欢 TiDB 的每个人。 与客户对话,客户眼中的 TiDB 过去一段时间,在和包括日本、美国、印度、欧洲等全球客户交流时,我们试图从更多不同客户的视角去了解他们到底是怎么看待 TiDB 的。 在 TiDB 的设计里,有很多设计是从第一天就开始的,我们甚至完全不觉得这个设计有什么特别之处。直到我问一些专家型用户“你到底为什么选择 TiDB ?”时,他们告诉我: 因为 TiDB 的开放式架构可以管理复杂性。 我当时挺诧异,因为这个东西第一天就是这样设计的,已经融入 PingCAP 的血液当中,所以我们自身已经无感。但对这些专家来说,他们当中很多人在各个大公司本身就做过数据库,甚至是大型分布式系统,做过这些系统的人都会产生一个心态,那就是对“复杂性”会无比敬畏。 [图片] 一个数据库,哪怕它是一个小型数据库,通常代码规模都会有几十万行,上百万行,如果是一个传统的成熟型商业数据库,那更是一个以千万行代码为单位的系统。 面对如此 复杂的系统,用户在考虑未来的迭代时,通常要做 3-5 年的规划。 如果用户需要花 3-5 年来替换一个 PB 级数据库,很大程度上意味着接下来 5-10 年的时间他就不想再动了,这也是本次峰会的主题为什么是“现在决定未来”。 今天我们做一个数据库替换的决定,它的影响周期很可能是接下来的 10-20 年。 在这个较长的周期中,大家看系统价值的时候就会看到完全不一样的价值。比如最近我意外地发现 TiDB 在 CFO 眼里其实很受欢迎,他们表示,在现有实践中,TiDB 至少可以降低一半的成本,所以 CFO 很快就会批下来对 TiDB 的部署和应用。大家可以试想一下,如果用户有 PB 级的数据,用 TiDB 替换能够省一半的成本,是不是非常有吸引力?

qt文件使用

.h头文件 #include <QKeyEvent> #include <QMouseEvent> public: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); void keyPressEvent(QKeyEvent *k); void mousePressEvent(QMouseEvent *m); private slots: void newActionSlot(); void openActionSlot(); void saveActionSlot(); connect(ui->newAction, &QAction::triggered, this, &MainWindow::newActionSlot); connect(ui->openAction, &QAction::triggered, this, &MainWindow::openActionSlot); connect(ui->saveAction, &QAction::triggered, this, &MainWindow::saveActionSlot); 新建函数 void MainWindow::newActionSlot() { ui->textEdit->clear(); this->setWindowTitle("新建文本文档.txt"); } 打开函数 void MainWindow::openActionSlot() { //选择文件将字符串赋给fileName QString fileName = QFileDialog::getOpenFileName(this, "选择一个文件", QCoreApplication::applicationFilePath(), "*.cpp"); if (fileName.isEmpty()) { QMessageBox::warning(this, "警告", "请选择一个文件"); } else { //qDebug() << fileName; QFile file(fileName); //创建文件对象 file.

Linux 中 MYSQL8.0 实现主从复制

1.修改主库配置文件my.ini,完成后重启 [mysqld] log-bin=mysql-bin //开启log-bin日志 server_id=1 //中的1可以任定义,只要是唯一的就行。 2.进行检验是否开启成功,log_bin为ON表示开启成功。show variables like '%log_bin%'; 3.在主服务器新建一个用户赋予“REPLICATION SLAVE”的权限。你不需要再赋予其它的权限。在下面的命令,把X.X.X.X替换为从服务器的IP。 CREATE USER 'user'@ 'X.X.X.X' IDENTIFIED BY 'password'; GRANT REPLICATION SLAVE ON *.* TO 'user'@'X.X.X.X' ; flush privileges; //刷新权限 4.查看主服务器状态,记录以下两个值,show master status -----------主库配置完成 5.修改从库配置文件my.ini,完成后重启 [mysqld] server_id=2 //必须唯一不管主还是从 6.执行下列sql语句,连接主库 CHANGE MASTER TO MASTER_HOST='X.X.X.X', MASTER_USER='user', MASTER_PASSWORD='password', MASTER_PORT=3306, MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=98; MASTER_HOST:主服务器的IP。 MASTER_USER:配置主服务器时建立的用户名 MASTER_PASSWORD:用户密码 MASTER_PORT:主服务器mysql端口,如果未曾修改,默认即可。 注意: master_log_file 与 master_log_pos 均是我们上一步在主库所查询的数据 如果无法执行以上sql语句,可能是你之前配置过,在所有操作之前,一定要执行一下 stop slave 停止从库,执行完成后在开启 start slave 7.查看从库状态,在从库中执行此命令,看到IO和SQL线程两个YES代表成功 show slave status\G

SpringCloud之熔断器

文章目录 一、简介二、作用三、核心概念3.1 熔断目的3.2 降级目的 四、实例4.1 基于Hystrix4.1.1 熔断触发降级4.1.2 超时触发降级4.1.3 资源隔离触发降级 4.2 基于OpenFeign 一、简介 当微服务中的某个子服务,发生异常服务器宕机,其他服务在进行时不能正常访问而一直占用资源导致正常的服务也发生资源不能释放而崩溃,这时为了不造成整个微服务群瘫痪,进行的保护机制 就叫做熔断,是一种降级策略 熔断的目的:保护微服务集群 二、作用 对第三方访问的延迟和故障进行保护和控制防止复杂分布式系统中的雪崩效应(级联故障)快速失败,快速恢复回退,尽可能优雅的降级启用近实时监控、报警和操作控制 三、核心概念 3.1 熔断目的 应对雪崩效应,快速失败,快速恢复 3.2 降级目的 保证整体系统的高可用性 四、实例 4.1 基于Hystrix pom.xml <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> </dependency> application @EnableHystrix // 开启熔断 @SpringBootApplication public class HystrixApplication { public static void main(String[] args) { SpringApplication.run(HystrixApplication.class, args); } } 4.1.1 熔断触发降级 /** * Date: 2022-09-16 星期五 * Time: 9:49 * Author: Dily_Su * Remark: */ @RestController @RequestMapping("/hystrix") public class HystrixController { @Autowired private RestTemplate restTemplate; /** * @param num 参数 * @return 字符串 */ @HystrixCommand( commandProperties = { @HystrixProperty(name = "

编写两个jsp文件,实现利用include动作完成参数传递计算1!+2!+...+n!

IncludeFile.jsp <%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>Jie Cheng</title> </head> <body> <font size =2> <table border=1> <tr> <th> Lei Jia</th> </tr> <tr> <td><jsp:include page="IncludeFile1.jsp"></jsp:include></td> </tr> </table> </font> </body> </html> IncludeFile1.jsp <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>阶乘和</title> </head> <body> <p>请输入一个正整数: <form action="

Java使用JaxWsDynamicClientFactory和HttpURLConnection调取Webservice接口

点击上方“猿芯”,选择“设为星标” 后台回复"1024",有份惊喜送给面试的你 方式1. 代理类工厂的方式,需要拿到对方的接口 try { // 接口地址 // 代理工厂 JaxWsProxyFactoryBean jaxWsProxyFactoryBean = new JaxWsProxyFactoryBean(); // 设置代理地址 wsdlAddress: WSDL地址(http://localhost:8082/ws/services/bank?wsdl) jaxWsProxyFactoryBean.setAddress(wsdlAddress); // 设置接口类型 jaxWsProxyFactoryBean.setServiceClass(ICommonService.class); // 创建一个代理接口实现 ICommonService cs = (ICommonService) jaxWsProxyFactoryBean.create(); // 数据准备 String userName = "Leftso"; // 调用代理接口的方法调用并返回结果 String result = cs.sayHello(userName); System.out.println("返回结果:" + result); } catch (Exception e) { e.printStackTrace(); } 方式2. 动态调用方式 //WSDL路径 String wsUrl = "http://localhost:8082/ws/services/bank?wsdl" ; //方法名 String method = "getCaseProve"; JaxWsDynamicClientFactory factory = JaxWsDynamicClientFactory.newInstance(); Client client = factory.

【Verilog我思我用】-generate

【Verilog我思我用】-generate 在使用xilinx官方例程《XAPP585》实现CameraLink接口发送或者接收数据时,有个程序还是值得学习的,下面把这段程序截出来: genvar i ; genvar j ; generate for (i = 0 ; i <= (N-1) ; i = i+1) begin : loop0 serdes_7_to_1_diff_sdr #( .D (D), .DATA_FORMAT (DATA_FORMAT)) dataout ( .dataout_p (dataout_p[D*(i+1)-1:D*i]), .dataout_n (dataout_n[D*(i+1)-1:D*i]), .clkout_p (clkout_p[i]), .clkout_n (clkout_n[i]), .txclk (txclk), .pixel_clk (pixel_clk), .reset (reset), .clk_pattern (clk_pattern), .datain (datain[(D*(i+1)*7)-1:D*i*7])); end endgenerate 主要是generate的用法,整个文件的功能是实现可选多通道数据发送,我们知道Cameralink中对于多通道传输时有一部分功能代码时相同的,只不过需要多通道复用,我们知道generate有一个功能就是重复操作多个模块的实例引用,当然就适合本例程。 下面我们先讲一讲generate的用法再结合代码简单讲解一下,对于generate其实很好理解,只不过写出来比较难。 generate用法 关键字generate和endgenerate(和begin / end类似)作为使用语法的起点,有三种衍生结构,分别为: generate - for 语句结构 generate - if 语句结构 generate - case 语句结构

实现一个通过多次递归串联起来的treeData

项目场景: 项目中没有现成的数组件形式的数据: 例如:一对多的树形关系 let arr = [ { id: 1, pid: null }, { id: 6, pid: null }, { id: 2, pid: 1 }, { id: 3, pid: 2 }, { id: 4, pid: 2 }, { id: 5, pid: 1 }, { id: 7, pid: 6 }, { id: 8, pid: 5 }, { id: 9, pid: 7 }, { id: 10, pid: 9 }, { id: 11, pid: 9 }, { id: 12, pid: 7 }, ]; 原因分析: 为什么会导致形成这样的数据

分词器详解

在全文搜索(Fulltext Search)中,**词(Term)**是一个搜索单元,表示文本中的一个词,**标记(Token)**表示在文本字段中出现的词,由词的文本、在原始文本中的开始和结束偏移量、以及数据类型等组成。 ElasticSearch 把文档数据写到倒排索引(Inverted Index)的结构中,倒排索引建立词(Term)和文档之间的映射,索引中的数据是面向词,而不是面向文档的。分析器(Analyzer)的作用就是分析(Analyse),用于把传入Lucene的文档数据转化为倒排索引,把文本处理成可被搜索的词。 什么是分析器 分析器由**一个分词器(Tokenizer)和零个或多个标记过滤器(TokenFilter)**组成,也可以包含零个或多个字符过滤器(Character Filter)。 ps:在实际使用中我们大多数听到的都是分词器,原本是因为过滤器用到的很少,所以在叫法上几乎分析器等价于分词器了。而且分词的结果经常与高亮结合使用。 在ElasticSearch引擎中,分析器的任务是分析(Analyze)文本数据,分析是分词,规范化文本的意思,其工作流程是: 首先,字符过滤器对分析(analyzed)文本进行过滤和处理,例如从原始文本中移除HTML标记,根据字符映射替换文本等。过滤之后的文本被分词器接收,分词器把文本分割成标记流,也就是一个接一个的标记。标记过滤器对标记流进行过滤处理,例如,移除停用词,把词转换成其词干形式,把词转换成其同义词等。过滤之后的标记流被存储在倒排索引中。 ElasticSearch引擎在收到用户的查询请求时,会使用分析器对查询条件进行分析,根据分析的结构,重新构造查询,以搜索倒排索引,完成全文搜索请求, 图解倒排索引与分析过程 以下重点描述分词器,过滤器不经常用,不做过多记录。 分词器种类 系统默认分词器 标准分词器(Standard Tokenizer) 标准分词器类型是standard,用于大多数欧洲语言,使用Unicode文本分割算法对文档进行分词。 字母分词器(Letter Tokenizer) 字符分词器类型是letter,在非字母位置上分割文本,这就是说,根据相邻的词之间是否存在非字母(例如空格,逗号等)的字符,对文本进行分词,对大多数欧洲语言非常有用。 空格分词器(Whitespace Tokenizer) 空格分词类型是whitespace,在空格处分割文本 小写分词器(Lowercase Tokenizer) 小写分词器类型是lowercase,在非字母位置上分割文本,并把分词转换为小写形式,功能上是Letter Tokenizer和 Lower Case Token Filter的结合(Combination),但是性能更高,一次性完成两个任务。 经典分词器(Classic Tokenizer) 经典分词器类型是classic,基于语法规则对文本进行分词,对英语文档分词非常有用,在处理首字母缩写,公司名称,邮件地址和Internet主机名上效果非常好。 简单分词器(Simple Tokenizer) 功能强于WhitespaceAnalyzer, 首先会通过非字母字符来分割文本信息,然后将词汇单元统一为小写形式。该分析器会去掉数字类型的字符。 停用词分词器(Stop Tokenizer) StopAnalyzer的功能超越了SimpleAnalyzer,在SimpleAnalyzer的基础上增加了去除英文中的常用单词(如the,a等),也可以更加自己的需要设置常用单词;不支持中文 正则分词器(Pattern Tokenizer) 一个pattern类型的analyzer可以通过正则表达式将文本分成"terms"(经过token Filter 后得到的东西 )。接受如下设置: 一个 pattern analyzer 可以做如下的属性设置: lowercaseterms是否是小写. 默认为 true 小写.pattern正则表达式的pattern, 默认是 \W+.flags正则表达式的flagsstopwords一个用于初始化stop filter的需要stop 单词的列表.默认单词是空的列表 语言分词器(Language Tokenizer) 一个用于解析特殊语言文本的analyzer集合。( arabic,armenian, basque, brazilian, bulgarian, catalan, cjk, czech, danish, dutch, english, finnish, french,galician, german, greek, hindi, hungarian, indonesian, irish, italian, latvian, lithuanian, norwegian,persian, portuguese, romanian, russian, sorani, spanish, swedish, turkish, thai.

【MySQL 第09章_性能分析工具的使用】

第09章_性能分析工具的使用 1. 数据库服务器的优化步骤2.查看系统性能参数3. 统计SQL的查询成本:last_query_cost4. 定位执行慢的 SQL:慢查询日志 4.1 开启慢查询日志参数4.2 查看慢查询数目4.3 案例演示4.4 测试及分析4.5 慢查询日志分析工具:mysqldumpslow4.6 关闭慢查询日志4.7 删除慢查询日志 5. 查看 SQL 执行成本:SHOW PROFILE6. 分析查询语句:EXPLAIN 6.1概述6.2 基本语法6.3 数据准备6.4 EXPLAIN各列作用 1.table演示2. id演示 3.select_type 演示 4. partitions (可略) :匹配的分区信息5. type ☆ 演示 6. possible_keys和key 演示 7. key_len 演示 8. ref 演示 9. rows ☆10. filtered11.Extra☆12.小结 7. EXPLAIN的进一步使用 7.1 EXPLAIN四种输出格式 1. 传统格式2. JSON格式3. TREE格式4. 可视化输出 7.2 SHOW WARNINGS的使用 8. 分析优化器执行计划:trace9. MySQL监控分析视图-sys schema 9.1 Sys schema视图摘要9.2 Sys schema视图使用场景 说明:本内容整理自尚硅谷B站MySQL视频>>尚硅谷B站MySQL视频

前端HTML+CSS基础:HTML部分(问答形式)

1.基础认知 1.1 认识网页 问题1:网页由哪些部分组成? 文字、图片、音频、视频、超链接等元素组成 问题2:我们看到的网页背后本质是什么? 前端开发工程师用开发工具编写的代码. 问题3:前端的代码是通过什么软件转换成用户眼中的页面的? 通过浏览器渲染再展示给用户. 1.2 五大浏览器和渲染引擎 问题1:常见的浏览器有几个?分别是? IE浏览器火狐浏览器(Firefox)谷歌浏览器(Chrome)Safari浏览器欧朋浏览器(Opera) 问题2:前端工程师推荐使用哪一个浏览器? 谷歌浏览器 问题3:相同的网页在不同浏览器中显示效果会一致吗? 不一致.因为不同浏览器内核(渲染引擎)不同,解析的效果会存在差异.Safari浏览器渲染引擎:Webkit谷歌浏览器渲染引擎:Blink (面试会问) 1.3 web标准(重要) 问题1:为什么需要web标准? 让不同的浏览器按照相同的标准显示结果,展示统一效果。 问题2:web标准构成有哪些? 结构(HTML)---->网页元素表现(CSS)---->网页样式,包括:版式、颜色、大小等行为(JavaScript)---->网页交互的动态效果 2.HTML初体验 2.1HTML的感知 问题1:什么是HTML? 超文本标记语言(Hyper Text Markup Language) 问题2:HTML中是通过什么来对网页中的文本、图片、音频、视频等内容进行描述的? HTML标签 [小练习] 在代码文件夹中点击鼠标右击 → 新建文本文档 → 命名为:网页体验.html 双击这个文件,输入以下代码等内容 → 记得保存! <p>这是HTML文件中P标签包裹的内容</p> 双击网页体验.html ,浏览器会自动打开文件并显示之前输入的内容 2.2 HTML骨架结构 问题 :HTML骨架结构由哪些标签组成? html标签:网页的整体(页面最大的标签,根标签)head标签:网页的头部body标签:网页的身体title标签:网页的标题 [小练习] 新建HTML文件→ 命名为:Html骨架结构标签.html输入以下代码 <html> <head> <title>网页标题</title> </head> <body> 这是网页中的内容。 </body> </html> 3 双击文件使用浏览器看效果 2.3 开发工具基本操作(VScode) 前端开发神器:VS Code → 速度快、体积小

PostgreSQL:不支持 10 验证类型

sudo vi /etc/postgresql/14/main/pg_hba.conf 把 # "local" is for Unix domain socket connections only 这行后面的配置数据注释掉,用下面这段替换: # "local" is for Unix domain socket connections only local all all trust # IPv4 local connections: host all all 127.0.0.1/32 trust # IPv6 local connections: host all all ::1/128 trust 如: # TYPE DATABASE USER ADDRESS METHOD # "local" is for Unix domain socket connections only #local all all peer # IPv4 local connections: #host all all 127.

109.SQLAlchemy中join的使用

from random import randint from sqlalchemy import Column, Integer, String,ForeignKey,func from sqlalchemy.orm import relationship,backref from util_db import Base, Session class User(Base): __tablename__ = 't_user' id = Column(Integer, primary_key = True, autoincrement=True) name = Column(String(32)) age = Column(Integer) def __repr__(self): return f'<User: id={self.id} name = {self.name} age = {self.age}>' class News(Base): __tablename__ = 't_news' id = Column(Integer, primary_key = True, autoincrement=True) title = Column(String(32), nullable = False) content = Column(String(32), nullable = False) read_count = Column(Integer) # uid = Column(Integer, ForeignKey('t_user.

MyBatis中ResultType和ResultMap的区别

ResultType和ResultMap都是执行查询语句时返回的结果集 ResultType ResultType相对与ResultMap而言更简单一点。只有满足ORM(Object Relational Mapping,对象关系映射)时,即数据库表中的字段名和实体类中的属性完全一致时,才能使用,否则会出现数据不显示的情况。如图所示,由于实体类Order的属性和表tb_order的字段不一致,导致页面数据不显示。 ResultMap ResultMap和ResultType的功能类似,但是ResultMap更强大一点,ResultMap可以实现将查询结果映射为复杂类型的pojo。 如上图的ResultType显示的结果,用ResultMap就可以解决。 说明: ResultMap标签的id属性是唯一的,和select标签的resultMap一致。type属性是pojo(普通的JavaBean对象)的包名加类名,用来封装信息。如果mybatis里面配置了别名包,也就是给包起别名,那么type里面直接写类名就可以了。 ResultMap中的id标签是用来描述表中的主键的对应关系,column用来描述数据库表中的主键字段名,property用来描述pojo中的属性名。 result标签是用来描述表中的普通字段的对应关系,column用来描述数据库表中的普通字段名,property用来描述pojo中的属性名。association标签用来实现一对一的关系collection标签用来实现一对多的关 转自:ResultType和ResultMap的区别_Share,Keep Life ^_^的博客-CSDN博客_resulttype和resultmap

Vector的迭代器 失效问题

1.erase insert 使用后会导致原来的迭代器失效, #include<iostream> using namespace std; #include<vector> void VectorTest() { vector<int> vec; for (int i = 0; i < 5; i++) { vec.push_back(i); } vector<int>::iterator it; cout << sizeof(it) << endl; for (it = vec.begin(); it != vec.end(); it++) { if (*it>2) vec.erase(it);//此处会发生迭代器失效 } for (it = vec.begin(); it != vec.end(); it++) cout << *it << " "; cout << endl; } int main() { VectorTest(); system("pause"); return 0; } 解决办法:更新迭代器

Linux下的防火墙服务

Firewalld 概述 动态防火墙后台程序 firewalld 提供了一个 动态管理的防火墙, 用以支持网络 “ zones” , 以分配对一个网络及其相关链接和界面一定程度的信任。它具备对 IP v4 和 IP v6 防火墙设 置的支持。它支持以太网桥 , 并有分离运行时间和永久性配置选择。它还具备一个通向服务或者应用程序以直接增加防火墙规则的接口 系统提供了图像化的配置工具 firewall-config 、 system-config-firewall, 提供命令行客户端 firewall-cmd, 用于配置 firewalld 永久性或非永久性运行时间的改变 : 它依次用iptables 工具与执行数据包筛选的内核中的 Netfilter 通信 firewalld 和 iptables 服务 firewalld 和 iptables 服务之间最本质的不同是 :iptables service 在 /etc/sysconfig/iptables 中储存配置 firewalld 将配置储存在 /usr/lib/firewalld/ 和/etc/firewalld/ 中的各种 XML 文件里 . 参数描述 source 指定源地址 , 可以是一个 ipv4/ipv6 的地址或网段 , 不支持使用主机名。 destination 指定目的地址 , 用法和 source 相同。

JavaScript——异步编程

目录 一、异步的概念 二、什么时候用异步编程 三、回调函数 四、异步 AJAX 一、异步的概念 异步(Asynchronous, async)是与同步(Synchronous, sync)相对的概念。 在我们学习的传统单线程编程种,程序的运行是同步的(同步不意味着所有步骤同事运行,而是指步骤在同一个控制流顺序种按顺序执行),而异步的概念则是不保证同步的概念,也就是说,一个异步过程的执行将不再与原有的续流又顺序关系。 简单来说就是:同步安妮的代码顺序执行,异步不按照代码顺序执行,异步的执行效率更高。 以上是关于异步的概念的解释,接下来我们通俗地解释一下异步,异步就是从主线程发射一个子线程来完成任务。 二、什么时候用异步编程 在前端编程中(甚至后端有时也是这样),我们在处理一些简短、快速的操作时,例如计算 1 + 1 的结果,往往在主线程中就可以完成。主线程作为一个线程,不能够同时接受多方面的请求。所以,当一个事件没有结束时,界面将无法处理其他请求。 现在有一个按钮,如果我们设置它的 onclick 事件为一个死循环,那么当这个按钮按下,整个网页将失去响应。 为了避免这种情况的发生,我们常常用子线程来完成一些可能消耗时间足够长以至于被用户察觉的事情,比如读取一个大文件或者发出一个网络请求。因为子线程独立于主线程,所以即使出现阻塞也不会影响主线程的运行。但是子线程有一个局限:一旦发射了以后就会与主线程失去同步,我们无法确定它的结束,如果结束之后需要处理一些事情,比如处理来自服务器的信息,我们是无法将它合并到主线程中去的。 为了解决这个问题,JavaScript 中的异步操作函数往往通过回调函数来实现异步任务的结果处理。 三、回调函数 回调函数就是一个函数,它是在我们启动一个异步任务的时候就告诉它:等你完成了这个任务之后要干什么。这样一来主线程几乎不用关心异步任务的状态了,他自己会善始善终。 function print() { document.getElementById("demo").innerHTML="RUNOOB!"; } setTimeout(print, 3000); 这段程序中的 setTimeout 就是一个消耗时间较长(3 秒)的过程,它的第一个参数是个回调函数,第二个参数是毫秒数,这个函数执行之后会产生一个子线程,子线程会等待 3 秒,然后执行回调函数 "print",在命令行输出 "RUNOOB!"。 当然,JavaScript 语法十分友好,我们不必单独定义一个函数 print ,我们常常将上面的程序写成: setTimeout(function () { document.getElementById("demo").innerHTML="RUNOOB!"; }, 3000); 注意:既然 setTimeout 会在子线程中等待 3 秒,在 setTimeout 函数执行之后主线程并没有停止,所以: setTimeout(function () { document.getElementById("demo1").innerHTML="RUNOOB-1!"; }, 3000); document.getElementById("demo2").innerHTML="RUNOOB-2!"; console.log("2"); 这段程序的执行结果是: RUNOOB-1! RUNOOB-2!

postgres dump备份和restore还原

1.将数据库备份成dump文件. 首先以管理员权限进入cmd的postgres的bin目录下方,然后执行下面的命令: pg_dump -U 'username' -p 'port number' -d 'databse' > 'dump file name' 例如: pg_dump -U postgres -p 5437 -d postgres > bills_with_5_tenants.dump 注意,上面的dump会同时包含数据库的data以及schema,如果只需要data不需要schema的话则需要使用下面的命令 pg_dump -F c -p 5432 -U postgres -d postgres -a > bills_with_6_tenants_for_automatic_close.dump 2. 将dump文件导入到数据库当中: 首先进入cmd的postgres的bin目录下方,然后执行下面的命令: pg_restore -U 'username' -p 'port number' -d 'databse' < 'dump file name' 例如 pg_restore.exe -U postgres -p 5437 -d postgres < open_bill_dump_file_with_tax.dump 生成的dump文件导入的时候报错: pg_restore: [archiver] input file does not appear to be a valid archive

设置Idea护眼背景色 简单明了

设置IDEA护眼背景色(简单明了,无废话) 步骤说明: File —>settings—>Editor—>Color Scheme—>General—>点击右侧Text—>选择Default text,再点击最右边的Background右边的小框框,设置颜色系数 R:202 G:234 B:206 详细图片说明: ①点击File再点击settings ②点击Editor,选择Color Scheme,在选择General,然后点击右侧Text,选择Default text,再点击最右边的Background右边的小框框 ③设置颜色系数 除了设置这种护眼色,还可以设置其他的颜色,当然,对于长时间使用idea的同学们来说,最好还是设置一个护眼色,毕竟对眼睛视力比较好~~~

YUM查询软件信息

我们常会碰到这样的情况,想要安装一个软件,只知道它和某方面有关,但又不能确切知道它的名字。这时yum的查询功能就起作用了。你可以用yum search keyword这样的命令来进行搜索,比如我们要则安装一个Instant Messenger,但又不知到底有哪些,这时不妨用yum search messenger这样的指令进行搜索,yum会搜索所有可用rpm的描述,列出所有描述中和messeger有关的rpm包,于是我们可能得到gaim,kopete等等,并从中选择。有时我们还会碰到安装了一个包,但又不知道其用途,我们可以用yum info packagename这个指令来获取信息。 ​ 使用YUM查找软件包命令:yum search 列出所有可安装的软件包命令:yum list ​列出所有可更新的软件包命令:yum list updates ​列出所有已安装的软件包命令:yum list installed ​列出所有已安装但不在 Yum Repository 內的软件包命令:yum list extras ​列出所指定的软件包命令:yum list <package_name> ​使用YUM获取软件包信息命令:yum info <package_name> ​列出所有软件包的信息命令:yum info 列出所有可更新的软件包信息命令:yum info updates 列出所有已安裝的软件包信息命令:yum info installed 列出所有已安裝但不在 Yum Repository 內的软件包信息命令:yum info extras ​列出软件包提供哪些文件命令:yum provides <package_name>

Grandle安装配置使用

Grandle安装配置使用 一 安装1.1 下载1.2 解压到指定目录1.3 配置环境变量1.4 验证gradle是否安装成功 二 配置2.1 gradle配置文件2.2 GRADLE_USER_HOME2.3 项目配置 三 idea设置 一 安装 1.1 下载 根据自己的需求去官网下载指定版本 https://gradle.org/releases/ 1.2 解压到指定目录 1.3 配置环境变量 新建GRADLE_HOME 1.4 验证gradle是否安装成功 二 配置 2.1 gradle配置文件 找到安装目录,进入init.d文件夹,新建init.gradle文件。文件内容如下: allprojects { repositories { maven { url 'file:///E:/repository-maven'} mavenLocal() maven { name "Alibaba" ; url "http://maven.aliyun.com/nexus/content/groups/public/" } mavenCentral() google() jcenter() } buildscript { repositories { maven { name "Alibaba" ; url 'http://maven.aliyun.com/nexus/content/groups/public/' } } } } 2.2 GRADLE_USER_HOME 值为maven仓库地址

转录组验证-qRTPCR作图

软件:GraphPad Prism 1. 步骤: 选择作图类型→输入分组信息和数据→点击Family的“Data 1”出现图(可修改图类型)→双击坐标轴、字体等修改美化图片 2.截断纵坐标: 统计绘图|(十) Graphpad Prism如何设置纵坐标截断图? 3.添加显著性符号: 在GraphPad Prism中如何在柱状图上插入有统计学意义的*符号? 来自 <在GraphPad Prism中如何在柱状图上插入有统计学意义的*符号? - 知乎>

好用的word插件汇总

汇总一下我用过的word文档插件。介绍一下各自的功能。配上了下载地址,欢迎使用。 感谢各位插件的制作人。 1、word精灵插件 下载地址:https://www.excelbbx.net/Word.htm 作者:罗刚君 这位大牛很高产,他还写了Excel精灵,ppt精灵等,都在官网可以下: Office精灵三合一:下载地址 Excel精灵:下载地址 PPT精灵:下载地址 好的说回word精灵,安装完以后,打开word文档,可以看到word精灵插件的功能如下。 ​ 功能介绍: 这款属于综合型选手,功能实在太丰富了。 个人认为比较有特色的有:自动生成二维码,段落加密,解除禁止编辑等功能。 还有金额大小写,计算表达式,转换文档格式等等。 适用于普通文档编辑,快速排版,财务统计等人员。 2、word常用工具插件 下载地址: 官网下载 作者:张立良 安装完以后,打开word文档,插件内容如下 ​ 功能介绍: 常用功能不赘述了,有特色的是破解工具,可以免密码看VBA。可以试试。 3、有道翻译插件 下载地址: 【有道翻译Word插件】有道翻译Word插件 V1.0.0免费版官方免费下载_正式版下载-多特软件站 功能介绍: 对word文档中的内容做翻译。适用于论文翻译,文档翻译等等,提高效率。 4、NoteFirst插件 下载地址:http://www.notefirst.com/download/# 安装完以后,打开word文档,会同步出来一个软件的登陆框。此处可以选择关闭,也可以选择单机使用,单机使用打开以后是这么个界面: ​ word相关插件内容截图如下: ​ 功能介绍: 写论文的一把好手。可以直接从数据库里导出论文插入到word文档中,连排版格式都给你整理的明明白白。推荐! 5、小恐龙公文排版插件 下载地址:小恐龙工作坊 – 免费源自科技 ​ 功能介绍: 公文排版的一把好手。 可以手动导入公文部件,导入公章,大大提高公文写作的效率! 6、文驰word排版大师 下载地址:https://gd.jisuxz.com/down_new/wordzhinengpaibanxitong.rar 这款插件不需要安装,下载后可以直接使用。 7、牛牛排版插件 下载地址:牛牛试题排版插件V3更新发布_rustic_erphone的博客-CSDN博客_牛牛排版

【学习笔记】ESP32-CAM初体验

能力背景 在ESP32上移植过Modbus模块,能使用ESP32提供的编译工具编译、查错、烧录,但对编译工具链的原理并不了解。会使用Git,但也只基于简单的拉取,上传的使用。Linux系统之前没怎么用过,不大会操作。本文主要记录了第一次使用ESP32-CAM编译下载官方固件并正常使用的整个过程。 学习目标 使用已有固件把摄像头用起来。下载其他已有代码,编译并下载,以学习相关工具链的知识。 过程 首次上电 先直接用,看官方文档说的是只要接上5V2A的电源即可,出厂板子里已存在固件。目前这手头上只有一个12V1A的电源,外加一个12转5V的电源转换板,不知道电流够不够,先上电试下。 直接上电,按官方文档来看,应该是可以直接搜到wifi热点的,但手机找了一圈没找到热点(这出师不大利呀)。也有可能之前板子烧过其他固件了,先接个串口看下打印什么信息。问题串口通信的波特率是多少?算了,先用115200试下,上电,有信息打印出来,但貌似跟出厂的固件打印信息不大一样,不知道烧的是什么固件。 看来没办法,只能跳过第一步了,开始第二步,自己下载一个程序,也是先使用官方出厂自带的固件来,试下硬件整体是否有问题。 下载程序 查了下网上,大部分都是使用ardunio ide下载,但既然是ESP32,那就应该可以使用乐鑫的ESP-IDF集成环境来下载。找了下安信可的官方教程,虽然教程写的是在Linux环境下开发,需要安装虚拟机,但我们可以跳过这些步骤,直接使用教程里的例程。即到github上同步代码。在安装git的基础上,在想要同步代码的地方右键,选择"Git Bash Here" 在终端窗口输入以下指令 git clone --recurse-submodules https://github.com/Ai-Thinker-Open/Ai-Thinker-Open_ESP32-CAMERA_LAN.git 在安装esp-idf工具链的基础上,使用ESP-IDF命令窗口,使用指令 cd esp_cam\examples\single_chip\camera_web_server 进入路径esp_cam\examples\single_chip\camera_web_server,然后直接输入idf.py build进行编译,结果报了个错。 百度下是什么原因,说是要设置一下再编译,看来不能跳过官方的步骤,但官方使用的是make menuconfig,这边使用不了这个指令,还好刚刚说要设置的那篇博客里用的是idf,把make改成idf.py就可以,顺利进入设置界面。即输入如下指令 idf.py menuconfig 跟着官方文档一步步设置,再编译。 以下是官方文档的操作: 进入Serial flasher config设置如下 进入Camera Web Server —>Camera Pins —> Select Camera Pinout —> 选择ESP32-CAM by AI-Thinker 设置WIFI模式(station/ AP模式二选一即可) station模式 进入camera_web> Camera Web Server > WiFi Settings,设置WIFI名字和密码 官方文档少了一个,进入Component config->Driver configurations->RTCIO configuration,选择Support array ‘rtc_gpio_desc’ for ESP32,不然就会报上面那个错。 然后又报了个xxx/aead_chacha20poly1305.c.obj:No such file or directory。

js判断某数值是否处于某区间内,区间形如[1,2](0,3)

使用时需要如下格式调用 this.compareArea({ name: [1,2] }, 2) compareArea(data, num) { if (data.name == "") { return true; } var smallValue = parseInt( data.name.split(",").shift().split("[").pop().split("(").pop() ); if (data.name.split(",").shift().indexOf("(") != -1) { smallValue += 0.01; } var bigValue = parseInt( data.name.split(",").pop().split("]").shift().split(")").shift() ); if (data.name.split(",").pop().indexOf(")") != -1) { bigValue -= 0.01; } if (isNaN(bigValue)) { if (smallValue <= num) { return true; } return false; } else { if (smallValue <= num && bigValue >= num) { return true; } return false; } },

QT使用以及定时器

qt数据类型 数值类型 QString字符串 QByteArray字符组类 //把QString转换成char //expression是QString类型 char opt[128] = {0}; QByteArray ba; ba.append(expression); //把QString转换成QByteArray strcpy(opt, ba.data()); //data可以把QByteArray转换成const char 目录: 创建函数以及引用库时要在widget.h中的private slots:中声明 int Widget::Priority(char ch) 输出类型 函数名 传入值 { switch(ch) { case '(': return 3; case '*': case '/': return 2; case '+': case '-': return 1; default: return 0; } } connect用于对某些不能使用 信号的发起者btn1, 发出信号 主窗口this, 实现 关闭(槽函数) connect(btn1,&QPushButton::clicked,this,&QWidget::close); 定时器 都是设置好一个时间开始倒数 第一种:QTimer .h中定义好 #include <QTimer> #define TIMEOUT 1 * 1000 QTimer *timer; widget.

密码学——古典密码中的基本加密运算附简单例题

本篇文章将对古典密码中使用到的基本加解密运算进行总结,并展示个别加减密运算的简单例题,从而使读者更加容易理解古典密码中的基本加减密运算的原理。 文章目录 前言一、单表古典密码中的基本加减密运算1.加法密码2.乘法密码3.仿射密码4.置换密码 二、多表古典密码中的基本加减密运算1.简单加法密码2.简单乘法密码3.简单仿射密码4.简单置换密码5.换位密码 结束语 前言 首先引入密码学中的几个基本定义: M:明文空间,明文的集合 C:密文空间,密文的集合 K:密钥空间(也称密钥的数量),密钥的集合 E:加密变换的集合,使明文加密生成密文的算法 D:解密变换的集合,使密文解密生成明文的算法 单表密码体制:明文字母对应的密文字母在密文中保持不变。(浅显一点就是相同的字母加密以后的字母也为相同的) 多表密码体制:明文中不同位置的同一明文字母在密文中对应的密文字母不同。(相同的字母在不同的位置加密以后的字母极大可能不同) Z q = { 0 , 1 , 2 , . . . , q − 1 } , Z q ∗ = { k ∈ Z q ∣ g c d ( k , q ) = 1 } Z_q=\{0,1,2,...,q-1\},Z_q^*=\{k\in Z_q \vert gcd(k,q)=1 \} Zq​={0,1,2,...,q−1},Zq∗​={k∈Zq​∣gcd(k,q)=1},其中 g c d ( k , q ) = 1 gcd(k,q)=1 gcd(k,q)=1表示k与q互素。

解决 VS 出现错误 MSB3644 找不到 .NETFramework,Version=v4.6.1 的引用程序集。要解决此问题,请为此框架版本安装......

环境 VS 2022 错误 MSB3644 找不到 .NETFramework,Version=v4.6.1 的引用程序集。要解决此问题,请为此框架版本安装… MSB3644 找不到 .NETFramework,Version=v4.6.2 的引用程序集。要解决此问题,请为此框架版本安装… 造成错误原因 拉去 github 代码,打开该项目的解决方案管理器(.sln),但是出现此错误。 我的 VS 2022安装的 .net 版本为 .net 6.0。 解决办法 官网下载 对应的 .net 运行时版本。 然后重启项目即可。

Gooey使用python打包后,print不能输出到GUI的命令行窗口内的问题解决

为了给自己的图片接口站api.horosama.com补充图片,写了个壁纸爬虫程序,同时用Gooey做了个简单的GUI,然而,程序在vscode里直接运行的时候,是可以print函数输出到GUI的命令行窗口的,用pyinstaller打包之后就不行了。 搜了一下github上Gooey的issue发现有大佬给出了解决方法,在代码前加入如下几行 import codecs import sys if sys.stdout.encoding != 'UTF-8': sys.stdout = codecs.getwriter('utf-8')(sys.stdout.buffer, 'strict') if sys.stderr.encoding != 'UTF-8': sys.stderr = codecs.getwriter('utf-8')(sys.stderr.buffer, 'strict') 然后记得print函数加入参数flush=True,再打包一次就可以啦~ 这行代码之所以能起作用,我推测应该还是和python的print编码以及windows的控制台编码的问题,可以参考下这篇博文python,window控制台下编码问题。 引用下这篇文章的开头部分如下: Python 的 print 语句有一个很奇怪的 bug。它的功能是向控制台输出字符,这本身不是问题。但是 Python 内部是支持 Unicode 字符串的,而 Unicode 字符串在用 print 输出时 print 要进行一次从 Unicode 到 ANSI/MBCS 编码的编码,编码后才会以 8-bit 流输出结果。 编码就编码吧,这也是很正常的。对于控制台程序来说,输出可能被重定向到文本文件。如果不指定编码,重定向时就不知道以何种 8-bit 字节流写入文本文件,所以,输出到控制台的东西理论上也应该是经过编码的 8-bit 流。综上所述,确实有必要进行一次 WCHAR 到 char 的转码。 但是问题在于,Python 的 print 语句在转码时,居然用的是 strict 规则。即,待输出字符串若含有当前代码页之外的字符,就会在转码过程中出现不可转码的文字,从而抛出 exception。print 语句又不处理这个 exception,导致一个平平常常 print 语句竟然会引起 Python 程序的异常!这简直是不可思议。

Ubuntu 怎样升级 python3.7

使用 apt-get 安装 python3.7 sudo apt-get install python3.7 将python3.6 或 python 3.7添加到 update-alternatives sudo update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.6 1 sudo update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.7 2 将 python3 指向 python3.7 sudo update-alternatives --config python3 输入python3.7对应的序号,回车即可 测试 $ python3 --version Python 3.7.5

【已解决】mysql 1877错误 1146错误:提示数据表丢失、损坏、错误数据

错误信息 Django中错误信息 django.db.utils.InternalError: (1877, “Operation cannot be performed. The table ‘XXX.xxx’ is missing, corrupt or contains bad data.”) XXX.xxx:数据库名:表名 大致意思是:操作没法执行,xxx表丢失、损坏或错误数据。 mysql进行表查询,报错 (1146, “Table ‘XXX.xxx’ doesn’t exist”) XXX.xxx:数据库名:表名 解决过程 通过大量搜索发现,并没有找到解决问题的方法, 基本的问题都是,mysql 3021 主从复制错误, 解决方法 最后最后,还是通过万能的重启大法进行解决的, 果然,重启解决一切 附上mysql重启命令: 重启 : sudo service mysql restart 启动 : sudo service mysql start 停止 : sudo service mysql stop

Android GPS定位

目录 1、GNSS 介绍 2、NMEA协议 3、Android 获取GPS定位信息 4、GPS 冷、温、热启动 定位开发常用链接 1、GNSS 介绍 GNSS(Global Navigation Satellite System)全球导航卫星系统,是能在地球表面或近地空间的任何地点为用户提供全天候的三维坐标和速度以及时间信息的空基无线电导航定位系统。定位是利用几组卫星的伪距、星历、卫星发射时间及用户钟差等来进行确定。 目前包含四大全球系统:GPS(美) GLONASS(俄) GALILEO(欧) BDS(中) 2、NMEA协议 NMEA (National Marine Electronics Association )美国国家海洋电子协会,现在是GPS导航设备统一的RTCM(国际海运事业无线电技术委员会)标准协议。NMEA协议有0180、0182和0183这3种,0183可以认为是前两种的升级,也是目前使用最为广泛的一种,大部分GNSS接收机、软件都是基于此协议的,Android 也是使用此协议,以下都是基于0183协议说明。 常用NMEA-0183语句的字段定义如下,也是后续GNSS log中常见的重要的部分。下文 GA/GL/GP/BD 分别表示上述 GPS/BDS 等四大系统缩写,Android 相关log日志中也是如此格式 (GA/GL/GP/BD)GSA 字段0$BDGSA,语句ID,表明该语句为BDS DOP(精度因子:Dilution of precision) and Active Satellites(GSA)当前卫星信息字段1定位模式,A=自动选择,M=手动选择字段2定位类型,1=未定位,2=2D定位,3=3D定位字段3PRN码(伪随机噪声码),第1信道正在使用的卫星PRN码编号(00)(前导位数不足则补0)...2-11信道正在使用的卫星PRN码编号(00)(前导位数不足则补0)字段14PRN码(伪随机噪声码),第12信道正在使用的卫星PRN码编号(00)(前导位数不足则补0)字段15PDOP综合位置精度因子(0.5 - 99.9)字段16HDOP水平精度因子(0.5 - 99.9)字段17VDOP垂直精度因子(0.5 - 99.9)字段18校验值($与*之间的数异或后的值) GNGGA 字段0$GNGGA,语句ID,表明该语句为Global Navigation Satellite System Fix Data(GGA)定位信息字段1UTC 时间,hhmmss.sss,时分秒格式字段2纬度ddmm.mmmm,度分格式(前导位数不足则补0)字段3纬度N(北纬)或S(南纬)字段4经度dddmm.mmmm,度分格式(前导位数不足则补0)字段5经度E(东经)或W(西经) 字段6 GPS状态,0=不可用(FIX NOT valid),1=单点定位(GPS FIX),2=差分定位(DGPS),3=无效PPS,4=实时差分定位(RTK FIX),5=RTK FLOAT,6=正在估算 字段7 正在使用的卫星数量(00 - 12)(前导位数不足则补0) 字段8 HDOP水平精度因子(0.5 - 99.

CentOS下安装JDK8

CentOS下安装JDK8 安装JDK8 去Java Downloads | Oracle中下载JDK的安装文件jdk-8u341-linux-x64.tar.gz。 新建/usr/java文件夹,将jdk-8u341-linux-x64.tar.gz放到该文件夹下,并切换到/usr/java目录下。 执行命令tar -zxvf jdk-8u341-linux-x64.tar.gz进行解压缩,解压后/usr/java目录下多了jdk1.8.0_341文件夹。 通过以上步骤,JDK安装完毕。下面开始配置环境变量。 配置环境变量 执行命令vim /etc/profile编辑profile文件。在/etc/profile底部加入如下内容: JAVA_HOME=/usr/java/jdk1.8.0_341 PATH=$JAVA_HOME/bin:$PATH CLASSPATH=$JAVA_HOME/jre/lib/ext:$JAVA_HOME/lib/tools.jar export PATH JAVA_HOME CLASSPATH 以上,环境变量配置完成。需要注意的是,PATH在配置的时候,一定要把$JAVA_HOME/bin放在前面,不然使用java命令时,系统会找到以前 的java,再不往下找了。这样java这个可执行文件运行的目录其实不在JAVA_HOME/bin下,而在其它目录下,会造成很大的问题。执行命令source /etc/profile让profile文件立即生效。 source /etc/profile 命令测试 使用javac命令,不会出现command not found错误。使用java -version,出现版本为java version “1.8.0_341”。看看自己的配置是否都正确。 echo $JAVA_HOME echo $CLASSPATH echo $PATH 代码测试 在自己的工作目录下创建新的文件Hello.java。写入如下内容: public class Hello{ public static void main(String[] args){ System.out.println("Hello World"); } } 执行命令如下,如果得到以下结果,说明jdk安装完成。 # javac Hello.java # java -cp . Hello Hello World 当然,我们安装的jdk8,应该测试下jdk8的特性。可以使用jdk8特有的stream来测试,代码如下: import java.util.Arrays; import java.util.Iterator; import java.

CentOS下安装mysql8.0

CentOS下安装mysql8.0 1.进官网,选择适合自己版本的linux下的MYSQL版本。 按照箭头上的数字,依次进行操作,进入下面这个图景。 等待下载好,这样第一步就完成了。 2.将其下载好的 mysql-8.0.30-el7-x86_64.tar.gz 上传至linux系统中进行解压 。 将这个文件上传至 /usr/mysql/ 目录下,首先查看 /usr/mysql/ 目录下的文件。以确保系统中有这个文件。 cd /usr/ mkdir mysql cd mysql/ ls 将文件进行解压。 tar -zxvf mysql-8.0.30-el7-x86_64.tar.gz 然后会在当前 /usr/mysql/ 目录下会生成 这个目录。 对mysql进行安装。 将mysql-8.0.30-el7-x86_64 安装到 /usr/local/mysql 下。 mv mysql-8.0.30-el7-x86_64 /usr/local/mysql #将文件移动到 /usr/local/ 目录下,并更名为mysql 。 为系统添加mysql 组和用户。 groupadd mysql useradd -r -g mysql mysql 进入 /usr/local/mysql 目录下,修改相关权限。 cd /usr/local/mysql #进入/usr/local/mysql 目录 chown -R mysql:mysql ./ #修改当前目录为mysql用户 mysql初始化操作,记录下临时密码,之后第一次登录的时候会用到。 bin/mysqld --initialize --user=mysql --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data #运行完成会生成一个暂时的密码。 结果如下

无人机——像素坐标系转世界坐标系(NED)

目录 前言 一、针孔相机的原理 二、像素坐标系转相机坐标系 三、相机坐标系转机体坐标系 四、机体坐标系转世界坐标系(NED) 前言 正文开始前先推荐我做这个坐标系转换受益最深的一本书《视觉SLAM14讲》,为什么要推荐这本书,首先这本书详细介绍了视觉slam的结构,从前端VO到后端Optimization到回环检测最后建图,十分详细并且通俗易懂。 我还没有读完这本书,因为最近正在做一个比赛,其中一项工作是做了一个圆圈检测,要将检测结果从像素坐标系转换到NED坐标系,起初找了别人的源码,但是还是想从原理上理解这个坐标系变换,所以我细读了《视觉SLAM14讲》这本书的第五讲“相机与图像”,从针孔相机的原理开始了解最后转换到世界坐标系。 整体的转换流程: 本人初次撰写博客,若全文有不当或者不合理之处,请予批评指正 一、针孔相机的原理 话不多说,先细说针孔相机的原理,为什么要介绍这个原理,因为这个原理让我认识清楚了相机内参(fx,fy,cx,cy)的含义,以及我们为什么要在使用相机前做矫正。 首先借用《视觉SLAM14讲》P97中的一张图: 左边的图大家应该很熟悉,和初二物理课本上的图很像,右边的图相当于左边图的俯视图(从上往下看),所以没有考虑y轴分量。这张图已经包含了整个转换过程的前两个坐标系,像素坐标系和相机坐标系。 二、像素坐标系转相机坐标系 现实中的点为,可以认为P在相机坐标系下,经过针孔投影后的点为,P’可以认为在像素坐标系下,但是要注意这个像素坐标系不是我们实际使用的像素坐标系,两者之间还相差缩放以及平移关系,这也就是相机内参的含义,后文将会详细介绍。还有一个比较重要的物理量是焦距(f),即相机光心O到成像平面的距离。 根据上图中的相似三角形的关系很容易可以得到: 对上式进行一个变换,将成像平面的坐标点放在左边: 到这一步,像素坐标系到相机坐标系的转换已经完成了一半,还差一个成像平面到像素坐标系的缩放平移。一般像素坐标系定义为o-u-v,其中o是像素坐标系的原点,位于图像的左上角,u轴与成像平面的x轴平行,v轴与成像平面的y轴平行,这个对于熟悉opencv的同学应该很熟悉。然后我们需要定义成像平面到像素坐标系的缩放平移关系,这里一定要弄明白,相机内参就是来源于此,缩放关系:我们假设像素坐标在u轴上缩放了α倍,在v轴上缩放了β倍,这里α和β的单位都是像素/m,因为成像平面和相机坐标系的点都是以m为单位的,平移关系:像素坐标系相对于成像平面平移了,那么成像平面P'的坐标和像素坐标系的关系如下: 将上式代入其中即可得到: 将αf合并成为,βf合并成为,那么上式就可以转换为: 再将其写成矩阵相乘的形式。 对于上式,定义相机内参矩阵K: 那么上式可以简化为: 将上式做一个简单的变形: 上式就是像素坐标系转相机坐标系的表达式,可以看出一个点要想从像素坐标系转换到相机坐标系需要三个信息,首先是该点在像素坐标系下的坐标,然后需要相机的内参矩阵K,最后一个需要的就是深度信息Z,即该点在相机坐标系下Z轴的分量,如果你使用的是单目相机,那么有单目测距的手段,如果你使用的是双目相机,有双目测距的手段,如果你使用的是RGBD相机,那么直接就可以获取深度信息,如此一下,像素坐标系转相机坐标系就完成了。 三、相机坐标系转机体坐标系 首先相机坐标系转机体坐标系并不存在平移的关系,只是定义的不同,相机坐标系满足右手定则,机体坐标系满足左手定则: 所以两者之间只需要一个简单的转换矩阵,定义机体坐标系下的点为,定义相机坐标系下的点为,定义相机坐标系到机体坐标系的转换矩阵为: 那么从相机坐标系到机体坐标系的转换如下: 四、机体坐标系转世界坐标系(NED) 首先要理清,机体坐标系是与机体固连的,随着飞机的飞行,机体坐标系的原点以及对应的x,y,z三轴的方向都会发生相应的变化,而世界坐标系(此处我们以NED坐标系,即北东地坐标系为例)的原点以及三轴方向不会发生变化,两者之间相差的就是飞机的位姿关系,位姿即飞机的位置信息和姿态信息(在NED坐标系下),这个信息可以依靠视觉里程计得到,而位姿信息我们一般用旋转矩阵R和平移向量t来描述,旋转矩阵描述的就是姿态信息,通过四元数或者欧拉角都可以得到旋转矩阵,而位置信息就是飞机在NED坐标系下的位置,那么机体坐标系下的某个点在NED坐标系下即可表示为: 至此,坐标系转换全部完成! 

图片格式,内联框架,音视频的插入播放

图片格式 jpeg(jpg)格式:支持颜色丰富,不支持动图,一般用于照片gif支持颜色少,支持动图png支持颜色丰富,支持复杂透明,不支持动图wedp它基本具有所有优点,但有一个缺点,就是兼容性不太强 有一个较为普遍规律:如果同一张图片的效果一样或者相差不大,则格式选择文件大小最小的那一个。 BASE64进行图片编辑 可直接将图片转换为字符,通过字符来引入图片。可在百度搜base64点击图片转化链接即可。 注:该图片可以和网页同时加载,除非这方面要求特别高,否则一般不太使用。 ............................................................................................................................ 内联框架 用于向当前页面引入或者说镶嵌一个其他页面 用iframe标签例如: <iframe src="https://www.baidu.com/fram border="0"></ifram> fram border 可以选择1或0,指的是;选o比较好看没有边框。 如果嫌太小也可给其中加入一个height和width进行调节。 注:大家可以试一试 ............................................................................................................................ 音视频的播放 audio标签 <audio src=""controls><audio>src依然指指定路径。 controls指的是可以控制音乐的开关播放 也可以在该标签中加一个autoplay标签,表示自动播放。 但该标签在现在大部分浏览器中大部分都不会有这个作用,因为这种的用户体验不太好,假如你把声音调的很大然后点进这个页面,就会被吓一跳,就好像我曾经在追剧的时候点错了点进了那个一刀九九九的页面,吓了我一跳。 autoplay在IE浏览器会起作用 也可以给controls后加一个loop标签,这样歌曲在播放完时就会循环播放。 如果你的audio标签不起作用了,可能是兼容性的问题,可以去zeal软件查查audio标签与你浏览器版本的兼容性。 比如:audio与IE8并不兼容。 除了通过src来指定路径以外,source也可以 <audio controls> 当前版本不适合。 <source src="..."> <source src="..."> </audio> 用该标签的特点:1.浏览器会从上向下依次识别,先与浏览器兼容的音频格式优先被播放 可以填多个source,这样可以适应大部分浏览器 在这个标签中添加(当前版本不合适)则当音频文件先被识别出来,则文字不会出现,若所有source都不能被识别,所有音频文件都与浏览器不兼容,这样就会出现这个文子提醒你,而不是显示一片空白让你懵逼。 番外:在某些老版本浏览器引入音视频播放器时也可以用 <embed src="..."type="...">(全自动播放) 也可以加width和height来调节宽和高。 type指类型type="audio/mp3'audio指大类型如之前说的img mp3则指具体类型格式。 视频标签video标签 使用方法与audio音频标签的方法基本一致。如果你嫌自己下的视频会极占内存从而会卡顿,你可以到第三方视频软件中如腾讯视频中的视频上点分享,然后有个复制代码直接引用。(不过你引用腾讯视频下面会显示腾讯视频的标志哦。)

VUE数据共享

父与子之间数据共享 父 => 子 属性绑定 父组件向子组件传值:v-bind属性绑定,子组件props接收 <template> <div id="app"> <school></school> <!--App props 配置方式 --> <student id="002" name="小寻" age="18" sex="男"></student> <student id="003" name="老王" sex="女"></student> </div> </template> <template> <div id="student"> <h2 >学生ID:{{ id }}</h2> <h2>学生姓名:{{ name }}</h2> <h2>学生性别:{{ sex }}</h2> <h2>学生年龄:{{ age }}</h2> <button @click="showName">显示名称</button> </div> </template> <script> import {mixin} from '../assets/js/mixin' export default { name: "student", data(){ return{} },mixins:[mixin], // 声明 接收app传递过来的数据 props:['id'+'name'+'sex'+'age'] } </script> <style scoped> </style> 子 => 父 事件绑定 子组件向父组件传值:v-on事件绑定

KNN海伦约会

记录一下knn经典算法,100行代码50行注释的那种,直接copy就能执行成功 from numpy import * import operator # 数据读取 def file2matrix(filename): fr = open(filename) numberOfLines = len(fr.readlines()) returnMat = zeros((numberOfLines, 3)) # 生成对应行数的零矩阵;returnMats是返回的数据集列表 classLabelVector = [] # return的标签列表 fr = open(filename) index = 0 for l in fr.readlines(): # 以行为单位删除前后空格 line = l.strip() # 以\t切割字符串,前三列存入数据集列表中 listFormLine = line.split('\t') # listFormLine中[0,3)个元素放入returnMat第index行中 returnMat[index, :] = listFormLine[0:3] # 最后一列标签列存到标签列表中 classLabelVector.append(int(listFormLine[-1])) index += 1 return returnMat, classLabelVector # 数据集归一化 def autoNorm(dataSet): ''' dataSet:数据集 归一化公式:Y=(X-Xmin)/(Xmax-Xmin) ''' # 求出最大值,最小值,范围 minVals = dataSet.

golang 短变量声明看这一篇就够了

刚开始看 golang 短变量声明的时候真有些懵逼,「变量重声明」是什么情况,有的时候还报错说 No new variables on the left side of ':='。 结合官方文档的一些描述 Short_variable_declarations ,好像是有些理解了, 先对短变量重声明来个个人理解吧: 只能在代码块作用域里使用 := 来声明一个新变量。在同一代码块作用域多次使用 := 来重声明相同变量,重声明的类型要操持一致,:=左边定义的变量名 list 需要有一个是新变量,不然会报错。最后重声明出来的相同变量名的地址是一样的。 下面来看看示例。 短变量重声明只能在局部代码块作用域里 func main() { // 作用域 1 err := test() if true { // 作用域 2 err := test() } if true { // 作用域 3 err := "error" } } func test() (err error) { return errors.New("error") } 局部代码块作用域,比如 if、for、switch 作用域。 不同作用里声明的变量是新的,地址不一样哦 func main() { err := test1() //声明并赋值一个error类型的变量 fmt.

2022 Android studio 最全必用插件

Android开发工具系列目录 Android项目中Git工具的使用史上最全Git命令使用手冊史上最新最全的ADB命令行Android中的su命令使用Postman测试WebService接口2022 Android studio 最全必用插件 好用又好插件 前言1. Background Image Plus2. Translation3. Rainbow Brackets4. Markdown Navigator5. Statistic6. GsonFormat7. Alibaba Java Coding Guidelines8. Android Parcelable code generator9. WIFI ADB ULTIMATE10. LeakCanary11. OK,Gradle12. Json Parser13. JUnitGenerator V2.​014. 码云 Gitee 博客创建时间:2022.05.30 博客更新时间:2022.09.25 以Android studio build=7.0.0,SDKVersion 31来分析讲解。如图文和网上其他资料不一致,可能是别的资料版本较低而已。 前言 Android studio为我们提供了丰富的插件,安装使用IDEA插件能让我们开发提升效率和使用体验,来和我看看这几款你不用后悔的插件。 我对各插件都进行了亲身体验推荐之后才推荐给大家的,推荐的都是截止2020还能实用且实用度特别高的插件,对于老旧的插件和花里胡哨没多大实际用处的插件我就不推荐了。 1. Background Image Plus 该插件支持用户自定义设置Idea的背景图,并且能修改背景图的透明度,效果如下: 一边看美女一边写代码是不是腰也不疼了,头也不昏了。 设置方法: 批量设置 Android Studio安装该插件后,打开settings,找到Background Image Plus。设置图片文件夹路径即可,可以设置循环切换背景图。 查找图片路径后不显示文件夹中的图片没关系,只要文件路径对,里有图片就可以,正常可用。 单张设置 在View菜单中,有多个选项中Random Background Image是手动切换一张随机背景,Clean Background Image 是清楚背景设置。重要的自定义设置背景图片Set Background Image 点击Set Background Image进入设置页面

[HUBUCTF 2022 新生赛]

checkin <?php show_source(__FILE__); $username = "this_is_secret"; $password = "this_is_not_known_to_you"; include("flag.php");//here I changed those two $info = isset($_GET['info'])? $_GET['info']: "" ; $data_unserialize = unserialize($info); if ($data_unserialize['username']==$username&&$data_unserialize['password']==$password){ echo $flag; }else{ echo "username or password error!"; } 先对代码进行审计,发现isset( )是我们没见过的用法,可以去了解一下。 isset() 函数用于检测变量是否已设置并且非 NULL。 以上是基本用途,而本题中用到的是php的三元运算符 $id = isset($_GET['id']) ? $_GET['id'] : ''; (条件) ? (值1):(值2); 解释:如果条件成立(为真),则执行冒号前边的“值1”,否则执行冒号后面的“值2”。 isset()函数是检测变量是否设置,$_GET['id']是通过get方法传过来的值。 这句话的意思就是:如果$_GET['id']已经被设置,即已经有值了,则$id=$_GET['id']; 如果$_GET['id']没有被设置,则$id = ''; 继续向下看,发现unserialize, 就可以知道和反序列化有关了。 exp: <?php $info = array( 'username'=>true, 'password'=>true ); $serialized_data = serialize($info); echo $serialized_data .

useEffect 完整使用指南

目录 一、每一次渲染都有它自己的 Props and State 二、每次渲染都有它自己的Effects 三、关于依赖项不要对React撒谎 四、两种诚实告知依赖的方法 五、来自 useReducer 的助攻 六、把函数移到Effects里 七、我不想把可复用的函数放到Effect里 这篇文章会假设你对useEffect API有一定程度的了解。 一、每一次渲染都有它自己的 Props and State 在我们讨论 effects 之前,我们需要先讨论一下渲染,当我们更新 state 的时候,React会重新渲染组件。每一次渲染都能拿到独立的 state,这个状态值是函数中的一个常量。 这里关键的点在于任意一次渲染中的常量都不会随着时间改变。渲染输出会变是因为我们的组件被一次次调用,而每一次调用引起的渲染中,它包含的值独立于其他渲染。 如果 props 和 state 在不同的渲染中是相互独立的,那么使用到它们的任何值也是独立的(包括事件处理函数)。它们都“属于”一次特定的渲染。即便是事件处理中的异步函数调用“看到”的也是这次渲染中的值。 二、每次渲染都有它自己的Effects 让我们先看向官网的 useEffect 的例子: function Counter() { const [count, setCount] = useState(0); useEffect(() => { document.title = `You clicked ${count} times`; }); return ( <div> <p>You clicked {count} times</p> <button onClick={() => setCount(count + 1)}> Click me </button> </div> ); } effect是如何读取到最新的count 状态值的呢?

UE4通过蓝图创建简单场景:一颗旋转的石头

1.打开UE新建关卡 视口出现一个只有地板的场景 2.创建蓝图类 在下侧的内容栏空白地方中右键鼠标菜单,在弹出菜单中选项选中“蓝图类” 在弹出的界面中选中Actor 在内容窗口中就会创建一个蓝图类,重新命名“旋转的石头” 3.创建旋转的石头 双击“旋转的石头”,进图蓝图编辑界面 在左上方有一个根节点【DefaultSceneRoot】,点击根节点上方的绿色按钮【+添加组件】-》【静态网格体】 重新命名为“一颗石头” 在右侧细节面板中,【静态网格体】选中石头 然后进入到【事件图表】,鼠标点击最下面一个节点“事件Tick”中的五边形向空白处拖动,在弹出菜单中输入“AddActor”选中“添加Actor场景旋转” 在Z轴方向上旋转,所以在Z轴上,输入每帧需要旋转的角度0.5 4.把石头添加到场景中 只要把内容中的石头拖动场景的地板上即可; 点击【运行】,通过键盘的W、A、S、D和鼠标的左键的配合,就可以看到一颗在场景中移动的石头了 aaa

UiPath快捷键

我们在哪里可以看到这些快捷键呢?顺便也帮助一下刚刚了解的新伙伴,普及一下基础知识。 第一:打开UiPath,切换到Design,如下图 点击Recording,我们随便选择一个,这里小U就用Basic,如下图 在弹出的画面,点击Record 当我们开始录制时,在屏幕的左上角会显示出快捷键提示 ESC:取消选择 F2:延迟选择---这个是使用的最多的,大家记住这个 F3:选择区域 F4:界面框架:默认 应用的场景,比如: 多层菜单,录制多层菜单的点击时,总是无法录到第二层或者第三层菜单中的值用UiPath点击“保存”按钮之后的“另存为” 以上的问题都可以用F2来解决,点击activity-Click中的“Indicateon screen”之后,按F2可以让UiPath暂停3秒钟,等鼠标将子菜单点击出来之后,UiPath继续选页面,这样就避免了一直无法选中的情况。 开发过程中我们使用比较多的快捷键: Ctrl + Z:这个快捷键,简直是横行了所有软件,撤销功能 Ctrl + D:将选中的活动/序列注释不执行 Ctrl + E:和Ctrl + D作用相反 Ctrl + K:新建一个变量 Ctrl + Shift+T:新建一个Activity,配合Alt+数字,快速选择我们需要的Activity,

转载一篇高通UEFI分析

高通uefi之原理 - DMCF - 博客园 背景 之前学习的lk阶段点亮LCD的流程算是比较经典,但是高通已经推出了很多种基于UEFI方案的启动架构。 所以需要对这块比较新的技术进行学习。在学习之前,有必要了解一下高通UEFI启动流程。 原文(有删改):【Android SDM660开机流程】- UEFI XBL 代码流程分析_CielleeX的博客-CSDN博客_sdm660 xbl 参考文档:80_P2484_117_B_UEFI_With_XBL_On_MSM8998_SDM660_SDM 总览 先来看下SDM660芯片冷启动的流程。可以看出,在设备上电后,先跑的是 APPS PBL,接着运行XBL SEC、XBL Loader,通过Loader引出XBL CORE APPSBL,最后进入HLOS。 我们来看下这几个涉及的模块大概功能: 1、Application primary boot loader (APPS PBL) PBL 启动时,CPU只开启了第一个核心 CPU Core 0,运行固件在ROM中,这部分是高通写死在芯片中的固件,外部开发人员是无法修改这部份的。 主要功能为: (1)系统安全环境的初始化,以确保后续的XBL中的APPS 能够正常运行。 (2)根据boot gpio的配置选择从什么设备启动操作系统(如 Nand,USB等)。 (3)通过检测GPIO判断是否进入Emergency Download mode,用户可以通过FILE来下载完整的系统镜像。 (4)通过L2 TCM来加载XBL1 ELF,OCIMEM 和 RPM CodeRAM 代码。 2、Extensible boot loader (XBL) 从XBL开始,跑的就是我们编译下载进eMMC/UFS的系统镜像了,在XBL中主要是初始化相关的硬件环境,及代码安全环境。 (1)初始化 Buses、DDR、Clocks、CDT,启动QSEE,QHEE,RPM_FW, XBL core images。 (2)使能memory dump through USB and Sahara(系统死机时memory dump),看门狗,RAM dump to SD support等功能。

我在windows环境下的YOLOV3环境搭建过程

我的操作系统系统为windows11,采用的python版本是python37,如何安装python就不说了。 一、安装pytorch 1.1安装过程 首先在安装pytorch之前,先要安装CUDA,因为一般我们都是用GPU去跑深度学习程序。具体安装过程我是参考的以下链接安装成功的: Pytorch安装,这一篇就够了,绝不踩坑_孔德浩的博客-CSDN博客_pytorch安装 【超详细】windows10系统下深度学习环境搭建CUDA11.3+cuDNN,以及tensorflow,Keras,pyTorch对应版本_勋章DhR的博客-CSDN博客 安装的pytorch相关软件版本如下图: 最后,输入以下不报错,则说明安装pytorch成功: import torch from torch import nn import torchvision 输入以下,输出相关结果则说明GPU环境配置成功: print(torch.__version__) # 输出pyTorch版本 print(torch.version.cuda) # 输出CUDA版本 print(torch.backends.cudnn.version()) # 输出cuDNN的版本 print(torch.cuda.get_device_name(0)) # 输出显卡版本 print(torch.cuda.is_available()) # 测试GPU是否生效 1.2下载whl依赖包 我现在有torch-1.11.0+cu113-cp37-cp37m-win_amd64.whl包,我想获取该包的依赖包。可以执行x下面命令,依赖包即下载到了downPK目录中。当然,如果你想在线安装,可以跳过该命令,直接使用pip install ...进行安装。 pip download -d D:\software\python\PyTorch\downPK torch-1.11.0+cu113-cp37-cp37m-win_amd64.whl 二、YOLOV3下载 下载地址为: https://download.csdn.net/download/wchwdog13/86669879 三、数据信息标注 3.1深度学习标注工具下载 我采用的标注工具为labelmev5.0.1,可以在网上下载到。 3.2数据标注 我一共标注了8张图片,共有2个目标分类,分别为ship和ball,其标注界面如下: 标注完成后,为每张图片生成一个json文件,json文件中主要记录了图片中的每个标记框信息,如下图: 其中label表示标注框的类别为ship,points为一个二维数组,第一个元素为矩形框的左上角(x1,y1),第二个元素为矩形框的右下角(x2,y2)。 四、生成模型配置文件 之前下载的PyTorch-YOLOv3项目目录如下: 进入config文件夹,执行create_custom_model.sh文件即可生成PyTorch-YOLOv3的模型配置文件, create_custom_model.sh是linux环境下的执行文件,而当前的环境为windows,可以使用构建git运行该文件,我下载的git版本为Git-2.37.1-64-bit.exe,安装成功后,在config目录中右击鼠标,点击Git Bash Here,进入终端,如下图所示。 在该终端环境可运行linux命令,输入命令bash create_custom_model.sh 2,其中参数2是指的是任务的类别(即前面提到的ship和ball),如下图: 回车运行成功,在当前目录中生成了一个名为yolov3-custom.cfg的文件,该文件中包含了YOLOV3的网络架构和相关配置,如下图,其中1、2为卷积神经网络训练时的相关参数设置,3为卷积神经网络结构,4为yolo相关参数,anchors为9个预测框的形状大小,classes代表2个类别等。 五、标签格式转换(labelme生成标签格式转yolo所需标签格式) 在前面,我使用labelme工具对每张图像进行标注,对为每张图像生成了对应的json文件,json文件通过矩形标注框的左上角(x1,x2)和右下角(y1,y2)进行描述,而yolo所需标签格式为(Cx,Cy,W,H),Cx和Cy为目标预测框中心点位位格子的偏移量,映射到区间为0-1,W和H为预测框的宽和高,这部分知识点可以查阅YOLOV3的相关论文解析。因此需要进行转换,下面的代码为转换所需的代码(也可到这个地址进行下载:https://download.csdn.net/download/wchwdog13/86695113): import json import os name2id = {'ship': 0, 'ball': 1} # 标签名称 def convert(img_size, box): dw = 1.

Zookeeper遇到的BUG

Zookeeper遇到的BUG-不要在回调函数中阻塞线程 在zookeeper api实现配置中心时,遇到watch失效问题,watch到父级节点下发生变更时,再次getChildren(),最终因其没有调用原先我们预料到的回调函数,导致问题出现。当然很少有人会使用原生的zookeeper api,使用zookeeper客户端直接封装自然可以解决问题。 最终解决方案watch回调函数再次去getData时开一个线程去做。 整体源码: public class ConfigServer implements AsyncCallback.StatCallback, Watcher, AsyncCallback.ChildrenCallback, AsyncCallback.Create2Callback { private String path;//path是配置数据节点的父级目录,表示当前集群需要从zk集群的哪个目录下取配置信息 private ZooKeeper zk; private String name; private byte[] data; private CountDownLatch publishCountDownLatch; private CountDownLatch getDateCountDownLatch; private CountDownLatch count; private HashMap<String, byte[]> res; public ConfigServer(String path, ZooKeeper zk) { this.path = path; this.zk = zk; res=new HashMap<>(); } //zk集群是二进制安全的,实际上内部存储的是字节流数据 public void publish(String name,byte[] data) throws InterruptedException { publishCountDownLatch=new CountDownLatch(1); this.name=name; this.data=data; String realPath=path+"

Vue3-组件基础

一. 单页面应用程序 1. 何为单页面应用程序 单页面应用程序(英文名:Single Page Application)简称为 SPA,本质是一个 Web 网站中只有唯一的一个 HTML 页面,所有的功能与交互,都在这唯一的一个页面中完成。 2. 单页面应用程序的特点 SPA 将所有的功能都局限在了一个 web 页面中,仅在该 web 页面初始化时加载相应的资源。 一旦页面加载完成,SPA 不会因为用户的操作而进行页面的重新加载或跳转。而是利用JavaScript 动态的切换 HTML 的内容,从而实现页面与用户的交互。 3. 单页面应用程序的优点 1. 良好的交互体验 ● 单页应用的内容的改变无需重新加载整个页面 ● 获取数据通过 Ajax 异步获取 ● 没有页面之间的跳转,不会出现 “白屏现象” 2. 良好的前后端工作分离模式 ● 后端专注于提供 API 接口,更容易实现 API 接口的复用 ● 前端专注于页面的渲染 更利于前端工程化的发展 3. 减轻服务器的压力 ● 服务器只提供数据,不负责页面的合成与逻辑的处理,吞吐能力会提高几倍 4. 单页面应用程序的缺点 1. 首屏加载慢 解决方案:路由懒加载、代码压缩、CDN加速、网络传输压缩 2. 不利于 SEO 解决方案:SSR 服务器端渲染 5. 如何快速创建 vue 的 SPA 项目 1.

excel使用vba校验单元格

学习目标: 使用excel操作vba完成对单元格的校验 学习内容: 例如: 开启 vba开发环境掌握 vba基本语法掌握条件语句掌握循环语句掌握常用函数 学习产出: 演示版本家庭和学生版2019 开启 vba开发环境 excel默认不开启宏,需手动打开 下面两种方式都可以进入开发模式 开发界面 掌握 vba基本语法 Public rgold As Range '---定义在模块中,记录从哪个单元格跳出 Public first As Integer '---初始化 Public value As String '---失去焦点的值 Public mRegExp As Object '正则表达式对象 Public result As Boolean '正则匹配结果 Private Sub Worksheet_SelectionChange(ByVal Target As Range) '单元格改动事件 End Sub 掌握条件语句 if else: If first = 0 And end=10 Then statement Else statement End If switch case: Select Case rgold.

C数据结构-翻转指针法、头插法实现单链表反转

目录 前言 力扣试题链接 一、翻转指针法 1.思路 起始位置与迭代过程 停止条件 特殊情况 2.代码 二、头插法 1.思路 起始位置 迭代过程 停止条件 特殊情况 2.代码 前言 本文介绍以C语言实现无头单链表反转的算法:翻转指针法与头插法。 力扣试题链接 LeetCode-206.反转链表https://leetcode.cn/problems/reverse-linked-list/submissions/ 一、翻转指针法 1.思路 如下图,翻转指针法的思路并不复杂,只需要改变原指针的方向即可。 关键在于如何通过迭代实现将所有结点的指针方向改变的效果。这里我们可以使用三个指针(n1、n2、n3)配合来进行翻转。 三个指针的初始化情况 起始位置与迭代过程 创建3个指针进行翻转操作。如图为3个指针的初始化情况。n1指针指向NULL,n2指针指向原来的首结点head,而n3指针指向n2所指位置的后一个(即head->next)。设计这三个指针的思路如下: 翻转指针方向至少需要两个指针。我们需要让原来指向后继结点的后继指针转而指向前驱结点,则必须有一个指针指向当前节点(即指针n2),另一个指针指向当前节点的前一个结点(即指针n1)。这样,改变后继指针所指方向只需一步: n2->next = n1; 但在翻转完一个指针后,还需要向后遍历将所有结点之间的指针都翻转。如何向后遍历?仅仅只有两个指针,是做不到的。因此我们必须把n2原来的后继结点也保存起来,以便能向后遍历。这时我们引入了n3这个结点,它的用处就是保存n2原来的后继结点。这样,实现n2指针向后移动只需要一步: n2 = n3; //n2指针向后移,寻找n2后头的结点 停止条件 n2表示的是当前结点。n2初始位置为head。当n2到达原链表的最后一个结点时,链表中所有的指针都已经被翻转。因此,当n2 == NULL时,迭代停止。此时把n1看作头结点指针,n1表示的链表即反转后的链表。 循环停止的情况 特殊情况 1. 如下图,当n2刚到在最后一个结点,还没有停止循环时,n3已经指向了链表外的空NULL。这时,就不能和上面的迭代方式一样走完最后一步,因为n3 = n3->next会造成空指针访问错误。因此,只需要加一句条件判断,让最后一步不要执行该语句,即可。 2. 如果链表本身就为空,则不需要进行任何操作,仍然返回空即可。 2.代码 /** * Definition for singly-linked list. * struct ListNode { * int val; * struct ListNode *next; * }; */ //翻指针方向法 struct ListNode* reverseList(struct ListNode* head){ if(head == NULL) { return NULL; } //初始条件 struct ListNode* n1 = NULL; struct ListNode* n2 = head; struct ListNode* n3 = n2->next; //结束条件 while(n2) { //迭代过程 n2->next = n1; n1 = n2; n2 = n3; if(n3) { n3 = n3->next; } } return n1; } 二、头插法 1.

could not open jvm.cfg

我在第一次运行java文件时碰到过这种情况,小小的研究了一下 研究结果:出现这种情况原因之一是下载jdk后因为某些原因又卸载重下了,但是卸载过程中没卸干净 解决方法:卸载重下jdk(因为我研究不明白,干脆重头开始得了) 1、应用卸载:打开控制面板,将jdk有关东西卸载 2、文件夹:删除idk jre文件夹 3、注册表:“win + R” 打开控制台输入regedit—注册编辑器,HKEY_LOCAL_MACHINE/SOFTWARE/JavaSoft ,将JavaSoft文件夹及其子目录全部删除。 4、环境变量:右键单击“此电脑”—“属性”—“高级系统设置”—“环境变量”—删除“JAVA_HOME”—编辑path将%JAVA_HOME%\bin删除 咳咳. 欢迎更正(不喜勿喷)

Charles乱码和SSL 代理问题解决

在刚接触Charles进行抓包使用时,遇到了两个问题: 1、Charles上抓的包出现了乱码; 2、Charles开启SSL Proxying代理后出现了手机无法上网或手机和电脑浏览器都无法上网的情况。浏览器提示证书不可用或过期。 尝试了很久终于解决了这两个问题,下面记录一下处理历程。 1、乱码问题解决 解决方案为:修改Charles.ini 文件(可选); vmarg.5=-Dfile.encoding=UTF-8 vmarg.6=-Dfile.encoding=UTF-8 2、Charles开启SSL Proxying代理电脑浏览器后手机都无法上网问题 Charles想要抓取Https请求的包,必须要在电脑和手机上都安装Charles 根证书。 (1)安装SSL证书 选择 “Help” -> “SSL Proxying” -> “Install Charles Root Certificate” 到此,Charles证书就安装成功了。 (2)防火墙配置 可以在电脑防火墙上看到 路径为:网络和Internet--windows防火墙--允许应用通过防火墙,在“允许的应用和功能”列表上要保证Cherles Web Debugging Proxy的所有勾选框都是被勾选的。如果要更改这里的配置,需要先点击一下“更改设置”按钮,然后删除按钮才会高亮显示。选中Cherles Web Debugging Proxy这一列可以进行设置和删除操作。 (3)设置Charles的SSL 代理 1、 回到Charles应用,点击工具栏的Proxy按钮 -- 选择Proxy Settings -- 设置代理端口并勾选上下面的两个复选框,特别是第二个复选框代表开启http代理明文传输。 2、选择Access Conctrol Setting,在这里可以控制访问设备。点击add可以添加需要抓包设备(pc或移动设备)的ip地址。设置好之后才能保证这些添加上的设备能够被Charles抓包。 从截图的文字描述可以看到,安装Charles的计算机默认是被包含在访问控制列表的。访问列表默认展示为空,需要用户自己添加需要控制的设备的ip地址。 3、SSL Proxying Settings设置 勾选enable SSL Proxying复选框代表开启SSL Proxying代理,并在include栏中添加域名和端口号。include中的列表项代表Charles能够展示这些域名的SSL请求和响应的明文。 并且说明中也提示了我们Charles要想使用SSL Proxying代理,需要进行SSL Certificates,即证书签名。这个我们在上面已经完成了。 Stop SSL Proxying按钮可以控制SSL 代理的开关。 到此,PC端的设置都已经配置好了。 (4)手机端配置网络的代理,并安装Charles证书 4.1、 手机端配置网络代理 手机端需要保证连接的wifi是和PC端在同一个局域网。 手机端进入到设置--WLAN--找到已连接的wifi--长按该wifi,弹出修改网络--点击修改网络,然后设置代理模式为手动--填写服务器主机名和端口后。服务器主机名即PC端的ip地址,端口号即在Charles应用中设置的Proxying 端口号。

Maven异常‘parent.relativePath‘ of POM...

异常信息: 'parent.relativePath' of POM io.renren:renren-fast:3.0.0 (C:\self_project\谷粒商城\project\gulimail\renren-fast\pom.xml) points at com.atguigu.gulimall:gulimall instead of org.springframework.boot:spring-boot-starter-parent, please verify your project structure 问题原因: 直接拖动一个SpringBoot的项目文件到总项目里面,并且在最外的pom的modules里添加了该项目的pom 由于parent里写的并不是xxx的上一级,而是继承了springboot: <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.8.RELEASE</version> </parent> 解决方案: 加上: <relativePath/> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.8.RELEASE</version> <relativePath/> </parent>

【MySQL】表的约束

文章目录 一. 什么是约束?二. 为什么要有约束?三. 如何约束?1. 空属性 --- not null2. 默认值 --- default3. 列描述 --- comment4. zerofill5. 主键 --- primary key6. 自增长 --- auto_increment7. 唯一键 --- unique8. 外键 --- foreign key 一. 什么是约束? 在上一篇介绍数据类型时就引入“约束”这个概念,约束字段的是数据类型,但是数据类型的约束很单一,还需要有一些额外的约束以更好的保证数据的合法性,这篇文章将重点说明MySQL中的几种约束。 下面给出约束的定义:约束本质上是MySQL通过限制用户操作的方式,来达到维护数据安全的一套完整性方案,即约束的最终目的是从业务逻辑的角度保证数据的正确性、安全性。 二. 为什么要有约束? 我们知道MySQL是一套数据存储容灾解决方法,除了完成基本的数据存储功能之外,还要保证数据尽可能的安全,减少用户误操作的可能性。 三. 如何约束? 1. 空属性 — not null 我们在注册账号或填写用户信息时,有些属性是必填的,有些是选填的: 对应到数据库层面,我们在定义表中的每一个字段时,它们有两种可供选择的属性:null(默认的)和not null(不为空)。数据库字段的默认属性是null,即允许为空;但是实际开发时,尽可能保证字段不为空,因为数据为空没办法参与运算。 举例: 创建一张Person表,字段包括人的姓名、性别,且都允许为空: 创建一张PersonNotNull表,也包含两个字段:姓名、性别,但是不都允许为空: 2. 默认值 — default 通常我们在注册社交平台账号时,需要绑定你的电话号码,对于电话号码,不同的国家有不同的国际区号。比如中国的国际区号就是+86,如果这个社交媒体平台是中国本土的,则默认中国人使用的最多,所以默认区号就是+86了: 默认值:某一个字段会经常性的用到某个具体的值,我们可以一开始就指定好这个值,在对该字段插入时,用户可以直接使用这个默认值而不需要再去指定。 使用方法:定义字段时在后面加上default 默认值。 举例: // 1、创建一张表 mysql> create table if not exists Person( -> name varchar(20), -> nationality varchar(20) default '中国', -> age tinyint unsigned default 0 -> ); Query OK, 0 rows affected (0.

什么是token?token是用来干嘛的?

相信很多从事计算机行业的朋友都听说过token这么个东西,但是其他行业的人就很少了解到token,下面就给大家来详细介绍一下token是什么意思?token是用来干嘛的这一块的内容,希望能帮助到大家。 🏻 token是什么意思 作为计算机术语时,是“令牌”的意思。Token是服务端生成的一串字符串,以作客户端进行请求的一个令牌,当第一次登录后,服务器生成一个Token便将此Token返回给客户端,以后客户端只需带上这个Token前来请求数据即可,无需再次带上用户名和密码。 token其实说的更通俗点可以叫暗号,在一些数据传输之前,要先进行暗号的核对,不同的暗号被授权不同的数据操作。说白了token是一个身份卡,有权限的作用。例如在USB1.1协议中定义了4类数据包:token包、data包、handshake包和special包。主机和USB设备之间连续数据的交换可以分为三个阶段,第一个阶段由主机发送token包,不同的token包内容不一样(暗号不一样)可以告诉设备做不同的工作,第二个阶段发送data包,第三个阶段由设备返回一个handshake包。 🏻 token产生的背景 HTTP 是一种没有状态的协议,也就是它并不知道是谁是访问应用。这里我们把用户看成是客户端,客户端使用用户名还有密码通过了身份验证,不过下回这个客户端再发送请求时候,还得再验证一下。 🏻 token是用来干嘛的 使用token机制的身份验证方法,在服务器端不需要存储用户的登录记录。 大概的流程: 1️⃣客户端使用用户名和密码请求登录。 2️⃣服务端收到请求,验证用户名和密码。 3️⃣验证成功后,服务端会生成一个token,然后把这个token发送给客户端。 4️⃣客户端收到token后把它存储起来,可以放在cookie或者Local Storage(本地存储)里。 5️⃣客户端每次向服务端发送请求的时候都需要带上服务端发给的token。 6️⃣服务端收到请求,然后去验证客户端请求里面带着token,如果验证成功,就向客户端返回请求的数据。 🌱 token的使用小结: ◾ 前端登陆的时候向服务器发送请求,服务器验证成功,会生成一个token ◾ 前端会存储这个token,放在session或cookie中,用于之后的业务请求身份验证 ◾ 拿着这个token,可以在当前登录的账号下进行请求业务,发送请求时,token会放在请求头里,服务器收到这个业务请求,验证token,成功就允许这个请求获取数据 ◾ token可以设置失效期 🏻 利用token机制进行登录认证,可以有以下方式: a. 用设备mac地址作为token 客户端:客户端在登录时获取设备的mac地址,将其作为参数传递到服务端 服务端:服务端接收到该参数后,便用一个变量来接收,同时将其作为token保存在数据库,并将该token设置到session中。客户端每次请求的时候都要统一拦截,将客户端传递的token和服务器端session中的token进行对比,相同则登录成功,不同则拒绝。 此方式客户端和服务端统一了唯一的标识,并且保证每一个设备拥有唯一的标识。缺点是服务器端需要保存mac地址;优点是客户端无需重新登录,只要登录一次以后一直可以使用,对于超时的问题由服务端进行处理。 b. 用sessionid作为token 客户端:客户端携带用户名和密码登录 服务端:接收到用户名和密码后进行校验,正确就将本地获取的sessionid作为token返回给客户端,客户端以后只需带上请求的数据即可。 此方式的优点是方便,不用存储数据,缺点就是当session过期时,客户端必须重新登录才能请求数据。 当然,对于一些保密性较高的应用,可以采取两种方式结合的方式,将设备mac地址与用户名密码同时作为token进行认证。 🏻 APP利用token机制进行身份认证 用户在登录APP时,APP端会发送加密的用户名和密码到服务器,服务器验证用户名和密码,如果验证成功,就会生成相应位数的字符产作为token存储到服务器中,并且将该token返回给APP端。 以后APP再次请求时,凡是需要验证的地方都要带上该token,然后服务器端验证token,成功返回所需要的结果,失败返回错误信息,让用户重新登录。其中,服务器上会给token设置一个有效期,每次APP请求的时候都验证token和有效期。 🏻 token的存储 token可以存到数据库中,但是有可能查询token的时间会过长导致token丢失(其实token丢失了再重新认证一个就好,但是别丢太频繁,别让用户没事儿就去认证)。 为了避免查询时间过长,可以将token放到内存中。这样查询速度绝对就不是问题了,也不用太担心占据内存,就算token是一个32位的字符串,应用的用户量在百万级或者千万级,也是占不了多少内存的。 🏻 token的加密 token是很容易泄露的,如果不进行加密处理,很容易被恶意拷贝并用来登录。加密的方式一般有: 在存储的时候把token进行对称加密存储,用到的时候再解密。 文章最开始提到的签名sign:将请求URL、时间戳、token三者合并,通过算法进行加密处理。 最好是两种方式结合使用。 还有一点,在网络层面上token使用明文传输的话是非常危险的,所以一定要使用HTTPS协议。

29.STM32红外遥控器

1.红外遥控器 红外遥控是一种无线、非接触控制技术,具有抗干扰能力强,信息传输可靠,功耗低,成本低,易实现等显著优点,被诸多电子设备特别是家用电器广泛采用,并越来越多的应用到计算机系统中。 红外遥控的编码目前广泛使用的是:NEC Protocol 的PWM(脉冲宽度调制)和Philips RC-5 Protocol 的PPM(脉冲位置调制)。 2.NEC协议 1.8位地址和8位指令长度; 2.地址和命令2次传输(确保可靠性) 3.PWM脉冲宽度调制,以发射红外载波的占空比代表“0”和“1”; 4. 载波频率为38Khz; 5.位时间为1.125ms或2.25ms(高电平持续时间来区分); 3.NEC码位定义 一个脉冲对应560us的连续载波 一个逻辑1需要2.25ms(560us的脉冲+1680us的低电平) 一个逻辑0需要1.125ms(560us的脉冲+560us的低电平) 故接收到的信息(信号会相反) 逻辑1为(560us的低电平+1680us的高电平) 逻辑0为(560us的低电平+560us的高电平) 4.NEC遥控器指命 NEC遥控指令的数据格式为:同步码头、地址码、地址反码、控制码、控制反码。 同步码由一个9ms的低电平和一个4.5ms的高电平组成(启动信号,有按键按下了) 地址码、地址反码、控制码、控制反码均是8位数据格式。按照低位在前,高位在后的顺序发送。 (地址码,确认遥控器的地址,就是编号,接收端会检测) (控制码,控制信息) 采用反码是为了增加传输的可靠性(可用于校验)。 控制码为10101000,低位在前高位在后就是00010101 后面有一部分是连发码(由9ms低电平+2.5m高电平+0.56ms低电平+97.94ms高电平组成), 如果在一帧数据发送完毕之后,按键仍然没有放开,则发射重复码,即连发码,可以通过统计连发码的次数来标记按键按下的长短/次数。 5.硬件连接 明显,红外遥控有一个输出引脚,叫DATE,我们得到编码需要解析,这时候就需要定时器输出捕获功能的引脚。 6.程序思路 1.开启定时器输入捕获,默认上升沿捕获。定时器的计数频率为1MHz,自动装载值位1000,也就是溢出时间为1/110^61000 = 10 ms 2.开启捕获中断和更新中断 3.当捕获到上升沿,就设置为捕获下降沿捕获,计算定时器数值差别,然后设置定时器计数值为0(清空定时器),同时设置Rmtsta的位4设置为1,标记已经捕获到上升沿。 4.当捕获到下降沿,就设置为捕获上升沿捕获,计算定时器数值差别,然后设置定时器计数值为0(清空定时器),同时检测Rmtsta的位4设置是否为1 5.对捕获值进行分析,300-800之间为(560中间)说明收到数据为0。1400-1800之前数据为1.2200-2600,说明是连发码,4200-4700就是同步码 6.如果是定时器发生溢出中断(就只能是连发信号这么长,97.94会溢出),那么分析,如果之前接收到了同步码,并且是第一次溢出,标记完成一次按键信息采集。 7.相关程序源码 红外函数 #include "remote.h" #include "delay.h" // //本程序只供学习使用,未经作者许可,不得用于其它任何用途 //ALIENTEK 阿波罗STM32F429开发板 //红外遥控解码驱动代码 //正点原子@ALIENTEK //技术论坛:www.openedv.com //创建日期:2016/1/16 //版本:V1.0 //版权所有,盗版必究。 //Copyright(C) 广州市星翼电子科技有限公司 2014-2024 //All rights reserved // TIM_HandleTypeDef TIM1_Handler; //定时器1句柄 //红外遥控初始化 //设置IO以及TIM1_CH1的输入捕获 //TIM1挂载APB2上 void Remote_Init(void) { TIM_IC_InitTypeDef TIM1_CH1Config; TIM1_Handler.

30.STM32 DS18B20

1.STM32 DS18B20 1.独特的单总线接口方式,DS18B20在与微处理器连接时仅需要一条口线即可实现微处理器与DS18B20的双向通讯。大大提高了系统的抗干扰性。 2.测温范围 -55℃~+125℃,精度为±0.5℃。 3.支持多点组网功能,多个DS18B20可以并联在唯一的三线(地,电源,数据线)上,最多只能并联8个,实现多点测温,如果数量过多,会使供电电源电压过低,从而造成信号传输的不稳定。 4 .工作电源: 3.0~5.5V/DC (可以数据线寄生电源)。 5.在使用中不需要任何外围元件。 6 .测量结果以9~12位数字量方式串行传送。 2.STM32 DS18B20封装 1. 2. 3.STM32 DS18B20硬件连接## 4.STM32 DS18B20 1.是一种单总线,只有一根数据线,是一种半双工通信方式 2.有6种信号,复位脉冲,应答脉冲,写0,写1,读0,和读1。这些信号,除了应答信号以为,都是由主机发送同步信号,而且发送的所有的命令和数据都是低位在前。 5.STM32 DS18B20信号 1.复位信号 单总线上的所有通信都是以初始化序列开始。主机输出低电平,保持低电平时间至少480 us,,以产生复位脉冲。(脉冲产生) 接着主机释放总线,4.7K的上拉电阻将单总线拉高,延时15~60 us。并进入接收模式(Rx)。 接着DS18B20拉低总线60~240 us,以产生低电平应答脉冲 就是产生脉冲,进入接收,产生应答 2.应答信号 把IO口设置为输入,等待DQ被拉低,或者等待200us超过时间了(直接返回没有应答) 第二个while是判断拉低的应答是否小于240us,如果超过就不是正常的应答 3.写信号 写时序包括写0时序和写1时序。所有写时序至少需要60us,且在2次独立的写时序之间至少需要1us的恢复时间,两种写时序均起始于主机拉低总线。 相反的 写1时序:主机输出低电平,延时2us,然后释放总线,延时60us。 写0时序:主机输出低电平,延时60us,然后释放总线,延时2us。 4.读信号 单总线器件仅在主机发出读时序时,才向主机传输数据,所以,在主机发出读数据命令后,必须马上产生读时序,以便从机能够传输数据。 所有读时序至少需要60us,且在2次独立的读时序之间至少需要1us的恢复时间。每个读时序都由主机发起,至少拉低总线1us。主机在读时序期间必须释放总线,并且在时序起始后的15us之内采样总线状态。 典型的读时序过程为:主机输出低电平延时2us,然后主机转入输入模式延时12us,然后读取单总线当前的电平,然后延时50us。 读一个位 读一个字节 6.STM32 DS18B20获取温度流程 复位 > 等待应答 > 发SKIP ROM命令(0xcc)> 发开始转换命令 > 延时 > 发送SKIP ROM命令 发读存储器命令(0xbe) > 连续读出两个字节数据 7.STM32 DS18B20源码 正点的ds18b20代码 #include "ds18b20.h" #include "

Springboot整合Cos云存储

1、导入相关依赖 首先导入Cos云存储的相关依赖。 <!--腾讯云COS--> <dependency> <groupId>com.tencentcloudapi</groupId> <artifactId>tencentcloud-sdk-java</artifactId> <version>3.0.1</version> </dependency> <dependency> <groupId>com.qcloud</groupId> <artifactId>cos_api</artifactId> <version>5.6.8</version> </dependency> 2、编写配置类 首先需要获取相关配置参数,进入腾讯云对象存储,创建存储桶并进入所创建的存储桶。 public class CosConfig { //腾讯云账号秘钥 private String secretId = ""; //密码秘钥 private String secretKey = ""; //存储桶地区 private String region=""; //存储桶名称 private String bucketName=""; //存储桶访问路径 private String path=""; ​ //初始化cos对象,配置相关配置信息 @Bean public COSClient cosClient(){ // 1 初始化用户身份信息(secretId, secretKey)。 COSCredentials cred = new BasicCOSCredentials(this.secretId, this.secretKey); // 2 设置 bucket 的区域 Region region = new Region(this.region); ClientConfig clientConfig = new ClientConfig(region); // 3 生成 cos 客户端。 COSClient cosClient = new COSClient(cred, clientConfig); return cosClient; } } 3、编写逻辑层 其实最好的方式是将Cos云配置信息放入application.

打jar包并将依赖包合并进去

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、修改pom文件二、右侧maven工具栏1.maven命令2.target下jar包 三、另一种方式四、另一种方式总结 前言 提示:这里可以添加本文要记录的大概内容: 例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。 一、修改pom文件 主要是下面的plugin标签 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.sd</groupId> <artifactId>Z20210922</artifactId> <version>1.0-SNAPSHOT</version> <packaging>jar</packaging> <dependencies> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.70</version> </dependency> <dependency> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-assembly-plugin</artifactId> <version>3.0.0</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.1.24</version> </dependency> </dependencies> <properties> <maven.compiler.source>8</maven.compiler.source> <maven.compiler.target>8</maven.compiler.target> </properties> <build> <finalName>Z20210922-1.0-SNAPSHOT</finalName><!--jar包名--> <plugins> <plugin> <artifactId>maven-assembly-plugin</artifactId> <configuration> <archive> <manifest> <mainClass>com.sd.Test</mainClass><!--程序入口--> </manifest> </archive> <descriptorRefs> <descriptorRef>jar-with-dependencies</descriptorRef> </descriptorRefs> <appendAssemblyId>false</appendAssemblyId><!--去掉jar-with-dependencies--> </configuration> <executions> <execution> <id>make-assembly</id> <phase>package</phase> <!-- packaging phase --> <goals> <goal>single</goal> </goals> </execution> </executions> </plugin> </plugins> </build> </project> 二、右侧maven工具栏 1.

用蒙特卡洛算法 编程求解Π的值

蒙特卡洛问题求PI值的原理 正方形的面积为4r^2 正方形内四分之一圆的面积为:Πr^2 正方形内四分之一圆的面积与正方形的面积的比值为Π/4 所以Π的值为4 * (四分之一圆的面积/正方形的面积) import random N = int(input("请输入要随机产生的点数:")) X=0 pi=0 for i in range(N): a = random.uniform(0,1) #随机产生0-1内的数 b = random.uniform(0,1) if a*a + b*b <= 1: #随机产生的坐标点坐落在以原点为中心半径为1的四分之一圆内的个数(X^2+Y^2=1 表示以原点为中心半径为1的圆) X=X+1 pi=(X/N)*4 print('pi近似等于:{0}'.format(pi))

身份证真伪辨别 Python

身份证真伪辨别 中华人民共和国居民身份证号码由17 位数字和1位校验码组成。 其中,前6位为所在地编号,第7~14 位为出生年月日,第15~17位为登记流水号,其中第17位偶数为女性,奇数为男性。 校验码的生成规则如下: 将前面的身份证号码17位数分别乘以不同的系数。第1~17位的系数分别为: 7,9,10,5,8 4,2,1,6,3,7,9,10,5,8,4,2,将这17 位数字和系数相乘的结果相加,用相加的结果与11求模,余数结果只可能是0,1,2,3,4,5,6,7,8,9,10这11个数字,它们分别对应的最后一位身份证的号码为1,0,x,9,8,7,6,5,4,3,2。例如,如果余数是2,最后一位数字就是罗马数字x,如果余数是10,则身份证的最后一位就是2。 请设计程序实现输入18位身份证号,辨别其真伪。若为真,则进一步判断性别: 若不是18位或身份证号非法,则提示重新输入。提示:定义如下两个元组,对输入字符串进行遍历。 factor=(7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2) last=(“1”,“0”,“x”,“9”,“8”,“7”,“6”,“5”,“4”,“3”,“2”) X = input("请输入您的身份证号码:") factor=(7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2) last=("1","0","x","9","8","7","6","5","4","3","2") i = 0 M = 0 if len(X) != 18: print("您输入的身份证号码有误") else: while i < 17: M = int(X[i]) * factor[i] + M i = i+1 N = M%11 if X[17] == last[N]: print("身份证号码合法") if int(X[16])%2==0: print("性别:女") else: print("性别:男") else: print("您输入的证件号有误")

C语言编程题 输入今天的日期年月日,输出明天的日期

#include <stdio.h> int main() { int y,m,d; printf("请输入年月日:"); scanf("%d%d%d",&y,&m,&d); if(d<=31) { switch(m) { case 1: case 3: case 5: case 7: case 8: case 10: d<31?d=d+1:(m=m+1,d=1); printf("明天是%d年%d月%d日",y,m,d); break; case 12: d<31?d=d+1:(y=y+1,m=1,d=1); printf("明天是%d年%d月%d日",y,m,d); break; case 4: case 6: case 9: case 11: d<30?d=d+1:(m=m+1,d=1); printf("明天是%d年%d月%d日",y,m,d); break; case 2: if((y%4==0&&y%100!=0)||(y%400==0)) { d==29?(d=1,m=3):d=d+1; } else { d=d+1; } printf("明天是%d年%d月%d日",y,m,d); break; default : printf("您的输入有误!\n"); } } else if(d>31) { printf("您的输入有误!\n"); } return 0; } 新手小白 第一次自己写出来的代码 欢迎大家指正!

第4章 初识HbuilderX之移动前端App开发

本人学习vue的根本目标是为了让手机移动端的(前端)App通过跨域(Cors)操作和与后端的已经部署在IIS中的.Net(Core)6程序进行数据交互操作,并通过交互操作获取数据后在让手机移动端的(前端)App中渲染显示出来;而不是把vue视图页面做为PC端或移动端浏览器的渲染显示页面,因为“*.cshtml” 这种对强类型支持的视图页面,更加符合后台开发者,对程序的快速、调质量的构建。 1 准备工作 1.1 在PC端安装移动模拟器(夜神模拟器:nox) 下载地址:“夜神安卓模拟器-安卓模拟器电脑版下载_安卓手游模拟器_手机模拟器_官网 (yeshen.com)”。 注意:夜神模拟器默认是安装在D:\Program Files\Nox中的,在安装时不要修改其置默认安装位置,至于原因会在下面说明。 1.2 设置夜神模拟器:nox 1.2.1 设置显示界面 夜神模拟器:nox的默认显示界面是“平板界面”,因此需要先设成“手机板界面”,如果下图所示: 1.2.2 设置启用“开发者选项” 1.3 在PC端安下载安装、配置HBuilderX 1.3.1 在PC端安下载安装HBuilderX 下载地址:“HBuilderX-高效极客技巧 (dcloud.io)” 注意: 最好下载“zip”版,不要下载“exe” 版,因为“zip”版是免安装的。“zip”版必须解压在D盘中,因为夜神模拟器默认是安装在D:\Program Files\Nox中的,为了避免 配置HbuilderX调用夜神模拟器时的各种意外,HbuilderX和夜神模拟器最好在同1个盘符中。 1.3.2 配置HbuilderX调用夜神模拟器 在运行配置中分别输入:“D:\Program Files\Nox\bin\nox_adb.exe”、“62001” ,如果下图所示: 注意:在配置HbuilderX调用夜神模拟器完成后,必先关闭HbuilderX程序后,再打开闭HbuilderX程序,否则该配置将不会生效。 1.3.3 HbuilderX调用夜神模拟器进行模拟的注意事项 在HbuilderX调用夜神模拟器进行模拟前,必须先启动“夜神模拟器”而不是“模拟器助手”,否则HbuilderX将会出现:“没有检测到设备,请插入设备后点击涮新再试”错误信息,如果下图所示: 2 HbuilderX之跨域(Cors)交互操作定义实现 本人在HbuilderX中以多种形式测试了当前网上已有的HbuilderX跨域(Cors)操作包,包含:axios(内置)、http 和escook/request-miniprogram(第3方),但是最终只有通过escook/request-miniprogram(第3方)包,能够获取服务器端的数据,其具体实现如下: 2.1 初始化安装必要文件及包 2.1.1 初始化安装“package.json”文件 使用Hbuilder默认模板新建的uin-app,并不包含有“package.json”文件,把“package.json”文件加载到项目的根目录中,需要先通过“终端”运行命令: npm init -y 2.1.2初始化安装“escook/request-miniprogram”(第3方)包 通过“终端”运行命令: npm install @escook/request-miniprogram 2.2 在main.js中导入全局“escook/request-miniprogram”(第3方)包 2.1.1 在main.js中正确导入全局“escook/request-miniprogram”(第3方)包示例 //把“escook/request-miniprogram”(第3方)包导入为全局变量:“$http”。 import { $http } from '@escook/request-miniprogram' //把全局变量:“$http”赋值给全局变量:“uni.$http”。 uni.$http = $http

Java顺序表的实现

目录 1.初始化数组 2.顺序表的打印 3.获取顺序表的长度 4.默认在数组最后位置新增的add方法 5.在指定位置新增的add方法 6.判断是否包含某个元素 7.查找某个元素对应的位置 8.获取pos位置的元素 9.将pos位置的元素更新成value 10.删除第一次出现的关键字key 11.清空顺序表 顺序表本质上就是一个数组,而顺序表就是实现对这个数组进行增删查改等操作方法的一个类,而Java中也有类似与顺序表的集合类:ArrayList<E> 下面我会对这个类里面比较重要且常用的方法进行实现。 1.初始化数组 我们首先创建一个我们自己的类MyArrayList,在里面定义一个int类型的数组,usedSize记录数组里面的元素个数,DEFAULT_SIZE 是建立数组的默认容量,通过构造方法对数组进行初始化容量 public class MyArraylist { public int[] elem; public int usedSize; private static final int DEFAULT_SIZE = 10;//默认容量 public MyArraylist() { this.elem = new int[DEFAULT_SIZE]; } } 2.顺序表的打印 遍历整个顺序表,用前面定义的 usedSize 判断数组的长度(elem.length也可以),对里面的元素进行打印,最后换行 public void display() { for (int i = 0; i < this.usedSize; i++) { System.out.print(this.elem[i] + " "); } System.out.println(); } 3.获取顺序表的长度 直接return usedSize即可。

Overleaf使用tips(自己随手记)

使用中文输入: 导入包:\usepackage[UTF8]{ctex} 切换编译器为XeLatex ----》 另起一段: 直接空几个行就行 比如 注释:选中后ctrl+/ 标题的使用 \section{这是一级标题} \subsection{这是二级标题} \subsubsection{这是三级标题} 插入公式 行间公式(inline):用$…$将公式括起来。比如$w^{[i]}$ 效果: 单独占一行的公式且自动编号: \begin{equation} .....//你的公式 \end{equation} //比如 \begin{equation} S(x)=\frac{1}{1+e^{-x}} \end{equation} (注意:我这里之前已经有四个公式了所以这个插进来编号为5) 具体插入的公式是啥,见这位大佬的博客: https://blog.csdn.net/baidu_38060633/article/details/79183905 可以用https://www.latexlive.com/先编辑后公式然后将对应代码复制进去 插入表格 2022/9/18 参考博客:https://blog.csdn.net/qq_33684682/article/details/125048367 直接用这个网站把表格做好,然后网站自动生成latex的代码 直接粘过去 https://www.tablesgenerator.com/ 因为自己看懒得详细写了直接粘贴复制看效果,可以对比着改: 三线表: \begin{table}[htbp] \renewcommand\arraystretch{1.5} \setlength{\tabcolsep}{3pt} %设置列宽 \centering \caption{Iris数据集中每个花卉类型的真实值得数量} \begin{tabular}{cccc}%l=left, r=right,c=center分别代表左对齐,右对齐和居中,字母c的个数代表列数 \hline %这是那个分隔线 花卉类别 &山鸢尾 &变色鸢尾 &维吉尼亚鸢尾\\ \hline 训练集 &36 &35 &39 \\ %这个\\换行必用 ,&就是对应的列 验证集 &14 &15 &11 \\ \end{tabular} \end{table} 效果: 还有一种: \newcommand{\tabincell}[2]{\begin{tabular}{@{}#1@{}}#2\end{tabular}} %表格自动换行 \begin{table*}[t] \caption{五种分类算法优缺点对比} \centering \begin{tabular}{|c|c|c|} \toprule {\bf 算法} & {\bf 优点} & {\bf 缺点} \\ %\bf表示字体加粗 \hline KNN & \tabincell{c}{简单、有效;对数据的分布无要求;\\直接使用训练集对 数据样本进行分类,训练阶段较快} & \tabincell{c}{\\不建立分类模型;K值不易选择;\\不易发现特征之间的关 系;数据不均 衡时,预测偏差比较大} \\ %需要分行的单元格的语句用\tabincell{c}{所填写第一行内容\\第二行内容···},可以根据需要换行,也不限定换多少行。 \hline NB & \tabincell{c}{训练和分类仅仅是特征概率的数学运算, 分类速度快;\\在对大样本进行处理 时有很大的优势;对结果解释容易理解} & \tabincell{c}{使用样本属性独立性的假设,\\样本属性 有关联时,会导致分类性能降低} \\ \hline DL & \tabincell{c}{结构简单,可以可视化分析;\\容易提取出分 类规则;适合处理量比较大的数据;} & \tabincell{c}{不易处理缺失数据;\\易出现过拟合;忽略 了数据集中属性的相互关联;} \\ \hline SVM & \tabincell{c}{解决小样本、非线性问题;\\无局部极小值 问题;可以很好的处理高维数据集;泛化 能力比较强} & \tabincell{c}{对缺失数据敏感\\适用于 二分类问题,\\对于多分类问题容易产生 过拟合} \\ \hline ANN & \tabincell{c}{分类准确度高,学习能力强;\\对噪声数据 鲁棒性和容错性较强;\\对未经训练的数据也 具有较好的预测分类能力} & \tabincell{c}{参数较多;\\训练时间较 长,有可能陷入局部极小值;\\黑箱过程,不能 观察中间结果,可解释性差;} \\ \bottomrule \end{tabular} \end{table*} 看效果:

dSPACE Mid-Size Simulator Introduction

dSPACE Simulator Mid-Size是一种闭环的硬件在环仿真器,其有以下特性: 支持信号调理 支持给ECU提供等效或真实负载 失效模拟 两路电压系统支持远程控制供电 主机需配备一块链接板卡-Link Board来进行总线接口连接。dSAPCE提供3种不同类型的Link Board来匹配主机不同的总线类型(有ISA/PCI/PCMIA接口)。总线接口用来将real-time model下载到仿真器中,对仿真过程进行控制。主机和仿真器之间通过RS232串口来控制故障注入单元(FIU). dSPACE Mid-Size仿真包含以下部件: 处理器板块DS1005/DS1006 I/O板卡DS2211/DS2202 链接板卡DS814 Load/FIU单元:5个DS790负载板卡,每个板卡包含10个通道,可配置低功率的阻性或感性负载;5个DS791故障注入单元,每个单元包含10个通道,可配置低功率的阻性或感性负载 一个DS686 Backplane 一个DS685 Midplane 可远程控制的供电单元 DS1006 Processor Board The DS1006 Processor Board is based on a single-core or a multicore AMD Opteron TM processor. This real time processor (RTP) is the main processing unit. It can access modular I/O boards via its PHS bus. It is multiprocessing-capable via the (optional) DS911 Gigalink Module.

Matlab-learn(9):sort,函数句柄

1.sort() 排序,默认升序(从小到大) vec=[12 78 10 6 98] sort(vec) ans = 6 10 12 78 98 升序参数: sort(vec,'ascend') ans = 6 10 12 78 98 降序参数: sort(vec,'descend') ans = 98 78 12 10 6 2.利用sort获取struct中某参数大小排序及序号排序, 以便利用序号取用按该参数排序的其它参数。 pack(1)=struct('code','c','dimension',struct('hsaj',1),'weight',2) pack(2)=struct('code','o','dimension',struct('hsaj',5),'weight',6) pack(3)=struct('code','j','dimension',struct('hsaj',-5),'weight',5) 样例1(struct数组): [w_sorted,i_sorted]=sort([pack.weight]) w_sorted = 2 5 6 i_sorted = 1 3 2 按weight大小输出code: pack([i_sorted]).code ans = 'c' ans = 'j' ans = 'o' 若不需要获得某个返回,则用~代替: [~,i_sorted]=sort([pack.weight]) i_sorted = 1 3 2 样例2(table数组): names={'Harry','Sally','Jose'}; heights=[185;133;210]; weight=[74;65.

CAN位时序及相关参数解读

相关概念 位速率(也叫做比特率) 表示的是单位时间内,总线上传输的信息量,即每秒能够传输的二进制位的数量,R=1/T ,单位是bit per second,bps。比如,比特率为8bit/s,意思为一秒传输了8bit,包含了8个二进制事件的信息量。 波特率(码元传输速率) 表示单位时间(1s)内传输的码元个数(脉冲个数或者信息变化次数),码元可以是多进制的;kBaud(1baud=1bit/second, 1KBaud=1KB=1000bits/second)(码元:就是一个脉冲信号,一个脉冲信号有可能携带1bit数据,也有可能携带2、4bit) Time Quantum 时间份额Tq CAN控制器工作的最小时间单位,通常对系统时钟分频得到。 位时间Tbit CAN上传输一个数据位的时间周期Tbit=1/Baudrate. 如下图中的帧起始位。 位时序 根据CAN规范,每个位的时间内又可细分成4段: 同步段(SS,Synchronization Segment,SYSNC_SEG)一个位的输出从同步段开始。若总线的跳变沿被包含在SS段的范围之内,则表示节点与总线的时序同步。节点与总线同步时,采样点采集到的总线电平即可被确定为该电平的电位。SS段的大小为1Tq. 传播段(PTS,Propagation Time Segment, PROP_SEG)用于补偿信号在网络和节点传播的物理延时时间,是总线上输入比较器延时和输出驱动器延时总和的两倍。通常1-8Tq 相位缓冲段1(PBS1,Phase Buffer Segment 1, PHASE_SEG1)主要用于补偿边沿阶段的误差,其时间长度在重新同步时可以加长或缩短。初始大小1-8Tq. 相位缓冲段2(PBS2,Phase Buffer Segment 2,PHASE_SEG2)也是用于补偿边沿阶段的误差,其时间长度在重新同步时可以缩短。初始大小2-8Tq. 采样点:是读取总线电平,并将它解析为数值的时间点。位于相位缓冲段1(PHASE_SEG1)的终点。 tsp =(SYNC_SEG + PROP_SEG + PHASE_SEG1) / (SYNC_SEG + PROP_SEG + PHASE_SEG1 + PHASE_SEG2) 如果位定时设置将采样点设置在位时间的末端,则传播段就会越长,能实现更远的网络。反之,则可提高重同步能力,对时钟误差的容忍能力越大。采样点的设置应使所有节点能够达到传播延迟和时钟误差的最佳折衷点。建议采样点设置应当靠近但是不超过0.875,这使传播延迟和时钟误差容忍达到最优 在CAN实现中,传播段(PROP_SEG)和相位缓冲段1(PHASE_SEG1)被统称为Time segment 1, 相位缓冲段2(PHASE_SEG2)被统称为Time segment 2. 重同步调整宽度(SJW, Resynchronization jump width)由于重同步的结果,相位缓冲段1(PHASE_SEG1)可被延长或者相位缓冲段2(PHASE_SEG2)可被缩短。这两个相位缓冲段的延长和缩短的总和上限由重同步跳转宽度给定. 一个位时间内包含多少个时间份额Tq,称为BTL Cycles。 CAN 总线定时寄存器 如果直接设置STM32的寄存器, 上面BRP、TS1、TS2和SJW的数值,全都需要减1后写入寄存器. SAM的确定:低频时,选SAM=1,即采样3次。高频100K以上时,取SAM=0,即采样1次. SJA1000 内部频率基准源F_BASE = Fclk/2,即外部晶振频率Fclk的2分频。注意任何应用中,当利用外部晶振作为基准源的时候,都是先经过2分频整形的.

pythonocc-core报错:SetPixelFormat failed. Error code: 2000 raised from method Init of class Display3d

错误内容 使用Pythonocc-core运行时,出现以下报错 ###### 3D rendering pipe initialisation ##### Display3d class initialization starting ... Aspect_DisplayConnection created. Graphic_Driver created. V3d_Viewer created. AIS_InteractiveContext created. V3d_View created WNT window created. Traceback (most recent call last): File "E:/Project/camera_calibration_tool/pingzi.py", line 41, in <module> display, start_display, add_menu, add_function_to_menu = init_display() File "F:\Anaconda\envs\CAL\lib\site-packages\OCC\Display\SimpleGui.py", line 192, in init_display win.canva.InitDriver() File "F:\Anaconda\envs\CAL\lib\site-packages\OCC\Display\qtDisplay.py", line 123, in InitDriver self._display.Create(window_handle=self.GetHandle(), parent=self) File "F:\Anaconda\envs\CAL\lib\site-packages\OCC\Display\OCCViewer.py", line 181, in Create self.Init(self._window_handle) File "F:\Anaconda\envs\CAL\lib\site-packages\OCC\Core\Visualization.py", line 171, in Init return _Visualization.

npm i 报错 The operation was rejected by your operating system

昨天晚上我把C:\Program Files里的node_cache、node_global文件夹移动到d盘,今早装依赖的时候,就报错没有权限或者文件正在被某个应用运行的错误,类似于下面这种: npm ERR! path /Users/Kyle/.npm/_cacache/index-v5/d8/1f/98ab242d0cbad080828ef3e3f4b864c25e506a719121c293fec810b14b3c npm ERR! code EACCES npm ERR! errno -13 npm ERR! syscall open npm ERR! Error: EACCES: permission denied, open '/Users/Kyle/.npm/_cacache/index-v5/d8/1f/98ab242d0cbad080828ef3e3f4b864c25e506a719121c293fec810b14b3c' npm ERR! { [Error: EACCES: permission denied, open '/Users/Kyle/.npm/_cacache/index-v5/d8/1f/98ab242d0cbad080828ef3e3f4b864c25e506a719121c293fec810b14b3c'] npm ERR! cause: npm ERR! { Error: EACCES: permission denied, open '/Users/Kyle/.npm/_cacache/index-v5/d8/1f/98ab242d0cbad080828ef3e3f4b864c25e506a719121c293fec810b14b3c' npm ERR! errno: -13, npm ERR! code: 'EACCES', npm ERR! syscall: 'open', npm ERR! path: npm ERR! '/Users/Kyle/.npm/_cacache/index-v5/d8/1f/98ab242d0cbad080828ef3e3f4b864c25e506a719121c293fec810b14b3c' }, npm ERR! isOperational: true, npm ERR!

Python数据分析——Pandas第二天之DataFrame表型数据结构

DataFrame(表型数据结构,二维数组,既有行索引也有列索引,可以看成是由若干个Series组成) DataFrame组成结构:pandas.DataFrame(data, index, column, dtype, copy) data:一组数据,每列都可以是不同类型的值 index:设置索引值,即:行标签 columns:设置列标签,当设置columns时行与列转置 dtype: 数据类型, 当前的格式设置的是整个数据表 copy: 是否拷贝数据,默认是FALSE data为字典类型 import pandas as pd data = { 'id': [12, 15, 18], 'name': ['Laotian', 'Xiaoping', 'xiaomi'], 'grades': [88, 99, 66], 'like': ['羽毛', '足球', '篮球'] } df = pd.DataFrame(data) # 按照源数据的格式转换成数据表 print(f"行索引为0,1,2:\n{df}") # 输出结果: #行标为0,1,2: # id name grades like #0 12 Laotian 88 羽毛 #1 15 Xiaoping 99 足球 #2 18 xiaomi 66 篮球 data为列表格类型时,设置行index、列column索引 import pandas as pd data1 = [ [12, 15, 18], ['Laotian', 'Xiaoping', 'xiaomi'], [88, 99, 66], ['羽毛', '足球', '篮球'] ] df1_1 = pd.

「Python3」基于qrcode和tkinter库实现二维码生成器(及Python3中少量避坑指南)

二维码生成器 qrcode库与tkinter库部分解析qrcode库前期准备 tkinter库前期了解 Tkinter构造二维码生成器框架Frame框架控件Entry输入文本控件Button按钮控件Label标签控件 按钮关联函数选择图片函数生成二维码函数二维码保存函数 完整代码代码问题 qrcode库与tkinter库部分解析 这里只列举了此次二维码生成器所用到的库函数的部分解析,主要针对其安装和避坑点进行讲解。详细参数作用将在后面给出。 qrcode库 前期准备 进入命令行窗口,执行以下命令: pip install qrcode 若是python不在C盘当中,可以在前面加上python所在地址,执行命令: 地址 -m pip install qrcode 简易二维码生成方法如下: import qrcode #导入qrcode库 img = qrcode.make("http://baidu.com") #括号里为二维码的内容,这里生成的二维码可以打开百度页面 img.save("path") #path为二维码保存路径 因为需要用到嵌入图片的操作,因此需要定义一个qrcode库中的QRcode类对象,使用make_image(),与make()相比,参数更加复杂,之后会详细说明。 tkinter库 前期了解 tkinter是Pyhton的标准GUI库,为Python内置的一个库,因此不需要再次进行安装。 #导入tkinter库 #方法一 import tkinter #方法二 from tkinter import * #方法三 from Tkinter import * 在Python3中已经没有Tkinter模块了,这是需要避坑的一个点。 这里对于后面所用到的tkMessageBox也进行一定的讲明: 在Python3中使用tkMessageBox from tkinter import * from tkinter import message #或者直接用tkinter.messagebox也可以 Tkinter构造二维码生成器框架 import tkinter as tk top = tk.Tk() top.title('二维码生成器') #框架名称 top.

SpringAOP超详细图文解释(深入学习笔记可用于面试)

文章目录 1.SpringAop(Aspect Oriented Programming)是什么?1.1springaop的概念1.2 SpringAOP的底层原理1.3SpringAop实现的技术内容 AOP代理模式2.1 AOP动态代理技术2.1.1 Jdk动态代理的实现原理2.1.2 GGLib动态代理的原理jdk动态代理的代码实现 3.AOP的相关概念3.1连接点的小知识补充 AOP在开发中的使用4.1XML配置AOP的详解 4.2重点讲解我们用的注解AOP4.2.1AOP详解注解配置 5.需求的实现:需要验证有权限的用户才能调用该接口代码实现 1.SpringAop(Aspect Oriented Programming)是什么? 我们听说过很多次关于springAop的问题,那么什么是AOP呢?怎样结合官方文档来学习这个呢?那么我们将从他的概念,底层原理进行深入分析,做到应对面试和深入理解的层级 1.1springaop的概念 AOP意思为面向切面编程和AOP比较像的一个词是我们的OOP,oop是面向对象编程,AOP是建立在OOP编程上的一种设计思想,而SpringAOP是实现AOP思想的主流框架.AOP目的:对业务逻辑的各个部分进行隔离,在不改动代码的前提下进行功能的增强,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,通过是提高了开发效率;应用场景:各个模块的横向切入点,比如日志、权限控制等具体如下: 1.在调用service具体一些业务方法的时候,想在前面打一些日志。 2.通过前后两次取时间戳来减一下,来统计所有业务方法执行的时间。 3.在调用某一类业务方法时,判断用户有没有权限。 4.在一系列业务方法前后加上事务的控制。比如startTransaction、commitTransaction(模拟事务控制)。 1.2 SpringAOP的底层原理 实际上AOP底层是通过Spring提供的动态代理技术实现的,在运行期间Spring通过动态代理技术动态的生成代理对象,代理对象方法执行时进行增强功能的介入,在调用目标对象的方法,从而完成业务功能的增强 1.3SpringAop实现的技术内容 Spring框架监控切入点(Pointcut)方法的执行,一旦监控到切入点方法被运行,使用代理机制(proxy),动态创建目标对象的代理对象,根据通知类别(advice),在代理对象的对应位置将通知对应的功能织入,完成完整代码逻辑运行; AOP代理模式 代理有两个,分别是动态代理和静态代理,SpringAOP是动态代理,而AspectJ是静态代理实现的AOP 2.1 AOP动态代理技术 上述提到我们的AOP是基于我们动态代理实现的,接下来我们看看AOP中的两种代理技术JDK动态代理(基于接口实现) cglib动态代理技术(非接口,基于父类) 在Spring里可以把一个类型注册成Spring里的一个Bean,这时候Spring就会帮我们把这个Bean初始化,变成一个可用的对象。加入我们需要在上面做一些增强,就是我们所谓的AOP。这时候我们就需要在中间加一层代理类或者增强类。 2.1.1 Jdk动态代理的实现原理 jdk动态代理,基于Java的反射机制实现,必须有接口才能使用该方法生成代理对象。JDK代理主要涉及到了两个类;Java.lang.reflect.InvocationHandler和java.lang.reflect.Proxy。这两个类的主要方法如下 大致流程是实现InvactionHandle接口创建方法调用器,通过Proxy类指定classLoader对象和一组interface创建动态代理,通过反射获取动态代理类的构造函数,参数类型就是调用器接口类型,通过构造函数创建动态代理类实例,构造时调用处理器接口类型。JdkProxy:假如说这个对象所在的类上面有接口(基于接口来做的),Spring会默认使用JdkProxy(JDK的动态代理),来生成一个代理,在代理里进一步的把所有对这个类做的增强操作,放到代理执行的代码里面。然后先做了增强的操作,再去调用原本的类的他的方法。 2.1.2 GGLib动态代理的原理 CGLIB 代理的工作原理:利用ASM开源包,将对象类的class文件加载进来,通过修改字节码生成的子类来进行处理;在这个子类里,当我们调用原先这个类的某个方法时,先做增强操作,再去调原本类的方法,最后再把结果返回回来。 jdk动态代理的代码实现 基于反射 proxyTargetClass:如果要代理的类有接口但想强制不用默认JDK的动态代理,也是用字节码增强的技术,就可以开启proxyTargetClass选项。同CGlib。 CGlib:假如说要增强或代理的这个类没有接口,只有一个类的定义,Spring会默认使用CGlib,对他做字节码增强。相当于硬生生的给他生成一个子类。在这个子类里,当我们调用原先这个类的某个方法时,先做增强操作,再去调原本类的方法,最后再把结果返回回来。 总之,Spring AOP面向切面的增强功能,都是作用在方法上的! 3.AOP的相关概念 在正式讲解AOP的操作之前,我们需要理解AOP的相关术语,常用的如下 Target(目标对象): 代理的目标对象JoinPoint(连接点):所谓连接点是指那些要被拦截到的点,在spring中这些点指的方法,因为spring只支持方法类型的连接点;典型的包括方法调用,对类成员的访问以及异常处理程序块的执行等等,它自身还可以嵌套其它 joint pointPointcut(切入点):所谓切入点是指我们要对那些joinpoint进行操作,是Joinpoint的集合体可以理解成Advice(通知、增强):所谓通知是拦截到joinpoint之后要做的事情就是通知Aspect(切面): 是指pointCut与Advice的结合体Weaving(织入) :是指把增强(advice)应用到目标对象(target)来创建新的代理对象的过程;spring采用动态代理织入;但AspectJ采用的是编译期织入和类加载时期织入(weaving)Proxy(代理): 一个类AOP织入(weaving)增强后,就产生一个结果代理类 3.1连接点的小知识补充 AOP中的Joinpoint可以有多种类型:**构造方法调用,字段的设置和获取,方法的调用,方法的执行,异常的处理执行,类的初始化。**也就是说在AOP的概念中我们可以在上面的这些Joinpoint上织入我们自定义的Advice,但是在Spring中却没有实现上面所有的joinpoint,确切的说,Spring只支持方法执行类型的Joinpoint。 AOP在开发中的使用 4.1XML配置AOP的详解 关于pointcut的example:其中(.)代表任意,流程是:返回类型.哪个包下的.哪个类.哪个方法.哪个参数` <aop:pointCut id = "sakura" expression = "

微软官方补丁下载

微软官方补丁综合查找: 安全更新程序指南 - Microsoft 微软官方补丁单个查找: 根据具体升级代码查找gMicrosoft Update Catalog

ZYNQ AXI GPIO

***AXI GPIO 😗**AXI GPIO是一个软核,ZYNQ芯片在出厂时并不存在这样的硬件电路,是由用户通过配置PL端的逻辑资源来实现的一个功能模块。 添加AXI GPIO IP核 配置AXI_GPIO IP核 点击自动连接 连接完成: 连接AXI GPIO 中断 双击ZYNQ IP 核 打开配置界面配置 PL to PS IRQ0 为 1点ok 将这两个连接 连接完成后Ctrl + S 保存 之后点击验证 输出之后 通过XDC文件进行引脚绑定 绑定引脚时 引脚名字要使用顶层文件中的引脚名 #压缩比特流文件 set_property BITSTREAM.GENERAL.COMPRESS TURE [current_design] #约束PL引脚 set_property PACKAGE_PIN AF12 [get_ports {AXI_GPIO_KEY_tri_io[0]}] #约束PL引脚电平 set_property IOSTANDARD LVCMOS33 [get_ports {AXI_GPIO_KEY_tri_io[*]}] 编译并生成比特流文件 导出XSA文件(包含比特流文件) 创建VITIS工程(步骤略) 代码编写 #include "xparameters.h" //器件参数信息 #include "xgpiops.h" //包含PS GPIO的函数声明 #include "xstatus.h" //包含XST_FAILURE和XST_SUCCESS的宏定义 #include "xplatform_info.h" #include <xil_printf.h> //包含print()函数 #include "

【困惑实验记录】用cv2和PIL取出的像素值为何不同?cv2读出的是颜色三元组,PIL的getpixel是读取出该位置的实际像素值(该点存放的值)

结论(不一定正确,暂是个人理解) PIL会自行判断出图像的模式是:1、L、P、RGB等哪一种(依次为二值图,灰度图,调色板图,真彩图),然后再调用image.getpixel((x,y))函数,则可得到该图该点的值,也就是图像中的真值(这个值不一定是反应到现实世界的像素色彩值,尤其是对于P模式尤为明显。在P模式中的这个值是映射到某一像素值的index,而且是P模式图像本身是8bit单通道图像,但是如果用cv2去逐像素读取像素值,会发现是正常的3元组像素值) cv2是会读出该图该点的颜色三元组,所以不管图像是什么模式的(P、L、RGB等)、多少bit的图(P、L:8bit,RGB:24bit),用cv2.imread(),注意是没有转成灰度图而是直接BGR读入的,反映出来的都是颜色三元组(三元组的顺序是BGR,记得要用image = image[...,::-1]来反一下变为RGB顺序) 当mode=RGB时,像素值与颜色三元组相同当mode=P时,像素值是colormap中的index,但是cv2读出来的就是映射出来的真实颜色值,例如当前位置的像素值是6时,对应的就是index=6时的真实颜色值(128, 0, 0),可移步看另一篇博文:【困惑实验记录】调色盘,即PIL读出的P模式,常用于语义分割标签格式。1)如何固定设置某些index的颜色?2)怎么查看调色盘颜色?3)不设置调色盘颜色的话,是否每次都会转成不同的颜色?当mode=L时,颜色三元组中的每个值都是当前的像素值。例如像素值=100,那么cv2读出的颜色三元组就是(100, 100, 100) 实验代码 def getpixel_count(path): image = Image.open(path) # print(image.mode) # P arr = [] for w in range(image.size[0]): for h in range(image.size[1]): p = image.getpixel((w, h)) if p not in arr: arr.append(p) print(arr) # 统计调色板情况 palette = image.getpalette() # 获取调色板 count = Counter(np.array(image).flatten()) print(count) return arr, count def getpixel_cv(image_gray): arr = [] dim = image_gray.ndim height, width = image_gray.shape[:2] for h in range(height): for w in range(width): if dim == 3: # 如果是3维图像,即RGB,则倒一下才是正确的RGB顺序 p = image_gray[h, w] p = (p[.

C#基础语法知识

复杂数据类型 1.概述 普通数据类型: 无符号变量:byte、ushort、uint、ulong 有符号变量:sbyte、short、int、long 浮点数:float、double、decimal 特殊类型:bool、char、string 复杂数据类型: 数据集合:一般是由多个数据或者变量集合在一起构成 自定义数据:一般是自己可以取名字并且可以自定义的数据 类型特点: 枚举:整形常量的集合,可以自定义 数组:任意变量类型顺序存储的数据 结构体:任意变量的数据集合,可以自定义 2.枚举 枚举是一个很特别的存在,它是一个被命名的整型常量的集合,我们一般用它来表示状态、类型等等。 申明枚举和申明枚举变量不同,申明枚举相当于创建一个自定义的枚举类型。而申明枚举变量是使用申明的自定义枚举类型来创建一个枚举变量 枚举大多与条件分支语句配合使用,比如switch,if ...else...等等。枚举可在namespace语句块或者class语句块或者struct语句块中申明,但一般都在namespa中申明,切记不可在函数语句块中申明。申明枚举时,枚举名应以E或者E_开头,定义枚举名时,如果不赋值,第一个枚举项的默认值为0,然后依次累加。 枚举可以与int类型和string类型相互转换,但是不可强行转换,需要利用特殊方法进行转换。枚举在游戏开发中,可以帮助我们更加清晰的了解代码的内容,来了解代码的具体含义。 3.数组 数组时存储一组相同类型数据的集合,数组分为一维、多维、交错数组,一把情况我们将一维数组简称为数组。简单来讲,数组时一种用于存放同一类数据的容器。 数组(一维)的申明方式(所有的变量类型皆可申明为数组): int[] array; array = new int[5];int[] array = new int[5];int[] array = new int[5]{1,2,3,4,5};int[] array = new int[]{1,2,3,4,5};int[] array = {1,2,3,4,5}; 二维数组是使用两个索引来确定元素的数组,这两个索引可以理解为X轴和Y轴。二维数组一般用于存储矩阵,例如可以在控制台小游戏中使用二位数组来表示地图格子。 交错数组是数组的数组,每个维度的数量可以不相同。其中二维数组每行的列数相同,交错数组每行的列数可能不同。交错数组可以用来存储同一类型的确定行不确定列的数据。 值类型和引用类型: 值类型:整形、浮点数、char、bool、结构体 引用类型:string、数组(一维、二维、交错)、类 值类型在相互赋值时,将内容拷贝给了对方;而引用类型在相互赋值时,会让双方指向同一个值。值类型和存储类型存储在内存区域是不同的,存储方式也是不同的,这就导致了双方在使用上产生了区别:值类型存储在栈空间,由系统分配,自动回收,数据量小,传输速度快;而引用类型存储在堆控件,需要手动申请和释放,数据量大,传输速度慢。 string虽然属于引用类型,但是它在拷贝内容时,和值类型相同。因为在C#中,string具备了值类型的特征。虽然string使用比较方便,但是在改变string时需要频繁的赋值,会产生大量的内存垃圾。 4.函数 函数也称方法,函数的本质时一块具有名称的代码块,可以使用函数的名称来执行这一代码块。函数通常用于封装代码,提升代码的复用率,也可以用于抽象行为。 函数我们一般用在class语句块或者strust语句块中,函数基本语法为: static 返回类型 函数名(参数类型 参数名,参数类型 参数名,...) { 函数的代码逻辑; 函数的代码逻辑; ... return 返回值;(如果有返回类型才返回) } 语法要求: 1.static不是必须的; 2.返回类型需要引用一个新的关键字,返回类型可以写任意的变量类型;

帧率与曝光的时间对于手机屏幕采集图像的影响

图像的采集过程 图像的采集大致可以分为以下两个阶段:曝光时间以及图像的读取时间,所以采集一幅图像的时间,可以近似地认为是 Frame Period = Exposure Time +Readout Time 根据两种排布方式的不一致有两种常见的方法:“non-overlapped”的曝光和“overlapped”的曝光。 1.non-overlapped 在非重叠(“non-overlapped”)模式中,每个图像采集的周期中,相机在下一个图像采集开始前,均要完成曝光 2.overlapped 为了提高相机的帧率,允许在下一帧图像开始曝光时候,将前一帧获得的图像数据读出并传送出去。相机“重叠”(“overlapped”)曝光的方式见图2所示。 帧率 相机的帧率表示图形处理器处理场时每秒钟能够更新的次数。注意:一般情况下,相机的帧率是相机读取图像的时间。若我们的相机的帧率为15fps,则表示相机ReadOut数据的时间为1000ms/15 =66.7ms。 帧率越大一般来说图像的流畅性越好,但是手机的屏幕同样也有一定的帧率,通常来说由于视觉残留的影响,人眼当达到16fps的时候可以认为图像是连贯的。手机的刷新屏幕的频率常见的有60hz,120hz等 曝光时间 曝光时间是指光投射到感光材料上的时间,也是快门所打开的时间。当曝光时间越长时,成像的图片越亮。可以用下图来表达曝光时间 1.当降低曝光时间时 当fps设置为11fps,曝光时间设置为50000us,即图像到感光芯片的频率为20hz,可以看到成像较为稳定 当fps设置为11fps,曝光时间设置为40000us,即图像到感光芯片的频率为25hz,可以看到成像也较为稳定 当fps设置为11fps,曝光时间设置为30000us,即图像到感光芯片的频率为33hz,成像开始变暗,但还是较为稳定 当fps设置为11fps,曝光时间设置为10000us,即图像到感光芯片的频率为100hz,成像更暗,开始出现条纹 当fps设置为11fps,曝光时间设置为5000us,即图像到感光芯片的频率为200hz,成像模糊,条纹明显 2.当降低帧率时 当fps设置为11fps,曝光时间设置为7000us可以看到成像模糊 当fps设置为10fps,曝光时间设置为7000us可以看到成像模糊 当fps设置为8fps,曝光时间设置为7000us可以看到成像模糊(截屏的图片不够明显,但仍然效果不好) 当fps设置为4fps,曝光时间设置为7000us可以看到成像模糊,屏幕变化较慢,成像较差 结论 可以看出曝光时间的设置会影响传输图片的整体帧率,曝光时间设置越大,帧率越低,但是帧率高时屏幕切换的显示效果也越好。但是同时由于手机有刷新频率,如果缩短曝光时间可以明显发现手机在刷新图片,对于图片的采集影响较大,所以可以设置成一个高帧率,高曝光时间对于采集图片的效果较好。

DW PCIE 的Register Module, LBC, and DBI章节学习笔记

SPIN互斥锁很好的链接 文章起源 PCIE的使用SPIN解决IP的LBC没有使用专用总线导致中断冲突问题的软件避归方案(特殊芯片使用)。后续再编写C语言的驱动程序时对IP的Register Module, LBC, and DBI章节进行一学习并记录学习理解和心得。 寄存器说明 Capability ID汇总 Capabilities结构说明 在初次看寄存器文档的时候比较容易迷糊。CAP 寄存器即对应功能的Capability(能力)说明,对应的地址都是B+0x** 容易让人迷糊。每个Resiters的描述内部都有个Capability指向下一个,每个CAP都有自己特定的ID号,对应固定的长度所以程序可以通过一个个的偏移量找到下个CAP从而完成全部的查找。 CAP的地址说明 PCI-X 和PCIe 总线规范要求其设备必须支持Capabilities 结构。在PCI 总线的基本配置空间中,包含一个Capabilities Pointer 寄存器,该寄存器存放Capabilities 结构链表的头指针。在一个PCIe 设备中,可能含有多个Capability 结构,这些寄存器组成一个链表,如下图所示。 其中每一个Capability 结构都有唯一的ID 号,每一个Capability 寄存器都有一个指针,这个指针指向下一个Capability 结构,从而组成一个单向链表结构,这个链表的最后一个Capability 结构的指针为0。链表开始的指针地址为0x34处的1byte数值,寻址过程如下。注意对应的偏移地址是绝对地址,不是从本身CAP计算的偏移地址。 相关说明链接 比如下面的读取 0X34->0X40(bit8-16)->0X50(bit8-16)->0X70(bit8-16)->0XD0(bit8-16) 在0XD0 对应下一个CAP地址为0,在这结束了CAP. [0000] abcd16c3 00100107 06040001 00010000 [0010] 00000000 00000000 00ff0100 20000000 [0020] 00000000 00010001 00000000 00000000 [0030] 00000000 00000040 00000000 000001ff [0040] 5bc35001 00000008 00000000 00000000 [0050] 038a7005 00000000 00000000 00000000 [0060] 00000000 00000000 00000000 00000000 [0070] 0042d010 00008021 00002110 00534842 [0080] 30420000 0006007f 004003c0 00000000 [0090] 00000000 80000410 00000000 80000006 [00a0] 40000002 00000000 00000000 00000000 [00b0] 00000000 00000000 00000000 00000000 [00c0] 00000000 00000000 00000000 00000000 [00d0] 00000003 00000000 00000000 00000000 [00e0] 00000000 00000000 00000000 00000000 [00f0] 00000000 00000000 00000000 00000000 我使用的芯片当切换到访问RC本身寄存器的时候对应地址列表:

c语言——入门级学生管理系统(只对基本信息操作)

目录 简介 完整代码 基本思路 简介 创建学生结构体数组(结构成员名称如下) 学号 char sno[10]; 姓名 char sname[5]; 年龄 int sage; 性别 char ssex[4]; 电话 char stel[15]; 实现功能:写多个函数,独立完成各个功能 录入学生 函数Add(); 按照学号删除学生 函数Delete(); 按照名字查找学生 函数Search(); 按照学号修改学生信息 函数Modify(); 完整代码 #include<stdio.h> #include<conio.h>//getch()的函数库。该函数可以接收单字符,无需按回车键就可自动结束 int num=1000;//学生数量 struct student{ char sno[10];//学号。如B22040_0_ 加一个\0,共10位 char sname[5];//名字。最多四个字吧? int sage;//年龄 char stel[15];//电话。数字较大,不方便用整型,一般号码11位,15凑个整而且以防意外 char ssex[4]; }students[1000];//暂定学生人数1000,每个学生对应一个结构体 void Add()//录入学生信息 { int i; char judge; for(i=0;i<num;i++) { printf("录入第%d名学生信息:\n",i+1); printf("请输入姓名\n"); scanf("%s",&students[i].sname); getchar(); printf("请输入学号\n"); scanf("%s",&students[i].sno); getchar(); printf("请输入年龄\n"); scanf("%d",&students[i].sage); getchar(); printf("请输入电话\n"); scanf("

单片机编程软件有哪些?

单片机作为现代智能电子产品的核心元器件,具备可编程的特性,产品想要实现某些功能,除了设计电路之外,还需要带有程序的单片机。单片机编程就是单片机软件开发,需要使用编程语言和编程软件。单片机编程语言我们之前有讲到过,常用的是汇编语言和C语言,那么单片机编程软件有哪些?这篇文章将带领大家一起来了解一下。 由于单片机的可编程性以及种类的多样性,加上很多行业都需要使用单片机,这使得单片机编程软件也复杂多样,甚至不同的单片机工程师可能使用不同的单片机编程软件。这里为大家介绍以下几种最常用的单片机编程软件,能够应付绝大多数产品的编程需求。 1、Keil 这个可以说是单片机编程初学者的必备工具,同时也是编程核心软件,除了能够用来编写和编译程序之外,还有一个非常重要的功能就是仿真,搭配上ST-Link或者其他的仿真器使用,可以帮助工程师快速定位程序BUG。 2、Notepad++ 这个软件适合用来找函数和变量,即便是一个代码量非常大的c文件,也能够迅速地找到。这里建议大家可以用Notepad++来编写和修改程序,然后用keil进行编译。 3、Altium Designer 这套软件通过把原理图设计、电路仿真、PCB绘制编辑、拓扑逻辑自动布线、信号完整性分析和设计输出等技术的完美融合,为设计者提供了全新的设计解决方案,使设计者可以轻松进行设计,熟练使用这一软件使电路设计的质量和效率大大提高。 4、Sscom串口调试软件 单片机开发每天都会用到的串口工具,Sscom可以说是个必备软件,支持多串口调试工具来调试蓝牙,能够显示串口信号,比如我们电脑增加了usb转串口设备,就可以在软件中看到串口信号。SSCOM支持110-256000bps波特率,软件支持范围非常广泛,据说可以调试中星九号升级小版。用户使用该软件可以设置数据参数,自由设置波特率,速度, 方向等操作。 单片机编程软件除了以上四个常用的之外,还有很多,但是大多数都是换汤不换药。在前期完全没有必要去装,能够掌握以上四种单片机编程软件,就能够应付绝大多数的产品开发了。

Linux守护进程的启动方法

“守护进程”(daemon)就是一直在后台运行的进程(daemon),通常在系统启动时一同把守护进程启动起来,本文介绍如何将一个 Web 应用,启动为守护进程。 一、问题的由来 Web应用写好后,下一件事就是启动,让它一直在后台运行,这并不容易,举例来说,下面是一个最简单的Node应用server.js,只有6行。 var http = require('http'); http.createServer(function(req, res) { res.writeHead(200, {'Content-Type': 'text/plain'}); res.end('Hello World'); }).listen(5000); 你在命令行下启动它。 $ node server.js 看上去一切正常,所有人都能快乐地访问 5000 端口了;但是,一旦你退出命令行窗口,这个应用就一起退出了,无法访问了,怎么才能让它变成系统的守护进程(daemon),成为一种服务(service),一直在那里运行呢? 二、前台任务与后台任务 上面这样启动的脚本,称为”前台任务”(foreground job)。它会独占命令行窗口,只有运行完了或者手动中止,才能执行其他命令,变成守护进程的第一步,就是把它改成”后台任务”(background job)。 $ node server.js & 只要在命令的尾部加上符号&,启动的进程就会成为”后台任务”。如果要让正在运行的”前台任务”变为”后台任务”,可以先按ctrl + z,然后执行bg命令(让最近一个暂停的”后台任务”继续执行)。 “后台任务”有两个特点。 1.继承当前session(对话)的标准输出(stdout)和标准错误(stderr)。因此,后台任务的所有输出依然会同步地在命令行下显示。 2.不再继承当前session的标准输入(stdin)。你无法向这个任务输入指令了。如果它试图读取标准输入,就会暂停执行(halt)。 可以看到,”后台任务”与”前台任务”的本质区别只有一个:是否继承标准输入。所以,执行后台任务的同时,用户还可以输入其他命令。 三、SIGHUP信号 变为”后台任务”后,一个进程是否就成为了守护进程呢?或者说,用户退出 session 以后,”后台任务”是否还会继续执行?Linux系统是这样设计的。 1.用户准备退出 session 2.系统向该 session 发出SIGHUP信号 3.session 将SIGHUP信号发给所有子进程 4.子进程收到SIGHUP信号后,自动退出 上面的流程解释了,为什么”前台任务”会随着 session 的退出而退出:因为它收到了SIGHUP信号。 那么,”后台任务”是否也会收到SIGHUP信号? 这由Shell 的huponexit参数决定的。 $ shopt | grep huponexit 执行上面的命令,就会看到huponexit参数的值。 大多数Linux系统,这个参数默认关闭(off)。因此,session 退出的时候,不会把SIGHUP信号发给”后台任务”。所以,一般来说,”后台任务”不会随着 session 一起退出。 四、disown 命令

23.STM32 I2C实验

1.I2C的通信协议 它是由数据线SDA和时钟SCL构成的串行总线,可发送和接收数据。在CPU与被控IC之间、IC与IC之间进行双向传送,高速IIC总线一般可达400kbps以上。 IIC是半双工通信方式。 1.空闲状态 SDA与SCL同时处于高电平状态时候为空闲状态 2.开始信号 当SCL为高电平期间,SDA由高电平到低电平的跳变,启动信号是一种电平跳变时序信号,而不是一个电平信号。 3.停止信号 当SCL为高电平期间,SDA由低电平到高电平的跳变。 4.应答信号 发送器每次发送一个字节,就在时钟脉冲9期间释放数据线,接收器会发送一个应答,高电平为无效应答,低电平为有效应答。 注意:在第9个信号时SDA需要拉低,而且确保在该时钟的高电平期间为稳定的低电平。 5.数据有效性 I2C总线进行数据转送时,时钟信号为高电平期间,数据线上的数据必须保持稳定,只有在时钟信号上的信号为低电平期间,数据线上的高电平或低电平在允许变化。 数据在SCL与上下降沿的时候需要已经稳定了 6.数据转输 在I2C总线上传送的每一位数据都有一个时钟脉冲相对应,即在SCL串行时钟的配合下,在SDA上逐位地串行传送每一位数据。数据位的传输是边沿触发。 2.I2C底层代码 1.初始化 void IIC_Init(void) { GPIO_InitTypeDef GPIO_Initure; __HAL_RCC_GPIOH_CLK_ENABLE(); //使能GPIOH时钟 //PH4,5初始化设置 GPIO_Initure.Pin=GPIO_PIN_4|GPIO_PIN_5; GPIO_Initure.Mode=GPIO_MODE_OUTPUT_PP; //推挽输出 GPIO_Initure.Pull=GPIO_PULLUP; //上拉 GPIO_Initure.Speed=GPIO_SPEED_FAST; //快速 HAL_GPIO_Init(GPIOH,&GPIO_Initure); IIC_SDA=1; //空闲的时候需要高电平 IIC_SCL=1; } 2.起始信号 当SCL为高电平期间,SDA由高电平到低电平的跳变,启动信号是一种电平跳变时序信号,而不是一个电平信号。 void IIC_Start(void) { SDA_OUT(); //sda线输出 IIC_SDA=1; IIC_SCL=1; delay_us(4); IIC_SDA=0;//START:when CLK is high,DATA change form high to low delay_us(4); IIC_SCL=0;//钳住I2C总线,准备发送或接收数据 } 3.停止信号 当SCL为高电平期间,SDA由低电平到高电平的跳变。 void IIC_Stop(void) { SDA_OUT();//sda线输出 IIC_SCL=0; IIC_SDA=0;//STOP:when CLK is high DATA change form low to high delay_us(4); IIC_SCL=1; delay_us(4); IIC_SDA=1;//发送I2C总线结束信号 } 4.

vue生命周期、vue请求、动画

一、生命周期 1.定义:从Vue实例创建、运行、到销毁期间,总是伴随着各种各样的事件,这些事件,统称为生命周期! 2.vue生命周期钩子函数:每个 Vue 实例在被创建时都要经过一系列的初始化过程——例如,需要设置数据监听、编译模板、将实例挂载到 DOM 并在数据变化时更新 DOM 等。同时在这个过程中也会运行一些叫做生命周期钩子的函数,这给了用户在不同阶段添加自己的代码的机会。 生命周期函数=生命周期事件=生命周期钩子 3、vue生命周期 (1)创建前:beforeCreate(){} 初始化尚未完成,data数据、methods方法都未挂载在vue实例上(一般用于页面重定向) (2)创建后:created(){} 第一个能够操作data数据的生命周期(一般用于接口请求+数据初始化) (3)挂载前:beforeMount(){} 虚拟DOM挂载前,此时页面元素尚未更新 (4)挂载后:mounted(){} 虚拟dom元素挂载后,如果需要操作dom,可以在此生命周期执行 (5)更新前:beforeUpdate(){} (6)更新后:updated(){} beforeUpdate和updated在页面初次渲染时并不执行,在更新时执行,故可执行0次或多次 (7)销毁前:beforeDestroy(){} 一般用于清除计时器 (8)销毁后:destroyed(){} 附:debugger 加入断点 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title></title> <script src="../lib/vue-2.4.0.js"></script> </head> <body> <div id='app'> <div> {{msg}}</div> <input type="text" v-model="msg"> </div> <script> const vm = new Vue({ el: '#app', data: { msg:'hello word!' }, methods: { }, // 初始化尚未完成,data数据,metheds方法都未挂在在vue实例上 // 一般用于页面重定向 beforeCreate(){ console.

Kali2022.3 vulhub靶场安装过程记录

前言: 用iso镜像安装过程出错了,后面下载这个文件(我不知道该怎么称呼!!)并压缩,虚拟机打开vmx格式的文件就可以啦 https://kali.download/virtual-images/kali-2022.3/kali-linux-2022.3-vmware-amd64.7z 默认账户密码均为kali 为了防止出错,改了字体大小后,做了快照,方便恢复捏~ 安装kali参考的大佬博客链接:下载安装最新kali虚拟机及切换中文方法_huayimu的博客-CSDN博客_怎么下载kali docker+vulhub安装过程 sudo su apt-get update(更新APT 因为更新软件时出错,所以开始换源: 参考的大佬博客链接:kali软件更新与更新失败问题解决_学会了再换名字的博客-CSDN博客_kali换源后更新出错 vim /etc/apt/sources.list 修改源 2、(键盘单击字母 "I" 就可以编辑文件了,编辑完成后先单击 "Esc" 键,再输入 ":wq" 后回车,就可以退出咯 #浙大 deb http://mirrors.zju.edu.cn/kali kali-rolling main contrib non-free deb-src http://mirrors.zju.edu.cn/kali kali-rolling main contrib non-free #东软大学 deb http://mirrors.neusoft.edu.cn/kali kali-rolling/main non-free contrib deb-src http://mirrors.neusoft.edu.cn/kali kali-rolling/main non-free contrib #重庆大学 deb http://http.kali.org/kali kali-rolling main non-free contrib deb-src http://http.kali.org/kali kali-rolling main non-free contrib #中科大 deb http://mirrors.ustc.edu.cn/kali kali-rolling main non-free contrib deb-src http://mirrors.ustc.edu.cn/kali kali-rolling main non-free contrib #阿里云 deb http://mirrors.

若依整合ureport2导出excel报错

若依整合ureport2 在本地导出没有问题,在服务器中的tomcat中导出Excel提示: “Handler dispatch failed; nested exception is java.lang.NoClassDefFoundError: org/apache/poi/POIXMLTypeLoader ” 解决办法: https://download.csdn.net/download/kay523393/86651368

Scratch 3的作品(sb3格式的文件)怎么生成可执行exe文件

Scratch 3的作品(sb3格式的文件)怎么生成可执行exe文件 Scratch 3.0和Scratch 2.0软件相比,界面和内部实现机制有了较大变化。 Scratch 3.0界面如下: 与以前2.0版本不同,Scratch3.0版本改用H5和JS语言编写;软件界面有较大变化,将变成编程序区块放在了中间,更有利于成品的预览,以及编程和实际图形的对比,减少了重复无效的点击率;Scratch3.0整合并添加了插件模块,使用的文字朗读插件、翻译插件、Makey Makey插件等等大大提高了成品的质量与丰富度;在Scratch 3.0中文版中你可以完全采用简体中文。 scratch项目(.sb格式)怎么生成可执行exe文件 制作完成的scratch项目(.sb格式)想要分享给更多的人,若想在没有安装scratch程序运行,或 只能让他人运行演示而不能看到代码,如何实现呢? 对于.sb2格式可以使用scratch2exe工具,安装完成后,运行软件,界面如下: 点击1找到刚才保存的小程序选择打开。 点击2,选择一个ico文件作为小程序的图标。 第三步点击小绿旗,完成以上三步操作,点击确定,此时你会发现电脑中多了一个可执行的exe文件。 双击这个exe文件,就可以正常出现游戏界面。 对于.sb3格式上述方法已经不能用。对于.sb3格式怎么生成可执行exe文件? Scratch3.0产生的文件是sb3文件,目前需要使用方法如下: 参考https://scratch.mit.edu/discuss/topic/341617/?page=1 先到https://nwjs.io/ 下载压缩包nwjs,如nwjs-v0.39.3-win-x64.zip,解压备用。 再到http://revocue.cz/en/make-sfx/index.php 下载makesfx.exe,(它不需要安装双击就运行)。 以下是将sb3转换为exe的步骤: 1.先转换为HTML5网页版本。打开https://sheeptester.github.io/words-go-here/scratch3-htmlifier/ 网站,Upload project上传本地sb3文件,或者先把本地sb3文件上传到mit scratch社区上,得到一个项目号Project ID。选择HTMLify without minification(recommended)如下图所示,完成后会下载得到文件project.html(这是网页版的)。 2.把下载的project.html移动到nwjs-v0.39.3-win-x64.zip解压后的目录。并在该目录下建立一个icon图标文件如a1.png,以及配置文件package.json文件(可以用记事本创建,注意文件的扩展名,如果含有中文字符,保存时编码选为UTF-8 如下图): package.json文件(其中的冒号引号等是英文的)内容包含:项目名字,主程序文件,图标,类似如: { "name": "您的应用程序或游戏名称", "main": "project.html", "icons": {"1":"a1.png"} } 注:“名称”和“图标”显示在窗口标题栏中。如果不用图标,则删除project.html后面的最后一个逗号和图标行,否则需要有一个png图标。 此时,双击运行nw.exe,就可以预览效果了(但还未实际产生出一个exe文件)。 要真正转换成的exe文件还需要进行下面的一步。 3.运行makesfx.exe,加入nw.exe,指定文件名和图标,制作成一个exe文件。参见下图: 说明: 1-源文件夹(可能包含子文件夹):包含nw.exe、package.json和所有其他文件的文件夹 2-目标SFX文件(exe文件):将在其中创建可执行文件 3-目标SFX文件图标:应用程序的图标。 4-提取后将运行的可执行文件:进入nw.exe和package.json所在的文件夹,选择nw.exe (其下命令行参数中不放置任何内容。) 5-UAC自动提升:(如果您不是管理员)建议您使用最高可用权限运行sfx。 您应根据实际情况填充内容,然后单击“MakeSfx”按钮,将构建一个可执行文件——exe文件,和原sb3文件相比,比较大。

工具类:JWT 工具类

import cn.hutool.core.date.DateField; import cn.hutool.core.date.DateTime; import com.xuecheng.system.commons.model.vo.AuthInfo; import io.jsonwebtoken.Claims; import io.jsonwebtoken.Jws; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.SignatureAlgorithm; import org.apache.commons.lang3.StringUtils; import javax.crypto.SecretKey; import javax.crypto.spec.SecretKeySpec; import java.util.Base64; import java.util.Map; /** * JWT 工具类 * 对JJWT的封装 */ public class JwtUtils { // 加密KEY private static final String TOKEN_ENCRY_KEY = "MDk4ZjZiY2Q0NjIxZDM3M2NhZGU0ZTgzMjYyN2I0ZjY"; /** * 加密token */ public static String createToken(Map<String, Object> claimMaps,int expire) { return Jwts.builder() .addClaims(claimMaps) .setExpiration(DateTime.now().offset(DateField.MINUTE,expire).toJdkDate()) .signWith(SignatureAlgorithm.HS256, generalKey()) .compact(); } /** * 由字符串生成加密key */ public static SecretKey generalKey() { byte[] encodedKey = Base64.