1.查看当前内存剩余
free -m 2.发现free剩余很少,buff/cache占用很高
3.安装hcache查看谁在占用
wget https://silenceshell-1255345740.cos.ap-shanghai.myqcloud.com/hcache chmod 755 hcache && mv hcache /usr/local/bin/ hcache -top 10 3.发现是journal这个东西,这是linux系统日志,出现这种情况,一般是日志没有配置好
查看配置文件
cat /etc/systemd/journald.conf 将Storage=persistent
重启日志服务
systemctl restart systemd-journald 手动清理缓存区
echo 1 > /proc/sys/vm/drop_caches 再次free -m 查看
为什么需要淘宝/天猫商品详情 API?
随着互联网的快速发展和电商市场的不断扩大,传统的购物方式已经无法满足人们的需求。越来越多的人开始选择在网上购物,而电商平台则成为了人们购物的主要渠道之一。在这个过程中,淘宝/天猫商品详情 API 扮演着至关重要的角色。本文将从市场需求、用户体验、开发者和商业应用四个方面来探讨为什么需要淘宝/天猫商品详情 API。
一、市场需求
在电商市场中,用户的需求是多种多样的,每个用户都有自己的购物需求和偏好。为了满足用户的个性化需求,电商平台需要提供更加丰富和全面的商品信息。然而,如果电商平台手动整理和编辑商品信息,不仅工作量大,而且容易出错。因此,通过淘宝/天猫商品详情 API,电商平台可以快速、准确地获取到商品详情信息,从而更好地满足用户的需求。
二、用户体验
对于用户来说,快速、准确地获取到商品信息是非常重要的。如果用户在搜索商品时需要等待很长时间才能得到结果,或者得到的结果不准确、不全面,那么用户的购物体验将会大打折扣。而淘宝/天猫商品详情 API 可以提供快速、准确的商品信息获取服务,从而使用户能够更加方便快捷地查找和购买商品。
三、开发者和商业应用
对于开发者和商业应用来说,淘宝/天猫商品详情 API 提供了丰富的商品信息,从而为各种商业应用提供了可能性。例如,开发者可以通过 API 获取商品信息,然后结合其他数据进行分析和挖掘,为电商企业提供更加准确的市场分析和预测服务。同时,电商企业也可以利用 API 获取到的商品信息进行个性化推荐、营销策略制定等应用。
四、安全性和合规性
在获取商品信息时,需要考虑安全性和合规性。淘宝/天猫商品详情 API 采用了严格的授权机制和数据加密措施,确保用户数据的安全性。此外,API 还符合相关法律法规和监管要求,保证了电商平台的合法性和稳健性。
综上所述,淘宝/天猫商品详情 API 的需求来自于市场需求、用户体验、开发者和商业应用以及安全性和合规性等多个方面。随着电商市场的不断扩大和技术的不断发展,淘宝/天猫商品详情 API 的重要性也将日益凸显。未来,我们可以预见该 API 将不断升级和完善,为电商平台的发展和用户的购物体验带来更多的创新和价值。
当你解压Spring Boot的JAR文件时,实际上是在打开一个压缩文件,类似于ZIP。你可以按照以下步骤进行替换文件并重新生成新的JAR:
解压原始的JAR文件: 使用任何ZIP工具(如WinRAR、7-Zip或命令行工具),将Spring Boot的JAR文件解压缩到一个目录。 jar -xf your-original-app.jar 替换文件: 在解压后的目录中,找到并替换你想要更新的文件。重新打包: 在包含替换文件的目录中,使用以下命令重新打包为JAR文件: jar -cf your-updated-app.jar -C your-extracted-directory . 这个命令将在当前目录下创建一个新的JAR文件,包含你替换过的文件。
测试新的JAR文件: 运行新的JAR文件,确保你的应用程序能够正常工作。 java -jar your-updated-app.jar 验证更改: 确保你的更改已经生效。你可以访问应用程序的相关端点或功能,以确保替换文件的效果。 请记住,这种方式可能不适用于所有情况,特别是在生产环境中。在生产环境中,更好的方法是通过持续集成和部署(CI/CD)工具来进行自动化构建和部署。
看了博客里大佬的做法,可以考虑到不用每次都去遍历那个时间所需资源数的数组或者列表,因为每次想要让整体时间缩短,就考虑所需天数最大的,当天数最大的不唯一时,比如样例中,开始需要6天的就有两个,所以想要让整体工期从6天到5天,就需要把所有6天的资源都给足才可以,代码里用到了cost数组,cost[i]表示所有需要i天才能完成的任务,想要缩短,所需要的资源总数(所有的都加起来)
#include<iostream> using namespace std; const int N = 100010; int cost[N] = {0}; //cost[i]表示的是还需要i天完成的所有任务都想缩短需要的资源数 int main(){ long long m,n,k,maxday = 0; cin >> n >> m >> k; for(int i = 0; i < n; i++){ int dayNum,c; cin >> dayNum >> c; cost[dayNum] += c; if(dayNum > maxday){ //用maxday记录当前最长的时间 maxday = dayNum; } } while((maxday > k) && (m >= cost[maxday])){ //两种情况下不能继续调整,第一个是已经达到了要求的最短开垦时间,第二个是当前剩余资源已经不够再减一天了 int maxCost = cost[maxday]; m -= maxCost; //调整剩余资源数 maxday--; cost[maxday] += maxCost; } cout << maxday; return 0; }
文章目录 机器人可以从一个成年人的细胞中创造出来,而且还无需任何基因改造,这意味着什么?
对无数患者来说,这意味着从他们自身衍生出的生物机器人,可以帮助他们恢复健康、愈合创伤、治疗疾病,这是医疗工具研发史上一个崭新的起点。
现在,美国塔夫茨大学和哈佛大学研究人员已经成功利用人类气管细胞,创建了一种微型生物机器人Anthrobot。它不但可在神经元表面移动,还能使实验室培养皿中的受损神经元恢复生长。
这种多细胞机器人的大小,从人类头发的宽度到削尖的铅笔尖不等,可自行组装,并显示出对其他细胞的显著治疗效果。
发表于《先进科学》杂志的这项研究成果,回答了更为广泛的医学问题:控制细胞在体内组装和协同工作的规则是什么?细胞是否可在自然生长环境中遵照不同的“身体计划”重新组合,从而执行其他功能?
人类细胞机器人,神秘又安全
研究人员吉泽姆·古姆斯卡娅认为,通过重新编程细胞之间的相互作用,可创建新的多细胞结构,类似于石头和砖块可排列成不同的结构,如墙壁、拱门或柱子。他们发现,这些细胞不仅会创造多细胞形状,而且能激发新的生长来填补因划伤细胞层而造成的间隙。
有意思的是,Anthrobot怎样做到这一点的,科学家尚不清楚,但他们看到了神经元确实生长在Anthrobot集群组装所覆盖的区域下。
使用人类细胞的优点非常明显。首先,由患者自身细胞构建的机器人,执行治疗任务不会引发免疫反应或承受免疫抑制剂风险;其次,它们只持续几周就会分解,因此在工作完成后很容易就被重新吸收到体内。
而在体外,Anthrobot只能在特定实验室条件下生存,没有暴露或意外传播到实验室外的风险。它们不会繁殖,也没有经过基因编辑、添加或删除,没有超出现有保障措施的风险。
人类细胞机器人如何生长
每个Anthrobot最初都是一个细胞,来自成年供体。这些细胞来自气管表面,覆盖着纤毛,可来回摆动。纤毛帮助气管细胞排出微小的颗粒,这些颗粒进入肺部的气道,人体通过咳嗽或清嗓子排出颗粒和多余液体,都需要纤毛细胞的帮助。早期研究表明,当细胞在实验室生长时,它们会自发形成称为类器官的微小多细胞球体。
此次,研究人员开发了纤毛在类器官上朝外生长的条件。几天之内,它们开始“四处走动”,由纤毛驱动,就像桨一样。团队注意到了不同的运动形状和类型,这是生物机器人平台的首个重要特征。
这些创建出来的不同类型的Anthrobot,有些是球形的,完全被纤毛覆盖;有些是不规则的,纤毛覆盖得更斑驳,或者只是在一侧覆盖着纤毛。
Anthrobot在实验室培养皿中可以自我组装,并不需要镊子或手术刀来塑造它们。研究人员可使用成体细胞,甚至是来自老年患者的细胞,而不是胚胎细胞来培养。它们还是完全可扩展的,人们可并行创建成群的机器人。
小小治疗师,绘制新蓝图
古姆斯卡娅解释说,细胞具有与生俱来的能力,能以某些基本方式自组装成更大的结构。这些细胞可形成片层、折叠形状、球体,可按类型分类和分离、融合在一起,甚至移动。
与那些“无生命砖块”的两个重要区别是,细胞可相互交流并动态地创建这些结构,并且每个细胞都具有许多功能,例如运动、分泌分子、检测信号等。
确切来说,人们不是“发现”了它们,人们只是在弄清楚如何结合这些元素来创造新的生物“身体计划”和功能,而这与自然界中发生的有很大不同。
研究人员称,生物机器人的下一步开发将会带来其他应用,包括清除动脉粥样硬化患者动脉中的斑块、修复脊髓或视网膜神经损伤、识别细菌或癌细胞,或将药物输送到目标组织。从理论上讲,Anthrobot不但可帮助愈合组织,还能向受损部位提供促进再生的药物。
由于很多项目喜欢使用传统的 Java 8 进行开发,而且 Java 8 的稳定性也是经过长久考验的,我们接下来就尝试一下,在一台新的 Mac 中配置 Java 环境,并且开始创建 SpringBoot 项目。
首先,去 Oracle 官网下载 java8 JDK ,选择 macOS 的 .dmg 版本安装包。
一路 continue 进行安装:
1. Java 环境配置
使用命令打开 .bash_profile 文件:
vim ~/.bash_profile 选择编辑模式,之后插入一下环境变量语句:
# java-environment-config JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.jdk/Contents/Home PATH=$JAVA_HOME/bin:$PATH CLASSPATH=$JAVA_HOME/lib/tools.jar:$JAVA_HOME/lib.dt.jar:. export JAVA_HOME export PATH export CLASSPATH 注意第二行中的 jdk1.8.jdk ,这里要改成你自己的 JDK 版本。
最后两行是maven需要的,这一步先忽略。
重要提示,博主之前在这里卡了一段时间,是由于jdk路径不对,导致后面的maven出错,最好按照以下两点核对一下路径是否正确:
1、查看Java的安装路径:/usr/libexec/java_home -V #这里一定要是大写的V。
2、查看变量值: echo $JAVA_HOME
保存以后,重新打开终端,输入以下命令保存刚才的文件:
source ~/.bash_profile 最后,新打开一个终端,输入命令 java查看环境是否生效:
验证 IDEA 使用 java1.8
打开 IDEA ,新建一个项目,发现这时候已经自动识别出来 Java 解释器:
一、介绍 Intro.js 是一个用于创建网站用户引导、功能介绍和教程的 JavaScript 库。它允许开发者通过步骤和提示突出显示网站上的特定元素,以帮助用户更好地了解和使用网站的功能。以下是 Intro.js 的一些关键特点和用法介绍:
更多Intro.js 功能网址:Intro.js Themes | Intro.js Docs
二、主要特点 用户引导: Intro.js 可以创建引导,引导用户在网站上执行特定的操作或了解关键功能。步骤和提示: 可以定义引导中的每个步骤,并为每个步骤提供提示,包括标题、描述和位置。高亮显示元素: Intro.js 允许高亮显示网站上的特定元素,使其在引导中更为突出。导航按钮: 提供导航按钮,使用户能够在引导的步骤之间进行切换。自定义样式: Intro.js 允许开发者自定义引导的样式,以匹配网站的设计风格。 三、代码实现 1.JS方式实现 (1)安装Intro.js插件 npm install intro.js --save // 使用npm安装 或
yarn add intro.js // 使用yarn安装 (2)引入Intro.js import IntroJs from 'intro.js' // introjs库 import 'intro.js/introjs.css' // introjs默认css样式 // import 'intro.js/themes/introjs-modern.css' // introjs主题 (3)实现整体Vue引导 <template> <div class="container"> <div id="one">引导111111</div> <div id="two">引导2222222</div> </div> <div id="finally">引导333333</div> </template> <script> import IntroJs from 'intro.
方法一:二分查找法
#include<cstdio> #include<iostream> using namespace std; int main() { int arr[10] = { 1,2,3,4,5,6,7,8,9,10 }; int k = 6;//在数组中找到6 int i = 0; int sz = sizeof(arr) / sizeof(arr[0]); int flat = 0; int left = 0; int right = sz-1; while (left <= right) { int mid = left + (right - left) / 2; if (arr[mid] < k) { left = mid + 1; } else if (arr[mid] > k) { right = mid - 1; } else { flat = 1; printf("
1 YAML概述 YAML 是 “YAML Ain’t a Markup Language”(YAML 不是一种标记语言)的递归缩写。在开发的这种语言时,YAML 的意思其实是:“Yet Another Markup Language”(仍是一种标记语言)。YAML 的语法和其他高级语言类似,并且可以简单表达清单、散列表,标量等数据形态。它使用空白符号缩进和大量依赖外观的特色,特别适合用来表达或编辑数据结构、各种配置文件、倾印调试内容、文件大纲(例如:许多电子邮件标题格式和YAML非常接近)。YAML 的配置文件后缀为 .yml,如:runoob.yml 。+ 2 YAML 语法 YAML基本语法:
大小写敏感
使用缩进表示层级关系
缩进不允许使用tab,只允许空格
缩进的空格数不重要,只要相同层级的元素左对齐即可
'#'表示注释
3 YAML 对象 YAML 支持以下几种数据类型,可以和JSON进行类比:
对象:键值对的集合,又称为映射(mapping)/ 哈希(hashes) / 字典(dictionary)
数组:一组按次序排列的值,又称为序列(sequence) / 列表(list)
纯量(scalars):单个的、不可再分的值
以 - 开头的行表示构成一个数组:
- A - B - C YAML 支持多维数组,可以使用行内表示:
key: [value1, value2, ...] 一个相对复杂的例子:意思是 companies 属性是一个数组,每一个数组元素又是由 id、name、price 三个属性构成。
companies: - id: 1 name: company1 price: 200W - id: 2 name: company2 price: 500W 数组也可以使用流式(flow)的方式表示:
一、Android.mk转成Android.bp是可以通过工具转换的
工具的路径为:ASOP/out/soong/host/linux-x86/bin/androidmk
直接把你要转换的Android.mk 文件放置到此目录下,然后执行命令:
./androidmk Android.mk > Android.bp
二、编译不同类型模块的写法
1、编译成 Java 库
Android.mk include $(BUILD_JAVA_LIBRARY) Android.bp java_library { ...... } 2 编译成 Java 静态库
Android.mk include $(BUILD_STATIC_JAVA_LIBRARY) Android.bp java_library_static { ...... } 3 编译成 App 应用
Android.mk include $(BUILD_PACKAGE) Android.bp android_app { ...... } 4、 编译成 Native 动态库
Android.mk include $(BUILD_SHARED_LIBRARY) Android.bp cc_library_shared { ...... } 5 编译成 Native 静态库
Android.mk include $(BUILD_STATIC_LIBRARY) Android.bp cc_library_static { ...... } 6、编译成 Native 执行程序
目录 前言的前言前言安装之前的准备系统版本:Ubuntu22.04建议的软件目录软件下载环境(依赖库)安装(重要) 编译和安装环境变量配置安装结束结语安装过程可能遇到的问题1.epydoc2.Make过程中的_byte2tif.c编译错误(2023年4月1日版本)(后续已修复) 前言的前言 考虑到该平台每况愈下的博客环境,我将这篇文章转移到了cplusv的个人博客,目前内容在CSDN平台上依旧保留,但可能在未来某个时间我会将这个平台上的内容撤下。
前言 Madagascar 是一款开源的地震数据处理软件,其不仅提供了地震数据处理所需要的各类软件包,还为数据处理提供了有力的编程环境。更多关于Madagascar 的介绍和使用方法,可以参考官方wiki页面:
Madagascar Main Page(ahay.org)
下面是摘自官方wiki介绍:
Madagascar is an open-source software package for multidimensional data analysis and reproducible computational experiments. Its mission is to provide:
a convenient and powerful environmenta convenient technology transfer tool for researchers working with digital image and data processing in geophysics and related fields. Technology developed using the Madagascar project management system is transferred in the form of recorded processing histories, which become “computational recipes” to be verified, exchanged, and modified by users of the system.
文章目录 Mabatis处理异常屏蔽SQL返回前端全局异常捕获处理结论1 java异常体系2 Spring框架异常处理3 定位Spring框架转化为哪种unchecked异常3.1 捕获RuntimeException定位Spring框架转化抛出的异常类3.2 进一步查看包名判断3.3 识别MyBatisSystemException下级实现3.3 识别MyBatisSystemException继承实现 Mabatis处理异常屏蔽SQL返回前端全局异常捕获处理 结论 在全局异常处理类中添加MyBatisSystemException即可单独对MyBatis中和数据库操作相关异常操作进行全局处理,同时屏蔽sql内容,只返回文字 “服务错误,请联系系统管理员” 给前端。
@Slf4j @ControllerAdvice public class ExceptionHandlerAdvice { /** * Sql查询失败在spring的包装下会统一抛出非受检异常,单独捕获,防止sql语句被返回给前端 */ @ResponseBody @ExceptionHandler(MyBatisSystemException.class) public Object handleBindException(HttpServletRequest req, MyBatisSystemException e) { String path = "http://"+req.getRemoteAddr()+":"+req.getServerPort() + req.getRequestURI(); log.error("访问 "+path +"报错,报错信息为: "+ e.getMessage(), e); return new BaseResult<>(CodeEnum.E500, false, "服务错误,请联系系统管理员。"); } //拦截所有Exception,展示Error页面 @ResponseBody @ExceptionHandler({Exception.class}) public BaseResult errorHandler(HttpServletRequest req, Exception e) { String path = "http://"+req.getRemoteAddr()+":"+req.getServerPort() + req.getRequestURI(); log.error("访问 "+path +"
1.使用 nohup 命令 可以使用 nohup 命令启动 Java 应用程序,使其在后台运行,这样即使退出终端或关闭 SSH 连接,Java 应用程序也能继续运行。 nohup java -jar myapp.jar & 2.使用 & 符号 使用 & 符号可以将 Java 应用程序放到后台运行。
java -jar myapp.jar &
目录:导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜) 前言 1、第三方支付功能测试点
支付流程:
我们在测试一个功能时,需要先了解一下这个逻辑,而订单支付逻辑普遍都会有以下内容:
1)创建本地唯一订单号;
2)去调用支付,在支付平台生成一个支付订单;
会返回一个支付凭证(payInfo)
支付订单号在回调方法中会拿到
3)此时待支付状态下,支付平台回调通知接口;
在本地保存待支付订单信息(此时有两个订单记录:一个本地订单,一个支付平台的订单,两个ID关联)
4)用户根据收到的支付凭证发起支付(只需要管支付成功的,不成功可以当成忽略)
5)支付平台回调通知接口(支付成功)
更新支付订单
更新本地订单
后续操作
6)主动查询订单状态
更新支付订单
更新本地订单
后续操作
退款或体现(不做具体阐述)
实际遇到支付的异常测试点:
上面的内容了解即可,大部分内容项目熟了就知道了,很多时候具体项目具体分析。下面的异常测试点大多是我亲身经历过的容易出现异常的情况。
具体测试场景:
1)连续访问2次(或以上)支付接口,在第一次访问未回调完成时,第二次访问需要做限制;
可能出现的问题:直接返回第二次的结果,而第一次就可能是成功的,只是第一次请求返回的结果被第二次请求返回的失败结果所覆盖;
2)连续访问回调订单接口(向支付平台提交支付请求接口),生成的多个签名,需要校验订单返回的是否是最新的签名;
可能出现的问题:使用前面生成的一个签名去支付,会报错;
3)一个订单反复提交支付再返回,退出支付再次调取支付只允许生成不同的签名,这个根据需求;
4)需要校验1个签名只能支付1次,这个根据需求;
5)支付签名的校验,这个看需求及个人。如:异常/特殊符号等;
6)支付0元/0.01元/0.001元;
7)支付负值;
8)支付回调超时情况后端处理:一个合理的文案。方法:加挡板/断点;
9)注意一下消息回调,如果是第三方支付系统,通常会有消息的异步回调。
如:支付后,会在一定时间内无限循环查询接口,最后会回传成功或失败,但是订单不会直接知道这个结果,系统需要再次访问一个接口了解支付的最新状态才能知道订单是否支付成功;
2、贷款知识面试题
1)假如要你测试6个月期限的p2p借款产品,你应该怎么设计案例,说出测试点?
回答思路:1站在用户的角度测试,用户怎么用,你就怎么测试。2 一个人扮演多种角色测试。 3多想出一些异常场景。
借款产品投标结束日T+7时,满标和不满标的情况。
借款产品投标结束日T+7前,产品提前满标情况
产品成立后,每个月还款日前,检查系统有没有发出邮件,短信,站内信通知借款人充值到平台账户。
在每月还款日,借款人充值用来还款时,充值资金足够、不足够、不充值情况,查看系统如何处理。充值资金不足或者没有充值时,系统应该有罚息。
借款人提前还清余款场景,有些产品不支持提前还款,有些产品要满一定期限才可以提前还款(提前还款有一定手续费)。
这些都是要关注的测试点。(自己要扮演借款用户去操作提前还清余款,然后扮演后台管理员去审核,然后又扮演投资人用户去检查虚拟账户的资金到账情况)
最后一期借款人还清资金时,去后台页面查看借款产品状态,应该已正常结束。再去前台页面搜索,应该无该借款产品了。 (或者补充说:去数据库里查看此借款产品的状态)
2)你们这个P2P上线了吗?能查吗?项目花了多久时间,预计多久完成?
回答:
两种方案:
还没上线,查不了,这个是新项目,计划半年时间完成,但是因为中途有出现一些问题没有解决完毕,所以现在还没有在预计时间内完成。
大家写的项目名在网上确实能查出来,就说上线了,能查到的。(面试官其实不一定会去查)
3)实名认证你们是怎么测得?调取什么平台的资料?
实名认证接口:
银行卡实名认证(调用银行接口,验证卡号,姓名,身份证号码,手机号码。需要利用到手机接收到的验证码)
身份证实名认证(全国公民身份证号码查询服务中心,或者直接说公安接口)
4)P2P你们也测试后台管理吗?个人芝麻信用积分是调取哪里的资料?
测试后台管理:
后台也测,但是我主要测试前台,我的关注点是前台,后台只是拿来用,能配合前台正常走完流程就行。
后台主要对前台进行管理,主要有贷款管理,资金管理。
贷款管理:可以查看投资人的投资情况,也可以查看借款人的借款产品,对借款产品进行管理。比如审批,每期的还款提醒,预警等。
资金管理:管理查看用户的充值,审批用户的提现过程。
芝麻信用积分:调用的是支付宝的接口,芝麻信用:调用的是支付宝那边的接口(支付宝提供这样的芝麻信用服务,每查一次收取大概0.1元)
5)P2P功能测试你们一般做几轮?
回答:
中型版本(大修改,一个月上线一次):
RK3588
RK3588是Rockchip的新一代旗舰SOC。它采用8nm制程工艺、基于A76 + A55的big.LITTLE设计,具备4K UI性能、8K VPU,拥有NPU2.0等。内置专用NPU主要用于AI应用程序。RK3588支持8K视频解码和4K视频编码,同时还支持多个4K输出,对于高端显示应用非常有吸引力。
RK3588的主要特性:
1.CPU:4个Cortex-A76和4个Cortex-A55内核,采用动态配置
2.GPU:ARM Mali-G610
3.NPU:6TOPs AI算力,支持INT4/INT8/INT16/FP16
4.多媒体:8K视频解码支持,4K编码支持
5.显示器:4K视频输出,双显示器支持
6.处理器:8纳米低压
7.影像接口:2*HDMI TX/2*DP TX/2*eDP TX/2*MIPI DSI TX/1*HDMI IN/6*MIPI CSI RX
8.数据接口:4*PCLe3.0/3*PCLe2.0/3*SATA3.0/3*USB3.1/4*USB2.0/2*TypeC/2*GMA
9.内存:LPDDR4X/LPDDR5,最高支持32GB内存
10.支持操作系统:Android、Linux及国产操作系统
11.图像信号处理器:最大48M像素ISP
即上一篇文章最终代码
前端vue导出PPT,使用pptxgen.js
前端vue导出PPT,使用pptxgen.js 一个平台下有10个国家,这个是后端返回数据固定的,每一个国家下面有10个物流方式,这10个物流方式是这10个国家都有的,也就是所有物流方式去重之后也只有10个物流方式,10个国家,物流方式method0到method9最多也为10个,但也可以不是10个,也就是method0到method9以内是不固定的,它跟methodTotalCount0数量是有联系的,methodTotalCount0也是0–9之内的范围
参数说明 buyerCountryName:对应国家
comparison:是否上涨下降
method0–method9:物流方式的名称
methodTotalCount0–methodTotalCount9:物流方式对应的数量
totalCount:每个国家的总数
为了方便查看逻辑代码,我把原数据放下面,temp1 就是模拟接口的数据 <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="utf-8"> <title>前端vue导出PPT,使用pptxgen.js Demo</title> </head> <body> <h1 style="text-align: center;">请打开F12控制台查看数据</h1> <div id="chart-container"></div> <!--加载整个Lodash库--> <script src="https://cdn.bootcdn.net/ajax/libs/lodash.js/4.17.21/lodash.js"></script> <script > // import _ from 'lodash' // temp1 就是模拟接口的数据 const temp1 = { // 这里的数据在下面******* } let salechannelArr = Object.keys(temp1).map(key1 => key1) // 获取平台的总数 console.log('temp1', temp1) console.log('获取平台的总数', salechannelArr) this.salechannelSumArr = salechannelArr let salechannelItemList = [] // 存放所有平台的数据 let buyerCountryList = [] // 存放所有平台对应国家的数据 let result = Object.
visual studio 使用open3d出现的问题及解决方式(持续更新中) Q1 使用open3d::utility::LogInfo系列出现LNK2001问题,如下所示:
LNK2001 无法解析的外部符号 “char __cdecl fmt::v6::internal::decimal_point_impl(class fmt::v6::internal::locale_ref)”
LNK2001 无法解析的外部符号 “public: static unsigned __int64 const * const fmt::v6::internal::basic_data::zero_or_powers_of_10_64” A1 【属性管理器】->【C/C++】->【预处理器】,添加“FMT_HEADER_ONLY”
比如删除temp目录下以a开头的所有文件:
首先要进到temp目录下
在删除前先使用ls a查看要删除哪些文件,防止误删除
确认无误后,使用 rm -rf a 命令,删除a开头的所有文件
●虽然“-rf”选项是用来删除目录的,但是删除文件也不会报错。所以,为了使用方便,一般不论是删除文件还是删除目录,都会直接使用“-rf”选项。
来源:https://blog.csdn.net/Rockandrollman/article/details/121237886
SVN 文件状态 这里有一张图片可以说明:
背景 我们的业务数据一般来说都是放在Mysql中的,而我们要分析的数据一般都存放在clickhouse中,所以如何把数据从mysql同步到ck,就变成了一个必须的步骤,本文简单记录下几种同步的方式
mysql数据同步到clickhouse 方式一:
在clickhouse中独立创建一个ck的表,对应着mysql的一张表数据,然后使用定时任务比如每天或者每小时从mysql中查询一天的增量或者一小时的增量数据插入到ck中,这种方式比较容易理解和实现
方式二:
使用canel+kafka同步二进制binlog的方式同步数据,具体来说是把每条db的变更转换成kafka的记录,然后消费kafka消息把数据插入到ck中
方式三:
使用ck提供的mysql引擎表
CREATE TABLE [IF NOT EXISTS] [db.]table_name [ON CLUSTER cluster] ( name1 [type1] [DEFAULT|MATERIALIZED|ALIAS expr1] [TTL expr1], name2 [type2] [DEFAULT|MATERIALIZED|ALIAS expr2] [TTL expr2], ... ) ENGINE = MySQL('host:port', 'database', 'table', 'user', 'password'[, replace_query, 'on_duplicate_clause']) SETTINGS [ connection_pool_size=16, ] [ connection_max_tries=3, ] [ connection_wait_timeout=5, ] [ connection_auto_close=true, ] [ connect_timeout=10, ] [ read_write_timeout=300 ] ; 方式四:
使用ck提供的当前还处于实验阶段的MaterializedMySQL引擎
CREATE DATABASE mysql ENGINE = MaterializedMySQL('localhost:3306', 'db', 'user', '***'); 方式五:
软件环境: JDK 1.8
SpringBoot 2.2.1
Maven 3.2+
Mysql 8.0.26
spring-boot-starter-data-redis 2.2.1
jedis3.1.0
开发工具
IntelliJ IDEA
smartGit
实现思路 相对于set来说,sorted set是一种有序的set,排序是根据每个元素的score排序的,score相同时根据key的ASCII码排序
根据ZSET的个性,我们可以实现一个排序,同时有个序号,也可以实现分页的逻辑,下面给出一个例子,看看具体的实现
项目搭建 使用Spring官网的https://start.spring.io快速创建Spring Initializr项目
选择maven、jdk版本
选择需要的依赖
因为pagehelper在里面搜索不到,所以手动加上
<dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper</artifactId> <version>5.1.8</version> </dependency> 动手实践 为了方便测试,写一个测试类,批量写入数据
import cn.hutool.core.date.DatePattern; import cn.hutool.core.date.DateUtil; import cn.hutool.core.date.TimeInterval; import cn.hutool.json.JSONUtil; import com.example.redis.model.dto.UserDto; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.dao.DataAccessException; import org.springframework.data.redis.connection.RedisConnection; import org.springframework.data.redis.core.RedisCallback; import org.springframework.data.redis.core.RedisTemplate; import javax.annotation.Resource; import java.time.LocalDateTime; import java.time.ZoneId; import java.time.temporal.ChronoUnit; import java.util.Date; import java.util.HashMap; import java.util.Map; import java.
操作符详解 前言一、操作符分类二、算术操作符1.成员2.小结 三、移位操作符1.成员2.移动内容2.1 计算机中的单位2.2 常见数据类型所占空间大小2.3 移位内容测试 3.原码、反码、补码3.1 原码3.2 反码与补码 4.算术移位4.1 正整数移位4.2 负整数移位 5.逻辑移位6.整数的存储7.移位方式的测试8.小结 四、位操作符1.成员2.操作内容3.运算规则4.小结 五、赋值操作符1.成员2.赋值逻辑3.自赋值操作符4.小结 六、单目操作符1.成员2.多种含义的操作符——'+'、'-'、'*'、'&'2.1 正值与负值——'+'、'-'2.2 地址的产生2.3 地址的作用2.4 取地址与解引用操作符——'*'、'&'2.5 小结 3.一种含义的单目操作符3.1 '!'——逻辑反操作3.2 'sizeof'——计算操作对象所占空间大小(以字节为单位)3.2.1 sizeof的用法3.2.2 sizeof计算表达式3.2.3 小结 3.3 '~'——对一个数的二进制按位取反3.4 前置--、后置--与前置++、后置++3.4.1 ++、--的作用3.4.2 前置、后置的区别 3.5 '(类型)'——强制类型转换 七、关系操作符1.成员2.用法介绍3.注意事项4.小结 八、逻辑操作符1.成员2.操作内容3.运算规则4.与位操作符的异同点4.1 相同点4.2 不同点 5.运算特点6.总结 九、条件操作符1.成员2.运算规则3.总结 十、逗号表达式1.成员2.用法介绍2.1 隔开同类型的操作对象2.2 隔开表达式 3.运算规则4.总结 十一、下标引用、函数调用、和结构成员1.成员2."[]"——下标引用操作符3."()"——函数调用操作符3.1 操作符的使用 4."."/"->"——结构体成员操作符4.1 什么是结构体?4.2 为什么结构体成员操作符有两个?它们有什么区别?4.2 操作符的使用 5.总结 十二、表达式求值1.隐式类型转换1.1 整型提升1.1.1 什么是整型提升?1.1.2 整型提升的意义 1.2 如何进行整型提升?1.3 截断1.4 小结1.5 算术转换1.6 什么是算术转换?1.7 小结 2.操作符的属性2.1 优先级2.2 结合性2.3 小结 3.问题表达式解析3.1 表达式一——a * b + c * d + e * f3.
【主题广范|见刊快】2024年海洋工程与测绘遥感国际学术会议(ICOESRS 2024)
2024 International Conference Ocean Engineering and Surveying Remote Sensing(ICOESRS 2024)
一、【会议简介】
随着人类对海洋的认识和开发不断深入,海洋工程和测绘遥感技术的研究和应用也日益重要。这个会议的召开,无疑为推动海洋科技的发展提供了一个国际化的交流平台。
在这次会议上,将会有众多知名专家和学者分享他们在海洋工程和测绘遥感领域的最新研究成果。这些研究涵盖了海洋资源开发、海洋环境保护、海洋灾害预警等多个方面。通过分享这些研究成果,与会者可以了解最新的技术进展和应用前景。
二、【征稿主题】主题包括但不限于以下
水下声学和声学海洋学
声呐信号/图像处理与通信
海洋观测平台、系统和仪器
遥感
海洋数据可视化、建模和信息管理
海洋环境、海洋学和气象学
光学、成像、视觉和 E-M 系统
海洋法律、政策、管理和教育
海洋工程结构与技术
远洋航行器和浮动结构
海底工程和海底作业
海底光学传感、成像和仪器仪表
深水开发技术
海洋工程结构与技术
船舶和机器人
远洋航行器和浮动结构
海洋环境、海洋学和气象学
环境遥感
图象数据处理技术
高光谱影像处理 遥感信息提取 光学成像 大数据分析与处理 光学遥感 全球定位和导航系统
合成孔径雷达
地理信息系统(GIS) 微波遥感 地理信息科学 全球导航卫星系统(GNSS)
摄影测量学
大地测量学 测绘技术 工程测量学
矿山测量学 精密测绘仪器 GPS原理与应用
数字测图
光学仪器
数字图像处理
三、【重要信息】
投稿邮箱:title_sub@163.com
投稿时请邮箱正文备注:论文投稿+苏老师推荐+投稿人姓名
最终截稿时间:请查看官网
接受/拒稿:投稿后2-3日内通知
四、【论文提交】
1. 文章需全英文,重复率低于30%。
2. 文章必须要有题目、作者、单位、邮箱、关键词、摘要、必要的图表、结论、参考文献等。
3. 投稿流程:投稿→审稿→录用→注册→开具增值税普票(专票)→电子版→纸质版→检索。
前端面试大全·JS浮点数精度问题及解决方案
🌟经典真题
🌟浮点数精度常见问题
🌟为什么会有这样的问题
🌟真题解答
🌟总结
🌟经典真题 为什么 console.log(0.2+0.1==0.3) 得到的值为 false 🌟浮点数精度常见问题 在 JavaScript 中整数和浮点数都属于 number 数据类型,所有数字都是以 64 位浮点数形式储存,即便整数也是如此。 所以我们在打印 1.00 这样的浮点数的结果是 1 而非 1.00 。
在一些特殊的数值表示中,例如金额,这样看上去有点别扭,但是至少值是正确了。
然而要命的是,当浮点数做数学运算的时候,你经常会发现一些问题,举几个例子:
场景一:进行浮点值运算结果的判断
// 加法 console.log(0.1 + 0.2); // 0.30000000000000004 console.log(0.7 + 0.1); // 0.7999999999999999 console.log(0.2 + 0.4); // 0.6000000000000001 console.log(2.22 + 0.1); // 2.3200000000000003 // 减法 console.log(1.5 - 1.2); // 0.30000000000000004 console.log(0.3 - 0.2); // 0.09999999999999998 // 乘法 console.log(19.9 * 100); // 1989.
一、安装LIO-SAM 1.环境配置 默认已经安装过ros
sudo apt-get install -y ros-Noetic-navigation sudo apt-get install -y ros-Noetic-robot-localization sudo apt-get install -y ros-Noetic-robot-state-publisher 安装 gtsam(如果是18.04的ubuntu直接按照官网配置,20.04见下面的链接)
sudo add-apt-repository ppa:borglab/gtsam-release-4.0 sudo apt install libgtsam-dev libgtsam-unstable-dev catkin_make in ROS Noetic [Error] · Issue #206 · TixiaoShan/LIO-SAM · GitHub
2.下载编译代码 cd ~/catkin_ws/src git clone https://github.com/TixiaoShan/LIO-SAM.git cd .. catkin_make 二、 lidar和imu的外参标定以及imu的内参标定 外参标定见我的上一个文章,这里只说一下imu内参标定
Ubuntu20.04编译并运行imu_utils,并且标定IMU-CSDN博客
这篇文章里面的第二章imu数据采集,其实就是运行imu驱动,然后录制一个bag包。其他的他都讲的很详细这里就不说了。
三、热室地图重建 修改lio-sam的config里面的params.yaml里面的lidar和imu话题以及imu内参,lidar_imu的外参等
针对密闭热室空间的重建这几个参数至关重要(因为空间里面好多相似的管道,所以对于点面特征的匹配要求很高)
实验发现:
mappingCornerLeafSize从0.1变成0.2,地图并不会发生大幅度飘逸,但是在局部区域对不齐,会有翻转和微量飘移。
mappingSurfLeafSize从0.2变为0.4,地图会直接飞走。
odometrySurfLeafSize从0.2变为0.4,效果和0.2差不多,但是会存在一定的拖影。
#============================== Global Settings =============================
[global]
samba服务器的全局设置,对整个服务器有效。
workgroup
语法:workgtoup = <工作组群>;
预设:workgroup = MYGROUP
说明:设定 Samba Server 的工作组
例:workgroup = workgroup 和WIN2000S设为一个组,可在网上邻居可中看到共享。
server string
语法:server string = <说明>;
预设:sarver string = Samba Server
说明:设定 Samba Server 的注释
其他:支持变量 t%-访问时间 I%-客户端IP m%-客户端主机名 M%-客户端域名 S%-客户端用户名
例:server string = this is a Samba Server 设定出现在Windows网上邻居的 Samba Server 注释为 this is a Samba Server
hosts allow
语法:hosts aoolw = <IP地址>; ...
预设:; host allow = 192.
本文并非基于微调训练模型,而是从头开始训练出一个全新的大语言模型的硬核教程。看完本篇,你将了解训练出一个大模型的环境准备、数据准备,生成分词,模型训练、测试模型等环节分别需要做什么。AI 小白友好~文中代码可以直接实操运行。欢迎阅读体验。
目录
1 准备训练环境
2 准备训练数据
3 训练分词器
4 训练模型
5 测试模型
6 完整代码
通过这篇文章,你可以预训练一个全新大语言模型。
注意是全新的模型,不是微调。
全新训练的好处是训练的数据、训练的参数都是可修改的,通过调试运行我们可以更好的理解大模型训练过程。我们可以用特定类型数据的训练,来完成特定类型数据的输出。
关于大模型已经有很多文章,微调模型的文章比较多,全新预训练全新模型的文章很少。个人觉得有的也讲的很复杂,代码也很难跑通。本文不会讲的很复杂,代码也很容易运行。仅用61行代码,就能训练出一个全新大语言模型。
本文以代码为主,运行代码需要 Python 环境。
01、准备训练环境 我的训练环境基于腾讯云的 GPU 机器。
地址:https://cloud.tencent.com/product/gpu
GPU类型:GN7.2XLARGE32 T4 显卡:1颗 显存:16GB;
python 3.11;
requirements.txt: tokenizers==0.13.3 torch==2.0.1 transformers==4.30. 02、准备训练数据 首先我们要为训练准备数据,比如我就想基于《三国演义》训练一个模型。三国演义下载地址:
https://raw.githubusercontent.com/xinzhanguo/hellollm/main/text/sanguoyanyi.txt
03、训练分词器 分词(tokenization)是把输入文本切分成有意义的子单元(tokens)。通过以下代码,根据我们的数据生成一个新的分词器:
from tokenizers import Tokenizer from tokenizers.models import BPE from tokenizers.trainers import BpeTrainer from tokenizers.normalizers import NFKC, Sequence from tokenizers.pre_tokenizers import ByteLevel from tokenizers.decoders import ByteLevel as ByteLevelDecoder from transformers import GPT2TokenizerFast # 构建分词器 GPT2 基于 BPE 算法实现 tokenizer = Tokenizer(BPE(unk_token="
目录:导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结(尾部小惊喜) 前言 1、银行项目转账功能的测试点
1)手机号转账模块
点击是否可以正常进入
是否可以输入手机号
是否可以选择收款银行
收款人姓名是否可以正常输入
附言是否可以正常输入
点击下一步是否可以跳转至转账确认界面
是否显示转账信息
是否可以选择安全工具
密码框是否可以输入
点击确认是否可以跳转至结果界面
是否显示转账详细信息
点击完成是否可以跳转至首页
2)账号转账模块
账号转账模块
是否可以正常打开该模块
点击转出账户模块是否可以选择账户
点击输入金额是否可以正常输入
点击转账币种是否可以选择其他币种
点击输入收款账户是否可以正常输入
点击收款人名称是否可以正常输入
点击短信通知收款人是否可以选择
点击附言是否可以正常输入
附言是否可以输入超出20个汉字字符
点击转账方式是否可以选择
点击下一步是否跳转至转账确认界面
是否显示默认安全工具
点击安全工具是否可以选择
选择安全工具是否跳转至输入交易密码的页面
密码框是否可以正常输入
点击确定是否可以跳转至操作结果模块
转账详情是否有详情按钮
点击详情按钮是否显示转账详细信息
是否显示完成按钮
点击完成是否跳转至转账模块
3)转账记录模块
转账记录模块是否可以正常进入
是否显示近三个月的转账记录
是否有筛选按钮
是否可以筛选近2年的交易记录
筛选区间是否可以大于三个月
点击一条转账记录是否可以跳转至详情界面
是否显示分享给微信好友的按钮
点击分享给微信好友是否生成交易回单
转账记录是否可以删除
4)预约转账
转账信息模块是否可以正常打开预约转账模块
点击发起预约转账是否可以跳转至转账页面
是否可以选择付款账户
是否可以选择币种
是否可以正常注入收款人名称
是否可以输入收款帐号
是否可以选择转账方式
是否可以点击立即预约
点击预约是否可以跳转至预约见面
预约界面选择预约日期执行
点击日期是否可以进行选择
点击下一步是否跳转至支付界面
选择预约周期执行
预约周期是否可以选择
起始日期是否可以选择
结束日期是否可以选择
点击下一步是否跳转至支付页面
转账确认模块是否显示转账信息
是否可以选择安全工具
文章目录 1 前言2 先上成果3 车道线4 问题抽象(建立模型)5 帧掩码(Frame Mask)6 车道检测的图像预处理7 图像阈值化8 霍夫线变换9 实现车道检测9.1 帧掩码创建9.2 图像预处理9.2.1 图像阈值化9.2.2 霍夫线变换 最后 1 前言 🔥 优质竞赛项目系列,今天要分享的是
🚩 机器视觉 深度学习 车道线检测 - opencv
该项目较为新颖,适合作为竞赛课题方向,学长非常推荐!
🥇学长这里给一个题目综合评分(每项满分5分)
难度系数:3分工作量:3分创新点:4分 🧿 更多资料, 项目分享:
https://gitee.com/dancheng-senior/postgraduate
2 先上成果 3 车道线 理解车道检测的概念
那么什么是车道检测?以下是百度百科对车道的定义:
车道,又称行车线、车行道,是用在供车辆行经的道路。在一般公路和高速公路都有设置,高速公路对车道使用带有法律上的规则,例如行车道和超车道。
对其进行定义是很重要的,因为它使我们能够继续进行车道检测概念。我们在建立一个系统时不能有任何含糊不清的地方。
正如我前面提到的,车道检测是自动驾驶汽车和自动驾驶汽车的关键组成部分。这是驾驶场景理解的重要研究课题之一。一旦获得车道位置,车辆就知道去哪里,并避免撞上其他车道或离开道路。这样可以防止驾驶员/车辆系统偏离车道。
以下是一些随机道路图像(第一行)及其检测到的车道(第二行):
4 问题抽象(建立模型) 我们希望执行的任务是实时检测视频中的车道。我们可以通过多种方式进行车道检测。我们可以使用基于学习的方法,例如在带注释的视频数据集上训练深度学习模型,或者使用预训练好的模型。
然而,也有更简单的方法来执行车道检测。在这里,学长将向你展示如何在不使用任何深入学习模型的情况下完成此任务。
下面是将要处理的视频的一个帧:
正如我们在这张图片中看到的,我们有四条车道被白色的车道标线隔开。所以,要检测车道,我们必须检测车道两边的白色标记。这就引出了一个关键问题——我们如何检测车道标线?
除了车道标线之外,场景中还有许多其他对象。道路上有车辆、路侧护栏、路灯等,在视频中,每一帧都会有场景变化。这很好地反映了真实的驾驶情况。
因此,在解决车道检测问题之前,我们必须找到一种方法来忽略驾驶场景中不需要的对象。
我们现在能做的一件事就是缩小感兴趣的领域。与其使用整个帧,不如只使用帧的一部分。在下面的图像中,除了车道的标记之外,其他所有内容都隐藏了。当车辆移动时,车道标线将或多或少地落在该区域内:
5 帧掩码(Frame Mask) 帧掩码只是一个NumPy数组。
当我们想对图像应用掩码时,只需将图像中所需区域的像素值更改为0、255或任何其他数字。
下面给出了一个图像掩蔽的例子。图像中某个区域的像素值已设置为0:
这是一种非常简单但有效的从图像中去除不需要的区域和对象的方法。
6 车道检测的图像预处理 我们将首先对输入视频中的所有帧应用掩码。
然后,我们将应用图像阈值化和霍夫线变换来检测车道标线。
7 图像阈值化 在这种方法中,灰度图像的像素值根据阈值被指定为表示黑白颜色的两个值之一。因此,如果一个像素的值大于一个阈值,它被赋予一个值,否则它被赋予另一个值。
如上所示,对蒙版图像应用阈值后,我们只得到输出图像中的车道标线。现在我们可以通过霍夫线变换很容易地检测出这些标记。
8 霍夫线变换 霍夫线变换是一种检测任何可以用数学方法表示的形状的方法。
前言 chatGPT是一款高效强大的语言模型,能够给我们的生活带来极大的改变。无论是学习知识还是工作效率,chatGPT都能为我们提供有力的帮助。它可以帮助我们快速获取所需的知识,同时可以帮助我们提高工作效率,包括写文章、文案、推荐策略、生成代码、写周报,流程图等等。此外,它还可以成为您智能的助手,帮您打理日常事务,如一键预约、贴心提醒等。对于小朋友们来说,他还可以为他们写作文。总之,chatGPT是一个多功能的智能管家,不管您的需求是什么,它都能为您提供强大的支持。欢迎有需要的朋友戳链接体验:Talk-Bot,不喜勿喷,广交益友
废话不多说,直接上代码
SseEmitter 这种方式比较常用,我们这里引入github上PlexPt大神封装好的类直接引用即可,地址为:chatgpt-java,也可以自己封装哈
<dependency> <groupId>com.github.plexpt</groupId> <artifactId>chatgpt</artifactId> <version>4.0.7</version> </dependency> private static final String OPENAI_API_HOST = "https://api.openai.com/"; @PostMapping(value = "/v1/stream") public SseEmitter streamEvents(@RequestBody ChatRequest chatRequest) { SseEmitter sseEmitter = new SseEmitter(-1L); // 不需要代理的话,注销此行 Proxy proxy = Proxys.http("192.168.1.98", 7890); ChatGPTStream chatGPTStream = ChatGPTStream.builder() .timeout(600) .apiKey("你的openApiKey") .proxy(proxy) .apiHost(OPENAI_API_HOST) .build() .init(); SseStreamListener listener = new SseStreamListener(sseEmitter); Message message = Message.of(chatRequest.getInput()); ChatCompletion chatCompletion = ChatCompletion.builder() .model(ChatCompletion.Model.GPT_3_5_TURBO.getName()) .messages(Arrays.asList(message)) .build(); chatGPTStream.streamChatCompletion(chatCompletion, listener); listener.setOnComplate(msg -> { //回答完成,可以做一些事情 sseEmitter.
校验List 在进行参数非空校验时,我们总是容易直接就对任何的东西都来一个!= null
其实这样并不完全正确,对list类型来说 不等于null和list.size != 0是不一样的。
不等于null是指已经声明了list的存在,并且在堆内存中有了引用。
size!=0是指里面没有东西。
将list就想成一个盒子,元素就是一个一个的球,list为null时,说明盒子不存在,size==0时,说明有盒子,只是盒子里没有球。
对于list的非空校验我通常使用的是
List list = new List(); if( list != null && list.size != 0)system.out.println(''集合存在且不空''); else system.out.println(''集合不存在或者集合为空''); 校验字符串 有两个方法:
1.StringUtil.isNotEmpty() 2.StringUtil.isNotBlank() 首先两个方法都可以对null进行判断
StringUtil.isNotEmpty( null ) 返回false StringUtil.isNotBlank( null ) 返回false 对空字符串 "" 进行判断
StringUtil.isNotEmpty( "" ) 返回false StringUtil.isNotBlank( "" ) 返回false 唯一的区别在于对于空格字符的判断
StringUtil.isNotEmpty( " " ) 返回true StringUtil.isNotBlank( " " ) 返回false 如果字符串是一连串的空格,那么isNotEmpty()的返回值就是true,认为该串不空
但是对于isNotBlank( " " )则会认为没有有效字符,返回false
通常我们使用isNotBlank来判断有效值
if(StringUtils.isBlank(phoneNumber)){ throw new RestException("
1.垃圾回收机制 #1.引用计数 x=10 # 直接引用 print(id(x)) y=x z=x l=['a', 'b', x] # 间接引用 print(id(l[2])) d = {'mmm': x} print(id(d['mmm'])) # 2.标记清除 # 循环引用=》导致内存泄露 l1 = [111, ] l2 = [222, ] l1.append(l2) # l1=[值111的内存地址,l2列表的内存地址] l2.append(l1) # l2=[值222的内存地址,l1列表的内存地址] print(id(l1[1])) print(id(l2)) print(id(l2[1])) print(id(l1)) print(l2) print(l1[1]) del l1 del l2 #3.分代回收 分代指的是根据存活时间来为变量划分不同等级(也就是不同的代) 新定义的变量,放到新生代这个等级中,假设每隔1分钟扫描新生代一次, 如果发现变量依然被引用,那么该对象的权重(权重本质就是个整数)加一, 当变量的权重大于某个设定得值(假设为3),会将它移动到更高一级的青春代, 青春代的gc扫描的频率低于新生代(扫描时间间隔更长),假设5分钟扫描青春代一次, 这样每次gc需要扫描的变量的总个数就变少了,节省了扫描的总时间, 接下来,青春代中的对象,也会以同样的方式被移动到老年代中。 也就是等级(代)越高,被垃圾回收机制扫描的频率越低 2.格式化输出 1.%号 # 1、格式的字符串(即%s)与被格式化的字符串(即传入的值)必须按照位置一一对应 # ps:当需格式化的字符串过多时,位置极容易搞混 print('%s asked %s to do something' % ('egon', 'lili')) # egon asked lili to do something print('%s asked %s to do something' % ('lili', 'egon')) # lili asked egon to do something # 2、可以通过字典方式格式化,打破了位置带来的限制与困扰 print('我的名字是 %(name)s, 我的年龄是 %(age)s.
bug如题,仅作个人记录。 Ubuntu 20.04Python 3.8.17terminal 运行python文件 本人是在用键盘控制Airsim仿真无人机时爆出该错误,网上搜索的方式都解决不了,这里简单记录。
用以下这套安装和运行命令,反正至少我的环境work了。
sudo pip3 install keyboard sudo python3 XXX.py PS. 我胡汉三终于回来咯,干了很久的杂事,回归老本行,开始陆陆续续恢复更新~
winpcap 官网:http://www.winpcap.org/
1.首先下载安装 winpcap.exe,http://www.winpcap.org/install/default.htm
目的是安装相关驱动和 dll,安装完成之后基于 winpcap 的应用程序才能够正常运行。
2.下载 winpcap 的开发包,头文件和库文件:http://www.winpcap.org/devel.htm,解压之后主要是头文件和库文件,记得将 WpdPack 复制到 D 盘(直接放在D盘,不要包含在其他文件夹下),如图所示:
VS2022新建一个C++工程,具体操作可参考我上一篇文章,文章链接如下:http://t.csdnimg.cn/RRO57
创建工程后,首先在 vs 中配置(vc++目录:include 目录和 lib 目录),具体步骤如下:
点击“项目”,再点击最下方的属性:
点击VC++目录,如图所示:
接下来修改“包含目录”和“库目录”,包含目录修改为:D:\WpdPack\Include;$(IncludePath)
库目录修改为:D:\WpdPack\Lib\x64;$(LibraryPath),如图所示:
接着,link 输入:wpcap.lib,ws2_32.lib,具体步骤如下:
在左边的配置属性找到“链接器”,点击,接着点击“输入”:
然后在“附加依赖项”处,添加wpcap.lib和ws2_32.lib两个库,如图所示:(前面的用这两个替换掉,后面的不要动)
接着点击配置预处理器定义,具体步骤如下:
在配置属性处点击C/C++,接着点击“预处理器”,如图所示:
在“预处理器定义”处修改为“WPCAP;HAVE_REMOTE;WIN32;_CRT_SECURE_NO_WARNINGS;_WINSOCK_DEPRECATED_NO_WARNINGS”,如图所示:
接着点击“应用”,再点击“确定”,如图:
代码如下:
//#define HAVE_REMOTE //#define WPCAP #include "pcap.h" #include <winsock2.h> #include <string.h> #include <stdio.h> using namespace std; #pragma comment(lib, "wpcap.lib") #pragma comment(lib, "Ws2_32.lib") #define LINE_LEN 16 #define MAX_ADDR_LEN 16 FILE* file = 0; int ip_len; int tcp_len; // 以太网协议格式的定义 typedef struct ether_header { u_char ether_dhost[6]; // 目标 MAC 地址 u_char ether_shost[6]; // 源 MAC 地址 u_short ether_type; // 以太网类型 }ether_header; // 用户保存 4 字节的 IP 地址 typedef struct ip_address { u_char byte1; u_char byte2; u_char byte3; u_char byte4; }ip_address; // 用于保存 IPV4 的首部 typedef struct ip_header { u_char version_hlen; // 首部长度 版本 u_char tos; // 服务质量 u_short tlen; // 总长度 u_short identification; // 身份识别 u_short flags_offset; // 标识 分组偏移 u_char ttl; // 生命周期 u_char proto; // 协议类型 u_short checksum; // 包头测验码 u_int saddr; // 源 IP 地址 u_int daddr; // 目的 IP 地址 }ip_header; // 用于保存 TCP 首部 typedef struct tcp_header { u_short sport; u_short dport; u_int sequence; // 序列码 u_int ack; // 回复码 u_char hdrLen; // 首部长度保留字 u_char flags; // 标志 u_short windows; // 窗口大小 u_short checksum; // 校验和 u_short urgent_pointer; // 紧急指针 }tcp_header; // 用于保存 UDP 的首部 typedef struct udp_header { u_short sport; // 源端口 u_short dport; // 目标端口 u_short datalen; // UDP 数据长度 u_short checksum; // 校验和 }udp_header; // 用于保存 ICMP 的首部 typedef struct icmp_header { u_char type; // ICMP 类型 u_char code; // 代码 u_short checksum; // 校验和 u_short identification; // 标识 u_short sequence; // 序列号 u_long timestamp; // 时间戳 }icmp_header; // 用于保存 ARP 的首部 typedef struct arp_header { u_short hardware_type; // 格式化的硬件地址 u_short protocol_type; // 协议地址格式 u_char hardware_length; // 硬件地址长度 u_char protocol_length; // 协议地址长度 u_short operation_code; // 操作码 u_char source_ethernet_address[6]; // 发送者硬件地址 u_char source_ip_address[4]; // 发送者协议地址 u_char destination_ethernet_address[6]; // 目的方硬件地址 u_char destination_ip_address[4]; // 目的方协议地址 }arp_header; #define str4cmp(m, c0, c1, c2, c3) \ (m[0] == c0 && m[1] == c1 && m[2] == c2 && m[3] == c3) void http_protocol_packet_handle(u_char* arg, const struct pcap_pkthdr* pkt_header, const u_char* pkt_content) { FILE* file1 = 0; //下面这个打开文件能写在这里吗?在这里打开有什么问题?写在这里合适吗?如何改进一下? if ((file1 = freopen("
有没有想过强化学习 (RL) 是如何工作的?
在本文中,我们将从头开始构建最简单的强化学习形式之一 —普通策略梯度(VPG)算法。 然后,我们将训练它完成著名的 CartPole 挑战 — 学习从左向右移动购物车以平衡杆子。 在此过程中,我们还将完成对 OpenAI 的 Spinning Up 学习资源的第一个挑战。
NSDT工具推荐: Three.js AI纹理开发包 - YOLO合成数据生成器 - GLTF/GLB在线编辑 - 3D模型格式在线转换 - 可编程3D场景编辑器 - REVIT导出3D模型插件 - 3D模型语义搜索引擎
本文的代码可以在 这里 找到。
1、我们的方法 我们将通过创建一个简单的深度学习模型来解决这个问题,该模型接受观察并输出随机策略(即采取每个可能行动的概率)。
然后,我们需要做的就是通过在环境中采取行动并使用此策略来收集经验。
当我们有足够的批量经验(几个episode经验的集合)后,我们需要转向梯度下降来改进模型。 在较高层面上,我们希望增加策略的预期回报,这意味着调整权重和偏差以增加高预期回报行动的概率。 就 VPG 而言,这意味着使用策略梯度定理,该定理给出了该预期回报的梯度方程(如下所示)。
这就是全部内容了—所以让我们开始编码吧!
2、创建模型 我们将首先创建一个带有一个隐藏层的非常简单的模型。 第一个线性层从 CartPole 的观察空间获取输入特征,最后一层返回可能结果的值。
def create_model(number_observation_features: int, number_actions: int) -> nn.Module: """Create the MLP model Args: number_observation_features (int): Number of features in the (flat) observation tensor number_actions (int): Number of actions Returns: nn.
以pulp为例,
已在cmd中使用pip安装pulp库,但是使用pycharm调用pulp库import pulp时报错,显示没有这个库
(pip list中有pulp库,但是pycharm中始终无法调用,即显示未安装pulp)
1、找原因:主要是pycharm运行的解释器是 Anaconda3 里的库,但是直接使用cmd+pip下载的库在系统里,并不是在这个Anaconda3环境里
解决方案:在Anaconda3环境里安装pulp库即可
2、使用【win+R】弹出运行窗口,输入cmd进入小黑框
此步骤主要参考:CMD安装库的方法
(https://jingyan.baidu.com/article/e4511cf39d7e386a855eaf25.html)
1)查看环境变量名字,如变量名为“base”
conda info --envs 2)激活环境
格式为activate <环境变量名>
activate base 3)转到.whl文件所在的文件地址去
转盘直接e:这样,转到E盘具体文件地址,用 cd\<地址>
(这里的安装是错误示范,因为并没有安装到 Anaconda3里去,仍然是系统的本身的环境,所以还是会显示没有安装pulp库)
报错如下: 显示已经安装过(在系统环境里),不能安装。
正确安装状态,如下图所示:
在Anaconda3环境里正常安装。
安装指令格式如:python -m pip install +空格+文件全名(包括后缀)
此时,再调用pulp包不再报错。
4)可以顺手把系统环境里的pulp库卸载掉
至此,问题解决。
其他第三方python库可同理。
还有一种偷懒的方法
若已经在python里下载了完整的库,且库比较大,下载时间耗时,可以直接把这个库挪到Anaconda里面就行
复制或者粘贴到Anaconda的site-packages里
kafak是一个分布式流处理平台,提供消息持久化,基于发布-订阅的方式的消息中间件,同时通过消费端配置相同的groupId支持点对点通信。
##适用场景:
构造实时流数据管道,用于系统或应用之间可靠的消息传输.数据采集及处理,例如连接到一个数据库系统,捕捉表的变更内容.构建实时流式应用程序,对这些流数据进行转换或者影响,如:应用程序作为一个流处理器,消费一个或者多个topic产生的输入流,然后生产一个输出流到一个或多个topic中去,在输入输出流中进行有效的转换.应用耦合:多应用间通过消息队列对同一消息进行处理,避免调用接口失败导致整个过程失败;异步处理:多应用对消息队列中同一消息进行处理,应用间并发处理消息,相比串行处理,减少处理时间;限流削峰:广泛应用于秒杀或抢购活动中,避免流量过大导致应用系统挂掉的情况;消息驱动的系统:系统分为消息队列、消息生产者、消息消费者,生产者负责产生消息,消费者(可能有多个)负责对消息进行处理; ##特性:
8. 生产者/消费者支持多语言。
9. 支持分布式横向扩缩容。
10. 高性能(高吞吐量)。
11. 版本向下兼容。
12. 提供消息持久化。
13. 流处理。
##高性能实现:
14. 磁盘顺序读取和写入(接近内存随机读写的性能)。
15. nio和零拷贝。
16. 消息批处理。
17. 消息压缩
##多个producer和多个consumer group及zk示意图如下:
其中zookeeper是基于zab分布式协议实现的一个组件,主要实现对broker集群起协调作用,详细的后面文章再探讨.
注意图中的消费者和生产者,均是仅和分区的leader相连,所有的flower不参与外部交互,在内部作为leader的消费者去拉去消息进行追赶.
其中broker中还有几个概念
##问:kafka是如何保证它的高吞吐量?
1.消息生产者批量发送压缩消息
结合磁盘顺序写入,批量处理无疑是非常有必要(如果用的时候每发送一条消息都调用future.get等待,性能至少下降2个数量级)。写入的时候放到RecordAccumulator进行聚合,批量压缩,还有批量刷盘等…
producer批量并压缩消息–>broker直接落盘–>consumer批量获取消息并解压
批量和压缩可以大大降低网络开销和磁盘io开销,极大的提高吞吐量,且消息体越大,单批消息越多,效果越好.
broker端有个压缩格式的配置,默认跟从producer配置,若是指明了压缩格式后,则必须保证producer和broker一致,否则将会导致0拷贝失效,建议采用默认配置,既该配置会尊重producer的压缩格式.
简单来讲,整个生产者客户端(java版本)由两个线程协调运行,这两个线程分别为主线程和Sender线程(发送线程)。在主线程中由KafkaProducer创建消息,然后通过可能的拦截器、序列化器和分区器的作用之后缓存到消息累加器(RecordAccumulator,也称为消息收集器)中。Sender 线程负责从RecordAccumulator中获取消息并将其发送到Kafka中。RecordAccumulator 主要用来缓存消息以便 Sender 线程可以批量发送,进而减少网络传输的资源消耗以提升性能。
2、pageCache的使用
kafka没有选择In-Process Cache的方式,而是在消息写入和读取的过程中充分的利用了操作系统的页缓存及磁盘预读取等特性。
pageCache避免在JVM内部缓存数据,当broker重启时,由于避免了缓存加载到jvm中的过程,大大加快broker的恢复速度,同时可避免不必要的GC,大大节约内存占用.磁盘预读取则有效的降低了磁盘io次数.kafka的消息读取和写入,时间复杂度为O(1)
3、零拷贝(Zero-Copy) (包括kafka收到消息写和kafka发出消息读)
由原来的四次拷贝转换为两次拷贝,这是其一;同时也减少了内核态和用户态的切换开销。
零拷贝是有硬件条件支持的,即DMA:DMA(Direct Memory Access,直接内存存取) 是所有现代计算机的重要特色,它允许不同速度的硬件装置直接沟通,而不需要依于CPU的大量中断负载.在现代计算机中,运算单元不再仅仅是cpu。网卡/磁盘等都可以认为是DMA设备,是一个半自治单元,比如网卡有它自己的运算单元(相当于特异化的cpu)和自己的缓存,网卡接收和发送数据时是不需要cpu的全程参与的,磁盘也是类似的.简单来讲就是dma设备就是cpu领导下的一个不太聪明的小弟,cpu负责指挥小弟去干活,但干活的过程中是不需要cpu参与的.nio和0拷贝都是为了解放cpu。
4、磁盘顺序读写(包括kafka收到消息写和kafka发出消息读)
kafka采用日志append的方式,一直在文件的末尾追加消息,既顺序写入,该方式比内存的随机写还要快一些,相当于按住磁头不动一直写,不需要多于的磁柱旋转时间和磁头寻址时间。还有一点是一个ProducerBatch是4KB,OS每次写是(8*512B)=4KB
5、Kafka二分查找定位数据
Kafka里面每一条消息,都有自己的offset(相对偏移量),存在物理磁盘上面,在position Position:物理位置(磁盘上面哪个地方)也就是说一条消息就有两个位置:offset:相对偏移量(相对位置)position:磁盘物理位置 稀疏索引: Kafka中采用了稀疏索引的方式读取索引,kafka每当写入了4k大小的日志(.log),就往index里写入一个记录索引。其中会采用二分查找
##问kafka什么情况下零拷贝失效?
1客户端的压缩格式和服务的压缩格式不一样
2由于消息格式的变动,若是集群版本和客户端版本不一致,有可能broker为了协议兼容,需要做消息格式转换,此转换会导致kafka的零拷贝失效,生产环境的表现就是kafka集群的性能大幅下降,尤其需要注意的是kafka的0.10.x和0.11.x,这两个版本把kakfa的消息格式分为了三个版本。
零拷贝可参考如下几篇优秀文章:
Linux I/O 原理和 Zero-copy 技术全面揭秘
张彦飞:图解Linux网络包接收过程
##1、KAFKA的核心组件/API
Producer API,它允许应用程序向一个或多个 topics 上发送消息记录
Consumer API,允许应用程序订阅一个或多个 topics 并处理为其生成的记录流
Streams API,它允许应用程序作为流处理器,从一个或多个主题中消费输入流并为其生成输出流,有效的将输入流转换为输出流。
Connector API,它允许构建和运行将 Kafka 主题连接到现有应用程序或数据系统的可用生产者和消费者。例如,关系数据库的连接器可能会捕获对表的所有更改
如下是KAFKA API图
##2、KAFKA的一些概念
我们从几个图来了解KAFKA的相关概念
2.1、broker/物理概念:一个kafka服务器实例就是一个broker,多个kafka instance构成kafka cluster。broker 接收来自生产者的消息,为消息设置偏移量,并提交消息到磁盘保存。broker 为消费者提供服务,对读取分区的请求作出响应,返回已经提交到磁盘上的消息。
2.2、topic/逻辑概念:在 kafka 中,使用一个类别属性来划分消息的所属类,划分消息的这个类称为 topic。在 kafka 中,可以无数个topic。
2.3、partion/物理概念:默认一个topic有一个分区(partition),自己可设置多个分区(分区分散存储在服务器不同节点上),partition在磁盘上就体现为一个目录。一个分区就是一个 提交日志。消息以追加的形式写入分区,先后以顺序的方式读取。
2.4、segment/物理概念:一个partition当中存在多个segment文件段,每个 segment 文件的大小相等且每个segment分为两部分,.log文件和.index文件,其中.index文件是索引文件,主要用于快速查询.log文件当中数据的偏移量位置
2.5、producer/物理概念:生产消息并通过zookeeper集群得知broker地址将消息push到broker中
2.6、consumer/物理概念:生产消息并通过zookeeper集群得知broker地址将消息从broker中pull到
2.7、zookeeper cluster/物理概念:相当于注册中心,含有broker信息,producer信息,consumer信息
2.8、consumer group/逻辑概念:由多个consumer组成共同消费broker/topic中的消息,消费者在消费消息时需要提供一个group id。注意的是同组消费者是处于竞争关系,即消息只能被同组中的某个消费者消费
2.9、controller/逻辑概念:控制器,在 Kafka 集群中会有一个或多个 broker,其中有一个 broker 会被选举为控制器(Kafka Controller),它负责管理整个集群中所有分区和副本的状态。
2.10、ConsumerCoordinator与GroupCoordinator:新版本消费者为了降低对zk的依赖,避免羊群效应和脑裂问题,服务端引入了组协调器,消费者客户端引入了消费者协调器负责与服务端的组协调器进行交互。最重要的职责就是负责执行消费者再均衡的操作,包括分区分配的工作也是在再均衡期间完成的。
##3、对于上面kafka概念补充说明
3.1、topic补充说明:
3.1.1:首先它是一个逻辑上的东西,它有多个或一个分区组成,并且当有多个分区且多个broker实例时,一个topic的消息以分区的形式可以存在在不同的broker上。如下图partition0+partition1+partition2=topic,且partition0、partition1、partition2可以自由地分布在不同broker中
3.1.2:topic的Partition数量在创建topic时配置。
3.1.3:Partition数量决定了每个Consumer group中并发消费者的最大数量。如下图有两个broker,且topic被分成P0,P1,P2,P3四个分区,一个组中最大的并发消费数量为group B中的四个。
3.1.4:Partition中写入的offset
kafka当中的partition的offset任何发布到此partition的消息都会被直接追加到log文件的尾部,每条消息在文件中的位置称为offset(偏移量),offset是一个long类型数字,它唯一标识了一条消息,消费者通过(offset,partition,topic)跟踪记录。结合3.3看就能理解
3.2、Partition副本补充说明:
3.2.1:一个broker下不存在某个partition的副本,副本只能存在在其他broker中,如下图:
3.2.2:副本分为leader副本和follower副本。
leader副本,代表分区本身,生产者的push和消费者pull的时候都只能通过leader推送和获取.凡事都可能例外,在最新版本中存在配置可消费非leader副本(与跨中心镜像容灾相关,日常使用不到)。
follower副本,leader的跟班,负责同步leader的消息,是leader的备份,防止broker故障时丢失消息.对用户来说,不用关心,kafka内部维护,并在leader崩溃时自动选举新的leader。
isr副本集合:跟随leader最快的副本,在leader故障时,可配置优先从isr中选举leader或仅从isr中选举leader. isr是为了提高kafka的吞吐量,当kafka收到消息时,不用等待所有副本回复确认,这是可用性和一致性的权衡.isr在高版本的kafka中有配置的最大等待同步时间确定,低版本中还要再加一个最大延迟的条数.总之是个动态维护的副本子集。
3.3、Segment补充说明
一个partition当中由多个segment文件组成,每个segment文件,包含两部分,一个是.log文件,另外一个是.index文件,其中.log文件包含了我们发送的数据存储,.index文件,记录的是我们.log文件的数据索引值,以便于我们加快数据的查询速度。下图是.index文件和.log文件对应关系:
3.3.1:.index文件3,497代表:数据文件中的第三个message,它的偏移地址为497;.log文件Message 368772表示:在全局partiton中是第368772个message
消息系统 1、消息系统的演变 在大型系统中,会需要和很多子系统做交互,也需要消息传递,在诸如此类系统中,你会找到源系统(消息发送方)和 目的系统(消息接收方)。为了在这样的消息系统中传输数据,你需要有合适的数据管道。如下:
这种数据的交互看起来就很混乱,如果我们使用消息传递系统,那么系统就会变得更加简单和整洁。如下:
2、为什么要消息系统 2.1. 解耦合
2.2 异步处理 例如电商平台,秒杀活动。一般流程会分为:1: 风险控制 、2: 库存锁定 、3: 生成订单 、4: 短信通知 、5: 更新数据
2.3 通过消息系统将秒杀活动业务拆分开,将不急需处理的业务放在后面慢慢处理;流程改为:1: 风险控制 、2: 库存锁定 、3: 消息系统 、4: 生成订单 、5: 短信通知 、6: 更新数据
2.4 流量的控制 :1. 网关在接受到请求后,就把请求放入到消息队列里面 2.后端的服务从消息队列里面获取到请求,完成后续的秒杀处理流程。然后再给用户返回结果。优点:控制了流量 缺点:会让流程变慢
3、消息队列的两种模式 3.1、点对点模式
点对点模式下包括三个角色:消息队列、发送者 (生产者)、接收者(消费者)
消息发送者生产消息发送到queue中,然后消息接收者从queue中取出并且消费消息。消息被消费以后,queue中不再有存储,所以消息接收者不可能消费到已经被消费的消息。
点对点模式特点:
每个消息只有一个接收者(Consumer)(即一旦被消费,消息就不再在消息队列中);
发送者和接收者间没有依赖性,发送者发送消息之后,不管有没有接收者在运行,都不会影响到发送者下次发送消息;
接收者在成功接收消息之后需向队列应答成功,以便消息队列删除当前接收的消息;
3.2、发布/订阅模式
发布/订阅模式下包括三个角色:角色主题(Topic)、发布者(Publisher)、订阅者(Subscriber)
发布者将消息发送到Topic,系统将这些消息传递给多个订阅者。
发布/订阅模式特点:
每个消息可以有多个订阅者;
发布者和订阅者之间有时间上的依赖性。针对某个主题(Topic)的订阅者,它必须创建一个订阅者之后,才能消费发布者的消息。
为了消费消息,订阅者需要提前订阅该角色主题,并保持在线运行;
文章目录 LTO介绍LTO 开启方法 LTO介绍 LTO(Link Time Optimization,链接时优化)是一种在链接阶段进行优化的技术。传统的编译过程中,编译器仅能对单个编译单元进行优化。LTO 允许编译器看到跨编译单元的代码,从而进行更复杂和更有效的优化。
LTO 可以提高程序的性能、缩减代码体积、提高代码安全性。
性能提升
LTO 可以通过以下方式提高程序的性能:
内联函数:将频繁调用的函数内联到调用点,可以减少函数调用的开销。函数重定位:将函数的代码移动到更合适的位置,可以减少函数调用的距离。代码融合:将多个代码块合并为一个代码块,可以减少代码的执行次数。数据流分析:通过分析数据流,可以消除不必要的代码。 代码体积缩减
LTO 可以通过以下方式缩减代码体积:
函数内联:将频繁调用的函数内联到调用点,可以减少函数代码的体积。代码删除:通过分析数据流,可以消除不必要的代码。代码融合:将多个代码块合并为一个代码块,可以减少代码的体积。 代码安全性提高
LTO 可以通过以下方式提高代码安全性:
函数内联:将频繁调用的函数内联到调用点,可以减少函数调用带来的安全风险。代码删除:通过分析数据流,可以消除不必要的代码,从而减少代码中的安全漏洞。 LTO 的使用
LTO 通常在生产环境中使用,以提高程序的性能和安全性。LTO 可以通过编译器的编译选项来启用。例如,在 GCC 中,可以使用 -flto 选项来启用 LTO。
LTO 的使用需要注意以下几点:
LTO 会增加编译时间。LTO 可能会导致代码的行为发生变化,需要进行充分的测试。LTO 可能与某些特定的编译器选项或平台不兼容。 LTO 的应用场景
LTO 适用于以下场景:
性能要求高的程序,例如游戏、图形处理程序等。安全性要求高的程序,例如金融软件、医疗软件等。代码体积较大的程序,例如大型应用程序、数据库软件等。 LTO 开启方法 function(target_enable_lto TARGET ENABLE) if(NOT ${ENABLE}) return() endif() include(CheckIPOSupported) check_ipo_supported(RESULT result OUTPUT output) if(result) message(STATUS "IPO/LTO is supported!") set_property(TARGET ${TARGET} PROPERTY INTERPROCEDURAL_OPTIMIZATION ${ENABLE}) else() message(WARNING "
Mysql 5.7设置大小写忽略可以登录到Docker内部,修改/etc/my.cnf添加lower_case_table_names=1,并重启docker使之忽略大小写。但MySQL8.0后不允许这样,官方文档记录:
lower_case_table_names can only be configured when initializing the server. Changing the lower_case_table_names setting after the server is initialized is prohibited.
1、 拉取mysql镜像 docker pull mysql:8.0.35 2、 启动 docker run -d --restart=always -p 3306:3306 --name mysql -v /path/to/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=root mysql:8.0.35 --lower_case_table_names=1 注意--lower_case_table_names=1作为MYSQL配置一定要放在镜像名后面 3、 查看效果 登录到镜像中
docker exec -it mysql /bin/bash mysql –uroot –proot show global variables like ‘%case%’ 出现lower_case_table_names=1表示已经忽略大小写了
nexus官方没有arm架构的镜像,下面介绍一种自己制作镜像的方式
1、事先准备 在一个arm架构机器上安装docker下载nexus的linux版(https://www.sonatype.com/download-oss-sonatype)下载centos的arm架构镜像(docker pull centos-centos8.4.2105)下载arm版本的java8(https://www.oracle.com/cn/java/technologies/downloads/archive/) 2、编写运行nexus的脚本start-nexus-repository-manager.sh 下面脚本中的java版本和nexus版本需要根据自己下载的修改
#!/bin/bash umask 0027 JAVA_HOME="/usr/local/jdk.1.8.0_391" PATH=$JAVA_HOME/bin:$PATH nexus_base="/opt/nexus" if [ -z "$(ls -A ${nexus_base})" ]; then cd /opt tar -zxf nexus-3.29.2-02-unix.tar.gz -C ${nexus_base} chown -R nexus:nexus ${nexus_base} rm -rf nexus-3.29.2-02-unix.tar.gz fi cd ${nexus_base}/nexus-3.29.2-02/bin exec ./nexus run 3、编写Dockerfile 下面文件中的nexus和java版本根据实际情况修改
FROM centos:centos8.4.2105 ENV NEXUS_VERSION="3.29.2-02" ENV NEXUS_BASE="/opt/nexus" ENV JRE_VERSION="8u391" RUN groupadd -g 1000 nexus && useradd -r -u 1000 -g 1000 -m -c "Nexus Repository Manager" -d ${NEXUS_BASE} -s /bin/false nexus && mkdir -p ${NEXUS_BASE} ADD jdk-${JRE_VERSION}-linux-aarch64.
1--Prompt-Tuning 1-1--Prompt-Tuning介绍 Prompt-Tuning 高效微调只会训练新增的Prompt的表示层,模型的其余参数全部固定;
新增的 Prompt 内容可以分为 Hard Prompt 和 Soft Prompt 两类;
Soft prompt 通常指的是一种较为宽泛或模糊的提示,允许模型在生成结果时有更大的自由度,通常用于启发模型进行创造性的生成;
Hard prompt 是一种更为具体和明确的提示,要求模型按照给定的信息生成精确的结果,通常用于需要模型提供准确答案的任务;
Soft Prompt 在 peft 中一般是随机初始化prompt的文本内容,而 Hard prompt 则一般需要设置具体的提示文本内容;
1-2--实例代码 from datasets import load_from_disk from transformers import AutoTokenizer, AutoModelForCausalLM, DataCollatorForSeq2Seq from transformers import pipeline, TrainingArguments, Trainer from peft import PromptTuningConfig, get_peft_model, TaskType, PromptTuningInit, PeftModel # 分词器 tokenizer = AutoTokenizer.from_pretrained("Langboat/bloom-1b4-zh") # 函数内将instruction和response拆开分词的原因是: # 为了便于mask掉不需要计算损失的labels, 即代码labels = [-100] * len(instruction["input_ids"]) + response["input_ids"] def process_func(example): MAX_LENGTH = 256 input_ids, attention_mask, labels = [], [], [] instruction = tokenizer("
WPS官网的WPS开放平台开发文档,摘抄一些以记录及作为文档的入口记录,以后对WPS表格的操作编程再也不是从网上搜索到的只字片语了^_^。
Workbook.SaveAs 在另一不同文件中保存对工作簿所做的更改。
语法
express.SaveAs(Filename, FileFormat, Password, WriteResPassword, ReadOnlyRecommended, CreateBackup, AccessMode, ConflictResolution, AddToMru, TextCodepage, TextVisualLayout, Local)
express 一个代表 Workbook 对象的变量。
参数
名称必选/可选数据类型说明Filename可选Variant一个表示要保存文件的文件名的字符串。可包含完整路径,如果不指定路径,ET 将文件保存到当前文件夹中。FileFormat可选Variant保存文件时使用的文件格式。要查看有效的选项列表,请参阅 XlFileFormat 枚举。对于现有文件,默认采用上一次指定的文件格式;对于新文件,默认采用当前所用 ET 版本的格式。Password可选Variant它是一个区分大小写的字符串(最长不超过 15 个字符),用于指定文件的保护密码。WriteResPassword可选Variant一个表示文件写保护密码的字符串。如果文件保存时带有密码,但打开文件时不输入密码,则该文件以只读方式打开。ReadOnlyRecommended可选Variant如果为 True,则在打开文件时显示一条消息,提示该文件以只读方式打开。CreateBackup可选Variant如果为 True,则创建备份文件。AccessMode可选XlSaveAsAccessMode工作簿的访问模式。ConflictResolution可选XlSaveConflictResolution一个 XlSaveConflictResolution 值,它确定该方法在保存工作簿时如何解决冲突。如果设为 xlUserResolution,则显示冲突解决对话框。如果设为 xlLocalSessionChanges,则自动接受本地用户的更改。如果设为 xlOtherSessionChanges,则自动接受来自其他会话的更改(而不是本地用户的更改)。如果省略此参数,则显示冲突处理对话框。AddToMru可选Variant如果为 True,则将该工作簿添加到最近使用的文件列表中。默认值为 False。TextCodepage可选VariantET中对于所有语言都忽略此参数。 注释:当 ET 将工作簿保存为某种 CSV 或文本格式(使用 FileFormat 参数指定)时, ET 使用对应于当前计算机上使用的系统区域设置语言的代码页。在“控制面板”中单击“区域和语言”,再单击“位置”选项卡,在“当前位置”下可获得此系统设置。TextVisualLayout可选VariantET中对于所有语言都忽略此参数。 注释:当 ET 将工作簿保存为某种 CSV 或文本格式(使用 FileFormat 参数指定)时,它按逻辑布局保存这些格式。如果文件中左至右 (LTR) 文本嵌在右至左 (RTL) 文本中,或者相反,那么逻辑布局将把文件的内容,按照文件中所有语言的正确阅读顺序保存,而不考虑方向。当应用程序打开文件时,每串 LTR 或 RTL 字符将根据代码页中的字符值范围,按照正确的方向呈现。(除非用来打开文件的应用程序是为显示文件的确切内存布局而设计的应用程序,如调试器或编辑器)。Local可选Variant如果为 True,则以 ET(包括控制面板设置)的语言保存文件。如果为 False(默认值),则以 示例代码 (VBA) 的语言保存文件。VBA 通常为美国英语版本,除非从中运行 Workbooks.
吃瓜🍉 因为最近老是用到Opencv这个库来处理视频,过程遇到了非常多的细节问题,最后把成品干脆直接放到博客来,这样以后可以随时过来取用。
Opencv读取视频没有声音的原因是因为:视频是分为图像与音频的,Opencv仅仅只是读取了一帧帧图像,并没有读取到音频,所以我们只需要再读取一次音频,并且两者同时播放就OK啦!
【方便的Opencv】实现播放有声音的视频+附带图片生成gif
前言
实现功能
代码:
将一个文件夹下的图片生成gif
实现功能 · ❥ 播放视频 ❤ · ❥ 播放音频 ❤ · ❥ 播放进度展示 ❤ · ❥ 帧数统计 ❤ · ❥ 按空格键可暂停。 ❤ 代码—Code show time!👑 # 使用cv2读取显示视频 # 引入math import math # 引入opencv import cv2 from ffpyplayer.player import MediaPlayer # opencv获取本地视频 def play_video(video_path, audio_play=True): cap = cv2.VideoCapture(video_path) if audio_play: player = MediaPlayer(video_path) # 打开文件状态 isopen = cap.isOpened() if not isopen: print("Err: Video is failure.
前端面试大全·JavaScript函数柯里化
🌟经典真题
🌟什么是函数柯里化
🌟柯里化快速入门
🌟函数柯里化实际应用
🌟封装通用柯里化函数
🌟一道经典的柯里化面试题
🌟真题详解
🌟总结
🌟经典真题 什么是函数柯里化? 🌟什么是函数柯里化 在计算机科学中,柯里化(英语:Currying),又译为卡瑞化或加里化,是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数的技术。
这个技术由克里斯托弗·斯特雷奇以逻辑学家哈斯凯尔·加里命名的,尽管它是 Moses Schönfinkel 和戈特洛布·弗雷格发明的。
在直觉上,柯里化声称如果你固定某些参数,你将得到接受余下参数的一个函数。
我们姑且叫它返回函数,在调用返回函数的时候,它将判断当前的参数和之前被柯里化函数固定的参数拼起来之后,是否达到了原本函数的参数个数。
如果是,则执行原本的函数,得到结果;如果没有达到,则要继续调用柯里化函数来固定目前的参数。
在理论计算机科学中,柯里化提供了在简单的理论模型中,比如:只接受一个单一参数的 lambda 演算中,研究带有多个参数的函数的方式。
函数柯里化的对偶是Uncurrying,一种使用匿名单参数函数来实现多参数函数的方法。
🌟柯里化快速入门 接下来,我们来通过一个简单的示例,让大家快速体会函数柯里化。
假设我们有一个求取两个数之和的函数:
function add(x, y) { return x + y; } console.log(add(1, 2)); // 3 console.log(add(5, 7)); // 12 在上面的示例中,我们有一个 add 函数,接收两个形参,返回两形参的和。
在调用的时候,我们每次也需要传递两个参数。
现在,我们对其进行柯里化,如下:
function add(x) { return function (y) { return x + y; } } console.log(add(1)(2)); // 3 console.log(add(5)(7)); // 3 在上面的代码中,我们对 add 函数进行了柯里化改造,只接受一个参数,但是返回的也不是值了,而是返回一个函数,这个函数也接收一个参数,然后利用闭包的特性,可以访问到最开始传入的 x 的值,最终返回 x 和 y 的和。
前端面试大全·JavaScript递归
🌟经典真题
🌟递归
🌟真题解答
🌟总结
🌟经典真题 使用递归完成 1 到 100 的累加 🌟递归 A recursive method is a method that calls itself.
递归调用是一种特殊的调用形式,指的是方法自己调用自己的形式。
下面是一个递归的示例:
function neverEnd() { console.log("This is the method that never ends!"); neverEnd(); } method 会先输出 This is the method that never ends! 然后再调用自己,导致无限递归(infinite recursion)。当然这一般是我们需要避免的状况。
在进行递归操作的时候,我们需要满足以下几个条件:
递归调用必须有结束条件每次调用的时候都需要根据需求改变传递的参数内容 下面是递归的一个示例,求某个数的阶乘。
function factorial(x) { if (x === 1) { return 1; } else { return x * factorial(x - 1); } } console.
背景 CSDN的话题活动,交流程序员的养生之法。
在这个平台,交流这个话题实在是再合适不过了,中国每年毕业的大学生“程序员”使用CSDN的比例没有100%也得用90%?可能我都说少了,因为我身边就有好多跨专业的朋友,学法律的,建筑的,化学的,物理的都来争做程序员,想来那一定是因为程序员会养生,活得久吧。
大纲 这里聊一聊我身边的程序员都是怎么养身的,主要非以下几个方向
背景
大纲
草药系
一把壶
花花草草 红枣+枸杞
黄芪粉/片
红豆薏米
罗汉果菊花茶
桂圆大枣
化学系
心灵系
躺平系
物理系
帽子
护膝
冲锋衣 长筒袜
颈部按摩仪
村口的足疗店
草药系 能入选草药系的,绝不是保温杯泡枸杞就能入选的!门槛要抬高一些~
一把壶 办公桌必备一把养生壶,或是小熊,或是美的,或是苏泊尔,这是硬件入门条件,保温杯只能说是入门。
如果再霸道一些,陶瓷煎药壶都会可以上的桌来,得敢想敢干,这个不是梦,一个合格的程序员大概率会需要这么一个壶,如果你面子薄,可以放家里,煮好了以后用保温壶带单位喝。
花花草草 养生壶里的门道太多了,我自己也不修这一系,就讲一讲身边常见的吧。
红枣+枸杞 枸杞那必须是宁夏的枸杞,滋阴补肾,明目养颜,有长寿果之称。
红枣,保肝护脾、美容、补气养血、预防心血管病。
这两者的搭配是最常见的~
黄芪粉/片 据说有调理气血,滋养脾胃的功效,还有助于提高免疫力,抗疲劳,非常适合经常熬夜的人士。
红豆薏米 女生常见的路子,祛湿减肥,煮完的渣渣还能当饭吃,省一顿晚饭呢
罗汉果菊花茶 清热去火,疏散风热、清肝明目,这个适合口若悬河的领导,开会多的,能喷的,一定记得多喝一些。 桂圆大枣 安神补脑,改善气血,味道很不错,适合女孩子。
先就这些吧,还有很多煮水果的,玉米的,看不懂是什么路子,就不讲了。
化学系 花花绿绿的小药片吃起来,您要是不说自己是程序员,旁人真可能以为你是重症患者呢。
不吃药不行啊,经常加班熬夜,生活不规律都是程序员的必经之路,你说自己不熬夜?那你不是大神就是混子。 嫌弃草药系太麻烦,直接上药片多,我不多说,光列举一下,列为看看是否熟悉?
善存复合维生素片:满足每日微量营养需求,给身体全面的维生素补充钙铁锌片:微量元素加补钙洋参含片:提高免疫力,抗疲劳,抗氧化褪黑素:调节睡眠,改善睡眠质量胶原蛋白片:帮助皮肤抗初老,维护皮肤弹性月见草精华:调节女性内分泌,呵护卵巢缓解姨妈痛黑糖芝麻丸:滋阴养发 心灵系 这一类人不合汤也不吃药,纯练心态,和谁都不生气,心态好到感觉已经成佛,一般的事情绝不会让他们收到干扰。
俗话讲,生气伤肝,不生气,没脾气的程序员哪还用得着养生?甭管是遇到再难缠的领导和再无理的产品经理,他们都会一笑而过,很大气的请领导和产品经理去吃药。
躺平系 这一类程序员是占大多数的,他们相信咖啡可以养生。
还可以减肥,助消化,晚上喝还可以提神。这被提起的神是哪里借的,要不要还?他们也不清楚。
物理系 用物理的方式养生,是从原始人时期就有的,说的当然是保暖,而保暖最重要的是保脑袋。
帽子 人人都知道女人爱买鞋子,而不知道程序员爱买帽子,当然不是为了美,而是为了保暖。
护膝 久坐的人为什么需要护膝?难道你身边的程序员真的不运动,不跑步吗?
跑啊,程序员是会跑步,但为什么需要护膝呢?因为大多数上年纪的程序员都有一副超重的身躯,这时候跑步会给膝盖带来巨大的压力,当然需要一副护膝。相信我,你需要的~
冲锋衣 据说今年的双十一的消费者群里有变化了,男人的消费终于超过的宠物狗,这真多亏了冲锋衣,拉起了男人的消费。
程序员穿冲锋衣的比例真的很大,不知道各位身边的同事是不是这样。
长筒袜 保护脚踝,给你一个温暖的冬天。
颈部按摩仪 便携的小电器,放在办公室也不占空间,太合适一坐一天的程序员了。
常用的单片机裸机非阻塞式框架 仅作参考
ADC采样滤波 0.约1024次AD后采样获取一次温度值
1.支持双电阻高低温区采样
2.一阶滤波、限幅滤波、温差比较 ---- 冒泡排序后取平均值
3.二分法获取查表获取温度
4.添加补偿温度
/**************************************************************************************************** Function Name :void NTC_GetTpTask(void) Description : Author :MECHT Version :V1.0 ****************************************************************************************************/ #define ADC_GROUP 8 #define NTC_GROUP_NUM 16 void NTC_GetTpTask(void) { static uint xdata Su16TempBuf1[ADC_GROUP] = {0}; static uchar xdata Su8BufIndex1 = 0; //单个通道ADC值数组下标 static uint xdata Su16TempBuf2[ADC_GROUP] = {0}; static uchar xdata Su8BufIndex2 = 0; //单通道平均值数组下标 static signed int xdata Su16TempBuf3[NTC_GROUP_NUM] = {0}; static uchar xdata Su8BufIndex3 = 0; static signed int xdata OldNtcValue = 0; static uint16_t Tempd = 0; static uint16_t OldAdcValue = 0; uint16_t AdcTempValue = 0; //临时值 uint16_t AdcTempAverage = 0; //临时平均值 // 此部分根据单片机不同更换,目标都是获取AD值 ADCCON &= ~(0X20); //清零 ADCCON |= 0X40; //Start ADC conversion while(!
简单的shell脚本,用于批量修改当前文件夹下被匹配的子文件夹中所有文件的内容:
#! /bin/bash echo "change all the file in this dir !" for dir in $(ls -d rfdig*); do [ -d $dir ] && echo $dir for file in $(cd $dir && ls *); do [ -e ${dir}/${file} ] && echo $file sed -i 's/gpio_ret_pd_p/gpio_mcu_p/g' ${dir}/${file} sed -i 's/gpio_out_set/gpio_mcu_out_set/g' ${dir}/${file} sed -i 's/gpio_out_clear/gpio_mcu_out_clear/g' ${dir}/${file} sed -i 's/pmu_dig_psw_ack/pmu_power_state/g' ${dir}/${file} sed -i 's/RFDIG_REGS\[crg_crg\]/RFDIG_REGS\[crg_ret_pd_crg\]/g' ${dir}/${file} sed -i 's/RFDIG_REGS\[dsm_denominator\]/RFDIG_REGS\[dsm_ret_pd_denominator\]/g' ${dir}/${file} sed -i 's/RFDIG_REGS\[dsm_divn_frac\]/RFDIG_REGS\[dsm_ret_pd_divn_frac\]/g' ${dir}/${file} sed -i 's/u_uwb_sub/u_pd_uwb_wrap/g' ${dir}/${file} sed -i 's/u_rfdig_top/u_rfdig_uwb_top/g' ${dir}/${file} sed -i 's/crg_crg_vcosel_clk_gate_en_bit/crg_ret_pd_crg_vcosel_clk_gate_en_bit/g' ${dir}/${file} sed -i 's/crg_txafe_crg/crg_txafe_ret_pd_crg/g' ${dir}/${file} done done