微信小程序列表页上拉加载更多数据-入门

onShow(){ this.getList() //也可以放在onLoad里面看实际需求 } getList() { util.request(api.teachPlanOwnList, { //这里是请求的接口和方式 不重要 userId: userInfo.userId, pageSize: pageSize, pageNum: pageNum, sortType: sortType }, 'POST').then(res => { // console.log(res); if (res.code == 200) { let list = this.data.planList.concat(res.rows.map(item=>{ //对数据做处理 不重要 let createTime = item.createTime.split(" ")[0].replace(/-/g, "."); item.createTime = createTime; if(!item.scheduledTime || item.scheduledTime == 'null'){ item.scheduledTime = '未安排时间' } return item; })); this.setData({ planList: list //这里是重点 }) // 判断是否加载完毕 if (list.length >= res.total) { //这里是重点 this.

python做简单的笑脸的编程,如何用python画一个笑脸

这篇文章主要介绍了python画笑脸步骤的中文翻译,具有一定借鉴价值,需要的朋友可以参考下。希望大家阅读完这篇文章后大有收获,下面让小编带着大家一起了解一下。 大家好,本文将围绕python画笑脸步骤的中文翻译展开说明,python做简单的笑脸的编程是一个很多人都想弄明白的事情,想搞清楚python画简单笑脸代码需要先了解以下几个事情。 用python的Turtle库画一个笑脸 最近刚了解到python的turtle库,就简单的尝试一下,画一个笑脸python编程代码中如何注释。 效果图: 效果图看起来和原图的差别还是有点大,但是没关系,这只是一个尝试而已如何安装python安装包。 附上代码: import turtle #导入库 turtle.TurtleScreen._RUNNING=True #用来避免xx问题,具体什么问题我忘记了 pen = turtle.Pen() pen.speed(10) #设置笔速度 #画外圆 pen.pencolor() #设置笔颜色 pen.penup() #提笔 pen.goto(0,-100) #移动位置 pen.pendown() #放笔 pen.begin_fill() #开始填充 pen.circle(100) #画半径为100的圆 pen.fillcolor("#FFFF00") #填充颜色 pen.end_fill() #结束填充 #画眼睛 def draweye(x): #画眼函数 pen.pencolor() pen.penup() pen.goto(x,0) pen.pendown() pen.begin_fill() pen.circle(25) pen.fillcolor("#F8F8FF") pen.end_fill() pen.begin_fill() pen.circle(15) pen.fillcolor("#000000") pen.end_fill() draweye(-40) #画左眼 draweye(40) #画右眼 #画嘴巴 pen.right(60) pen.penup() pen.goto(-65,-30) pen.pendown() pen.circle(75,120) #勾股定理求出75 #将画笔移动中间 pen.penup() pen.setheading(-90) pen.goto(0,-20) #结束画图 turtle.done() emm,我自己都觉得太难看了。

[SWPUCTF 2021 新生赛]hardrce

[SWPUCTF 2021 新生赛]hardrce wp 参考博客:https://www.cnblogs.com/bkofyZ/p/17644820.html 代码审计 题目的代码如下: <?php header("Content-Type:text/html;charset=utf-8"); error_reporting(0); highlight_file(__FILE__); if(isset($_GET['wllm'])) { $wllm = $_GET['wllm']; $blacklist = [' ','\t','\r','\n','\+','\[','\^','\]','\"','\-','\$','\*','\?','\<','\>','\=','\`',]; foreach ($blacklist as $blackitem) { if (preg_match('/' . $blackitem . '/m', $wllm)) { die("LTLT说不能用这些奇奇怪怪的符号哦!"); }} if(preg_match('/[a-zA-Z]/is',$wllm)) { die("Ra's Al Ghul说不能用字母哦!"); } echo "NoVic4说:不错哦小伙子,可你能拿到flag吗?"; eval($wllm); } else { echo "蔡总说:注意审题!!!"; } ?> 蔡总说:注意审题!!! 其中设置了一个黑名单 $blacklist 过滤了许多字符; 此外 preg_match('/[a-zA-Z]/is',$wllm) 过滤了所有大小写字母。 无字母 RCE 首先推荐一篇博客:老生常谈的无字母数字 Webshell 总结 。 无字母数字绕过,就是把非字母数字的字符经过各种转换,变为数字和字母。 由于黑名单中 ’ $ ’ , ’ ^ ‘,’ ` ’ ,’ "

git 分支的使用

参考 Git 分支 - 分支的新建与合并 1.创建分支 1.1 创建本地分支 创建本来不存在的分支 dev_test 并且切换到该分支 git checkout -b dev_test 等同于这两条命令: git branch dev_test git checkout dev_test 1.2 将本地分支推动到远程 将创建的本地分支推送到远程。这样,其他人也可以看到、操作这个分支了。 git push origin dev_test:dev_test 2.分支操作 2.1 拉取远程分支到本地 拉取远程分支(origin/dev_test) 到本地,本地就有了 dev_test 分支 git fetch origin dev_test:dev_test 2.2 将本地分支和远程分支关联 将本地分支和远程分支关联,这样本地分支在可以执行 git pull 、git push 等操作。 git branch --set-upstream-to=origin/dev_test dev_test 关联之后可以用 git branch -vv 、git branch -va 命令查看当前分支情况。 2.3 在分支上操作 分支上的提交方法和主分支一样。 2.4 分支的修改合并到主分支 回到主分支,然后使用 git merge 合并分支的修改

微信开发---------扫描二维码事情该怎么做?

目录 说明 微信公众号文档 表结构 思路 处理器 说明 本例基于wx-tools.jar 微信公众号文档 微信公众号文档告诉我们,是有两种扫描二维码事件的,如果是已经关注过公众号的,则是event=scan,如果没有关注过的,则是event=subscribe,他们的event是不同的. 我们在设计详细需求的时候一般是event=scan这种比较多的,比如扫描二维码后可以做什么.但也有event=subscribe这种需求情况,比如拉新用户扫描关注获得多少积分. 表结构 基础表有两张,其他随着需求的增加而看. 基础表wx_qr CREATE TABLE `wx_qr` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '自增id', `ticket` varchar(300) DEFAULT NULL COMMENT '二维码票据', `type` int(11) DEFAULT NULL COMMENT '二维码类型/枚举索引', `create_time` datetime DEFAULT NULL COMMENT '创建时间', `body` varchar(100) DEFAULT NULL COMMENT '携带的数据', `over` tinyint(1) DEFAULT NULL COMMENT '二维码是否关闭?当关闭时,就没有用了.', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=74 DEFAULT CHARSET=utf8 基础表wx_qr_user CREATE TABLE `wx_qr_user` ( `quid` int(11) NOT NULL AUTO_INCREMENT COMMENT '自增id', `qrid` int(11) DEFAULT NULL COMMENT '二维码id', `userid` int(11) DEFAULT NULL COMMENT '扫描的用户', `create_time` datetime DEFAULT NULL COMMENT '创建时间', `is_effective` tinyint(1) DEFAULT NULL COMMENT '扫描是否有效', PRIMARY KEY (`quid`) ) ENGINE=InnoDB AUTO_INCREMENT=54 DEFAULT CHARSET=utf8 扫码这个动作在后台是需要三步走的:1.

7个Python爬虫小案例,人人都能用到,适合零基础小白!

在这篇文章中,我们将分享7个Python爬虫的小案例,帮助大家更好地学习和了解Python爬虫的基础知识。以下是每个案例的简介和源代码: 1. 爬取豆瓣电影Top250 这个案例使用BeautifulSoup库爬取豆瓣电影Top250的电影名称、评分和评价人数等信息,并将这些信息保存到CSV文件中。 2. 爬取猫眼电影Top100 这个案例使用正则表达式和requests库爬取猫眼电影Top100的电影名称、主演和上映时间等信息,并将这些信息保存到TXT文件中。 3. 爬取全国高校名单 这个案例使用正则表达式和requests库爬取全国高校名单,并将这些信息保存到TXT文件中 4. 爬取中国天气网城市天气 这个案例使用xpath和requests库爬取中国天气网的城市天气,并将这些信息保存到CSV文件中。 5. 爬取当当网图书信息 这个案例使用xpath和requests库爬取当当网图书信息,并将这些信息保存到CSV文件中。 6. 爬取糗事百科段子 这个案例使用xpath和requests库爬取糗事百科的段子,并将这些信息保存到TXT文件中。 7. 爬取新浪微博 这个案例使用selenium和requests库爬取新浪微博,并将这些信息保存到TXT文件中。 Python经验分享 学好 Python 不论是就业还是做副业赚钱都不错,但要学会 Python 还是要有一个学习规划。最后给大家分享一份全套的 Python 学习资料,给那些想学习 Python 的小伙伴们一点帮助! 小编为对Python感兴趣的小伙伴准备了以下籽料 ! 对于0基础小白入门: 如果你是零基础小白,想快速入门Python是可以考虑培训的! 学习时间相对较短,学习内容更全面更集中可以找到适合自己的学习方案 包括:Python激活码+安装包、Python web开发,Python爬虫,Python数据分析,人工智能、机器学习、Python量化交易等学习教程。带你从零基础系统性的学好Python! 一、Python所有方向的学习路线 Python所有方向路线就是把Python常用的技术点做整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。 二、学习软件 工欲善其事必先利其器。学习Python常用的开发软件都在这里了,给大家节省了很多时间。 三、入门学习视频 我们在看视频学习的时候,不能光动眼动脑不动手,比较科学的学习方法是在理解之后运用它们,这时候练手项目就很适合了。 四、实战案例 光学理论是没用的,要学会跟着一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。 五、面试资料 我们学习Python必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有阿里大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。 我已经上传至CSDN官方,如果需要可以扫描下方官方二维码免费获取【保证100%免费】 *今天的分享就到这里,喜欢且对你有所帮助的话,记得点赞关注哦~下回见 !

Spring Boot整合MyBatis-Plus框架快速上手

最开始,我们要在Java中使用数据库时,需要使用JDBC,创建Connection、ResultSet等,然后我们又对JDBC的操作进行了封装,创建了许多类似于DBUtil等工具类。再慢慢的,出现了一系列持久层的框架:Hibernate、JPA和MyBatis等。 其实利用MyBatis 来进行持久层的开发已经大大减少了工作人员的工作量了,但它的使用还是需要一定的门槛的。Mybatis-Plus的出现,进一步降低了这道槛。那我们今天就来看看,Mybatis-Plus到底是如何进一步实现MyBatis的增强的。 1.MyBatis-Plus简介 MyBatis-Plus官网地址: https://baomidou.com MyBatis-Plus(简称MP)是一个MyBatis的增强工具,在MyBatis的基础上只做增强不做改变,为简化开发、提高效率而生。MP的愿景是成为MyBatis最好的搭档,就像魂斗罗中的1P、2P,基友搭配,效率翻倍。 MyBatis-Plus特性 无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑。损耗小:启动即会自动注入基本CURD,性能基本无损耗,直接面向对象操作。强大的CRUD操作:内置通用Mapper、通用Service,仅仅通过少量配置即可实现单表大部分CRUD操作,更有强大的条件构造器,满足各类使用需求。支持Lambda形式调用:通过Lambda表达式,方便的编写各类查询条件,无需再担心字段写错。支持主键自动生成:支持多达4种主键策略(内含分布式唯一ID生成器–Sequence),可自由配置,完美解决主键问题。支持ActiveRecord模式:支持ActiveRecord形式调用,实体类只需继承Model类即可进行强大的CRUD操作。支持自定义全局通用操作:支持全局通用方法注入(Write once, use anywhere)。内置代码生成器:采用代码或者Maven插件可快速生成Mapper、Model、Service、Controller层代码,支持模板引擎,更有超多自定义配置等您来使用。内置分页插件:基于MyBatis物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通List查询。分页插件支持多种数据库:支持MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、Postgre、SQLServer等多种数据库。内置性能分析插件:可输出SQL语句以及其执行时间,建议开发测试时启用该功能,能快速揪出慢查询。内置全局拦截插件:提供全表delete、update操作智能分析阻断,也可自定义拦截规则,预防误操作。 支持数据库 任何能使用MyBatis进行CRUD,并且支持标准SQL的数据库,具体支持情况如下: MySQL,Oracle,DB2,H2,HSQL,SQLite,PostgreSQL,SQLServer,Phoenix,Gauss ,ClickHouse,Sybase,OceanBase,Firebird,Cubrid,Goldilocks,csiidb。达梦数据库,虚谷数据库,人大金仓数据库,南大通用(华库)数据库,南大通用数据库,神通数据库,瀚高数据库。 使用SpringBoot整合MyBatis-Plus MyBatis-Plus部署配置 1.引入依赖。在pom.xml文件中添加Mybatis-Plus依赖。 <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!-- MyBatis依赖启动器 --> <!-- <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.2.0</version> </dependency> --> <!-- MySQL数据库连接驱动 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <!-- 阿里巴巴的Druid数据源依赖启动器 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.1.17</version> </dependency> <!-- 添加Mybatis-Plus依赖 --> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.5.2</version> </dependency> </dependencies> 2.编写实体类。在springbootdata数据库中创建products商品信息表并插入数据。 CREATE TABLE t_product ( id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(50), #商品名称 price DOUBLE, flag VARCHAR(2), #上架状态 goods_desc VARCHAR(100), #商品描述 images VARCHAR(400), #商品图片 goods_stock INT, #商品库存 goods_type VARCHAR(20), #商品类型 created_user VARCHAR(20) COMMENT '日志-创建人', created_time DATETIME COMMENT '日志-创建时间', modified_user VARCHAR(20) COMMENT '日志-最后修改执行人', modified_time DATETIME COMMENT '日志-最后修改时间' ); INSERT INTO t_product VALUES ( NULL, 'HUAWEI P60', 6999, '1', '华为P60 5G手机 分期 麒麟990 晨曦金 8+256GB', 'https://img14.

PTA 最小生成树-kruskal

7-92 最小生成树-kruskal 分数 10 全屏浏览题目 作者 任唯 单位 河北农业大学 题目给出一个无向连通图,要求求出其最小生成树的权值。 温馨提示:本题请使用kruskal最小生成树算法。 输入格式: 输出格式: 输出一个整数表示最小生成树的各边的长度之和。 输入样例: 4 5 1 2 2 1 3 2 1 4 3 2 3 4 3 4 3 输出样例: 7 代码长度限制 16 KB 时间限制 500 ms 内存限制 64 MB 代码分享及思路分享: #include <iostream> #include<bits/stdc++.h> #include <algorithm> using namespace std; struct edge{ int u,v; int value; }s[1000001]; int f[1000001];//用f数组的下标和对应存储的值来判断是否已经连通 int find(int x){ if(x!=f[x]) return f[x]=find(f[x]); return f[x]; }//调用递归 bool cmp(edge a,edge b){ return a.

【面试】前端面试八股文

前端思维导图优点大可爱html+css+js+node全面可下载千峰html+css简洁漂亮千峰js简洁漂亮 一、JS 1、使用 (1)标签引用 <script> alert("Hello,World!"); </script> (2)文件引用 <script src="main.js"></script> 2、特点 解释型语言:JS不需要被编译为机器码而是直接执行,开发轻松动态型语言:JS变量与任何值类型都不关联,都可以重新分配类型值弱类型语言:变量数据类型不确定,赋值后定义。当操作涉及不匹配的类型时,允许隐式转换基于原型的面向对象严格区分大小写 3、标识符 标识符:指给变量、函数、属性或函数参数起名字要求: 第一个字符必须是字母、下划线( _ )或美元符号( $ )其它字符可以是字母、下划线、美元符号或数字按照惯例,ECMAScript 标识符采用驼峰命名法标识符不能是关键字和保留字符 4、数据类型 (1)数据类型 简单/基本数据类型:在存储变量中存储值本身,因此也叫值类型,存放到栈(空间) 名称类型值String字符串型‘123’Number数值型123Boolean布尔型true/falseNullnull型空UndefinedUndefined型未定义SymbolSymbol型Symbol() 生成唯一值Bigint整数型大整数 复杂数据类型:在存储变量中存储地址,因此也叫引用数据类型,存放到堆(空间) 通过new关键字创建的对象(系统对象、自定义对象) 名称类型值Object对象{ “key”:“value” }Array数组[…]Function函数fn()Date日期函数new Date()Math数学公式MathRegExp正则new RegExp(“正则表达式”, “匹配模式”) (2)类型判断 typeof obj:不适用复杂类型判断,多显示object console.log(typeof "123") // string console.log(typeof 123) // number console.log(typeof true) // boolean console.log(typeof undefined) // undefined console.log(typeof null) // object => 所有值均32位,最低的3位表示数据类型,null全部为0,而object前三位是000 obj instanceof Object :不适用基本类型判断 console.log([1, 2] instanceof Array) // true console.log(function(){} instanceof Function) // true console.

如何优雅的写 Controller 层代码?

📌 原文链接: https://mp.weixin.qq.com/... 目录 前言Controller 层参数接收统一状态码统一校验统一响应统一异常 前言 本篇主要要介绍的就是 controller 层的处理,一个完整的后端请求由 4 部分组成: 接口地址(也就是 URL 地址)请求方式(一般就是 get、set,当然还有 put、delete)请求数据(request,有 head 跟 body)响应数据(response) 本篇将解决以下 3 个问题: 当接收到请求时,如何优雅的校验参数返回响应数据该如何统一的进行处理接收到请求,处理业务逻辑时抛出了异常又该如何处理 Controller 层参数接收(太基础了,可以跳过) 常见的请求就分为 get 跟 post 两种: @RestController @RequestMapping("/product/product-info") public class ProductInfoController { @Autowired ProductInfoService productInfoService; @GetMapping("/findById") public ProductInfoQueryVo findById(Integer id) { ... } @PostMapping("/page") public IPage findPage(Page page, ProductInfoQueryVo vo) { ... } } RestController:之前解释过,@RestController=@Controller+ResponseBody。 加上这个注解,springboot 就会吧这个类当成 controller 进行处理,然后把所有返回的参数放到 ResponseBody 中。 @RequestMapping:请求的前缀,也就是所有该 Controller 下的请求都需要加上 /product/product-info 的前缀。

Docker Compose

Docker Compose 1.安装 Docker Compose2.编写 Compose 文件3.启动、停止、恢复服务4.构建和升级服务 Docker 是一个开放源代码的应用程序容器引擎,可以帮助用户轻松地打包、分发和运行任何应用程序,并且具有开发效率高、部署便捷等优点。 Docker Compose 是 Docker 的一个子项目,可以帮助用户定义和运行多容器 Docker 应用程序。使用 Docker Compose 可以更轻松地管理多个容器的应用程序,例如在本地或云平台上构建和部署微服务应用程序。 参考链接 https://zhuanlan.zhihu.com/p/620097083 1.安装 Docker Compose 在使用 Docker Compose 之前,您需要先安装 Docker 引擎。 然后,您可以通过以下步骤来安装 Docker Compose: 打开官方文档 Docker Compose Releases (https://github.com/docker/compose/releases) 找到适合您服务器系统的版本进行下载。 服务器一般都是时linux系统的 下载后传到虚机一定要 改名字成docker-compose!!! 上传docker-compose到 /usr/local/bin/路径 赋予权限:chmod +x /usr/local/bin/docker-compose 验证是否成功安装docker-compose:docker-compose -v 2.编写 Compose 文件 Docker Compose 使用 YAML 文件来定义应用程序的组件和它们之间的联系。下面是一个使用 Docker Compose 启动 web 应用程序的样例文件: version: '3' services: web: image: nginx ports: - "

十:爬虫-多线程

一:进程与线程 1.什么是进程? 电脑中时会有很多单独运行的程序,每个程序有一个独立的进程 而进程之间是相互独立存在的,比如下标中的QQ播放器、小鹅通等等 2.什么是线程? 进程可以简单的理解为一个可以独立运行的程序单位,它是线程的集合,进程就是有一个或多个线程构成的。 而线程是进程中的实际运行单位,是操作系统进行运算调度的最小单位。 可理解为线程是进程中的一个最小运行单元。 3.什么是多进程? 同理,多进程就是指计算机同时执行多个进程,一般是同时运行多个软件 4.什么是多线程? 提到多线程这里要说两个概念,就是串行和并行搞清楚这个,我们才能更好地理解多线程: 串行: 所谓串行,其实是相对于单条线程来执行多个任务来说的, 我们就拿下载文件来举个例子:当我们下载多个文件时,在串行中它是按照一定的顺序去进行下载的, 也就是说,必须等下载完A之后才能开始下载B,它们在时间上是不可能发生重叠的。 并行: 下载多个文件,开启多条线程,多个文件同时进行下载, 这里是严格意义上的,在同一时刻发生的,并行在时间上是重叠的。 #简单了解了这两个概念之后,我们再来说说到底什么什么是多线程? 举个例子,我们打开腾讯管家,腾讯管家本身就是一个程序,也就是说它就是一个进程,它里面有很多的功能,我们可以看下图,能查杀病毒、清理垃圾、电脑加速等众多功能。 按照单线程来说,无论你想要清理垃圾、还是病毒查杀,那么你必须先做完其中的一件事,才能做下一件事,这里面是有一个执行顺序的。 如果是多线程的话,我们其实在清理垃圾的时候,还可以进行查杀病毒、电脑加速等等其他的操作,这个是严格意义上的同一时刻发生的,没有执行上的先后顺序。 简单理解为:多线程就是指一个进程中同时有多个线程正在执行。 二:多线程爬虫 由于外部网络不稳定,在使用单线程爬取网页数据时,如果有一个网页响应速度慢或者卡住了,那整个程序都要等待下去,这显然是无效率的。因此,我们可以使用多线程、多进程、协程技术来实现并发下载网页。 那么,在Python中多线程、多进程和协程应该如何选择呢? 一般来说,多进程适用于CPU密集型的代码,例如各种循环处理、大量的密集并行计算等。多线程适用于I/O密集型的代码,例如文件处理、网络交互等。协程无需通过操作系统调度,没有进程、线程之间的切换和创建等开销,适用于大量不需要CPU的操作,例如网络I/O等。 实际上,限制爬虫程序发展的瓶颈就在于网络I/O,原因是网络I/O的速度赶不上CPU的处理速度。结合多线程、多进程和协程的特点和用途,我们一般采用多线程和协程技术来实现爬虫程序。 1.多任务基本介绍 有很多的场景中的事情是同时进行的,如开车的时候 手和脚共同来驾驶汽车,再比如唱歌跳舞也是同时进行的 程序中模拟多任务: import time def sing(): for i in range(3): print("正在唱歌... %d"%i) time.sleep(1) def dance(): for i in range(3): print("正在跳舞...%d"%i) time.sleep(1) if __name__ == '__main__': sing() dance() 2.多线程的创建 (1)通过函数来创建 1 通过函数来创建 通过threading模块当中的一个Thread类,有一个target参数。这个参数需要我们传递一个函数对象。这个函数就可以实现多线程的逻辑 def Demo01(): print('hello 子线程') if __name__ == "

【开题报告】基于Spring Boot的传统服饰宣传网站设计与实现

1.研究背景和意义 研究背景: 随着社会的进步和时代的发展,传统服饰逐渐被现代服饰所取代,年轻一代对传统服饰的了解和认同度不高。很多传统服饰面临着失传的风险,其所承载的文化和历史价值也可能因此而逐渐消失。因此,设计和实现一个基于Spring Boot的传统服饰宣传网站具有重要的研究背景。 研究意义: 传统服饰作为一个国家或地区的文化遗产,具有独特的历史和艺术价值。通过设计和实现一个基于Spring Boot的传统服饰宣传网站,可以达到以下几个方面的意义: (1)传播传统服饰文化:网站可以通过展示传统服饰的图片、介绍、历史背景等信息,向用户传达传统服饰的美丽和文化内涵。让更多的人了解和认识传统服饰,增加对传统服饰的兴趣和认同,推广传统服饰文化。 (2)保护传统服饰的独特价值:通过宣传网站,可以提高人们对传统服饰的认识和重视程度,加强对传统服饰文化的保护意识。保护传统服饰的独特价值和魅力,促进其在现代社会中的传承和发展。 (3)提升传统服饰的影响力:通过网站的用户评论、分享、在线购买等功能,增加用户参与度,提升传统服饰的影响力。激发人们对传统服饰的兴趣和热情,为传统服饰的发展注入新的活力。 (4)促进文化交流和传承:宣传网站可以打破地域限制,让更多的人了解和接触到不同地区的传统服饰。促进不同文化之间的交流和借鉴,推动传统服饰文化的传承和创新。 总之,基于Spring Boot的传统服饰宣传网站的设计和实现具有重要的研究背景和意义,可以有效推广传统服饰文化,增加年轻人对传统服饰的兴趣和认识,保护和传承传统服饰的独特价值和魅力。 2.研究目标 本项目的主要目标是设计和实现一个基于Spring Boot的传统服饰宣传网站,通过展示传统服饰的图片、介绍、历史背景等信息,向用户传达传统服饰的美丽和文化内涵。同时,通过交互式的功能模块,如用户评论、分享、在线购买等,增强用户参与度,提升传统服饰的影响力。 具体目标如下: (1)明确网站的功能需求和用户需求,包括展示传统服饰的图片、简介和详细信息、提供用户评论和分享功能、提供在线购买传统服饰的功能等。 (2)选择适合的技术栈,如Spring Boot作为主要框架、MySQL作为数据库、Thymeleaf作为模板引擎、Bootstrap作为前端框架等。 (3)设计网站的系统架构,包括前端页面设计、后端接口设计、数据库设计等。 (4)使用Spring Boot进行开发,实现网站的各个模块和功能。 (5)进行功能测试、性能测试和安全性测试,并根据测试结果进行系统优化。 (6)将网站部署到服务器上,并确保网站的稳定运行。 通过实现以上目标,我们可以成功设计和实现一个基于Spring Boot的传统服饰宣传网站,提高人们对传统服饰的认识和重视程度,促进传统服饰文化的传承和发展,推广传统服饰文化,增加年轻人对传统服饰的兴趣和认识,保护和传承传统服饰的独特价值和魅力。 3.国内外研究现状 目前国内外关于基于Spring Boot的传统服饰宣传网站设计与实现的研究还比较有限,以下是一些相关研究现状: (1)国内传统文化网站设计及实现的研究:如《基于JSP的中国传统文化网站设计与实现》(王春兰,2014)、《传统文化数字化展示网站的设计与实现》(李雪梅,2015)等。这些研究主要探讨了传统文化网站的设计和实现,但没有具体涉及到传统服饰方面的内容。 (2)国外服饰文化网站的研究:如《Online Exhibition System for Traditional Costumes Based on Virtual Environment》(Abdulaziz Alomair,2018)和《Preserving Traditional Textile Heritage Through Digital Archiving and Online Exhibitions》(Pallavi Kharade,2019)等。这些研究主要探讨了虚拟环境下的传统服饰展示和数字化保存,但没有涉及到基于Spring Boot的传统服饰宣传网站的设计与实现。 (3)国内外基于Spring Boot的电商网站设计研究:如《基于Spring Boot的电商网站的设计与实现》(吴茜,2019)、《基于Spring Boot的B2C电子商务网站设计与实现》(刘涛,2020)等。这些研究主要探讨了电商网站的设计和实现,但没有具体涉及到传统服饰方面的内容。 综上所述,目前关于基于Spring Boot的传统服饰宣传网站设计与实现的研究还比较有限,需要进一步深入探讨和研究。 4.研究内容和方法 基于Spring Boot的传统服饰宣传网站设计与实现的研究内容和方法包括以下几个方面: (1)网站需求分析:首先需要对传统服饰宣传网站的功能需求进行详细分析,包括展示传统服饰的图片、介绍、历史背景等信息,提供用户评论和分享功能,提供在线购买传统服饰的功能等。 (2)技术选型:选择适合的技术栈用于开发,如Spring Boot作为主要框架、MySQL作为数据库、Thymeleaf作为模板引擎、Bootstrap作为前端框架等。同时,还需要考虑到网站的安全性和性能问题。 (3)系统架构设计:设计网站的系统架构,包括前端页面设计、后端接口设计、数据库设计等。需要根据需求分析的结果来确定网站各个模块之间的关系和交互方式。 (4)功能开发与实现:基于Spring Boot框架进行开发,实现网站的各个功能模块,如用户注册登录、传统服饰展示、用户评论和分享、在线购买等。在开发过程中需要注意代码的可维护性和可扩展性。 (5)测试与优化:进行功能测试、性能测试和安全性测试,确保网站的各个功能正常运行,并根据测试结果进行系统优化,提高网站的性能和用户体验。

(04730)半导体器件之基本放大器工作原理(二)

共集电极放大电路 电路的组成 在晶体三极管组成的放大电路中,将集电极作为输入和输出信号的公共端,输入电压从基极对地(集电极)之间输入,输出电压从发射极对地(集电极)之间取出,这种放大电路称为共集电极放大电路,简称共集放大电路,电路的组成如图2.2.23所示。由于从发射极对地输出信号,因此又称为射极输出器。 工作原理 (1)静态分析 由图2.2.23共集放大电路图画出其直流通路如图2.2.24所示。 (2)动态分析 共集放大器的交流通路和微变等效电路分别如图2.2.25和图2.2.26所示。 综上所述,共集放大电路具有电压放大倍数小于1(近似等于1)、输出电压与输入电压同相位、电压跟随特性好、输入电阻高、输出电阻低、有电流放大和功率放大等特点,在电子线路中应用十分广泛。 (3)应用简介 ①作为多级放大电路的输人级,利用其输人阻抗高的特点来提高放大电路接收信号的能力。 ②作为多级放大电路的输出级,利用其输出阻抗低的特点来改善放大电路带负载的能力。 ③作为多级放大电路的中间缓冲级,利用。≈u:的特点隔离前后级的相互影响,解决阻抗变换和信号传输等问题。 场效应管放大电路 场效应管也可组成一些基本放大电路,由于输入输出回路的公共点选择的不同,也可分为共源、共漏、共栅等三种基本接法,场效应管为电压控制电流的元件,共栅接法基本不用,本节重点讨论共源接法放大电路的工作情况,与三极管放大电路一样,场效应管放大电路也必须设置合适的静态工作点,下面以分压式偏置共源放大电路为例进行讨论。 1.分压式偏置共源放大电路 图2.2.28所示为分压式偏置共源放大电路,图中R可增大电路的输人电阻,而不影响V的值,通常R可选几兆欧。静态时,栅极绝缘,无栅极电流Ic,R3上没有电压降,所以栅极电位为: 2.共源放大电路的工作过程 可见共源放大电路的输出电压与输入电压反相;输人电阻主要由RG3确定,其值选择很大,接收信号的能力很强;输出电阻主要由漏极负载电阻RD确定,其值为几千欧至几十千欧。

移动应用开发框架概览:细节深入,全面解析

一、引言 随着移动互联网的飞速发展,移动应用开发已经成为当今软件领域最重要的方向之一。为了满足日益增长的移动应用需求,开发者们借助各种框架来提高开发效率和应用质量。本文将详细介绍目前流行的移动应用开发框架,并对每个框架的特点、优势和适用场景进行深入剖析。 二、跨平台开发框架 1. React Native React Native是Facebook推出的开源跨平台移动应用开发框架,基于JavaScript和React构建。它允许开发者使用统一的JavaScript代码库开发iOS和Android应用,同时保持原生应用的性能和用户体验。React Native通过桥接技术实现与原生组件的交互,提供了丰富的原生API和组件库。此外,React Native社区活跃,有大量的第三方库和工具支持。 2. Flutter Flutter是Google推出的开源跨平台移动应用开发框架,使用Dart编程语言。Flutter采用自绘引擎,可以实现高度定制化的UI设计,同时保持高性能。Flutter提供了丰富的组件库和开发工具,支持热重载和快速迭代。Flutter的应用性能接近于原生应用,特别适合于需要高度定制化UI和追求性能的应用场景。 3. Xamarin Xamarin是Microsoft推出的跨平台移动应用开发框架,使用C#编程语言和.NET平台。Xamarin允许开发者使用统一的C#代码库开发iOS、Android和Windows应用,实现真正的跨平台开发。Xamarin提供了丰富的原生API和组件库,以及强大的Visual Studio集成开发环境支持。Xamarin适合于企业级应用和需要充分利用.NET生态系统的项目。 三、原生开发框架 1. iOS开发框架 (1)SwiftUI:SwiftUI是Apple推出的原生iOS开发框架,使用Swift编程语言。SwiftUI采用声明式编程范式,简化了UI开发过程。它提供了丰富的组件库和布局系统,支持动态类型和暗黑模式。SwiftUI与Xcode紧密集成,为开发者提供了强大的开发工具链。 (2)UIKit:UIKit是iOS传统的原生开发框架,也使用Swift编程语言。它提供了丰富的UI组件和事件处理机制,支持高度定制化的UI设计。UIKit具有成熟的生态系统和广泛的应用场景,适合于各种规模的iOS应用项目。 2. Android开发框架 (1)Jetpack Compose:Jetpack Compose是Google推出的原生Android开发框架,使用Kotlin编程语言。Jetpack Compose采用声明式编程范式,简化了UI开发过程。它提供了丰富的组件库和布局系统,支持动态主题和暗黑模式。Jetpack Compose与Android Studio紧密集成,为开发者提供了便捷的开发体验。 (2)AndroidX:AndroidX是Android传统的原生开发框架,也使用Kotlin编程语言。它提供了全面的API和组件库,支持各种Android设备和版本。AndroidX具有广泛的社区支持和丰富的应用场景,适合于各种规模的Android应用项目。 四、混合开发框架 1. Cordova Cordova(也称为Apache Cordova)是一个开源的移动应用开发框架,允许开发者使用HTML5、CSS3和JavaScript构建跨平台应用。Cordova通过WebView容器来展示Web内容,并通过JavaScript桥接技术实现与原生功能的交互。Cordova支持广泛的设备和平台,具有灵活的扩展性,适合于快速构建原型或简单的跨平台应用。 2. Ionic Ionic是一个基于Cordova的开源移动应用开发框架,专注于提供高质量的UI组件和交互体验。Ionic使用Angular作为核心框架,结合了Web技术和原生功能,实现了高性能的跨平台应用。Ionic提供了丰富的组件库和主题定制功能,以及强大的命令行工具支持。Ionic适合于构建具有丰富交互和美观界面的跨平台应用。 当然可以,以下是另外几个值得关注的移动应用开发框架: 五、其他值得关注的框架 1. NativeScript NativeScript 是一个开源框架,允许开发者使用 JavaScript、TypeScript 或者 Angular 来开发原生应用。它的主要优势在于可以直接访问原生 API,无需 WebView 包装,从而确保应用的性能和用户体验。NativeScript 支持 iOS 和 Android 平台,并且可以与现有的 JavaScript 库和插件集成。 2. Weex Weex 是阿里巴巴推出的一个高性能、可扩展的跨平台移动应用开发框架。它允许开发者使用 Vue.js 或 Rax(基于 React)来编写应用代码,然后编译成原生应用。Weex 的主要优势在于其高性能和灵活的扩展性,适合于需要高度定制化和高性能的应用场景。 3. Fuse Fuse 是一个专注于设计的移动应用开发框架。它提供了一个直观的视觉开发环境,允许设计师和开发者无缝协作,快速构建美观且高性能的移动应用。Fuse 使用一种名为 FuseML 的标记语言来描述界面和交互,同时提供了丰富的原生组件和动画效果。Fuse 适合于追求设计美感和用户体验的项目。

MySQL命令速查——常用函数

注:若测试单个函数的话,需要在函数前面加上SELECT,要不会报错 SELECT 函数 name; name是搜索出来,想要展示的列名,比如 字符串函数 合并字符串 CANCAT(str1,str2,…) 比较字符串大小 STRCMP(str1,str2) 获取字符串长度 LENGTH(str) 全部转换为大写 UPPER(str) 全部转换为小写 LOWER(str) 返回字符串2在字符串1中的位置 LOCATE(str1,str2) 或 POSITION(str2 IN str1) 截取字符串 从左边数截取字符串 LEFT(str,num) 比如 LEFT('helloworld',3)会返回 'hel' 从右边数截取字符串 RIGHT(str,num) 比如 RIGHT('helloworld',3)会返回 'rld' 替换字符串 根据位置替换 INSERT(原字符串,开始位置,结束位置,待替换的字符串) 比如 INSERT('hellomysqlyes',6,10,'vue')结果就是'hellovueyes' 根据内容替换 REPLACE(str,substr,newstr) 将把str中的字符串substr替换成newstr 数值函数 返回绝对值 ABS(x) 返回x除以y的余数 MOD(x,y) 返回0~1的随机数 RAND() 返回数值x的四舍五入值,保留y位小数 ROUND(x,y) 返回数值x,保留y位小数 TRUNCATE(x,y) 返回大于或等于x的最小整数值 CEIL(x) 返回小于或等于x的最大整数值 FLOOR(x) 日期和时间函数 获取当前日期 CURDATE() 返回结果:年-月-日 获取当前时间 CURTIME() 返回结果:时:分:秒(24小时制) 获取当前日期和时间 NOW() 返回结果:年-月-日 时:分:秒 返回date为一年中的第几周 WEEK(date) 例如:WEEK(NOW())

PCAN FD

1 CAN FD 1.1 MCU with CAN FD GD32C103: USART upgrade STM32G0B1: RM0444, DS13560, AN5096, USART1 (PA9, PA10) and DFU (PA11, PA12) STM32G431: RM0440, DS12589, AN5093, USART1 (PA9, PA10) and DFU (PA11, PA12) Refer to AN2606 to get what STM32 devices support DFU bootloader. NUCLEO-G431RB评估板上的唯一一个USB接口不是连接到STM32G431的,而是给ST-Link用的。 Discovery开发板一般有2个USB接口,一个是ST-Link,另外一个是USB通信口。 1.2 FD Format bit STM32G0x1 R1.FDF: Receive Register 1, FD Format bit; if this bit is set, a CAN FD frame was received, otherwise, a CAN 2.

SATA和M.2接口的异同点

SATA和M.2接口是连接存储设备的两种常见接口,它们在物理尺寸、传输速度、线缆和接头以及适用设备类型等方面有着显著的异同点。 物理尺寸 SATA接口通常用于2.5英寸硬盘、3.5英寸硬盘等传统机械硬盘以及SSD,而M.2接口则是一种较为新型的接口标准,尺寸小巧,适用于笔记本电脑、超薄型设备以及一些台式机主板上。 传输速度 SATA接口的传输速度受限于其最大速度为SATA III(6Gbps),而M.2接口支持更高的传输速度,可以达到SATA III甚至更高的速度。特别是基于PCIe总线的M.2接口,可以提供更快的数据传输速度,适合高性能存储设备。 线缆和接头 SATA接口需要使用数据线和电源线连接,而M.2接口则是直接插入主板或扩展卡的插槽中,不需要额外的数据线和电源线。 设备类型 SATA接口通常用于连接传统的机械硬盘和2.5英寸的固态硬盘,而M.2接口可以连接各种尺寸的固态硬盘,包括2280、2260、2242等不同规格的M.2固态硬盘。 结论: SATA接口适用于传统的存储设备,而M.2接口则更适合于小型、高速的固态硬盘,也更适合于对性能和尺寸要求较高的设备。

基于OpenCV的图像颜色与形状识别设计与实现实验指导书

基于OpenCV的图像颜色与形状识别设计与实现实验指导书 一、实验目的: 通过本实验,学生将了解图像颜色与形状的基本概念,并掌握使用OpenCV进行图像颜色与形状识别的方法。具体操作包括图像剪裁、颜色识别、轮廓检测。 二、实验器材: 计算机安装了Python和OpenCV库的开发环境彩色图像 三、实验步骤: 1、导入必要的库: import cv2 as cv import numpy as np import math from PIL import Image, ImageDraw, ImageFont 2、设定颜色阈值: 根据需要识别的颜色,设定相应的颜色阈值。例如: lower_red = np.array([0, 120, 100]) upper_red = np.array([10, 255, 255]) 3、定义计算角度和距离的函数: def calculating_angle(p1, p2, p0): # 计算角度 def calculating_distance(p0, p1): # 计算距离 4、定义形状识别函数: def getShape(cnt): # 根据轮廓获取形状 5、定义添加文本和矩形框的函数: def cv2ImgAddText(img, shapes, textColor=(255, 0, 0)): # 添加文本 def cv2ImgAddRect(img, shapes): # 添加矩形框 6、定义颜色分割函数: def colorDivision(name, roi_bgr, lowerb, upperb):

【读书笔记】深入理解Java虚拟机(周志明)(5)第五部分 高效并发

文章目录 文章说明第五部分 高效并发第12章 Java内存模型与线程12.1 概述12.2 硬件的效率与一致性12.3 Java内存模型12.3.1 主内存与工作内存12.3.2 内存间交互操作12.3.3 对于volatile型变量的特殊规则12.3.4 对于long和double型变量的特殊规则12.3.5 原子性、可见性与有序性12.3.6 先行发生原则 12.4 Java与线程12.4.1 线程的实现12.4.2 Java线程调度12.4.3 状态转换 第13章 线程安全与锁优化13.1 概述13.2 线程安全13.2.1 Java语言中的线程安全13.2.2 线程安全的实现方法 13.3 锁优化13.3.1 自旋锁与自适应自旋13.3.2 锁消除13.3.3 锁粗化13.3.4 轻量级锁13.3.5 偏向锁 文章说明 本文是《深入理解Java虚拟机(周志明)》这本书的重点摘要。 本笔记仅作为复习,不过多的对内容进行讲解。 本笔记按照书的目录进行,如遇到需要细看的,可以到书中找对应内容。 本笔记并不是按照书中原话进行摘要,而是根据自己的理解使用大白话进行记录,同时进行了少部分扩展。如有错误欢迎指出。 由于内容较多,一共分为三篇: 篇幅链接深入理解Java虚拟机(周志明)(1)第一部分 走进Java(2)第二部分 自动内存管理机制https://blog.csdn.net/zhaohongfei_358/article/details/134927759深入理解Java虚拟机(周志明)(3)第三部分 虚拟机执行子系统(4)第四部分 程序编译与代码优化https://blog.csdn.net/zhaohongfei_358/article/details/135067398深入理解Java虚拟机(周志明)(5)第五部分 高效并发https://blog.csdn.net/zhaohongfei_358/article/details/135111650 第五部分 高效并发 第12章 Java内存模型与线程 12.1 概述 无重点 12.2 硬件的效率与一致性 硬件在并行计算时处理一致性问题的方式是增加了一层“缓存一致性协议”,如图所示: 12.3 Java内存模型 Java内存模型的主要目标是:定义程序中各个变量的访问规则,即在虚拟机中将变量存储到内存和从内存中取出变量这样的底层细节。 12.3.1 主内存与工作内存 Java内存分为主内存和线程工作内存。 主内存线程共享。 各个线程有自己的工作内存。 线程只能使用自己的工作内存,不能直接读写主内存,只能将主内存的变量拷贝一个副本到自己的工作内存,然后再同步给主内存。 12.3.2 内存间交互操作 Java内存模型定义了8种“原子操作”来进行工作内存和主内存的交互: lock:锁定主内存中的某个变量;unlock:释放lock锁定的变量锁。read:将主内存的变量传输到工作内存中。load:将read到工作内存的变量生成副本。use:使用工作内存中的变量,即将变量值传递给执行引擎。assign(赋值):将执行引擎返回的结果值赋值给工作内存中的变量。store:将工作内存的值传输到主内存。write:将store过来的变量值放入到主内存变量中。 线程读变量就是“read+load”操作,写变量就是“store+write”操作。 read和load之间可以插入其他操作,例如:可以 read a, read b, load a, load b。 (store+write同理)

【读书笔记】深入理解Java虚拟机(周志明)(3)第三部分 虚拟机执行子系统(4)第四部分 程序编译与代码优化

文章目录 文章说明第三部分 虚拟机执行子系统第6章 类文件结构6.1 概述6.2 无关性的基石6.3 Class类文件的结构 第7章 虚拟机类加载机制7.1 概述7.2 类加载的时机7.3 类加载过程7.4 类加载器7.4.1 类与类加载器7.4.2 双亲委派模型7.4.3 破坏双亲委派模型 第8章 虚拟机字节码执行引擎8.1 概述8.2 运行时栈帧结构8.3 方法调用8.3.1 解析8.3.2 分派8.3.3 动态类型语言支持8.4 基于栈的字节码解释执行引擎 第9章 类加载及执行子系统的案例与实战9.1 概述9.2 案例分析9.2.1 Tomcat:正统的类加载器结构9.2.2 OSGi:灵活的类加载器结构9.2.3 字节码生成技术与动态代理的实现9.2.4 Retrotranslator:跨越JDK版本 9.3 实战:自己动手实现远程执行功能 第四部分 程序编译与代码优化第10章 早期(编译期)优化10.1 概述10.2 Javac编译器10.3 Java语法糖的味道10.3.1 泛型与类型擦除10.3.2 自动装箱、拆箱与遍历循环10.3.3 条件编译 10.4 实战:插入式注解处理器 第11章 晚期(运行期)优化11.1 概述11.2 HotSpot虚拟机内的即时编译器11.3 编译优化技术11.3.1 优化技术概览11.3.2 公共子表达式消除11.3.3 数组边界检查消除11.3.4 方法内联11.3.5 逃逸分析 11.4 Java与C/C++的编译器对比 文章说明 本文是《深入理解Java虚拟机(周志明)》这本书的重点摘要。 本笔记仅作为复习,不过多的对内容进行讲解。 本笔记按照书的目录进行,如遇到需要细看的,可以到书中找对应内容。 本笔记并不是按照书中原话进行摘要,而是根据自己的理解使用大白话进行记录,同时进行了少部分扩展。如有错误欢迎指出。 由于内容较多,一共分为三篇: 篇幅链接深入理解Java虚拟机(周志明)(1)第一部分 走进Java(2)第二部分 自动内存管理机制https://blog.csdn.net/zhaohongfei_358/article/details/134927759深入理解Java虚拟机(周志明)(3)第三部分 虚拟机执行子系统(4)第四部分 程序编译与代码优化https://blog.csdn.net/zhaohongfei_358/article/details/135067398深入理解Java虚拟机(周志明)(5)第五部分 高效并发https://blog.

【读书笔记】深入理解Java虚拟机(周志明)(1)第一部分 走进Java(2)第二部分 自动内存管理机制

文章目录 文章说明第一部分 走近Java第1章 走进Java1.1 概述1.2 Java技术体系1.3 Java 发展史1.4 Java虚拟机发展史1.5 展望Java技术未来1.6 实战:自己编译JDK 第二部分 自动内存管理机制第2章 Java内存区域与内存溢出异常2.1 概述2.2 运行时数据区域2.3 HotSpot虚拟机对象探秘2.3.1 对象的创建(过程)2.3.2 对象的内存布局2.3.3 对象的访问定位 2.4 实战:OutOfMemoryError异常(OOM) 第3章 垃圾收集器与内存分配策略3.1 概述3.2 对象已死吗(如何判断对象可以被回收)3.2.1 引用计数法(不常用)3.2.2 可达性分析算法(常用)3.2.3 再谈引用(强/软/弱/虚引用、引用队列)3.2.4 生存还是死亡(finalize方法)3.2.5 回收方法区 3.3 垃圾收集算法3.3.1 标记-清理算法3.3.2 复制算法3.3.3 标记-整理算法3.3.4 分代收集算法 3.4 HotSpot的(收集)算法实现3.4.1 枚举根节点3.4.2 安全点(Safepoint) 3.5 (不同实现的)垃圾收集器3.5.1 Serial收集器(不常用)3.5.2 ParNew收集器(不常用)3.5.3 Parallel Scavenge收集器3.5.4 Serial Old收集器3.5.5 Parallel Old收集器3.5.6 CMS收集器(JDK1.8的收集器)3.5.7 GI 收集器3.5.8 理解GC日志3.5.9 垃圾收集器参数总结 3.6 内存分配与回收策略 第4章 虚拟机性能监控与故障处理工具4.1 概述4.2 JDK的命令行工具4.2.1 jps:虚拟机进程状况工具4.2.2 jstat:虚拟机统计信息监视工具4.2.3 jinfo:Java配置信息工具4.2.4 jmap:Java内存映像工具4.2.5 jhat:虚拟机堆转储快照分析工具4.2.6 jstack:Java堆栈跟踪工具4.2.7 HSDIS:JIT生成代码反汇编 4.

Java AQS 核心数据结构-CLH 锁及优化

Java AQS 核心数据结构-CLH 锁 什么是CLH锁 CLH 锁是对自旋锁的一种改进,有效的解决了以上的两个缺点。 第一个是锁饥饿问题。在锁竞争激烈的情况下,可能存在一个线程一直被其他线程”插队“而一直获取不到锁的情况。第二是性能问题。在实际的多处理上运行的自旋锁在锁竞争激烈时性能较差。 首先它将线程组织成一个队列,保证先请求的线程先获得锁,避免了饥饿问题。其次锁状态去中心化,让每个线程在不同的状态变量中自旋,这样当一个线程释放它的锁时,只能使其后续线程的高速缓存失效,缩小了影响范围,从而减少了 CPU 的开销。 CLH 锁数据结构很简单,类似一个链表队列,所有请求获取锁的线程会排列在链表队列中,自旋访问队列中前一个节点的状态。当一个节点释放锁时,只有它的后一个节点才可以得到锁。CLH 锁本身有一个队尾指针 Tail,它是一个原子变量,指向队列最末端的 CLH 节点。每一个 CLH 节点有两个属性:所代表的线程和标识是否持有锁的状态变量。当一个线程要获取锁时,它会对 Tail 进行一个 getAndSet 的原子操作。该操作会返回 Tail 当前指向的节点,也就是当前队尾节点,然后使 Tail 指向这个线程对应的 CLH 节点,成为新的队尾节点。入队成功后,该线程会轮询上一个队尾节点的状态变量,当上一个节点释放锁后,它将得到这个锁。 下面用图来展示 CLH 锁从获取到释放锁的全过程。 CLH 锁初始化时会 Tail 会指向一个状态为 false 的空节点,如图1所示。当 Thread 1(下称 T1)请求获取锁时,Tail 节点指向 T1 对应的节点,同时返回空节点。T1 检查到上一个节点状态为 false,就成功获取到锁,可以执行相应的逻辑了,如图2所示。当 Thread 2(下称 T2)请求获取锁时,Tail 节点指向 T2 对应的节点,同时返回 T1 对应的节点。T2检查到上一个节点状态为 True,无法获取到锁,于是开始轮询上一个节点的状态,如图3所示。当 T1 释放锁时,会将状态变量置为 False,如图4所示。T2 轮询到检查到上一个节点状态变为 False,则获取锁成功,如图5所示。 CLH 锁 Java 实现解析 1、节点中的状态变量为什么用 volatile 修饰?可以不用 volatile 吗?

SQL实践篇(一):使用WebSQL在H5中存储一个本地数据库

文章目录 简介本地存储都有哪些?如何使用WebSQL打开数据库事务操作SQL执行 在浏览器端做一个英雄的查询页面如何删除本地存储参考文献 简介 WebSQL是一种操作本地数据库的网页API接口,通过它,我们可以操作客户端的本地存储。 WebSQL曾经是H5里很重要的一种技术,但是后来被废弃了,有的浏览器可能仍旧可以正常使用,但是已经不推荐了,而且大多数浏览器,如Chrome,已经直接禁用了WebSQL了,目前流行的替代品,应该是IndexedDB。 所以本节就是兴趣了解下就行。 主要包括以下内容: 本地存储都有哪些?什么是WebSQL?使用WebSQL的三个核心方法是什么?使用WebSQL在本地浏览器里创建一个数据库,并对其进行查询和呈现。 本地存储都有哪些? 本地存储是一个很大的概念,其包括了Cookies、Local Storage、Session Storage、WebSQL、IndexedDB。 Cookies是最早的本地存储,是浏览器端提供,并且对服务器和JS开放,不过可以存储的数据总量只有4KB,如果超过了这个限制就会忽略,没法进行保存,所以一般用来记录一些登陆有关的信息之类的。 Local Storage与Session Storage都属于Web Storage。Web Storage跟Cookies类似,区别在于它有更大容量的存储。Local Storage是持久化的本地存储,除非我们主动删除数据,否则会一直保存在本地。Session Storage只存在于Session会话中,就是说只有在同一个Session页面才能使用。当Session会话结束时,数据也会自动释放。 Web SQL与IndexedDB都是最新的HTML5本地缓存技术,相比前面三种来说,其存储功能更强,支持的数据类型也更多,比如说图片、视频等。 Web SQL,准确的说是Web SQL DB API,它其实是一种操作客户端本地数据库的一类API接口,通过它我们可以很方便的实现基于SQL对本地数据库的增删改查。对浏览器来讲,所谓的本地数据库,一般是指SQLite,比如Chrome和Safari会用SQLite实现本地存储。 如果说WebSQL方便我们对RDBMS进行操作,那么IndexedDB就是一种NoSQL,它存储的是key-value型数据,通常可以超过250M,且支持事务。 可以看到,本地存储是包含了多种存储方式,它可以很方便的将数据存储在客户端中,从而避免重复调用服务器资源。 而WebSQL,其实并不属于是H5规范的一部分,是一个单独的规范,只是浏览器端同时接受了它跟H5规范。当年,主流的浏览器(Chrome、Safari和Firefox)基本都支持WebSQL,可以在js里通过WebSQL来对客户端数据库进行操作。 2023-11-9 14:15:17 不过我查了下,目前多数浏览器基本都关闭了WebSQL。 如何使用WebSQL 怎么检测你的浏览器是否支持WebSQL? 在你的浏览器里,F12打开命令行,执行以下代码: if (!window.openDatabase) { alert('浏览器不支持WebSQL'); } 或者是打开以下html: <!DOCTYPE HTML> <html> <head> <meta charset="UTF-8"> <title>SQL必知必会</title> <script type="text/javascript"> if (!window.openDatabase) { alert('浏览器不支持WebSQL'); } </script> </head> <body> <div id="status" name="status">WebSQL Test</div> </body> </html> 如果浏览器不支持WebSQL,会弹窗提示"浏览器不支持WebSQL",否则不会有弹窗提示。试了一下,连chrome现在都禁用WebSQL了。 不过出于兴趣,接下来还是简单介绍下WebSQL的使用吧。 打开数据库 如果数据库存在,则会直接打开,返回一个数据库句柄,不存在则会创建。

游戏服务器列表-增量处理

前言 服务器列表比较简单 固定表/开服表(一般只会增加及合并),操作频率很低 一般由 服务器ID IP NAME 开服时间 为什么要自己写个, MySQL的增量备份日志,相对太复杂了 看下 一条UPDATE 语句 随便找了表 修改了 10002 level 1 ->2 得用专门的库去完成,而这里需求很简单 这章主要针对 开服表 优化处理 这工具主要是配合前面openresty(登录服/微中台)给运维人员 使用的 2种方式,按需处理 (json数据,方便前端处理) 后端提供 基础版本与最新增量版本号(主动/被动式 —定时查询或 收到某请求去查询) 1> 可以直接由服务器把列表(从数据库或redis读取)给前端,可以请求时带版本号,只发送增量部分 2> 导出文件 放到cdn(并发量大时),前端去拉去增量文件/基础文件,自行比较 更新,由服务器告诉前端基础版本号+最新版本号,到默认的CDN 地址去拉取 eg:CND地址/patch_107 1:环境 (自行安装,没什么难度,这里直接跳过) win10 vs2015 jsoncpp 库 mysql5.7 (这里搭建在linux上) 2: 说明 1> 数据库 srvlist srvlistincr 还有2张这里暂时用不到,就不说了 2> 工具界面(MFC 界面做的有点粗糙,请谅解) ( 这工具8月就做完了,今天才想起,看看对大伙有用没) 3>重点说明 sid 服务器开始ID eid 服务器结束ID 比如 这个区有合服101-105 5个合服了,这里就是101 105 缺点不能中间中断

【c++】OpenMP自动并行

标题 自动并行相关技术入门博客:omp例子嵌套并行操作 自动并行相关技术 【c++】多线程下利用Gcc内置原子操作保证多线程相加安全【c++】cilk的使用 文档教程OpenMP 推荐!!!下面的几篇博客为此教程的翻译整理版本。 官网:OpenMP应用程序编程接口 入门博客: 最简单的并行计算——OpenMP的使用OpenMP入门教程(一)OpenMP入门教程(二)OpenMP入门教程(三)通过 GCC 学习 OpenMP 框架OpenMP编程入门之一OpenMP中几个容易混淆的函数(线程数量/线程ID/线程最大数)以及并行区域线程数量的确定并行编程-OpenMP(必看!)嵌套并行操作(必看!) omp例子 #include <iostream> #include <omp.h> #include <thread> void report_num_threads(int level) { // #pragma omp single { printf("Level %d: number of threads in the team: %d\n", level, omp_get_num_threads()); // 获取当前线程的 ID std::thread::id this_id = std::this_thread::get_id(); // 输出线程 ID std::cout << " Current thread ID: " << this_id << std::endl; } } int main() { const int n = 32; int sum = 0; // int data[n]; int a1 = 0; // int data2[n]; int a2 = 0; // int data3[n]; int a3 = 0; // int data4[n]; int a4 = 0; // int data5[n]; int a5 = 0; bool is_nested = false; is_nested = omp_get_nested(); std::cout<<"

AndroidStudio 生成签名

Android Stuido 生成签名 Android平台签名证书(.keystore)生成指南 具体看这篇文章就够了。主要使用的是jre 的 keytool 功能生成 .keystore 文件。 Android证书的生成是自助和免费的,不需要审批或付费。 可以使用JRE环境中的keytool命令生成。以下是windows平台生成证书的方法: 使用keytool获取apk签名 keytool -list -v /Users/chao/Code/Other/app/android/app/key.jks keytool -list -v -keystore /Users/chao/Code/Other/app/android/app/my-release-key.keystore keytool -list -printcert -jarfile /Users/chao/Desktop/base.apk 没有md5 其实生成的 ,keystore 都是有 md5 的,只是后来的版本不显示而已。 1.可获取MD5签名的JDK版本 分享 2.新版jdk的keytool没有md5,解决 windows安装OpenSSL(转载)

百分百能遇到的接口自动化测试面试题,看完的现在已经在办理入职了...

1. 什么是接口自动化测试? 答:接口自动化测试是指使用自动化工具对接口进行测试,验证接口的正确性、稳定性和性能等方面的指标。 2. 为什么要进行接口自动化测试? 答:接口自动化测试可以提高测试效率,减少人工测试的工作量,同时可以更快地发现和解决问题,提高软件质量。 3. 接口自动化测试的优点是什么? 答:接口自动化测试可以提高测试效率、减少测试成本、提高测试覆盖率、增强测试的可重复性和可靠性。 4. 接口自动化测试的缺点是什么? 答:接口自动化测试需要编写测试脚本,需要一定的技术水平和时间投入,同时也无法完全替代手工测试。 5. 接口自动化测试的工具有哪些? 答:常见的接口自动化测试工具有:Postman、SoapUI、JMeter、Requests、Selenium等。 6. 接口自动化测试的流程是什么? 答:接口自动化测试的流程包括:需求分析、测试计划、测试用例设计、测试脚本编写、测试执行、测试报告生成和问题跟踪等。 7. 接口自动化测试中的测试用例应该包括哪些内容? 答:测试用例应该包括接口的输入数据、预期输出结果、测试步骤、测试环境、测试数据等信息。 8. 接口自动化测试中的测试脚本应该包括哪些内容? 答:测试脚本应该包括接口的请求方法、请求参数、请求头、请求体、响应状态码、响应头、响应体等信息。 9. 接口自动化测试中的断言应该包括哪些内容? 答:断言应该包括响应状态码、响应头、响应体等信息,用于验证接口的正确性和稳定性。 10. 接口自动化测试中的数据驱动测试是什么? 答:数据驱动测试是指使用不同的测试数据来执行相同的测试用例,以验证接口的正确性和稳定性。 11. 接口自动化测试中的性能测试是什么? 答:性能测试是指对接口的响应时间、并发访问量、吞吐量等方面进行测试,以验证接口的性能和可靠性。 12. 接口自动化测试中的安全测试是什么? 答:安全测试是指对接口的安全性进行测试,包括对接口的认证、授权、加密、防护等方面进行测试。 13. 接口自动化测试中的Mock测试是什么? 答:Mock测试是指使用虚拟的接口数据来模拟真实的接口数据,以验证接口的正确性和稳定性。 14. 接口自动化测试中的集成测试是什么? 答:集成测试是指对多个接口进行测试,以验证接口之间的交互和协作是否正确。 15. 接口自动化测试中的回归测试是什么? 答:回归测试是指在软件修改后重新执行之前的测试用例,以验证修改是否影响了原有的功能和性能。 16. 接口自动化测试中的异常处理是什么? 答:异常处理是指对接口返回的异常信息进行处理,以保证测试的正确性和稳定性。 17. 接口自动化测试中的并发测试是什么? 答:并发测试是指对接口的并发访问量进行测试,以验证接口的性能和可靠性。 18. 接口自动化测试中的压力测试是什么? 答:压力测试是指对接口的负载能力进行测试,以验证接口的性能和可靠性。 19. 接口自动化测试中的持续集成是什么? 答:持续集成是指将接口自动化测试集成到软件开发的过程中,以保证软件的质量和稳定性。 20. 接口自动化测试中的代码覆盖率是什么? 答:代码覆盖率是指测试用例覆盖的代码行数占总代码行数的比例,用于评估测试用例的覆盖率和质量。 21. 接口自动化测试中的代码审查是什么? 答:代码审查是指对测试脚本的代码进行审查,以发现和解决潜在的问题和错误。 22. 接口自动化测试中的日志记录是什么? 答:日志记录是指对测试过程中的信息进行记录,以便于问题的追踪和解决。 23. 接口自动化测试中的报告生成是什么? 答:报告生成是指对测试结果进行汇总和分析,生成测试报告,以便于管理和决策。

使用TLS/SSL Pinning保护安卓应用程序

使用TLS/SSL Pinning保护安卓应用程序 在现代术语中,“SSL”(安全套接层)通常指的是“TLS”(传输层安全)。虽然 SSL 和 TLS 不是同一个东西,但 TLS 是 SSL 的改进和更安全的版本,并且在实践中已大部分取代了 SSL。 简介 SSL/TLS:互联网安全的动态二人组!🔒💻 这些是建立安全通信渠道的加密协议,确保在线交换过程中的数据隐私、完整性和认证。SSL率先出击,但TLS就像超级英雄一样赶来,解决了混乱,拯救了一天!🦸‍♂️ 现在,它们携手合作,保护我们的数据免受邪恶黑客的侵害!🔒😎 在互联网安全领域,现代技术斗篷下的是 TLS,让 SSL 在怀旧的尘埃中留下了身影!🚀 所以下次当你浏览网页时,记住,是 TLS 像老板一样守护你的秘密!🤫🔐 以下是 SSL 和 TLS 发布的完整历史: SSL 1.0 —— 因安全问题从未公开发布。 SSL 2.0 —— 1995 年发布。2011 年弃用。有已知的安全问题。 SSL 3.0 —— 1996 年发布。2015 年弃用。有已知的安全问题。 TLS 1.0 —— 1999 年作为 SSL 3.0 的升级版本发布。计划于 2020 年弃用。 TLS 1.1 —— 2006 年发布。计划于 2020 年弃用。 TLS 1.2 —— 2008 年发布。 TLS 1.3 —— 2018 年发布。

【JVM】虚拟机的组成+字节码文件组成+类的生命周期

什么是JVM? JVM 本质上是一个运行在计算机上的程序,他的职责是运行Java字节码文件。 JVM的功能 1.解释和运行:对字节码文件中的指令实时的解释成机器码让计算机执行。 2.内存管理:自动为对象、方法等分配内存,自动的垃圾回收机制。 3.即时编译:对热点代码进行优化,提升执行效率,回收不再使用的对象。 常见的JVM Hotspot(OracleJDK版):闭源、使用最广泛,稳定可靠,社区活跃JIT支持OracleJDK默认虚拟机。 HotSpot(OpenJDK版):同上,开源,OpenJDK默认虚拟机,适用于对JDK有二次开发需求。 GraalVM:多语言支持高性能、JIT、AOT支持,适用于微服务、云原生架构需要多语言混合编程。 DragonwellJDK(龙井):基于OpenJDK的增强高性能、bug修复、安全性提升JWarmup、ElasticHeap、Wisp特性支持,适用于电商、物流、金融领域对性能要求比较高。 Eclipse Openj9(原IBMJ9):高性能、可扩展JIT、AOT特性支持,适用于微服务、云原生架构。 虚拟机的组成 类加载器(ClassLoader):加载class字节码文件中的内容到内存中。 运行时的数据域(JVM管理的内存):负责管理JVM使用到的内存,比如创建对象和销毁对象。 执行引擎(即时编译器,解释器,垃圾回收器等):将字节码文件中的指令解释成机器码,同时使用即时编译器优化性能。 本地接口:调用本地已经编译的方法,比如虚拟机中提供的c/c++的方法。jdk中用native修饰的方法。 字节码文件的组成 基础信息 魔数、字节码文件对应的Java版本号 、访问标识(public final等等)、父类和接口 Magic魔数 ⚫ 文件是 无法通过文件扩展名 来确定文件类型的,文件扩展名可以随意修改,不影响文件的内容。 ⚫ 软件使用文件的头几个字节(文件头)去校验文件的类型,如果软件不支持该种类型就会出错。 ⚫ Java字节码文件中,将文件头称为 magic魔数 主副版本号 ⚫ 主副版本号指的是编译字节码文件的 JDK 版本号, 主版本号用来标识大版本号,JDK1.0-1.1使用了 45.0-45.3,JDK1.2是46之后每升级一个大版本就加1;副版本号是当主版本号相同时作为区分不同 版本的标识,一般只需要关心主版本号。 ⚫ 版本号的作用主要是判断当前字节码的版本和运行时的 JDK 是否兼容。 访问标识 标识是类还是接口、注解、枚举、模块 标识public final abstract 类、父类、接口索引 通过这些索引可以找到类、父类、接口的信息 常量池 保存了字符串常量、类或接口名、字段名 、主要在字节码指令中使用 ⚫ 字节码文件中常量池的作用:避免相同的内容重复定义,节省空间。 ⚫ 常量池中的数据都有一个编号,编号从1开始。在字段或者字节码指令中通过编号可以快速的找到对应的数据。 ⚫ 字节码指令中通过编号引用到常量池的过程称之为 符号引用 。 字段 ⚫当前类或接口声明的字段信息 方法 当前类或接口声明的方法信息 、字节码指令

Settings中电池选项-Android13

Settings中电池选项-Android13 1、设置中界面2、电池计算2.1 充电时间计算2.1.1 BatteryUsageStats获取2.1.2 BatteryStatsImpl计算 2.2 电池剩余使用时间2.2.1 Estimate获取2.2.2 BatteryStatsImpl计算 3、电池信息来源4、命令模拟* 日志 [电池]Android 9.0 电池未充电与充电字符串提示信息[通俗易懂] 1、设置中界面 packages/apps/Settings/src/com/android/settings/fuelgauge/PowerUsageSummary.java packages/apps/Settings/res/xml/power_usage_summary.xml packages/apps/Settings/src/com/android/settings/fuelgauge/BatteryUtils.java packages/apps/Settings/src/com/android/settings/fuelgauge/BatteryInfo.java 12-23 13:13:23.184 602 715 I ActivityTaskManager: START u0 {act=android.intent.action.MAIN cmp=com.android.settings/.SubSettings (has extras)} from uid 1000 12-23 13:13:23.285 994 2135 D BatteryTipLoader: BatteryInfoLoader post query: 5ms 12-23 13:13:23.356 994 2135 D BatteryInfo: time for getBatteryInfo: 1ms 12-23 13:13:23.357 994 2135 D BatteryTipLoader: BatteryInfoLoader.loadInBackground: 82ms 12-23 13:13:23.950 994 994 D SettingsActivity: Switching to fragment com.

浅谈Dubbo核心概念及架构流程

浅谈Dubbo核心概念及架构流程 前言重要概念1、SPI2、ServiceBean3、URL4、Invoker 整体流程1、架构图2、调用链路 笔者碎碎言,我们学习Dubbo应该学的是什么? 笔者是一名业务开发,认为一切目的都要为我们的目标服务,即日常工作有帮助,所以笔者今天应该学的是它的源码实现流程、设计思想、扩展点,过于细节的去理解记忆源码细节ROI则太低。 源码实现流程:让我们对Dubbo有一个整体的了解,日常遇到框架报错,可以更快定位原因设计思想:在面对类似的复杂的业务场景时,我们可以参考Dubbo设计,毕竟Dubbo已经给出了一个相对最优解扩展点:可以帮助我们在日常开发中借助三方框架更加方便的实现我们的功能。以我的亲身经历来说,就借助过Dubbo的Filter扩展链,完成对标记了@Deprecated接口的流量收集。还有泛化调用等场景 官网地址 前言 Dubbo源码主体流程可以总结为:服务提供者将编写的业务Service服务,按照某种协议序列化到注册中心,标记当前服务的网络资源所在的位置;服务消费者根据指定的key(version+interfaceName+group)去注册中心中找到对应的序列化数据,再将数据反序列化为服务消费者能够识别的格式,最终对目标资源发起调用。以此达到我们调用远程服务变成跟调用本地服务一样。 整体功能完成的基础上,Dubbo在设计上对扩展开放,一些比较重点的节点都能够进行扩展。如:自定义注册中心、自定义配置中心、自定义序列化协议、请求过滤器链Fiter等。一些个性功能的设计也是基于扩展点完成,如:mock机制、心跳机制、泛化掉用、异步调用、异常重试机制、回声测试等 重要概念 1、SPI Dubbo的SPI机制与Java原生的SPI基本类似,但功能更加丰富。 使用@Adaptive注解来指定某个类为某个接口的代理类,Dubbo在生成自适应扩展点对象时,实际上生成的就是@Adaptive注解所注解的类的实例对象实现了一套简单的AOP,如果一个接口的扩展点中包含了多个Wrapper类,那么在Dubbo在实例化完某个扩展点后,就会利用这些Wrapper类对这个实例进行包裹,比如:现在有一个DubboProtocol的实例,同时对于Protocol这个接口还有很多的Wrapper,比如ProtocolFilterWrapper、ProtocolListenerWrapper,那么,当对DubboProtocol的实例完成了IOC之后,就会先调用new ProtocolFilterWrapper(DubboProtocol实例)生成一个新的Protocol的实例,再对此实例进行IOC,完了之后,会再调用new ProtocolListenerWrapper(ProtocolFilterWrapper实例)生成一个新的Protocol的实例,然后进行IOC,从而完成DubboProtocol实例的AOP(类比装饰器模式,包一层) 基本用法如下:表示获取"dubbo"对应的Protocol扩展点。Protocol是一个接口。 ExtensionLoader<Protocol> extensionLoader = ExtensionLoader.getExtensionLoader(Protocol.class); Protocol http = extensionLoader.getExtension("dubbo"); System.out.println(http); 2、ServiceBean ServiceBean表示一个Dubbo服务,相关参数含义: ref,表示服务的具体实现类interface,表示服务的接口parameters,表示服务的参数(@Service注解中所配置的信息)application,表示服务所属的应用protocols,表示服务所使用的协议registries,表示服务所要注册的注册中心 补充:在扫描到一个@Service注解后,会得到两个Bean: 一个就是服务实现类本身一个Bean对象一个就是对应的ServiceBean类型的一个Bean对象 3、URL 官网:Dubbo 中的 URL 统一模型 定义了服务资源的协议、参数等信息。主要用于在各个扩展点之间传递数据,组成此 URL 对象的具体参数如下: protocol:一般是 dubbo 中的各种协议 如:dubbo thrift http zkusername/password:用户名/密码host/port:主机/端口path:接口名称parameters:参数键值对 dubbo 认为 protocol,username,passwored,host,port,path 是主要的 URL 参数,其他键值对存放在 parameters 之中。示例如下: dubbo://192.168.1.6:20880/moe.cnkirito.sample.HelloService?timeout=3000 描述一个 dubbo 协议的服务 zookeeper://127.0.0.1:2181/org.apache.dubbo.registry.RegistryService?application=demo-consumer&dubbo=2.0.2&interface=org.apache.dubbo.registry.RegistryService&pid=1214&qos.port=33333&timestamp=1545721981946 描述一个 zookeeper 注册中心 consumer://30.5.120.217/org.apache.dubbo.demo.DemoService?application=demo-consumer&category=consumers&check=false&dubbo=2.0.2&interface=org.apache.dubbo.demo.DemoService&methods=sayHello&pid=1209&qos.port=33333&side=consumer&timestamp=1545721827784 描述一个消费者 4、Invoker 属于Dubbo的核心模型,在代码实现层面类比递归调用的责任链设计模式 在服务提供方Invoker是javassist创建的服务类的实例,可以实现调用服务类内部的方法和修改字段。 在服务消费方的Invoker是基于Netty的客户端。 通过服务消费方Netty客户端获得服务提供方创建的服务类实例,而后消费方为保护服务类就需要为其创建代理类,这样就可以在不实例化服务类情况下安全有效的远程调用服务类内部方法并且得到具体数据了。

【五】【C语言\动态规划】删除并获得点数、粉刷房子、买卖股票的最佳时机含冷冻期,三道题目深度解析

动态规划 动态规划就像是解决问题的一种策略,它可以帮助我们更高效地找到问题的解决方案。这个策略的核心思想就是将问题分解为一系列的小问题,并将每个小问题的解保存起来。这样,当我们需要解决原始问题的时候,我们就可以直接利用已经计算好的小问题的解,而不需要重复计算。 动态规划与数学归纳法思想上十分相似。 数学归纳法: 基础步骤(base case):首先证明命题在最小的基础情况下成立。通常这是一个较简单的情况,可以直接验证命题是否成立。 归纳步骤(inductive step):假设命题在某个情况下成立,然后证明在下一个情况下也成立。这个证明可以通过推理推断出结论或使用一些已知的规律来得到。 通过反复迭代归纳步骤,我们可以推导出命题在所有情况下成立的结论。 动态规划: 状态表示: 状态转移方程: 初始化: 填表顺序: 返回值: 数学归纳法的基础步骤相当于动态规划中初始化步骤。 数学归纳法的归纳步骤相当于动态规划中推导状态转移方程。 动态规划的思想和数学归纳法思想类似。 在动态规划中,首先得到状态在最小的基础情况下的值,然后通过状态转移方程,得到下一个状态的值,反复迭代,最终得到我们期望的状态下的值。 接下来我们通过三道例题,深入理解动态规划思想,以及实现动态规划的具体步骤。、 740. 删除并获得点数 题目解析 我们发现选择了一个数字,假设是x,那么x+1和x-1我们都不能再选择,这种模式非常像打家劫舍题目的模式。由此我们可以把此问题转化为打家劫舍问题。 由于1<=nums[i]<=1e4,所以我们可以创建一个1e4+1大小的数组count,count[i]表示i数字拥有的点数,也就是i*(i出现的次数),这样我们就可以把原问题转化为打家劫舍问题。 状态表示 我们将nums数组转化为count数组,接着对count数组分析即可。 我们可以定义dp[i]表示,1到i 这些数中,我们选择其中不相邻的部分项,所能得到的最大点数。 状态转移方程 我们想一想dp[i]怎么由其他的状态推导出来。 dp[i]表示,1到i 这些数中,我们选择其中不相邻的部分项,所能得到的最大点数。 dp[i-1]表示,1到i-1 这些数中,我们选择其中不相邻的部分项,所能得到的最大点数。 dp[i-2]表示,1到i-2 这些数中,我们选择其中不相邻的部分项,所能得到的最大点数。 我们对i的状态进行研究,一共可以分为两种情况,要么1-i这些数中,我们选择其中不相邻的部分项,其中选择了i,要么我们不选择i。 当我们选择i,那我们就不可能选择i-1,所以此时最大的点数应该是dp[i-2]+count[i] 如果我们不选择i,那我们就可以选择i-1,此时最大的点数应该是dp[i-1],也就是从1到i-1这些数选择不相邻的部分项所能获得的最大点数。 故状态转移方程为,dp[i]=max(dp[i-2]+count[i],dp[i-1]) 初始化 由状态转移方程我们知道,想要推导出i位置的状态,需要用到i-1和i-2位置的状态,所以我们需要初始化前两个位置的状态,也就是下标1和2。因为count[0]是不考虑的,nums>=1。 很容易可以得出。 dp[0]=count[0] dp[1]=max(count[0],count[1]) 填表顺序 从左到右 返回值 返回最后一个元素即dp[1e4] 代码实现 int deleteAndEarn(int* nums, int numsSize) { int n=numsSize; const int m=1e4+1; int count[m]; memset(count,0,sizeof(count)); for(int i=0;i<n;i++){ count[nums[i]]+=nums[i]; } int dp[m]; dp[1]=count[1]; dp[2]=fmax(count[1],count[2]); for(int i=3;i<=1e4;i++){ dp[i]=fmax(dp[i-2]+count[i],dp[i-1]); } return dp[m-1]; } 我们知道nums中存储的数字的范围是1到1e4,所以我们可以利用count数组, 定义count[i]表示i数字拥有的点数,我们只需要对count数组做一次打家劫舍就可以了。

WinForm控件的数据绑定

参考学习视频链接:01_哔哩哔哩_bilibili 1、控件的数据绑定通过 DataBindings进行绑定 label1.DataBindings.Add("Text", person, "Name"); 2、控件的双向绑定 通过类的继承 INotifyPropertyChanged 在类中增加委托函数,如下类范例 using System; using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Linq; using System.Runtime.CompilerServices; using System.Text; using System.Threading.Tasks; namespace WindowsFormsApp15 { public class Person :INotifyPropertyChanged { private string name; public string Name { get { return name; } set { name = value; OnPropertyChanged(); } } private int age; public event PropertyChangedEventHandler PropertyChanged; public int Age { get { return age; } set { age = value; if (age>45) { //用属性来赋值,可以触发set函数,若用字段则需要增加 OnPropertyChanged("

Jmeter、postman、python 三大主流技术如何操作数据库?

1、前言 只要是做测试工作的,必然会接触到数据库,数据库在工作中的主要应用场景包括但不限于以下: 功能测试中,涉及数据展示功能,需查库校验数据正确及完整性;例如商品搜索功能 自动化测试或性能测试中,某些接口要跑通,需要关联到数据库操作;例如注册接口中短信验证码获取 自动化测试中断言处理,除了响应结果的断言,还包括到数据库断言 自动化测试或性能测试中,某些场景需批量造数据,可能需要用到数据库造数据 测试中,发现bug,需定位bug,可能需要查询到数据库进行定位 当我们利用Jmeter或postman工具进行接口测试,又或者利用python去进行自动化测试,比如商品搜索功能,需查库校验搜索商品结果的正确完整性,去实现断言。这里涉及到数据库如何操作呢? 如果你想学习自动化测试,我这边给你推荐一套视频,这个视频可以说是B站播放全网第一的自动化测试教程,同时在线人数到达1000人,并且还有笔记可以领取及各路大神技术交流:798478386 【已更新】B站讲的最详细的Python接口自动化测试实战教程全集(实战最新版)_哔哩哔哩_bilibili【已更新】B站讲的最详细的Python接口自动化测试实战教程全集(实战最新版)共计200条视频,包括:1、接口自动化之为什么要做接口自动化、2、接口自动化之request全局观、3、接口自动化之接口实战等,UP主更多精彩视频,请关注UP账号。https://www.bilibili.com/video/BV17p4y1B77x/?spm_id_from=333.337.search-card.all.click 2、Jmeter如何操作数据库? 第一步:通过JDBC Connection Configuration,建立数据库连接 在Jmeter线程组下右键->配置元件->选择 JDBC Connection Configuration,做如下配置 **注意:**jmeter工具去操作数据库不带驱动,需要自己添加驱动jar包,下载一个,并放到jmeter的lib目录下,然后点开测试计划,添加jar包路径。如下: 第二步:通过JDBC Request编写sql语句操作数据库,获取数据 在Jmeter线程组下右键->取样器->选择 JDBC Request,做如下配置: 点击运行,可以正常看到搜索结果: 3、postman如何操作数据库? postman本身没有数据库连接功能,需要用到node.js中的xmysql实现Rest API生成,再利用postman去对API进行请求,实现对数据库的操作。 第一步:环境准备,安装xmysql 1、node.js的安装:访问https://nodejs.org/en/download 进行下载并安装。安装成功后,在cmd命令行窗口输入node --verison,出现版本信息则表示安装成功。 2、xmysql的安装:在命令行窗口输入npm install -g xmysql 即可进行安装。安装完成后,输入xmysql 看到使用说明,则说明安装成功。 第二步:连接数据库 命令行窗口输入:xmysql -h 主机名 -u 用户名 -p 密码 -d 库名。如下: 第三步:postman操作数据库 postman对xmysql生成的Rest API进行增删改查操作,详见官方文档:https://github.com/o1lab/xmysql?utm_source=testingpai.com#xmysql--one-command-to-generate-rest-apis-for-any-mysql-database 示例如下: postman查询数据操作如下: 4、python如何操作数据库? 第1步:环境准备,安装pymysql python中操作mysql数据库,需借助第三方库例pymysql来实现。所以需要先安装pymysql: 通过cmd命令行窗口输入pip install pymysql。安装后,通过pip show pymysql 检测是否安装成功。显示pymysql库信息则成功。 第2步:python文件中,编写代码操作数据库 import pymysql # 导包 # 第1步:连接数据库 conn = pymysql.

7-1 递归二路归并排序

7-1 递归二路归并排序 本题目要求读入N个整数,采用递归的二路归并排序法进行排序,输出前3轮排序后的结果。 输入格式: 输入不超过100的正整数N和N个整数(空格分隔)。 输出格式: 输出三行,第一行为第一轮排序结果,第二行为第二轮排序结果,第三行为第三轮排序结果。数据间用一个空格分隔。 为简便起见,最后一个元素后也有一个空格。 输入样例: 5 5 4 3 2 1 输出样例: 4 5 3 2 1 3 4 5 2 1 3 4 5 1 2 简化版代码: #include <iostream> #include <algorithm> using namespace std; const int N = 110; int a[N], n, cnt; void merge_sort(int l, int r) { if (l >= r) return ; int mid = l + r >> 1; merge_sort(l, mid); merge_sort(mid + 1, r); sort(a + l, a + r + 1); if (++cnt > 3) return ; for (int i = 0; i < n; ++i) { printf("

Flask 页面布局layout_main.html

Flask 页面布局layout_main.html 【源码来自编程浪子的flask点餐小程序】 web/templates/common/layout_main.html <!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> <link href="{{ buildStaticUrl('/bootstrap/bootstrap.min.css') }}" rel="stylesheet"> <link href="{{ buildStaticUrl('/font-awesome/css/font-awesome.min.css') }}" rel="stylesheet"> <link href="{{ buildStaticUrl('/css/style.css') }}" rel="stylesheet"> {%block css %}{% endblock %} <body> <div id="wrapper"> <nav class="navbar-default navbar-static-side" role="navigation"> <div class="sidebar-collapse"> <ul class="nav metismenu" id="side-menu"> <li class="nav-header"> <div class="profile-element text-center"> <img alt="image" class="img-circle" src="{{ buildStaticUrl('/images/common/logo.png') }}"/> <p class="text-muted">编程浪子</p> </div> <div class="logo-element"> <img alt="image" class="

Flask 密码重设系统

Flask 密码重设系统【源码来自编程浪子Flask点餐小程序】 web/templates/user/reset_pwd.html {% extends "common/layout_main.html" %} {% block content %} {% include "common/tab_user.html" %} <div class="row m-t user_reset_pwd_wrap"> <div class="col-lg-12"> <h2 class="text-center">修改密码</h2> <div class="form-horizontal m-t m-b"> <div class="form-group"> <label class="col-lg-2 control-label">账号:</label> <div class="col-lg-10"> <label class="control-label">{{ current_user.login_name }}</label> </div> </div> <div class="hr-line-dashed"></div> <div class="form-group"> <label class="col-lg-2 control-label">手机:</label> <div class="col-lg-10"> <label class="control-label">{{ current_user.mobile }}</label> </div> </div> <div class="hr-line-dashed"></div> <div class="form-group"> <label class="col-lg-2 control-label">原密码:</label> <div class="col-lg-10"> <input type="password" id="old_password" class="form-control" value=""> </div> </div> <div class="

[java] 注释

目录 单行注释: 多行注释: 文档注释: doc标签 单行注释: 多行注释: 注意多行注释不能嵌套多行注释: 文档注释: 注释内容可以被JDK提供的工具 javadoc 所解析,生成一套以网页文件形式体现的该程序的说明文档,一般写在类。 doc标签 标签 描述 示例 @author 标识一个类的作者 @author description @deprecated 指名一个过期的类或成员 @deprecated description {@docRoot} 指明当前文档根目录的路径 Directory Path @exception 标志一个类抛出的异常 @exception exception-name explanation {@inheritDoc} 从直接父类继承的注释 Inherits a comment from the immediate surperclass. {@link} 插入一个到另一个主题的链接 {@link name text} {@linkplain} 插入一个到另一个主题的链接,但是该链接显示纯文本字体 Inserts an in-line link to another topic. @param 说明一个方法的参数 @param parameter-name explanation @return 说明返回值类型 @return explanation @see 指定一个到另一个主题的链接 @see anchor

[java] 转义字符&&控制台最常用快捷键

转义字符 1)\t:一个制表位,实现对齐的功能 2)\n:换行符 3) \\:一个\ 4)\":一个" 5) \':一个' 6) \r:一个回车System.out.println(''我亦无他AA\r唯手熟尔"); 因为只是回车没有换行所以会输出为--- 唯手熟尔AA 回车重回前面开始输出 6) \r\n:一个回车System.out.println(''我亦无他\r\n唯手熟尔"); 输出为--- 我亦无他 唯手熟尔 控制台最常用快捷键 tab 在输入部分文件名后按下tab自动补齐剩余文件名 。 ↑ 按下上光标自动复制上一条指令 。

【JAVA】分布式链路追踪技术概论

目录 1.概述 2.基于日志的实现 2.1.实现思想 2.2.sleuth 2.2.可视化 3.基于agent的实现 4.联系作者 1.概述 当采用分布式架构后,一次请求会在多个服务之间流转,组成单次调用链的服务往往都分散在不同的服务器上。这就会带来一个问题: 故障难以溯源。 发起请求,然后请求报错,到底是调用链中哪一环出了问题?很难以定位。这时候就需要用到链路追踪技术了。所谓的链路追踪技术,也就是想办法让分布式系统中的单次请求的链路调用成为可被追踪的,便于在出现故障的时候进行快速的定位溯源。 目前有两套实现思路: 基于日志来实现,常用到的有Sleuth、zipkin 基于agent来实现,常用到的有skywaiking 本文着重于介绍链路追踪的概念和大概体系,sleuth、zipkin、skywalking具体的详细教程会在后续有文章推出进行具体介绍。 2.基于日志的实现 2.1.实现思想 当分布式系统中的一次请求报错时,如何定位错误?大家的第一反应可能都是去挨着看链路上各个服务的日志。这是肯定的,因为只能从这里下手。查这些日志的过程中有个很麻烦的问题——如何将不同服务间的日志对起来?一次调用在调用链的上一个服务留下了一条日志,我怎么知道这条日志对应着链路的下一个节点的哪条日志喃?所以要给每一次请求一个编号。基于这个思想,于是有了标准日志格式规范——OpenTracing。 OpenTracing规定了标准的日志格式如下: 服务ID,服务名称。 trace ID,每一次请求,调用链上的各个服务trace ID是相同的,也就是每一次请求的编号。 span ID,各个服务不同,用来区分链路上的不同节点。 导出标识, 2.2.sleuth 依赖: <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-sleuth</artifactId> <version>3.1.8</version> </dependency> 这里我们搭建了一个简单的微服务集群,然后在APP、AuthenticationCenter、Bis中均引入sleuth: AuthenticationCenter,鉴权中心,用来登录获取token,校验token是否合法。 APP,服务提供方。 Bis,Bis调用AuthenticationCenter登录,然后校验token是否合法,合法的话,再去调用APP中提供的服务: 最后去访问bis,会看到: bis的日志: AuthenticationCenter的日志: APP的日志: 可以看到Bis中一个方法中发出的所有请求在下游的trace ID全是一致的,只是span ID不同。 2.2.可视化 光有了日志,进行问题排查还是要一条条的翻,还是很繁琐。所以配套出现了可视化工具,由推特开发的——zipkin。其能对标准opentracing格式的日志进行收集和展示: 效果图: 3.基于agent的实现 skywalking是基于java agent来实现的,java agent是jkd 1.5引入的新特性,允许在main方法之前执行premain方法,来完成一些准备动作。关于 java gent,其在很多地方都有使用到,博主后续会有文章专门体系化的介绍java agent,并用java agent+字节码增强的方式来对类进行增强和监控,此处不展开。 sky walking的使用很简单,用-agent来启动即可: java -javaagent:skywalking-agent.jar -Dskywalking.agent.service_name=a-service -Dskywalking.collector.backend_service=192.168.31.10:11800 -Dskywalking.logging.file_name=a-service-api.log -jar a-service.jar -Dskywalking.agent.service_name,应用的名称。 -Dskywalking.logging.file_name,数据需要上传到哪里。 skywalking拥有更加的强大和细粒度的图形监控界面。

7-5 单源最短路径

7-5 单源最短路径 请编写程序求给定正权有向图的单源最短路径长度。图中包含n个顶点,编号为0至n-1,以顶点0作为源点。 输入格式: 输入第一行为两个正整数n和e,分别表示图的顶点数和边数,其中n不超过20000,e不超过1000。接下来e行表示每条边的信息,每行为3个非负整数a、b、c,其中a和b表示该边的端点编号,c表示权值。各边并非按端点编号顺序排列。 输出格式: 输出为一行整数,为按顶点编号顺序排列的源点0到各顶点的最短路径长度(不含源点到源点),每个整数后一个空格。如源点到某顶点无最短路径,则不输出该条路径长度。 输入样例: 4 4 0 1 1 0 3 1 1 3 1 2 0 1 输出样例: 1 1 简化版代码 #include <iostream> #include <vector> #include <queue> #include <cstring> using namespace std; using PII = pair<int, int>; const int INF = 0x3f3f3f3f; const int N = 2e4 + 10; vector<pair<int, int>> mp[N]; bool vis[N]; int dis[N]; int main() { memset(dis, INF, sizeof dis); int n, m; scanf("

强化学习(五)-Deterministic Policy Gradient (DPG) 算法及公式推导

针对连续动作空间,策略函数没法预测出每个动作选择的概率。因此使用确定性策略梯度方法。 0 概览 1 actor输出确定动作2 模型目标: actor目标:使critic值最大 critic目标: 使TD error最大3 改进: 使用两个target 网络减少TD error自举估计。 1 actor 和 critic 网络 确定性策略网络 actor: a= π ( s ; θ ) \pi(s;\theta) π(s;θ) 输出为确定性的动作a动作价值网络 critic Q=q(s,a;w) ,用于评估动作a的好坏 2 critic网络训练 观察一组数据 ( s t , a t , r t , s t + 1 ) (s_t,a_t,r_t,s_{t+1}) (st​,at​,rt​,st+1​) 即在状态 s t s_t st​时,执行动作 a t a_t at​,得到奖励 r t r_t rt​,和下一状态 s t + 1 s_{t+1} st+1​ a t 时刻 Q 值 : q t = q ( s t , a t , w ) a_t时刻Q值: q_t=q(s_t,a_t,w) at​时刻Q值:qt​=q(st​,at​,w) a t + 1 时刻 Q 值 : q t + 1 = q ( s t + 1 , a t + 1 , w ) a_{t+1}时刻Q值: q_{t+1}=q(s_{t+1},a_{t+1},w) at+1​时刻Q值:qt+1​=q(st+1​,at+1​,w) ,其中 a t + 1 = π ( s t + 1 ; θ ) a_{t+1}=\pi(s_{t+1};\theta) at+1​=π(st+1​;θ)

Python 潮流周刊#32:打造个人的新闻聚合阅读器

△△请给“Python猫”加星标 ,以免错过文章推送 你好,我是猫哥。这里每周分享优质的 Python、AI 及通用技术内容,大部分为英文。本周刊开源,欢迎投稿[1]。另有电报频道[2]作为副刊,补充发布更加丰富的资讯。 🐱产品推荐 本周刊由“Python猫”出品,这是一个以 Python 技术科普和分享为主的科技自媒体,欢迎关注同名公众号。品牌合作请私信联系。 🦄文章&教程 1、在并行程序中实际最多能用多少个 CPU?[3] 在 CPU 密集型任务中,通常要根据 CPU 核心数来设置线程/进程池的大小。但如何确定实际用多少个 CPU 最合适呢?物理 CPU 和逻辑 CPU 是什么?如何测试设置多少 CPU 数比较合适? 2、你的 Python 包都装到哪了?[4] Python 新手经常会遇到包相关的问题,主要原因之一是不清楚 Python 是如何找包的。文章介绍了 Python 查找包的顺序、它是如何安装包的、虚拟环境的作用、脚本运行方式对搜索路径的影响等。 3、移除 CPython 中的私有 C API 函数[5] Victor Stinner 是很活跃的核心开发者,他在 Python 3.13 alpha 1 中删除了 300 多个私有 C API 函数,收到了一些负面反馈,在 alpha 2 版本中又恢复了 50 个函数。文章记录他所做的事情,以及社区中大家的反馈。 4、Python 小陷阱:复制列表时的问题[6] 如何给 list 这种可变对象创建副本?对于一维列表,文章介绍了三种方法;但是对于二维列表,就涉及浅拷贝与深拷贝问题,需要使用 copy.deepcopy()。(附注:作者的“Python Gotcha”系列短文,介绍了 Python 的一些使用注意事项。) 5、取消 Asyncio 任务的最佳实践[7]

Windows本地部署ChatGLM-6B模型并用CPU运行

下载模型代码 git clone https://github.com/THUDM/ChatGLM2-6B 相关代码会下载到ChatGLM2-6B文件夹中 创建虚拟环境 cmd 打开 ChatGLM2-6B文件夹 python -m venv venv # 创建了一个叫做 venv 的虚拟环境,会出现一个 venv 的文件夹 venv\Scripts\activate.bat # 来激活虚拟环境,如果报错,就先cd到Scripts文件夹,执行activate.bat pip install -r requirements.txt -i https://pypi.douban.com/simple # 安装所需要的包 下载模型 https://huggingface.co/THUDM/chatglm-6b-int4 从这个网站上下载模型相关的文件 在ChatGLM2-6B文件夹下创建THUDM/chatglm-6b-int4文件夹,将下载的文件放到这个文件夹中 运行 from transformers import AutoTokenizer, AutoModel # 绝对路径 tokenizer = AutoTokenizer.from_pretrained("D:\ChatGLM\ChatGLM2-6B\THUDM\chatglm2-6b-int4", trust_remote_code=True) model = AutoModel.from_pretrained("D:\ChatGLM\ChatGLM2-6B\THUDM\chatglm2-6b-int4", trust_remote_code=True).float() model = model.eval() input = "我该怎么训练你" response, history = model.chat(tokenizer, input, history=[]) print(response) 运行结果 问题 1、报错 No module named ‘transformers_modules.

[工具]java_sublime的快速使用

目录 使用 : 怎么运行: 调整字体: 使用 : 新建--->写好代码后-->另存为尾缀是.java的文件 怎么运行: 在你另存为的目录下cmd调用控制台输入dos指令--->执行javac 文件名.java(有.java尾缀)(编译为.class文件)--->java 文件名(没有.class尾缀设计者认为执行的是文件名这个类) (tips:控制台的文字编码格式是编码格式是gbk, 所以在sublime也要设置为gbk在保存, 避免打印的中文乱码) 调整字体: 首选项--->设置-用户--->调整"font_size"的值

Web漏洞扫描技术之wmap

Metasploit的一个模块,要使用wmap模块,必须载入Metasploit中,才可使用。(终端打开) *如果初次使用,需要初始化并启动数据库: msfdb init msfdb start (已启动) 运行 Metasploit 前,先启动用于存储扫描结果的数据库服务: service postgresql start 步骤 1.启动Metasploit,在msf中载入wmap的插件 利用wmap添加并查看已添加网站: wmap_sites -a <target> //添加 wmap_sites -l //查看 wmap_sites -d id号 //删除 wmap_targets -t ip //设置待扫描的目标主机 wmap_targets -l //查看 wmap_run -t //可用扫描模块 wmap_run -e //执行测试 wmap vulns -l //检查漏洞记录

VSCode正则表达式替换

1. Visual Studio Code正则表达式替换样例 最近需要将一段代码里的所有args.parameter_name转化成args[“parameter_name”],然而包含"args."的关键词有一百多个,如果手动一个一个地去改,非常浪费时间,所以想到用正则表达式去替换 按下Ctrl+F弹出替换界面,点击’Abl’右边的星号图标,然后就可以采用正则表达式进行替换了。 然后点击左边的右箭头图标,可以看到,上面一行输入关键词的正则表达式,下面输入期望得到的替换结果正则表达式。 注意"."需要转义符\将其从特殊符号变成普通的原始字符。 [a-z, _]是我的参数大概规律:只包含小写字母和_这两种字符类型; +是指重复这种字符多次。()是将需要这个关键词指定为参数,可用$number指代,number是()出现的顺序。 在下面一行里将对应的parameter_name用$1指代输入进去即可。 2. 2023.9.3 Update: DotMap in Python 最近突然发现,如果args是dict,在python里面有一种很简便的方法可以将dict转化类,并可以使用点获取(dot-access)方法访问元素。 安装Python dotmap包: pip install dotmap 然后使用下面的代码将args转化为类: import dotmap import DotMap args = {"name":"Bob"} cls = DotMap(args) print(cls.name) # output: "Bob" 参考材料: regular-expression in Visual Studio IDE DotMap usage

STM32 MCU上显示器概述、分类、接口

文章目录 前言一、显示模块分类二、显示技术三、显示接口标准四、LTDC控制器 前言 嵌入式显示器已经在现代嵌入式系统中变得至关重要,为各种应用领域提供了强大的用户界面和信息展示功能。从智能家居设备到医疗仪器,从工业控制系统到汽车内部控制面板,嵌入式显示器在提高用户体验、简化交互、增强可视化信息传达方面发挥着关键作用。 一、显示模块分类 显示模块主要分为两大类,取决于它们是否嵌入了内部控制器和GRAM。 第一类对应于具有显示屏控制器和GRAM的显示器,优点MCU无需频繁刷新,无需大内存,驱动简单 以正点原子屏幕举例,这种就是带显示屏控制器和GRAM的显示器 第二类对应的显示器,其显示屏没有主控制器,仅有低电平时序控制器。 MCU需要实时刷新,需要大内存,驱动稍微复杂 二、显示技术 1、LCD-TFT显示器(液晶显示器- 薄膜晶体管):是一种LCD变体,它采用TFT技术提高了对每个像素的控制。得益于TFT技术,每个像素都可以通过晶体管进行控制,从而实现快速的响应时间和精确的色彩控制。 2、OLED显示器(有机LED):像素由直接发光的有机LED组成,可以实现更好的对比度并优化功耗。LED技术可以使用柔性显示器,不再需要玻璃屏或背光源。响应时间非常快,视角不受任何光线偏振的影响。 区别:TFT和OLED技术中驱动显示模块的方式非常相似,它们的主要区别在于是否需要背光源,因为OLED不需要任何背光源。 三、显示接口标准 MIPI(移动行业处理器接口)联盟是一个致力于定义和推广移动设备接口规范的全球协作组织。MIPI联盟不仅开发了新标准,还将现有的显示接口进行了标准化。可分为两大类,MIPI-DBI(MIPI显示总线接口)、MIPI-DPI(MIPI显示并行接口)。 MIPI-DBI:是MIPI联盟发布的第一个显示标准,用来规定显示接口。MIPI-DBI中又定义了三类接口:A类:基于Motorola 6800总线,B类:基于Intel® 8080总线 用的很多,C类:基于SPI协议。MIPI-DBI用来与带有集成图形RAM(GRAM)的显示器进行连接,也就是上面提到的第一类屏幕。像素数据在显示器的本地GRAM中进行更新。也称为MCU接口。 MIPI-DPI:DPI用来与没有帧缓冲器的显示器进行连接。像素数据必须实时流式传输到显示器。其实时性能非常好,但它要求MCU具有大带宽以支持显示。也成为RGB接口 四、LTDC控制器 STM32微控制器上的LTDC是片上LCD显示控制器,可提供高达24位的并行数字RGB信号,以便与各种显示面板连接。LTDC还可以像AMOLED显示器一样使用并行RGB接口来驱动其他显示技术。LTDC可以连接既不嵌入控制器也不嵌入图形RAM的低成本显示面板。总结一句话,便宜。不用带控制器和RAM的屏幕。 整体框图:

如何在Spring Boot中优雅地进行参数校验

1. 前言 在平时的开发工作中,我们通常需要对接口进行参数格式验证。当参数个数较少(个数小于3)时,可以使用if ... else ...手动进行参数验证。当参数个数大于3个时,使用if ... else ...进行参数验证就会让代码显得臃肿,这个时候推荐使用注解来进行参数验证。 在Java中,注解(Annotation)是一种代码标记,通常用于提供元数据,这些元数据可以被编译器或运行时环境使用。这些注解通常用于框架和库中,以实现更加灵活和可配置的代码。 2. 常用注解描述 @NotNull 描述:标记一个值不能为null。示例: public class User { @NotNull private String name; // ... } @NotEmpty 描述:标记一个集合(如List、Set等)不能为空。示例: public class User { @NotEmpty private List<String> interests; // ... } @NotBlank 描述:标记一个字符串不能为空白(即null、空字符串或只包含空格)。示例: public class User { @NotBlank private String username; // ... } @Size 描述:标记一个字符串或集合的大小必须在指定的范围内。示例: public class User { @Size(min = 2, max = 50) private String username; // ... } @Min 和 @Max