LaTex头部加点

LaTex 头部加点 使用Latex 编辑文章时,会遇到在字母上面加各种符号的问题,小结一下 加^号 输入\hat 或 \widehat 加横线 输入 \overline 加波浪线 输入 \widetilde 加一个点 \dot{要加点的字母}加两个点\ddot{要加点的字母} Ref: Latex 字母上面加符号 波浪线 横线 角号等 http://www.360doc.com/content/17/0725/21/5601039_674116656.shtml

【C语言】AscII码值详解

什么是ASCII码? ASCII (American Standard Code for Information Interchange):美国信息交换标准代码是基于拉丁字母的一套电脑编码系统,主要用于显示现代英语和其他西欧语言。它是最通用的信息交换标准,并等同于国际标准 ISO/IEC 646。ASCII第一次以规范标准的类型发表是在1967年,最后一次更新则是在1986年,到目前为止共定义了128个字符。 ASCll是最简单的西文编码方案,目前的文字编码标准主要有 ASCII、GB2312、GBK、Unicode等. 一. 在C语言中,我们可以将字符通过特殊转化为数字,通过数字的大小比较两个字符的大小: 小写字母转换大写字母,使用ASCll值进行转换 解题思路:利用 ASCII 码中大写字母和小写字母之间的转换关系(差值为 32),可以将小写字母转换为大写字母。编写程序实现,从键盘上输入一个小写字母,按回车键,程序将该小写字母转换为大写字母,并输出其 ASCII 值。 #include <stdio.h> int main() { char a, b; int c; printf("输入一个字符:"); a = getchar(); printf("转(1)大写\n (2)小写"); scanf("%d", &c); switch (c) { case 1: if (97 <= a && a <= 122) //小写 { b = a - 32; printf("%c", b); } else { printf("输入正确的小写;"); } break; case 2: if (65 <= a && a <= 90) { b = a + 32; printf("

Java中String的split函数的详解及应用

文章目录 一、 split函数详解二、应用 一、 split函数详解 split(String regex)为java.lang.String类的方法,其功能通俗的说就是以传入的分隔符参数拆分该字符串 方法具体为: public String[] split(String regex) { return split(regex, 0); } 方法内部调用了一个重载的 split(regex,0) 方法,split(regex)方法最终返回一个字符串数组。方法 split(regex,0)原形是split(String regex, int limit),该方法中的regex为匹配样板,通俗的说就是拆分字符串的标志,而limit在官方文档中是这样描述的: The parameter controls the number of times the pattern is applied and therefore affects the length of the resulting array. If the limit n is greater than zero then the pattern will be applied at most n - 1 times, the array’s length will be no greater than n, and the array’slast entry will contain all input beyond the last matched delimiter.

Vite 如何过滤 console.log

1、需求:console.log一般都是在开发环境下使用的,在生产环境下需要去除 2、思路:vite构建时默认使用Esbuild,打包速度是其他打包工具的十几倍,但是缺点也很明显,不具备操作AST的能力,vite也补充了terser来解决这个问题,通过terser的api可以轻松去除console.log,就是打包速度会降下来,果然鱼和熊掌不可兼得; 3、实现: 先安装terser,官网:Vite 官方中文文档 ---- 构建选项 npm add -D terser 再去vite.config.ts里面配置 import { defineConfig } from 'vite' export default defineConfig( { ... build : { minify : 'terser' , terserOptions : { compress : { drop_console : true , drop_debugger : true , } , } , } , ... } ) 大功告成!!!

android查漏补缺(8)Binder framework架构和调用方法

1.Binder简介 Binder是android系统中实现进程间通信的主要组件,包括各种AMS,PMS,SMS等服务和APK的通信都是通过binder实现。但是调用过PMS的同学肯定会有疑问,既然是进程通信,怎么没有消息的发送和接收,为什么调用不同进程的服务的接口能像调用相同进程的接口一样呢?要解答这个疑问就得弄清楚framework层对binder机制的封装的作用。 2,Binder基本框架 Binder主要分为驱动层和框架层,驱动层通过创建/dev/binder设备文件实现和应用层进行通信,框架层封装了驱动层通信的细节,对外提供IInterface,BnInterface,BpInterface,IServiceManager,ProcessState,IPCThreadState这几个类对象,如果要扩展Android管理服务则需要对这几个对象进行操作。 IInterface:作为自定义服务接口的父类,本身作用不大 BnInterface:作为实现接口的Service的父类,主要需要实现其中的onTransact接口 BpInterface:作为实现接口的client的父类,主要实现接口中信息传递给service的方式 IServiceManager:作为管理服务的框架管理类,提供defaultServiceManager,addservice,getservice等接口 ProcessState:作为线程状态类提供唯一的binder操作对象。 IPCThreadState:作为binder驱动操作类提供和驱动直接操作的接口 3,helloworld参考代码 参考github:https://github.com/weidongshan/APP_0004_Binder_CPP_App

JavaScript中小数点计算问题

加法运算 方法一:转整计算 将需要运算的小数扩大10倍、100倍、。。。将小数扩大到整数,然后进行运行,最后再缩小扩大的倍数 var num1 = 0.1 var num2 = 0.2 var num3 = (num1 * 10 + num2 * 10) / 10 console.log(num3) // 0.3 方法二:toFixed 通过js中Number的内置方法toFixed,强制保留小数点后位数 var num1 = 0.1 var num2 = 0.2 var num3 = num1 + num2 console.log(num3.toFixed(3)) // 0.300 - 强制保留小数点后3位 方法三:封装1 封装数学运算方法 function add(...args) { try { args.forEach((item) => { if (typeof item !== 'number') throw '数学运算要使用数字' }) const arr = args .

为什么要做ERP集成 ERP系统如何与其他业务应用程序集成

花在搜索一条信息上的每一刻,都是没有对这些信息采取行动的时间。企业资源规划 (ERP) 系统从每个业务功能收集大量信息,并将其存储在一个中心位置,以便于发现。这样,您就可以为您的业务做出最佳的数据驱动型决策。 但是,信息如何流入和流出ERP通常既耗时又繁琐。当这种情况发生时,重要的业务信息可能会隐藏在其他专用系统中,除了每天与该系统打交道的人之外,所有人都会隐藏起来。这就是我们在讨论“数据孤岛”以及它们如何阻碍业务生产力时的意思。 不过,不一定非要这样。ERP集成消除了跨所有业务应用程序手动传输数据的障碍。本指南将解释什么是ERP集成,为什么可能使用它,以及如何将ERP与其他关键业务应用程序集成。 什么是企业资源规划 (ERP)? ERP系统是企业用来收集,存储,跟踪和分析大量数据和业务活动的平台。ERP系统充当整个组织信息的中央存储库,通常被认为是业务的单一事实来源。 ERP系统通常会涉及组织的许多方面,包括财务,人力资源规划(HRP),商业智能(BI),客户关系管理(CRM),供应链管理(SCM)和物料需求计划(MRP)。鉴于ERP系统对内部职能部门和外部受众(如客户和合作伙伴)的广泛影响,ERP数据必须始终尽可能准确和完整。这就解释了ERP系统与其他业务应用程序之间持续、实时连接的重要性。 什么是ERP集成? ERP集成是在公司的业务应用程序套件与其ERP系统之间建立连接的过程。当这些应用程序与ERP集成时,所有相关的业务数据都会自动导入ERP系统,ERP数据将共享回其他应用程序。这拓宽了可用的信息来源,使本组织的财务和业务状况有了更丰富和更全面的了解。 企业数据集成的优势 当业务数据存储在专用系统中时,信息是孤立的。这带来了许多风险,包括重复工作、根据不完整或不准确的信息做出决策以及失去合作机会。 当您的ERP与其他业务应用程序集成时,组织中的每个人都可以访问数据 - 以及其他所有应用程序。ERP集成的好处是众多且深远的。以下是三个示例: 实时数据 通过ERP集成,输入到一个系统中的数据会在连接到ERP的所有其他系统中自动更新。这大大减少了手动数据输入的需要以及人为错误导致信息不准确的可能性。当数据在除ERP之外的整套应用程序之间同步时,对准确性的信任度将更高。这样可以实现更快、更可靠的数据分析,从而做出合理的业务决策。 工作流程自动化 ERP集成不仅仅是提供数据。它还使数据具有可操作性,而无需人工干预。许多流程(如技术支持票证和合同生命周期管理)可以将事件设置为在更新记录时自动触发。这减轻了推进工作流程的责任,使他们能够专注于更高价值的任务。 360 度客户档案 集成的客户体验需要集成的业务系统。ERP集成将每个客户详细信息附加到其个人资料中,无论他们处于销售流程的哪个位置。这使销售代表、产品开发人员甚至营销自动化平台能够全面了解个人客户,并深入了解原本无法获得的更广泛市场趋势。 集成的 ERP 用例 ERP集成可以改进组织内许多职能部门的流程。以下是一些实际用例,展示了如何将ERP系统完全集成到业务中可以立即提供实际收益。 ERP与电子商务平台的集成 电子商务平台生成大量客户数据,例如购买时间、最受欢迎的产品和平均购物车价值。所有这些数据在季度预测之外都是有用的。将公司的电子商务平台与ERP系统集成可以通过自动化简化订单履行流程,更新库存软件,并使客户分析数据在整个组织中可用,而无需授予组织范围内对电子商务平台的访问权限。 ERP与项目管理工具的集成 大多数ERP系统将具有本地项目管理工具。但是,由于ERP系统不是专门为项目管理而构建的,因此与其他专用工具相比,功能可能会受到限制。项目管理工具和ERP系统之间的集成使您可以在不牺牲数据可移植性的情况下利用团队所需的功能。 ERP与BI工具的集成 商业智能 (BI) 工具包含有关公司内部运作的大量信息。这些信息传统上是孤立的,这使公司无法实时了解内部流程和趋势。当这些数据在整个组织中都可以访问时,可能会出现独特的见解,以应对任何数量的业务挑战。 企业资源规划集成方法 ERP集成在每个组织中看起来并不相同。如何实施 ERP 集成将取决于业务需求、法规要求、员工能力等。 ERP集成主要有三种方法: 点对点集成 ERP与其他应用程序的集成可能相对简单。如果应用程序具有预构建的集成模块,则尤其如此。但是,当所需的集成数量随着业务规模的扩大而增加时,这种类型的集成将变得劳动密集型。 企业服务总线 (ESB) 企业服务总线 (ESB) 集成通过标准化数据处理和共享方式,在组织内的多个程序之间创建连接。此集成方法是内部开发的,因此可以根据任何给定组织的需求进行自定义。然而,另一方面,这些连接也需要在内部维护和更新,新连接可能会干扰甚至破坏旧连接。 集成平台即服务 (iPaaS) 使用 iPaaS 进行 ERP 集成是一种快速灵活的解决方案。iPaaS 将为组织使用的几乎每个应用程序提供预构建的连接器,以便 ERP 集成过程具有与 ESB 系统的多应用程序连接的点对点集成的简单性。更重要的是,由于这是一个“即服务”解决方案,它不需要内部维护,并将继续为新兴应用开发新的连接器。 ERP与数环通的集成 数环通是iPaaS领域的先驱,并继续引领其发展。我们致力于通过应用集成和自动化使企业能够实现最佳结果。这种连接始于确保ERP与整个业务集成。

Flutter 开发、测试,网络调试工具

一、Github地址 NetworkCapture 二、效果图 三、使用方式 添加pub依赖latest_version dependencies: network_capture: ^latest_version Change your App to NetworkCaptureApp void main() { runApp(NetworkCaptureApp( enable: true, navigatorKey: navigatorKey, child: const MyApp(), )); } 重点!请不要在生产环境使用,对此产生的后果概不负责。

代码覆盖率统计Super-jacoco在公司级容器化项目中的具体应用方案

目录 一、介绍 二、自己在本地搭建Super-jacoco服务 2.1 准备工作 2.2 部署super jacoco服务 1、下载super jacoco 项目 2、初始化数据库 3、配置application.properties 4、编译super jacoco项目 5、部署 super jacoco 服务 2.3 启动被测项目 2.4、代码覆盖率收集 2.4.1 启动代码覆盖率收集 2.4.2 获取代码覆盖率 三、公司项目级docker容器化项目Super-jacoco应用 3.1 镜像准备 3.2 部署项目 3.3 测试同学部署Super-jacoco服务 3.3.1 、数据库准备,用于存储报告信息等。 3.3.2 配置Super-jacoco服务application.properties信息 3.3.3、编译super jacoco项目 3.3.4、部署 super jacoco 服务 3.4、代码覆盖率收集 3.4.1 启动代码覆盖率收集 3.4.2 获取代码覆盖率 四、报错处理 4.1 "errMsg": "统计失败:编译代码出错" 4.2 编译失败 (权限相关) 4.3 编译失败 (网络慢) 4.4 编译失败 五、Super-jacoco原理 5.1 整体流程 5.2 获取增量代码 5.3. jacoco 二次改造,支持增量方法列表参数 5.4. 执行

企业应用集成的9大业务优势

企业应用集成 (EAI) 允许组织通常通过应用程序编程接口 (API) 将其 SaaS 应用和本地系统相互连接,以便同步数据和自动化业务流程。 为了帮助您确定企业应用集成是否值得在您的组织中执行,我们将重点介绍其最大优势。 企业应用集成的9大业务优势: 01 消除数据孤岛 数据孤岛,或者当信息存在于某个应用或一组应用中时,可能会导致各种问题。例如,员工可能不知道某些类型的数据,因为这些数据并不存在于他们所依赖的应用程序中。此外,如果员工知道某种类型的数据,但在他们的应用中找不到它,他们就会被迫请求访问它,并且请求可能需要一些时间才能提交和处理。 企业应用集成可以帮助打破许多现有的孤岛,因为员工可以访问他们已经使用的应用中的其他信息。 02 提高生产力 通过跨应用同步数据,员工可以减少在繁琐、非生产性任务上花费的时间,例如跨应用搜索信息或跨应用重新输入数据,并将更多时间放在可能影响业务的活动上。 这可以采取不同的形式,具体取决于团队:销售人员可以分配更多时间来制作给潜在客户的个性化电子邮件;客户成功经理可以投入更多精力来支持有风险的客户;人力资源部门可以投入更多时间来吸引目标候选人等。 03 防止人为错误 手动重新输入数据可能会导致代价高昂的错误,从在发票上输入不正确的费用到在候选人的录取通知书中添加不准确的薪水。 EAI 可以帮助最大限度地减少这些人为错误,因为它可以减少员工日常执行的数据输入量。 04 支持自动化用例 集成应用程序后,您可以通过自动化跨这些应用工作的业务流程来更进一步。 例如,假设您已将应用跟踪系统与 HRIS、身份和访问管理工具以及 IT 服务管理工具连接起来。然后,您可以自动执行员工入职流程。 05 提升员工体验 EAI使员工能够专注于不仅对业务更重要,而且执行起来更愉快和更有价值的任务。例如,支持代表可以花更少的时间在跨应用的工单上键入详细信息,而是将更多的注意力用于代表客户解决具有挑战性的问题。 随着时间的推移,这将帮助您的组织雇用更敬业和更满意的员工队伍,这将有助于您的组织提高生产力、降低人员流动率以及其他好处。 06 提升客户体验 由于面向客户的员工基本上不需要手动任务,他们将能够提供改进的客户体验,例如提供积极主动和周到的外展服务,更快地响应问题以及开发满足关键客户需求的解决方案。 07 提高业务敏捷性 随着组织的成熟,他们使用的技术和部署的流程将不断发展。 EAI 工具可以通过为各种应用和数据库提供低代码/无代码 UX和预置的应用连接器,帮助您的组织适应此类变化。这两个组件将允许您的团队快速轻松地修改连接和集成流程,并从头开始构建新流程。 08 消除数据孤岛 随着不同类型的人工智能不断出现和发展,人工智能的集成用例只会增长。 EAI 平台可以通过提供具有 AI 和 ML 模型的连接器(例如 OpenAI)来帮助您利用该领域的最新发展。 数环通提供的一些预置AI人工智能连接器: 09 提供企业级治理和安全控制 您连接的应用和系统可能会收集和存储有关您的业务、客户、潜在客户和员工的敏感信息。确保这些数据安全对于保持对各种数据保护和隐私法规的遵守、通过安全审计以及也许最重要的是保持与关键利益相关者的信任至关重要。 为了帮助保护您的数据和应用,企业应用集成平台可以提供基于角色的精细访问控制、企业密钥管理和审核日志等功能。 数环通是iPaaS领域的领导者,具有本文中强调的所有优势。 我们的低代码平台还提供企业级AGI:LinkBot,这是一个可定制的平台机器人,允许员工通过自然语言触发自动化并与之交互;工作流应用程序:帮助您构建交互式和集成的工作流应用程序;一个嵌入式平台:允许组织使用数环通构建与自己产品的集成等等。 目前,数环通已对接打通钉钉、金蝶云、维格表、抖音、企业微信、CRM、巨量千川、用友等1000+应用系统,拥有超20000+指令动作,且持续周周更新。能够快速扩展您现有系统的功能,并将各个系统串联起来。

C/C++关键字总结及解释

由美国国家标准协会(ANSI)定义的C语言关键字共有32个,根据关键字的作用,可分其为数据类型关键字、控制语句关键字、存储类型关键字和其它关键字四类。在命名变量名的时候应该避开这些关键字。部分关键字的使用方法我会进行单独讲解,直接点击即可阅读。希望本文能给你带来收获。 C/C++关键字总结及解释 C语言的关键字(32个)一、 数据类型关键字(12个)二、控制语句关键字(12个)三、存储类型关键字(4个)四、其它关键字(5个) C++的关键字(10个) C语言的关键字(32个) 一、 数据类型关键字(12个) (1) char :声明字符型变量或函数 (2) double :声明双精度变量或函数 (3) enum :声明枚举类型 (4) float:声明浮点型变量或函数 (5) int: 声明整型变量或函数 (6) long :声明长整型变量或函数 (7) short :声明短整型变量或函数 (8) signed:声明有符号类型变量或函数 (9) struct:声明结构体变量或函数 (10) union:声明共用体(联合)数据类型 (11) unsigned:声明无符号类型变量或函数 (12) void :声明函数无返回值或无参数,声明无类型指针(基本上就这三个作用) 二、控制语句关键字(12个) A循环语句 (1) for:一种循环语句(可意会不可言传) (2) do :循环语句的循环体 (3) while :循环语句的循环条件 (4) break:跳出当前循环 (5) continue:结束当前循环,开始下一轮循环 B条件语句 (1)if: 条件语句 (2)else :条件语句否定分支(与 if 连用) (3)goto:无条件跳转语句 C开关语句 (1)switch :用于开关语句 (2)case:开关语句分支 (3)default:开关语句中的“其他”分支 D返回语句 (4)return :函数返回语句,用于返回各种类型的值

SQL SERVER 表分区

1. 概要说明 SQL SERVER的表分区功能是为了将一个大表(表中含有非常多条数据)的数据根据某条件(仅限该表的主键)拆分成多个文件存放,以提高查询数据时的效率。创建表分区的主要步骤是 1、确定需要以哪一个字段作为分区条件; 2、拆分成多少个文件保存该表; 3、分区函数(拆分条件); 4、分区方案(按拆分函数拆分后需要对应到哪些文件组中去)。 不是企业版的sql server不支持分区; 参考:SQL SERVER 表分区实施步骤_sqlserver表分区步骤_Henry_Wu001的博客-CSDN博客 sql server 分区表 性能 sqlserver分区表实战_mob6454cc77db30的技术博客_51CTO博客 (0.1)SQL Server分区介绍 在SQL Server中,数据库的所有表和索引都视为已分区表和索引,默认这些表和索引值包含一个分区;也就是说表或索引至少包含一个分区。SQL Server中数据是按水平方式分区,是多行数据映射到单个分区。已经分区的表或者索引,在执行查询或者更新时,将被看作为单个逻辑实体;简单说来利用分区将一个表数据分多个表来存储,对于大数据量的表,将表分成多块查询,若只查询某个分区数据将降低消耗提高效率。需要注意的是单个索引或者表的分区必须位于一个数据库中。在使用大量数据管理时,SQL Server使用分区可以快速访问数据子集,减少io提高效率。 同时不同分区可以存放在不同文件组里,文件组若能存放在不同逻辑磁盘上,则可以实现io的并发使用以提高效率 (0.2)SQL Server分区创建概述 创建分区函数:确定分区方式和界点 创建分区架构:将分区函数指定的分区映射到文件组 新建分区表 索引分区知识详解 (0.3)SQL Server分区管理概述 拆分分区(split) 合并分区(merge) 切换分区(switch) $PARTION 【1】创建表分区 未分区的表,相当于只有一个分区,只能存储在一个FileGroup中;对表进行分区后,每一个分区都存储在一个FileGroup,或分布式存储在不同的FileGroup中。对表进行分区的过程,实际上是将逻辑上完整的一个表,按照特定的字段拆分成多个分区,分散到相同或不同的FileGroup中,每一个部分叫做表的一个分区(Partition),一个分区实际上是一个独立的,内部的物理表。也就是说,分区表在逻辑上是一个表,而在物理上是多个完全独立的表。 分区(Partition)的特性是: 每一个Partition在FileGroup中都独立存储,分区之间是相互独立的 每一个parititon都属于唯一的表对象, 每一个Partition 都有唯一的ID, 每一个Partition都有一个编号(Partition Number),同一个表的分区编号是唯一的,从1开始递增; Step0,准备工作:构建文件组和文件 登录后复制 --添加文件组 alter database testSplit add filegroup db_fg1 --添加文件到文件组 alter database testSplit add file (name=N'ById1',filename=N'J:\Work\数据库\data\ById1.ndf',size=5Mb,filegrowth=5mb) to filegroup db_fg1 一,新建分区表分为三步 Step1, 创建分区函数 要先创建函数

ubuntu 飞书 VLC is unable to open the MRL

在 ubuntu 下使用飞书,播放消息里的视频时会遇到如下错误 VLC is unable to open the MRL… 解决方法是在系统设置里将视频的默认播放器改为 vlc

springboot + minio 实现断点续传、秒传

基于springboot + minio 实现的断点续传和秒传功能 Controller /** * 断点续传 * @param chunk 文件块对象(分片除了最后一片,必须大于等于5M,minio固定要求) * @return 文件块信息 */ @RequestMapping(value = "/fileUpload", method = {RequestMethod.GET,RequestMethod.POST}) public R<FileChunkVO> fileUpload(@ModelAttribute FileChunkDTO chunk){ return sysFileService.fileUpload(chunk); } Service /** * 断点续传 * @param chunk 文件块对象 * @return 文件块信息 */ R<FileChunkVO> fileUpload(FileChunkDTO chunk); ServiceImpl private final RedisTemplate redisTemplate; private final MinioTemplate minioTemplate; private final MinioProperties minioProperties; @Value("${minio.defualt-bucket}") private String minioDefaultBucket; @Value("${minio.tmp-bucket}") private String minioTmpBucket; @Override public R<FileChunkVO> fileUpload(FileChunkDTO dto) { // 返回对象 FileChunkVO vo = BeanUtil.

Retrofit 网络请求参数注解@Path @Field @Query 等使用

请求参数呢大致如下,盗个别人的图, 下面就说下这些内容使用 其中 @Path、@Query、@QueryMap 使用 Get 请求 , 假如使用了Post 请求注解使用@Path 一般都会使项目崩溃的, 所以这里我总结了一下自己使用的经验 1 @Path 会是url 中带有参数一般配合{} 一起 @GET("toutiao/index/{type}/{key}") Observable<BaseBean<LoginBean>> getLogin(@Path("type")String type,@Path("key") String key); 请求地址类似这样的 这样的请求一般 是把要传递的参数直接拼接到url 后面 2 @Query 是把key-value 拼接到url 后面 不要使用{} @GET("toutiao/index/ ") Observable<BaseBean<LoginBean>> getLogin(@Query("type") String type,@Query("key") String key); 请求地址类似这样的 3 @QueryMap 这个和@Query 差不多,就是当参数很多的时候直接传递一个map 写法如下 @GET("toutiao/index/ ") Observable<BaseBean<LoginBean>> getLogin(@QueryMap Map<String, String> map); 请求接口地址 上面三个请求参数使用的GET请求 常使用的@Field 和@FieldMap 实用与POST 请求 4 @Field 一般 配合 @FormUrlEncoded 使用 ************************************************************* 标记类 :

UnrealSynth虚幻合成数据生成器

UnrealSynth 虚幻合成数据生成器利用虚幻引擎的实时渲染能力搭建逼真的三维场景,为 YOLO 等 AI 模型的训练提供自动生成的图像和标注数据。UnrealSynth 生成的合成数据可用于深度学习模型的训练和验证,可以极大地提高各种行业细分场景中目标识别任务的实施效率,例如:安全帽检测、交通标志检测、施工机械检测、车辆检测、行人检测、船舶检测等。 1、UnrealSynth 合成数据工具包内容 UnrealSynth 基于 UE5 虚幻引擎开发,目前支持 YOLO 系列模型合成数据的生成,当前版本号 V1.0,主要文件和目录的组织结构如下: 目录内容Engine/发布本程序的原始软件的编码和资源文件,其中包含构件此程序的二进制编码和一些存放在 content 文件中的原始资产等UnrealSynth/Binaries/本程序兼容系统及其他的二进制文件UnrealSynth/Content/本程序中所使用的所有资产文件已被烘焙成 pak 包UnrealSynth.exe运行程序LICENSE.md开发包许可协议文件 运行UnrealSynth的推荐配置为: 处理器:13th Gen Intel(R) Core(TM) i5-13400 2.50 GHzRAM:64.0 GB独显:NVIDIA GeForce RTX 3080 Ti 2、UnrealSynth 合成数据生成 以下是以 YOLO 模型为例,详细讲述如何使用 UnrealSynth 虚幻引擎数据生成器来生成为 YOLO 模型生成训练的合成数据。 打开 UnrealSynth 虚幻引擎合成数据生成器,点击【虚幻合成数据生成器】按钮,进入虚幻场景编辑页面,点击【环境变更】按钮切换合适的场景,输入【模型类别】参数后就可以开始导入模型,点击【导入 GLB 模型】弹出文件选择框,任意选择一个 GLB 文件,这里以抱枕文件为例,添加抱枕 GLB 文件后的场景如下: 将 GLB 文件添加到场景后,接下来就可以配置 UnrealSynth 合成数据生成参数,参数配置说明如下: 模型类别: 生成合成数据 synth.yaml 文件中记录物体的类型环境变更 : 变更场景背景截图数量 : 生成合成数据集 image 目录下的图像数量,在 train 和 val 目录下各自生成总数一半数量的图片物体个数 : 设置场景中的物体个数,目前最多支持 5 个,并且是随机的选取模型的类别随机旋转 : 场景中的物体随机旋转角度随机高度 : 场景中的物体随机移动的高度截图分辨率: 生成的 images 图像数据集中的图像分辨率缩放 : 物体缩放调整大小 点击【确定】后会在本地目录中.

C查漏补缺

c语言基础 1,void func1(void);普通函数声明,任意参数无返回值,需要实现函数体才能使用。 2,void *func2(void);普通函数声明,任意参数返回任意函数指针,需要实现函数体才能使用。 3,void (*func3)(void);函数指针声明,函数任意参数无返回值,属于变量声明,可以赋值。 4,void (*func4(void))(void);函数指针声明,属于一个返回函数指针的函数指针,本体函数指针任意参数,返回的函数指针任意参数无返回值 5,fork只会复制当前进程的调用fork的线程到子进程中。 6,c/c++可以看到0x0001u的用法,这个u表示unsigned,还有其他的一些修饰数字的前后缀,比如01中0表示8进制,1L中L表示long int , 1u中u表示unsigned int。 7,c语言中变量定义和赋值中逗号和分号的应用: 结构体定义:内部用分号,结尾用分号。 枚举定义:内部逗号,结尾分号。 c++类定义:内部分号,结尾分号。 8,数组指针的部分误解: 如果有int a[10];,那么a和&a表示相同的地址,但是代表不同的含义,a表示数组的首地址,&a表示数组大小为10的数组的地址。 也就是a+1表示a[1]的地址,但是&a+1表示a[10]的地址 9,当表达式中有有符号数据和无符号数据时,一律将有符号转化为无符号。 这一点可能和向上转换原则不太一样,一般情况是小范围转大范围,但是有符号和无符号其实范围是一样的 10,结构体补齐规则 以前总是按照那3个准则来记忆,类似于: 对齐原则:每一成员的结束偏移量需对齐为后一成员类型的倍数 补齐原则:最终大小补齐为成员中最大值的倍数 有种方法更容易记忆。结构体成员以最大成员补齐,如果下个成员能填充到上个成员为对齐而空出的内容中的话,则这个成员会挤到上个成员会移到上个成员后的空位中 typedef struct A{ int a; //aaaa ***b cccccccc //如果没有b则a后仍空出4字节,b发现可以b的大小小于到4字节就会挤到空位中 char b; double c; }A; //16byte typedef struct B{ char b;//b*** aaaa cccccccc int a; double c; }B;//16byte typedef struct C{ int a;//aaaa**** cccccccc b******* double c; char b; }C;//24byte typedef struct D{ char b;//bbbbbbbb cccccccc aaaa**** double c; int a; }D;//24byte typedef struct E{ char b;//b*** aaaa c*** int a; char c; }E;//12byte 11,thread默认是非分离的,也就是如果thread_create后不进行thread_join,线程资源是不会释放的,一般可以手动设置detach,接下来线程结束后会自动释放,或者不设置detach,调用thread_join等待线程结束并释放资源。

Step7 OB组织块介绍和使用技巧

导读: 在OB1中可以调用FB、SFB、FC、SFC等用户程序使其循环执行。除OB90以外,OB1优先级最低,可以被其他OB中断。OB1默认扫描监控时间为150ms(可设置),扫描超时,CPU自动调用)B80报错,如果程序中没有建立OB80,CPU进入停止模式。 每种类型的OB块的分析及其使用方法: 1、自由循环组织块OB1 S7 CPU启动完成后,操作系统循环执行OB1,OB1执行完成后,操作系统再次启动OB1。在OB1中可以调用FB、SFB、FC、SFC等用户程序使其循环执行。除OB90以外,OB1优先级最低,可以被其他OB中断。OB1默认扫描监控时间为150ms(可设置),扫描超时,CPU自动调用)B80报错,如果程序中没有建立OB80,CPU进入停止模式。 2、日期中断组织块OB10~OB17 在CPU属性中,可以设置日期中断组织块OB10~OB17触发的日期、执行模式(到达设定的触发日期后,OB只执行一次或按每分、每小时、每周、每月周期执行)等参数,当CPU的日期值大于设定的日期值时,触发相应的OB并按设定的模式执行。在用户程序中也可以通过调用SFC28系统函数设定CPU日期中断的参数,调用SFC30激活日期中断投入运行,与在CPU属性中的设置相比,通过用户程序,可以在CPU运行时灵活地修改设定的参数,两种方式可以任意选择,也可以同时对一个OB进行设置。 3、时间延迟中断组织块OB20~OB23 时间延迟中断组织块OB20~OB23的优先级及更新过程映像区的参数需要在CPU属性中设置,通过调用系统函数SFC32触发执行,OB号及延迟时间在SFC32参数中设定,延迟时间为1~60000ms,大大优于定时器精度。 4、循环中断组织块OB30~OB38 循环中断组织块OB30~OB38按设定的时间间隔循环执行,循环中断的间隔时间在CPU属性中设定,每一个OB默认的时间间隔不同,例如)B35默认的时间间隔为100ms,在OB35中的用程序将每隔100ms调用一次,时间间隔可以自由设定,最小时间间隔不能小于55ms。OB中的用户程序执行时间必须小于设定的时间间隔,如果间隔时间较短,由于循环中断OB没有完成程序扫描而被再次调用,从而造成CPU故障,触发OB80报错,如果程序中没有创建OB80,CPU进入停止模式。通过调用SFC39~SFC42系统函数可以禁止、延迟、使能循环中断的调用。循环中断组织块通常处理需要固定扫描周期的用户程序,例如PID函数块通常需在循环中断中调用以处理积分时间的计算。 5、硬件中断组织块OB40~OB47 硬件中断也叫过程中断,由外部设备产生,例如功能模块FM、通信处理器CP及数字量输入、输出模块等。通常使用具有硬件中断的数字量输入模块触发中断响应,然后为每一个模块配置相应的中断OB(一个模块只能良一个中断OB,S7-300系列PLC CPU只能触发硬件中断OB40),在模块配置中可以选择输入点的上升沿、下降沿或全部作为触发中断OB的事件。配置中的中断事件出现,中断主程序,执行中断OB中的用户程序一个周期,然后跳回中断处继续执行主程序。使用中断与普通输入信号相比,没有主程序扫描和过程映像区更新时间,适合需要快速响应的应用。 如果输入模块中的一个通道触发硬件中断,操作系统将识别模块的槽号及触发相应的OB,中断OB执行之后发送与通道相关的确认。在识别和确认过程中,该通道再次触发的中断事件将丢失;如果模块其他通道触发中断事件,中断不会丢失,在当前正在运行的中断确认之后触发;如果是不同的模块触发的中断事件,中断请求被记录,中断OB在空闲(没有模块其他通道的中断请求)时触发。通过调用SFC39~SFC42系统函数可以禁止、延迟、使能硬件中断的调用。 6、DPV1中断组织块OB55~OB57 CPU响应PROFIBUS-DP V1从站触发的中断信息。 7、多处理器中断组织块OB60 用于S7-400系列PLC多CPU(一个机架中最多插入4个CPU完成同一个复杂任务)处理功能,通过调用SFC35,可以触发OB60在多个CPU中同时执行。 8、时钟同步中断组织块OB61~OB64 用于处理PROFIBUS-DP V1等时钟同步,从采集各个从站的输入到逻辑结果输出,需要经过从站输入信号采样循环(信号转换)、从站背板总线循环(转换的信号从模块传递到从站接口)、PROFIBUS-DP总线循环(信号自从站传递到主站)、程序执行循环(信号的程序处理)、PROFIBUS-DP总线循环(信号从主站传递到从站)、从站背板总线循环(信号从从站接口传递到输出柜块)及模块输出循环(信号转换)7个循环,时钟同步中断将7个循环同步,优化数据的传递并保证PROFIBUS-DP各个从站数据处理的同步性。PROFIBUS时钟同步中断只能用于S7-400系列PLC CPU(具有DP V2 功能)。 9、工艺同步处理中断组织块OB65 用于T-CPU(具有运动控制功能的CPU)工艺块与开始程序的同步处理。 10、冗余故障中断组织块OB70、OB72 用于S7-400H冗余系统,当I/O冗余故障,例如冗余的PROFIBUS-DP从站故障时,触发OB70的调用,当CPU冗余故障,如CPU切换、同步故障时,触发OB72的调用。如果I/O冗余,或者CPU冗余故障而在CPU中没有创建OB70、OB72,CPU不会进入停止模式。 11、异步故障中断组织块OB80~OB87 异步故障中断用于处理各种故障事件。 OB80:处理时间故障、CIR(Configuration In Run)后的重新运行等功能,例如OB1或OB35运行超时,CPU自动调用OB80报错,如果程序中没有创建OB80,CPU进入停止模式。 OB81:处理与电源相关的各种信息(S7-400系列PLC CPU只有电池故障时调用),出现故障,CPU自动调用OB81报错,如果程序中没有创建OB81,CPU不会进入停止模式。 OB82:诊断中断,如果使能一个具有诊断中断模块的诊断功能(例如断线、传感器电源丢失),出现故障时调用OB82,如果程序中没有创建OB82,CPU进入停止模式。诊断中断还对CPU所有内外部故障,包括模块前连接器拔出、硬件中断丢失等作出响应。 OB83:用于模块插拔事件的中断处理,事件出现,CPU自动调用OB83报警,如果程序中没有创建OB83,CPU进入停止模式。 OB84:用于处理存储器、冗余系统中两个CPU的冗余连接性能降低等事件。 OB85:用于处理操作系统访问模块故障、更新过程映像区时I/O访问故障、事件触发但相应的OB没有下载到CPU等事件,事件出现,CPU自动调用OB85报错,如果程序中没创建OB85,CPU进入停止模式。 OB86:用于处理扩展机架(不适用于S7-300系列)、PROFIBUS-DP主站、PROFIBUS-DP或PROFINET I/O分布I/O系统中站点故障等事件,事件出现,CPU自动调用OB86报错,如果程序中没有创建,CPU进入停止模式。 OB87:用于处理MPI GD 通信及时钟同步故障,事件出现,CPU自动调用OB87报错,如果程序中没有创建,CPU不会进入停止模式。 12、处理中断组织块OB88 用于处理程序嵌套、区域数据分配故障,故障出现,CPU自动调用OB88报错,如果程序中没有创建,CPU进入停止模式。 13、背景循环中断组织块OB90 优先级最低,保证CPU最短的扫描时间,避免过程映像区更新过于频繁。程序的下载和CPU中程序的删除触发OB90的调用。只能用于S7-400系列PLC CPU。 14、启动中断组织块OB100~OB102 用于处理CPU启动事件,暖启动CPU调用OB100,热启动CPU调用OB101(不适合S7-300系列PLC和S7-400H),冷启动CPU调用OB102,温度越低,CPU启动时清除存储器中数据区的类型越多。 15、同步错误中断组织块OB121、OB122 OB121处理与编程故障有关的事件,例如调用的函数没有下载到CPU中、BCD码出错等,OB122处理与I/O地址访问故障有关的事件,例如访问一个I/O模块时,出现读故障等。如果上述故障出现,在程序中没有创建OB121、OB122,CP进入停止模式。 注意:不是所有的OB都可以在S7 CPU中使用,例如S7-300系列PLC PU中只有暖启动OB100,操作系统不能调用OB101、OB102,CPU中可以使用的OB请参考CPU选型手册。 S7-300系列PLC中组织块的优先级是固定的,不能修改,在S7-400系列PLC中下列组织块的优先级可以进行修改: OB10~OB47:优先级修改范围2~23。 OB70~OB72:优先级修改范围2~38。 OB81~OB87:优先级修改范围2~26,优先级24~26确保异步故障中断不被其他的事件中断。 几个组织块可以具有相同的优先级,当事件同时出现时,组织块按事件出现的先后顺序触发,如果超过12个相同优先级的OB同进触发,中断可能丢失。 我们在使用相应OB时要注意以下问题。 1.OB只是及时反应出了故障,但并不解决故障,OB允许CPU带故障运行。 2.诊断OB如OB82/86/122反映的是硬件上的故障,靠软件是解决不了的,软件的作用是尽快指向故障点,硬件的问题还是硬件解决。 3.诊断OB的产生会影响CPU的整个程序的执行速度,会影响系统的控制品质,尤其是一些带过程中断,大量运算及运动控制的高速生产线。 4.无条件的让OB去掩盖故障是一件很危险的事情,应该有应对的措施,让系统尽快的进入一种可控的安全状态。

linux安装redis

1,安装redis 1,导入redis包 2,解压 [root@MyServer ~]# cd /usr/local [root@MyServer local]# tar -zvxf redis-6.2.6.tar.gz 3,解压完成之后重命名 [root@MyServer local]# mv redis-6.2.6 redis 4,进行编译 [root@MyServer local]# cd redis [root@MyServer redis]# make 5,安装redis [root@MyServer redis]# make install cd src && make install make[1]: 进入目录“/usr/local/redis/src” CC Makefile.dep make[1]: 离开目录“/usr/local/redis/src” make[1]: 进入目录“/usr/local/redis/src” Hint: It's a good idea to run 'make test' ;) INSTALL redis-server INSTALL redis-benchmark INSTALL redis-cli make[1]: 离开目录“/usr/local/redis/src” 6,创建bin,etc文件 [root@MyServer redis]# mkdir bin [root@MyServer redis]# mkdir etc 7,将redis.

数据仓库-拉链表

在数据仓库中制作拉链表,可以按照以下步骤进行: 确定需求:首先明确需要使用拉链表的场景和需求。例如,可能需要记录历史数据的变化,以便进行时间序列分析等。设计表结构:在数据仓库中,拉链表通常由两个表组成:当前表和历史表。当前表存储最新的数据,历史表存储过去的数据。两个表的结构应该相同,包含相同的字段。建立当前表:创建一个当前表,用于存储最新的数据。该表应包含需要记录的所有字段,以及一个表示有效期的字段。有效期字段用于标识该条数据在何时失效。建立历史表:创建一个历史表,用于存储过去的数据。该表的结构与当前表相同,但还应包含一个表示生效日期的字段。生效日期字段用于标识该条数据在何时生效。数据插入与更新:当有新数据插入时,将其插入到当前表中,并设置相应的有效期。同时,将过期的数据从当前表中移动到历史表中,并更新它们的生效日期和有效期。数据查询:在查询数据时,同时查询当前表和历史表。根据查询的时间范围,确定在哪个表中查找数据。定期维护:定期对历史表进行维护,例如删除过期的数据、优化索引等,以确保拉链表的性能和存储空间的有效利用。 需要注意的是,拉链表在数据仓库中的应用可能因具体需求和场景而有所不同。因此,在实际制作拉链表时,建议根据数据仓库的设计规范、业务需求和数据特点进行调整和优化。同时,也要确保数据的完整性、一致性和准确性。 参考:漫谈数据仓库之拉链表(原理、设计以及在Hive中的实现)_拉链表实现方式_小强签名设计的博客-CSDN博客 二、什么是拉链表 拉链表是针对数据仓库设计中表存储数据的方式而定义的,顾名思义,所谓拉链,就是记录历史。记录一个事物从开始,一直到当前状态的所有变化的信息。 我们先看一个示例,这就是一张拉链表,存储的是用户的最基本信息以及每条记录的生命周期。我们可以使用这张表拿到最新的当天的最新数据以及之前的历史数据 1. 拉链表的使用场景 在数据仓库的数据模型设计过程中,经常会遇到下面这种表的设计: 有一些表的数据量很大,比如一张用户表,大约10亿条记录,50个字段,这种表,即使使用 ORC 压缩,单张表的存储也会超过100G,在 HDFS 使用双备份或者三备份的话就更大一些。表中的部分字段会被 update 更新操作,如用户联系方式,产品的描述信息,订单的状态等等。需要查看某一个时间点或者时间段的历史快照信息,比如,查看某一个订单在历史某一个时间点的状态。表中的记录变化的比例和频率不是很大,比如,总共有10亿的用户,每天新增和发生变化的有200万左右,变化的比例占的很小。 那么对于这种表我该如何设计呢?下面有几种方案可选: 方案一:每天只留最新的一份,比如我们每天用Sqoop抽取最新的一份全量数据到Hive中。方案二:每天保留一份全量的切片数据。方案三:使用拉链表。 拉链表 拉链表在使用上基本兼顾了我们的需求。 首先它在空间上做了一个取舍,虽说不像方案一那样占用量那么小,但是它每日的增量可能只有方案二的千分之一甚至是万分之一。 其实它能满足方案二所能满足的需求,既能获取最新的数据,也能添加筛选条件也获取历史的数据。 所以我们还是很有必要来使用拉链表的。 三、拉链表的设计和实现 1. 如何设计一张拉链表 我们先看一下在 Mysql 关系型数据库里的 user 表中信息变化。 在 2017-01-01 这一天表中的数据是: 在 2017-01-02 这一天表中的数据是,用户 002 和 004 资料进行了修改,005 是新增用户: 在 2017-01-03 这一天表中的数据是,用户 004 和 005 资料进行了修改,006 是新增用户: 如果在数据仓库中设计成历史拉链表保存该表,则会有下面这样一张表,这是最新一天(即 2017-01-03 )的数据: 说明: t_start_date 表示该条记录的生命周期开始时间,t_end_date 表示该条记录的生命周期结束时间。t_end_date = ‘9999-12-31’ 表示该条记录目前处于有效状态。如果查询当前所有有效的记录,则 select * from user where t_end_date = ‘9999-12-31’。如果查询 2017-01-02 的历史快照,则 select * from user where t_start_date <= ‘2017-01-02’ and t_end_date >= ‘2017-01-02’。(此处要好好理解,是拉链表比较重要的一块。 where条件筛选当前有效数据,开始日期小于等于当前日期并且结束日期大于等于当前日期,则为有效。) 2.

cocos tilemap的setTileGIDAt方法不实时更新

需要取消勾选 Enable Culling。同时代码添加:markForUpdateRenderData函数。 floor.setTileGIDAt(1024+27,newP.x,newP.y,0); //中心 floor.markForUpdateRenderData(); 具体问题参考官网说明: Cocos Creator 3.2 手册 - 项目设置

集美大学计算机组成原理复习(软件工程专业)

第一章 1. 冯诺依曼体系三大要点:二进制,存储程序,五大部件 P2 (1)采用二进制代码表示数据和指令,即数据和指令的数字化。 (2)采用存储程序工作方式,即事先编制程序,事先存储程序,自动、连续地执行程序。(3)由存储器、运算器、控制器、输入设备、输出设备5大部件组成计算机硬件系统 存储程序工作方式三点含义 P3 1.事先编制程序 将求解问题的处理过程用程序来实现。在程序中规定计算机需要做哪些事,按什么步骤去做。预先编好的程序最终变成:指令序列和有关的原始数据。 2.事先存储程序 编好的程序经由输入设备送入计算机,存放在存储器中。 3.自动、连续地执行程序 由于程序已经事先存储在存储器中,启动计算机并运行程序后,计算机就可以依照一定顺序从存储器中逐条读取指令,按照指令的要求执行操作,直到运行的程序执行完毕。 3. CPU区分数据和指令,指令的连续执行基本方式,ALU ,两大类控制器 P6-7 1. 区分数据和指令 指令的连续执行基本方式 在CPU中有一个程序计数器PC,存放着当前指令所在存储单元的地址。如果程序是顺序执行,在读取一个或连续几个存储单元的指令代码后,PC的内容就加1或加几,以指出下一条指令的地址:如果程序需要转移,则将转移地址送入PC。因此,PC就像一个指针,指引着程序的执行顺序。可按照PC中的地址信息去读取指令,再按照指令给出的操作数地址去读取数据。 2. ALU CPU内有一个或多个算术逻辑部件ALU。通常按照指令的要求将有关数据送入ALU,进行指定的算术或逻辑运算,然后将运算结果送到主存单元,或暂存在CPU内的寄存器中。 3.两大类控制器 组合逻辑控制器和微程序控制器。 组合逻辑控制器完全靠若干组合逻辑电路产生微命令序列。其优点是形成微命令的速度快。 微程序控制器是将微命令序列以代码形式编制成微程序,存入一个控制存储器中;当CPU执行指令时,通过读取并执行对应的一段微程序,产生微命令序列,控制完成指定的操作。微程序控制方式比较规整,硬件代价较小,易于扩充功能,但速度较慢。 4. 主存储器(内存)的单元组成与地址 P7 主存储器划分为许多单元,通常每个单元存放8位二进制数,称为1字节。每个单元都有一个唯一的编号,称为存储单元地址,简称地址。向主存储器送出某个地址编码,就能根据地址选中对应的一个单元。主存储器的一项重要特性是:能按地址存取内容,也就是允许CPU直接编址访问。 5. 总线的三大类型 P8 系统总线可分为三组,即地址总线、数据总线和控制总线 地址总线: CPU如果需要访问主存,就向地址总线送出地址码以选择某个主存单元: 数据总线: 通过数据总线送出数据,写入主存:或从主存读出数据,通过数据总线送入CPU的寄存器。 控制总线: 大部分控制信号是由CPU提供的,它们通过控制总线送往主存和IO设备:也有些信号是IO设备提供的,其中有些信号也送往CPU。 6. 语言处理的两种类型:解释与编译,具体含义,区别 P10-11 解释方式: 边解释边执行。将源程序输入计算机后,启动并执行解释器,逐步分析源程序中的语句,执行一个等价的机器语言指令序列,直到整个源程序都被扫描一遍,并被解释执行完毕。 优点: 支持人机对话方式的程序设计,可以边执行边修改:所需主存较小。 缺点: 执行速度较慢,不能解释那些前后关联较多、较难理解的程序设计语言。 编译方式: 将源程序输入计算机后,先启动编译器将源程序全部翻译成机器语言指令序列。执行时,计算机将直接执行目标程序,不再需要源程序与翻译程序。 优点: 运行用户程序时,所需主存较小,执行速度较快。 缺点: 在编译过程中,所需主存较多:花费时间较长。 7. 虚拟机的概念,JVM虚拟机工作原理与其意义 P15 虚拟机是通过配置软件扩充机器功能后所形成的一台计算机。实际硬件在物理功能级上并不具备这种机器功能,因而称为虚拟机。采用虚拟机概念是计算机设计中的又一重要策略,它将功能抽象出来,使其脱离具体的物理机器,这有利于摆脱真实物理机细节的束缚,获得超越物理机的功能。 8. 软硬件逻辑等价的意义 P15 有许多功能既可以直接由硬件实现,也可以在硬件支持下靠软件实现,对用户来说在功能上是等价的,我们称为软、硬件在功能上的逻辑等价。 设计指令系统时,选择恰当的软、硬件功能分配,使计算机结构简单而又具有较强的功能或有更高的处理速度; 在软件支持下具有更强的功能 9. 指令执行过程 P17-18

Qt 路径处理

1、路径拼接 QDir::separator():路径分割符号; QDir::cleanPath():消除windows与linux下"/","\\"的拼接问题; QDir::currentPath():当前工作目录。 当前工作目录下文件"1.txt"路径: QString path = QDir::cleanPath(QDir::currentPath() + QDir::separator() + QString("/1.txt")) 2、工作目录、运行目录 工作目录是指当前目录,运行目录是指exe所在路径。所以将1.txt放到对应命令行执行得目录就行,当然这肯定不是最终得解决办法,最终得解决办法就是使用“QCoreApplication::applicationDirPath()”,即为exe所在得目录。 QDir::currentPath() // 当前工作目录。 QCoreApplication::applicationDirPath() // 当前exe所在目录 3、文件路径和文件名、后缀名 QString fullPath = "./Resources/Config/Version.ini"; QFileInfo fileInfo = QFileInfo(fullPath); fileInfo.absoluteDir().path(); // 绝对目录, "E:/App/Resources/Config" fileInfo.absolutePath(); // 绝对目录, "E:/App/Resources/Config" //文件的路径规范路径(不包括文件名),即没有符号链接或冗余“.”或“..”元素的绝对路径 fileInfo.canonicalPath(); // E:/App/Resources/Config fileInfo.absoluteFilePath(); // 绝对路径, E:/App/Resources/Config/Version.ini // 文件的路径规范路径包括文件名,即没有符号链接或冗余“.”或“..”元素的绝对路径 fileInfo.canonicalFilePath(); // E:/App/Resources/Config/Version.ini fileInfo.baseName(); // 文件名, Version fileInfo.completeBaseName(); // 完整的基名由文件中的所有字符组成,直到(但不包括)最后一个“.”字符 fileInfo.suffix() // 文件后缀,"ini" fileInfo.completeSuffix(); //ini, 完整的后缀由文件中第一个“.”之后(但不包括)的所有字符组成 fileInfo.fileName(); // 文件名,"Version.ini" fileInfo.dir().path(); // 文件夹路径, .

uniapp封装图片上传

今天看同事代码,他写小程序图片上传运用了uview Upload的上传组件,但是他没有封装成公用组件,让我浑身不舒服。 我利用了uniapp的 chooseImage和uploadFile这样我们可以直接调用方法就行,并且支持选择图片上传或者拍照上传,话不多说,上代码 //图片选择 export const chooseImage = function(data) { return new Promise((resolve, reject) => { uni.chooseImage({ count: data.count || 1, //默认1 sizeType: 'compressed', //可以指定是原图还是压缩图,默认二者都有 sourceType: data.sourceType || ['camera', 'album'], //从相册选择 success: function(res) { resolve(res.tempFiles); }, fail: err => { uni.hideLoading() reject(err); } }); }); } // 上传图片 export const selectImg = async function(callback) { let files; let options = {}; let token = 'Bearer ' + uni.getStorageSync('token'); // 看个人需求 try { files = await chooseImage(options); console.

判断一个字符串中是否包含中文字符

下面我将为你提供三种常用的方法: 方法一:使用正则表达式 import java.util.regex.Pattern; import java.util.regex.Matcher; public class ChineseCharacterChecker { public static boolean containsChineseCharacters(String input) { String regex = ".*[\\u4e00-\\u9fa5]+.*"; // 正则表达式匹配包含中文字符的字符串 Pattern pattern = Pattern.compile(regex); Matcher matcher = pattern.matcher(input); return matcher.matches(); } public static void main(String[] args) { String str1 = "Hello, 你好吗?"; // 包含中文字符 String str2 = "Hello, how are you?"; // 不包含中文字符 System.out.println(containsChineseCharacters(str1)); // 输出true System.out.println(containsChineseCharacters(str2)); // 输出false } } 方法二:遍历字符串 public class ChineseCharacterChecker { public static boolean containsChineseCharacters(String input) { for (char c : input.

linux用户管理

目录 前瞻 用户 组 uid与gid 查看用户信息 指令 useadd passwd usermod userdel groupadd gpasswd 文件权限与管理 文件的三大权限 chmod chown 前瞻 用户 超级管理员:权限最高普通用户:权限受限程序用户:用来启动程序时所需用户,系统默认,登不上去 组 基本组(私有组):有且唯一添加组(公共组):多个 uid与gid uid是用户的身份,gid是组的身份 vid的范围 超级管理员:0程序用户:centos6 1-499 centos7 1-999普通用户:centos6 500-60000 centos7 1000-60000 查看用户信息 普通用户信息 程序用户信息 查看用户密码信息 注:创建用户并设置密码才能进入以此用户身份进入系统 指令 useadd useadd -u:指定用户的uid useradd -s:按照shell类型创建用户 useradd -M:不建立家目录 useradd -d:指定家目录路径 useradd -e:指定用户失效的时间 useradd -g:指定基本组 useradd -G:指定附加组 useradd -r:随机生成系统用户 passwd passwd 不加任何东西:改当前用户的密码 echo 123 | passwd root --stdin:修改root密码为123 passwd -d:清空密码,不需要密码登录 passwd -l:锁定账户 passwd -S:查看用户是否被锁定

协同网络入侵检测CIDS

协同网络入侵检测CIDS 1、概念2、CIDS的分类3、解决办法4、CIDS模型5、挑战与不足 ⚠申明: 未经许可,禁止以任何形式转载,若要引用,请标注链接地址。 全文共计2598字,阅读大概需要3分钟 🌈更多学习内容, 欢迎👏关注👀【文末】我的个人微信公众号:不懂开发的程序猿 个人网站:https://jerry-jy.co/ 1、概念 协同入侵检测技术( collaborative intrusion detection system,CIDS) 以分布式入侵检测系统 DIDS ( distributed intrusion detection system,DIDS) 结构为基础,能够结合其他技术,通过多种协同方式检测出大规模协同攻击,是一种能够提高检测精度、可以部署在大规模网络的入侵检测技术。 协同概念引入到 IDS 中,旨在通过多源数据采集、多方协同处理来提高整体 IDS 的检测率。目前研究人员普遍将 CIDS 定义为: 两个及以上具备一定独立检测能力的个体,通过数据收集、检测分析、告警响应三个方面的协同工作,共同达到入侵检测目的的综合入侵检测系统。 2、CIDS的分类 分层式 CIDS 即子系统协同 IDS,是集中式 CIDS 的改进。它将整个 IDS 分成若干个小的子系统,子系统能够对收集的数据进行过滤和关联,并反馈给上级的处理节点,最终交付到顶层处理中心,实现以顶层处理中心为根节点的树状层次检测模型。在分层式 CIDS 中,通过子处理器对数据的过滤和聚合缓解了中心处理器的数据处理压力,提高了系统处理性能和处理效率,但是数据在每一层都被聚合处理,存在数据损失的情况,一些隐蔽性强的攻击可能会被忽略; 此外,基于上下级的协同关系容易因为单点故障而使检测路径中断,进而影响整体检测能力; 最后,系统安全性仍然受限于根节点,对根节点的安全要求较高。 对等式 CIDS 是在分层式 CIDS 基础上的进一步改进,节点的自主性得到进一步加强。在对等式 CIDS 中,各个节点地位平等,具有完整的入侵检测能力,因此可以并行处理数据,通过节点间的数据共享和聚合检测出复杂协同攻击,提高了系统检测能力,同时可以有效避免单点故障,提高了系统的健壮性。在基于机器学习的对等式CIDS 中,各节点通过与其他节点共享学习经验,能够不断提高自己的检测能力,进而有效提高系统的检测水平。 CIDS 相较于传统 IDS 的优势在于可以检测出大规模的分布式攻击和协同攻击,如网络扫描、蠕虫病毒与分布式拒绝服务攻击(DDoS) 等,还可以通过数据的共享改善检测方法,提高入侵检测精度,这就涉及到数据聚合的问题。在 CIDS 中,数据聚合是指将各分布式节点收集的数据进行聚合处理后,再综合分析攻击行为的方法。 3、解决办法 解决协作入侵检测问题的一种有前途的方法是通过用于消息通信的基于内容的关联方案,即用于警报关联的发布-订阅模型。发布-订阅模型已广泛应用于事件通知、移动支持服务等任务的文献中以及 Java 消息服务中。在协作入侵检测的背景下,当参与者 IDS 检测到其受监控子网中可能存在攻击时,它会生成警报,并将该警报报告给 CIDS。这称为订阅,即IDS 向 CIDS 注册其兴趣,以确认警报是否是大规模协同攻击的一部分。CIDS 的作用是关联参与 IDS 订阅的警报。如果收到足够的订阅警报来确认攻击,则 CIDS会向订阅该攻击的参与 IDS 发布已确认攻击的通知。

为什么会被【禅道】工具的公司踢出QQ群的反思…………

周末备份Gitlab的代码库,把Gitlab更新到了最新的16.5。顺带看了禅道官网出了最新版本18.8。但是禅道的升级更新并不顺利…………。 先说一下为什么用禅道这个工具: 再使用禅道这个工具前,使用过的工具有QC(Quality Center)、jira,redmine,bugzilla。 用禅道是因为刚到公司的领导,在之前的公司用的是禅道。所以公司由redmine改为使用禅道。 周六更新禅道遇到的问题: 1.问题1截图 2.问题2截图,升级进度一直停留在7%。僵死状态,页面无响应3.问题3与问题2的现象是一样的。升级进度一直停留在100%。僵死状态,界面无任何相应。 禅道QQ群的里的沟通过程: 1.周六群里: 把上述截图发到禅道的QQ沟通群里。有个QQ叫做“青岛-个人-碧”的人进行了回复。首先我看到了这个网名后,我认为,个人的回答不能代表禅道公司所属研发人员的回复,不权威,可以作为参考。 2.周一群里: 周六禅道的升级由(17.6.1~18.8)。尝试了3次,都是失败。今天一上班,就到群里@他们的研发。想咨询问题,研发回复要看日志,但是周六升级3次失败的情况就恢复到了17.6.1版本,没有日志,给研发人员说得时候顺口说了一句:周六你们公司也没有人回复。然后研发人员说,有人回复。还给截了个图,研发说得回复的人是“青岛-个人-碧”。然后我说我看到网名有个人(禅道的QQ群里,禅道公司的人的网名备注是:禅道-商务、禅道-研发,都是禅道开头的),觉得不是你们公司的回复。然后就因为这个,开始了争论……, 禅道商务回复:他们会对专业版本用户提供升级服务,比如:预约升级时间,对开源用户会提供支持。 连续升级过程重复了3次,本来就着急,看到这个回复,心里更不舒服。让人觉得不交钱还想要我们时刻提供服务,但是不能否定,一个开源的工具,可能会有很多问题是这些开源用户发现。 过了一会时间研发回复:他们的研发人员也得需要休息。 看到这个我心里还纳闷呢,群里从来没有说过,不让禅道的研发人员休息。然后上午由再次进行了一次升级,还是有问题,和问题1的现象一样。然后又把这个截图发到群里(时间是上午11:30多了)手机里保存的截图: 禅道研发人员回复我得时候应该是12点多了,我出去吃饭了……再然后,看截图 回来看这个消息,我回的是:哎呦,我去……,我没有不配合,吃饭时间,休息时间,我根本就没有看到消息。 最后“开源春哥”就说:我不尊重他们的资深研发人员。我这种人,自己解决问题去把,他们不伺候了。最最后的结果就是:(因为被踢出群了,无法截图) 接受这个结果但是对于禅道公司的这种做法,我真是觉得不专业: 1.一开始我只是觉得青岛-个人-碧这个人的回复信息,不是禅道专业人员的回复,我不知道他是禅道公司的人。 2.禅道-商务的回复,让我觉得他们对付费用户提供专业的服务,开源的回复不会这么及时。作为商务,我认为,你回复一句:不好意思,青岛-个人-碧,她没及时修改备注。都比上来就说他们对付费版本(专业版,企业版收费)的用户提供专业服务这个回答,好一些。 3.在我把第四次升级出错图片发的禅道群里的时候,我是想着吃完饭回来,看看禅道研发怎么说得,连出错日志。我都打包好了。11:30多把截图发的QQ群里以后,研发12点多才给的回复。然后等我吃完饭回来就看到开源-春哥的消息。 最后禅道会停留在17.8版本。开源-春哥把我提出群之后,我再次把版本恢复到17.6.1然后升级到18.0版本,报错与升级到18.8的错误是一样的。最最后把版本再次恢复到17.6.1然后升级到17.8版本。升级成功。我想公司的禅道的版本应该会停留在17.8.因为重复升级了这么多次,出现的问题都一样,大概率的是: 1.整个架构做了大的改版,造成升级有问题 2.数据库表格进行了大更新,造成升级有问题 3.当然不排除,公司服务器硬件问题,以及我个人的能力问题。 4.最后想说,我用的是开源的版本,免费的,我11点半把问题截图发给你们以后,就应该不吃饭,贱兮兮的的等着你们研发的回复?可以把我踢出群,那付费版本的用户,是不是不管啥都可以忍着。 5.我朋友说你被踢出群还有一个原因,就是因为说之前用的redmine,来了新领导才换成了禅道。因为同行是冤家,肯定听不得你说别的软件。 最后,不管用啥就是为了方便工作,但要记住,需要好的服务,要付出金钱。其实新领导来公司后,我们还真咨询过付费的,后来为啥没有用付费版本呢,因为这个领导在公司没有待太长时间,所以就此作罢

Chrome 常用快捷键

文章目录 窗口选项卡网页功能参考文献 Chrome 是一款由谷歌开发的免费网络浏览器。 Chrome 是目前使用最广泛的网络浏览器,没有之一。适用于多个操作系统,包括 Windows、macOS、Linux、Android 和 iOS。 Chrome 拥有丰富的功能和相关的快捷键,掌握其常用的快捷键,有助于我们更加高效的使用 Chrome 畅游网络。 窗口 打开新窗口 Ctrl + N 无痕模式打开新窗口 Ctrl + Shift + N 关闭当前窗口 Ctrl + Shift + W 或 Alt + F4 选项卡 跳转到下一个标签页 Ctrl + Tab 或 Ctrl + PgDn 跳转到上一个标签页 Ctrl + Shift + Tab 或 Ctrl + PgUp 关闭当前标签页 Ctrl + W 或 Ctrl + F4 打开新的标签页并跳转到该标签页 Ctrl + T 按标签页的关闭顺序重新打开先前关闭的标签页 Ctrl + Shift + T 网页 刷新页面 F5 跳转到页首 Home 跳转到页尾 End 回退到上一页 Alt + ← 前进到下一页 Alt + → 在当前标签页打开主页 Alt + Home 功能 打开开发者工具 F12 或 Ctrl + Shift + J 显示或隐藏书签栏 Ctrl + Shift + B 参考文献 Chrome keyboard shortcuts - Computer - Google Support

寄存器、CPU缓存、内存。以及他们之间的关系

寄存器 CPU寄存器是CPU内部的高速存储区域,用于临时存储数据和指令。寄存器是CPU的重要组成部分,用于提高程序的执行效率。它们比主存储器更快,可以使得CPU更有效地处理数据和执行指令。 寄存器可以分为不同类型,下面列出部分ARMv8寄存器: 通用寄存器:ARMv8架构有大量的通用寄存器,包括x0 ~ x30(在AArch64架构中)和w0~w30(在AArch32架构中),这些寄存器是32位或64位宽,用于存储数据和参与运算。状态寄存器:ARMv8使用PSTATE寄存器表示当前处理器状态,其中包含了一些状态标志位,如处理器模式、异常标志等。特殊寄存器:ARMv8有一些特殊的寄存器,如SP(stack pointer register)和PC(program counter),分别用于指向当前栈的指针和保存当前指令的地址。系统寄存器:ARMv8还有很多系统寄存器,用于完成对处理器不同功能的配置。例如,在ARMv7中定义的cp15寄存器,在ARMv8中仍然存在并被重命名为CP15_64。此外,还有一些特殊目的寄存器、VMSA(虚拟内存架构)特殊寄存器、ID寄存器、性能监控寄存器、DEBUG寄存器、RAS寄存器、通用定时器寄存器、Cache维护相关寄存器、地址转换寄存器和TLB维护寄存器等。浮点寄存器:ARMv8架构支持浮点运算,有32位和64位的浮点寄存器,用于存储浮点数和参与浮点运算。虚拟寄存器:ARMv8架构支持虚拟化技术,有一些虚拟寄存器用于虚拟化操作。调试寄存器:ARMv8架构有一些调试寄存器,用于调试程序和检查处理器状态。内存管理寄存器:ARMv8架构有一些内存管理寄存器,用于管理内存和缓存。电源管理寄存器:ARMv8架构有一些电源管理寄存器,用于控制处理器的功耗和节能模式。 CPU缓存 CPU缓存是位于CPU与内存之间的临时存储器,它的容量比内存小但交换速度却比内存要快得多。CPU高速缓存的出现主要是为了解决CPU运算速度与内存读写速度不匹配的矛盾。因为CPU运算速度要比内存读写速度快很多,这样会使CPU花费很长时间等待数据到来或把数据写入内存。在缓存中的数据是内存中的一小部分,但这一小部分是短时间内CPU即将访问的,当CPU调用大量数据时,就可先从缓存中调用,从而加快读取速度。 CPU缓存的结构和大小对CPU速度的影响非常大,CPU内缓存的运行频率极高,一般是和处理器同频运作,工作效率远远大于系统内存和硬盘。实际工作时,CPU往往需要重复读取同样的数据块,而缓存容量的增大,可以大幅度提升CPU内部读取数据的命中率,而不用再到内存或者硬盘上寻找,以此提高系统性能。但是从CPU芯片面积和成本的因素来考虑,缓存都很小。 CPU缓存一般分为三级:CPU一级缓存、二级缓存、三级缓存等不同级别的缓存也各有其特点和用途。例如,一级缓存主要存储指令和特定于数据的缓存,二级缓存则用于CPU和内存之间的数据交换,三级缓存通常用于更低速率的存储器,例如硬盘或网络连接。 飞腾D2000/8 CPU集成了8个FTC663核: 一级缓存:每个核都有32kb的L1指令缓存和32kb的速率缓存,共计256kb的指令缓存和256kb的速率缓存 二级缓存:每个 Cluster 内有 2MB,共 8MB。 三级缓存:分为8个Bank,共4MB。 内存 用于暂时存放CPU中的运算数据,以及与硬盘等外部存储器交换的数据。内存是CPU直接与之沟通,并用其存储数据的部件,存放当前正在使用的(即执行中)的数据和程序,它的物理实质就是一组或多组具备数据输入输出和数据存储功能的集成电路,内存只用于暂时存放程序和数据,一旦关闭电源或发生断电,其中的程序和数据就会丢失。 寄存器、CPU缓存、内存之间的关系 执行引擎:面向寄存器进行操作,它负责执行指令和处理数据。在执行指令时,执行引擎需要从寄存器中读取数据,或者把数据写入寄存器。 当执行引擎执行时,会从寄存器中读取数据,寄存器会从CPU缓存中读取,或者从内存中读取。如下示意图:

python函数讲座【修改】

python函数讲座 函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段。函数能提高应用的模块性,和代码的重复利用率。简单地说,在Python中,函数是一组执行特定任务的相关语句。 Python 中函数的应用非常广泛,前面讲座中我们已经使用过过多个函数,比如 input() 、print()、range()函数等等,这些都是 Python 的内置函数,可以直接使用。 除了可以直接使用的内置函数外,Python 还支持自定义函数,即将一段有规律的、可重复使用的代码定义成函数,从而达到一次编写、多次调用的目的。 注意:和C语言、Visual Basic语言等函数定义不可以嵌套,调用可以嵌套不同,python函数定义和调用都可以嵌套,这一点和JavaScript函数一样。 Python函数的一般分类 (1)内置函数。Python语言内置了若干常用的函数,例如abs()、len()等等,在程序中可以直接使用。 (2)标准库函数。Python语言安装程序同时会安装若干标准库,例如math、random等等。通过import语句,可以导入标准库,然后使用其中定义的函数。 (3)第三方库函数。Python社区提供了许多其他高质量的库,如Python图像库等等,需要下载安装。下载安装这些库后,通过import语句,可以导入库,然后使用其中定义的函数。 (4)用户自定义函数。本讲座将讨论函数的定义和调用方法。 自定义函数的简单规则: 函数代码块以 def 关键词开头,后接函数标识符名称和圆括号 ()和冒号:。 任何传入参数和自变量必须放在圆括号中间,圆括号之间可以用于定义参数。 函数内容(函数体)缩进。 Python 定义函数的语法格式 Python 定义函数使用 def 关键字,一般格式如下: def 函数名([参数列表]): ["""docstring"""] 函数体 [return [返回值]] 各部分的含义如下: 其中[ ]表示其内的部分是可选的即不一定有——可写有可不写,[ ]本身不写。 关键字def标志这一个函数头部的开始。 函数名:其实就是一个符合 Python 语法的标识符,但不建议读者使用 a、b、c 这类简单的标识符作为函数名,函数名最好能够体现出该函数的功能。 参数列表:是可选的。设置该函数可以接收多少个参数,多个参数之间用逗号( , )分隔。即使函数不需要参数,也必须保留括号()。 一个冒号(:)是标志着函数头部的结束。 docstring:是documentation string的缩写。它用来简单地解释函数的作用。 函数体:由一个或多个有效python语句组成。语句必须有相同的缩进(通常是4个空格)。 [return [返回值] ]:整体作为函数的可选参参数,用于设置该函数的返回值。也就是说,一个函数,可以用返回值,也可以没有返回值,是否需要根据实际情况而定。函数体中没有 return 语句时,函数运行结束会隐含返回一个 None 作为返回值,类型是 NoneType,与 return 、return None 等效,都是返回 None。 函数中可以有多条return语句,只要执行了一条return语句,程序返回到调用程序。 注意,在创建函数时,即使函数不需要参数,也必须保留一对空的“()”,否则 Python 解释器将提示“invaild syntax”错误。

Java字符串整齐输出

一、使用String.format() String.format( "%-27s\t%-27s\t%s\n", "key:" + key, "value:" + value, "value:" + value)

数据清洗(1)--数据查缺补漏

前言 之前使用scikit 进行一些基础模型的选择(SVM支持向量机,LR算法,KNN,SGD,Bays贝叶斯,决策树,随机森林),创建,训练(测试集+验证集)(分类规则-基尼划分标准,熵划分标准->交叉验证),和调参(主要在决策树和随机森林上面试了下)。多多少少了解了一点模型的由来。但是始终不太了解数据是从何而来,需要如何清洗,需要如何正则化,归一化之类的。于是就有了以下的文章。以下都是本人看了别人的文章或者敲了一些代码后对数据的一些认知,本人对python不是很熟,所以很多时候可能理解得不对。有错误麻烦指出来,谢谢! 条件 lianjia.json 格式如下 json数据先转换成csv文件 # 将json数据转换成csv数据,方便后面进行数据的运算 import json import csv import os def jsonToCsv(jsonFile, csvFile): # 查看当前的路径 path = os.getcwd() print(path) # 1,读取json数据 读取csv文件 # json_fp = open(jsonFile, "r", encoding='utf-8') csv_fp = open(csvFile, "w", encoding='utf-8', newline='', ) writer = csv.writer(csv_fp) with open(jsonFile, 'r', encoding='utf-8') as json_fp: isTitle = True; # 2,提取出表头和表的内容 for line in json_fp.readlines(): lineStr = json.loads(line) # 将每一条数据读取出来 print(lineStr) if isTitle: sheet_title = lineStr.keys() print(sheet_title) isTitle = False writer.

STM32的hex文件格式的分析

前言 最近研究Bootloader,通过串口实现STM32程序的更新。需要学习了解STM32的Hex文件格式。在这进行一下总结。 HEX文件格式 我们通过文本形式打开hex文件,可以看到: 这一行就是一条指令数据,这里对数据帧格式进行说明: 报头本行数据长度数据起始地址数据类型数据校验码:(冒号)1 byte2 byte1 byten byte1 byte 结合这个格式可以发现,它将数值1byte变成了字符串形式的2个字符来表示。 用第一行数据 :020000040800F2 作为示例: ":" 表示 指令头 "02" 表示 数据部分有两字节(即四个字符) "0000" 表示 数据的16位起始存储器地址偏移量,是0x0000。数据的物理地址是通过将此偏移量添加到先前建立的基地址来计算的。 "04" 表示 数据类型。基地址 "0800" 表示 数据内容,为 0x08 和 0x00 "F2" 是检验码。LRC校验(纵向冗余校验):在线LRC校验(纵向冗余校验)计算器 (lddgo.net) 该条语句功能即说明 基地址为0x0800<<16为0x08000000. 后面的数据语句的地址则是在该条语句基地址基础上的偏移量。 第四字节表示数据类型,数据类型有:0x00、0x01、0x02、0x03、0x04、0x05。 数据类型功能描述示例00数据包含数据和该数据的16位起始地址。字节计数指定记录中的数据字节数。右侧显示的示例为0B (十一)个数据字节(61, 64, 64, 72, 65, 73, 73, 20, 67, 61, 70)位于以地址开头的连续地址 0010。:0B0010006164647265737320676170A701文件结束每个文件在文件的最后一行必须恰好发生一次。数据字段为空(因此字节数为00),并且地址字段通常为 0000。:00000001FF02扩展段地址数据字段包含一个16位的段基址(因此字节数始终为02)与80x86实模式寻址兼容。地址字段(通常为0000)被忽略。最近的段地址02记录乘以16,然后加到每个后续数据记录地址,以形成数据的物理起始地址。这允许寻址多达1 MB的地址空间。:020000021200EA03起始段地址对于80x86处理器,请指定CS:IP寄存器的初始内容(即起始执行地址)。地址字段是0000,字节数始终为04,前两个数据字节是CS值,后两个是IP值。:0400000300003800C104扩展线性地址允许32位寻址(最大4GiB)。记录的地址字段将被忽略(通常是0000),其字节数始终为02。两个数据字节(大字节序)为所有后续类型指定32位绝对地址的高16位00记录; 这些高位地址位适用于下一个04记录。类型的绝对地址00 通过组合最近的高16位地址位形成记录 04 用低16位的地址记录 00记录。如果是类型00 记录之前没有任何类型 04 记录,然后其高16位地址位默认为0000。:02000004FFFFFC05起始线性地址地址字段是 0000(未使用),字节数始终为04。四个数据字节代表一个32位地址值(big-endian)。对于80386和更高版本的CPU,此地址将加载到EIP寄存器中。:0400000508000135B9 总结 了解了这个东西,似乎自己也能做一个stm32版本的类似arduino的bootloader了。

linux自己搭建远程桌面软件Rustdesk(2023)

1. liunx安装rustdesk server yum install wget wget --no-check-certificate https://github.com/rustdesk/rustdesk-server/releases/download/1.1.6/rustdesk-server-linux-x64.zip unzip rustdesk-server-linux-x64.zip 2. 启动端口 21115(tcp), 21116(tcp/udp), 21118(tcp),21117(tcp), 21119(tcp),36001(tcp),36000(tcp/udp) hbbs是ID/Rendezvous 服务器。默认监听:21115(tcp), 21116(tcp/udp), 21118(tcp) hbbr是中继服务器。默认监听:21117(tcp), 21119(tcp) 36000(注意要去云安全组、服务器系统防火墙方形哦 注意是TCP+UDP哦) 36001(注意要去云安全组、服务器系统防火墙方形哦 注意是TCP即可) 1) liunx依次执行上面端口,我不列举了 firewall-cmd --zone=public --add-port=36000/udp --permanent firewall-cmd --zone=public --add-port=36000/tcp--permanent firewall-cmd --zone=public --add-port=21116/tcp--permanent firewall-cmd --zone=public --add-port=21116/udp --permanent firewall-cmd --zone=public --add-port=36001/tcp--permanent firewall-cmd --zone=public --add-port=21119/tcp--permanent firewall-cmd --zone=public --add-port=21117/tcp--permanent firewall-cmd --zone=public --add-port=21118/tcp--permanent firewall-cmd --zone=public --add-port=21115/tcp--permanent firewall-cmd --reload 2) 服务器防火墙也要开放以下端口 21115(tcp), 21116(tcp/udp), 21118(tcp),21117(tcp), 21119(tcp),36001(tcp),36000(tcp/udp) 3、启动服务 1)启动 hbbr 是中继服务器 修改hbbr默认端口为 21117 -> 36001(注意要去云安全组、服务器系统防火墙方形哦 注意是TCP即可)

数据处理中判断空值的方法(np.isnan、is np.nan和pd.isna)

1、np.isnan(只有数组数值运算时可使用) 注意:numpy模块的isnan方法仅支持对数值进行判断,因此传入的如果是字符串类型会报错 2、is np.nan(不建议使用) 如果我们的空值只会出现由numpy模块的nan,或只想判断由numpy模块生成的nan值,可以使用,但其他场合一律不建议使用 注意:因为math模块同样可以产生nan值,且math.nan由is np.nan判断是False 3、pd.isna(大部分数据处理的场合推荐使用) 如果我们的空值既会出现np.nan,也会出现math.nan,甚至还会出现None,或者要判断的数据值既可能是数值型也可能是字符串(符合大部分场景的实际情况),墙裂推荐使用pd.isna pd.isna(np.nan) Out[29]: True pd.isna(math.nan) Out[30]: True pd.isna(None) Out[31]: True pd.isna('a') Out[32]: False pd.isna(10) Out[33]: False 参考:https://www.cnblogs.com/oceanicstar/p/10869725.html

视频增强修复软件Topaz Video AI mac中文版支持功能

Topaz Video AI mac是一款使用人工智能技术对视频进行增强和修复的软件。它可以自动降噪、去除锐化、减少压缩失真、提高清晰度等等。Topaz Video AI可以处理各种类型的视频,包括低分辨率视频、老旧影片、手机录制的视频等等。 使用Topaz Video AI非常简单,只需要将需要处理的视频文件导入软件中,选择所需的增强选项,然后点击“开始处理”按钮即可。软件会根据所选的选项和视频的特性自动进行优化处理,并生成增强后的视频文件。 除了增强和修复视频效果,Topaz Video AI还可以进行画面缩放、帧率转换、色彩调整等操作。此外,该软件还支持GPU加速,可以大大提高处理速度。 总之,Topaz Video AI是一款功能强大、易于使用的视频增强和修复软件,适合专业和非专业用户使用。 苹果:Topaz Video AI for mac(视频增强和修复工具) 4.0.1中文版 Win:Topaz Video Enhance AI(视频质量增强工具)

作为一名新媒体运营,如何做副业一个月挣了3000多,分享实操方法和技巧

我是一名新媒体运营人,现在每个月的收入七七八八也就2万左右,但是其实工资收入只有月6000左右,大部分收益是来源于我的副业。 因为自己所工作的行业就是新媒体运营,所以对于做自媒体账号这一方面也是有自己的一点经验的,于是就在工作之余自己做了自媒体账号作为副业,所以即使我也是朝九晚五,但是我不觉得我自己在无所事事混日子。 而我自媒体账号选择的方向就是最近挺火的AI作画 上个月我测试了一个方法,在小红书就赚了3千多。那么我们话不多说,接下来我分享下具体操作方法。记得点赞收藏加保存。 一、项目介绍 2023年以来,AI的热度一度飙升。不少人讨论AI在将来是否会取代大部分岗位,导致大量人员失业。而在这一切到来之前,有一种新的副业正在悄然而至,那就是AI作画。 这个项目是如何变现的呢,继续往下看。 二、如何操作 第1步,注册账号。 注册账号后,需要养3到5天的号再去发布作品,期间每天至少活跃半小时以上,观看AI绘画领域的同行作品,这样不仅可以提高账号权重,还方便了解同行动态。 第2步,准备素材和制作。 制作过程非常简单,只需要将素材导入,选择AI帮你画即可。制作好后,在封面和标题上上点心,可以提高点击率。 温馨提示:最好是使用原创图片制作,否则有可能被平台判搬运。 三、如何引流 将素材同步发布到某音、某手、视频号等多个平台,矩阵化坚持发布,点爆流量引流变现到微信。 四、获图分享 在实践中,可以用话术引导客户,为了让照片不被发送,压缩画质,并将原图放在网盘中引导用户到网盘下载,以增加作品的变现效率,还可以开展收图挣米活动,根据素材的质量和市场需求定价,收益可达几百上千不等。 五、渠道推广 可以利用社交媒体,比如:微信群、Q群等多种渠道,扩大项目的影响力,也可以结合其他项目,例如网盘拉新,AI作画项目形成联动,进一步提高变现效果。 六、AI绘画神器(感兴趣的可以自己去搜索试一下) liblib AI:哩布哩布是目前用起来很顺手的AI绘画平台了,原创模型很多,用户反馈的图片质量也很好。 Midjourney:Midjourney可谓是2023年最火的AI绘画工具,一经发布就让无数设计师直呼“要失业了”。只要输入关键词,它就能生成任何你想要的图片。 Stable Diffusion:只需要输入一句提示词(prompt),就能快速生成出令人惊叹的绘画作品,和MJ相似,但效果图远比MJ清晰好看。 无界AI:无界AI是一款国产绘图软件。集prompt搜索、AI图库、AI创作、AI广场等为一体的在线产品。提供一站式AI搜索-创作-交流-分享服务。 七 关于AI绘画技术储备 学好 AI绘画 不论是就业还是做副业赚钱都不错,但要学会 AI绘画 还是要有一个学习规划。最后大家分享一份全套的 AI绘画 学习资料,给那些想学习 AI绘画 的小伙伴们一点帮助! 对于0基础小白入门: 如果你是零基础小白,想快速入门AI绘画是可以考虑的。 一方面是学习时间相对较短,学习内容更全面更集中。 二方面是可以找到适合自己的学习方案 包括:stable diffusion安装包、stable diffusion0基础入门全套PDF,视频学习教程。带你从零基础系统性的学好AI绘画! 零基础AI绘画学习资源介绍 👉stable diffusion新手0基础入门PDF👈 (全套教程文末领取哈) 👉AI绘画必备工具👈 温馨提示:篇幅有限,已打包文件夹,获取方式在:文末 👉AI绘画基础+速成+进阶使用教程👈 观看零基础学习视频,看视频学习是最快捷也是最有效果的方式,跟着视频中老师的思路,从基础到深入,还是很容易入门的。 温馨提示:篇幅有限,已打包文件夹,获取方式在:文末 👉12000+AI关键词大合集👈 这份完整版的AI绘画全套学习资料已经上传CSDN,朋友们如果需要可以点击下方链接免费领取【保证100%免费】 CSDN大礼包:《全套AI绘画基础学习资源包》免费分享 CSDN大礼包:《全套AI绘画基础学习资源包》免费分享

【机器学习】loss损失讨论

大纲 验证集loss上升,准确率也上升(即将overfitting?)训练集loss一定为要为0吗 Q1. 验证集loss上升,准确率也上升 随着置信度的增加,一小部分点的预测结果是错误的(log lik 给出了指数级的惩罚,在损失中占主导地位)。与此同时,大量其他点开始预测良好(argmax p=label),主导了预测的准确性。 Q2. 训练集loss一定为要为0吗 一般来说,我们是用训练集来训练模型,但希望的是验证机的损失越小越好,而正常来说训练集的损失降到一定值后,验证集的损失就会开始上升,因此没必要把训练集的损失降低到 0 既然如此,在已经达到了某个阈值之后,我们可不可以做点别的事情来提升模型性能呢?ICML2020 的论文《Do We Need Zero Training Loss After Achieving Zero Training Error?》回答了这个问题,不过实际上它并没有很好的描述 “为什么”,而只是提出了 “怎么做” 假设原来的损失函数是 L ( θ ) \mathcal {L}(\theta) L(θ),现在改为 L ~ ( θ ) \tilde {\mathcal {L}}(\theta) L~(θ): L ~ ( θ ) = ∣ L ( θ ) − b ∣ + b (1) \tilde{\mathcal{L}}(\theta)=|\mathcal{L}(\theta)-b|+b\tag{1} L~(θ)=∣L(θ)−b∣+b(1) 其中 b b b 是预先设定的阈值。当 L ( θ ) > b \mathcal {L}(\theta)>b L(θ)>b 时 L ~ ( θ ) = L ( θ ) \tilde {\mathcal {L}}(\theta)=\mathcal {L}(\theta) L~(θ)=L(θ),这时就是执行普通的梯度下降;而 L ( θ ) < b \mathcal {L}(\theta)<b L(θ)<b 时 L ~ ( θ ) = 2 b − L ( θ ) \tilde {\mathcal {L}}(\theta)=2b-\mathcal {L}(\theta) L~(θ)=2b−L(θ),注意到损失函数变号了,所以这时候是梯度上升。因此,总的来说就是以 b b b 为阈值,低于阈值时反而希望损失函数变大。论文把这个改动称为 “Flooding”

UE5使用Dash插件实现程序化地形场景制作

目录 0 dash下载后激活 1 初步使用 2 导入bridge的资产路径 3 练习成果 4 参考链接 0 dash下载后激活 1 初步使用 Dash插件点击蓝色的A,可以使用。 通过输入不同提示命令,来激活不同的功能。 2 导入bridge的资产路径 这里需要注意是UAsserts的上一级目录。 3 练习成果 实现程序化地形,程序化植被,日光模拟,摄像机视角等功能。 4 参考链接 POLYGONFLOW - YouTube Dash — Quick Guide (notion.site) 【虚幻5】如何快速搭建一个国风场景_哔哩哔哩_bilibili 【虚幻5】虚幻小技巧,如何制作一个风铃晃动的动画,UE5.3骨骼编辑系统初体验_哔哩哔哩_bilibili

K8s开发人员也需要了解的相关知识

工作变动总结一下之前的笔记,整理一个速查的东西,方便之后查阅 K8s开发相关 1、k8s yml apiverison: Kubernetes (k8s) 的 API 版本表示资源定义在 API 服务器中的稳定性和支持程度。API 版本由一个字符串表示,如 v1 或 apps/v1,其中包括两个部分: 组 (Group): 如果资源属于某个 API 组,则该字段表示该组的名称。例如,apps 表示应用程序相关的资源如 Deployments。版本 (Version): 表示 API 的版本,常见的有 v1、v1beta1 等。 常见的 API 版本有: v1: 核心组的稳定版本,包括常用的资源如 Pods、Services、ConfigMaps 和 Secrets。apps/v1: 用于管理应用的稳定版本,包括 Deployments、StatefulSets、DaemonSets 等。batch/v1: 用于批处理任务,包括 Job 资源。batch/v1beta1: 包括 CronJob 资源。extensions/v1beta1: 早期版本的一些资源,例如 Ingress(现在推荐使用 networking.k8s.io/v1)。networking.k8s.io/v1: 网络相关资源,包括 NetworkPolicies 和 Ingresses。rbac.authorization.k8s.io/v1: 用于角色基础访问控制的资源,包括 Roles 和 RoleBindings。storage.k8s.io/v1: 存储相关的资源,包括 StorageClasses 和 VolumeAttachments。autoscaling/v1: 自动缩放相关资源,包括 HorizontalPodAutoscalers。policy/v1beta1: 包括 PodSecurityPolicies,用于定义 Pod 的安全性相关设置。 2、开发人员比较常用的一些 Kubernetes Kind类型: 核心资源类型 Pod: 作为应用的最小和最简单的单元,每个 Pod 包含一个或多个容器。Service: 提供稳定的 IP 地址和 DNS 名称,将外部网络流量路由到后端的 Pod。Deployment: 用来描述应用的期望状态,Kubernetes 会确保真实状态符合期望状态。ConfigMap: 存储非敏感数据的键值对,可以用来存储环境变量、配置文件等信息。Secret: 存储敏感数据,如密码、OAuth 令牌等。PersistentVolume 和 PersistentVolumeClaim: 提供 Pod 持久化存储的能力。Namespace: 提供一种将集群资源分隔成多个独立的部分的方式。 配置和管理资源类型 ResourceQuota: 确保每个命名空间下的资源使用量不超过设定的配额。LimitRange: 限制命名空间下资源的大小,请求和限制。HorizontalPodAutoscaler: 根据 CPU 使用或其他选择的度量自动缩放 Pod 的数量。 网络资源类型 Ingress: 为服务提供外部可访问的 URL,负载均衡,SSL/TLS 终止等。NetworkPolicy: 定义 Pod 间通信的网络策略。 其他资源类型 Job 和 CronJob: 用于执行一次性或周期性的任务。StatefulSet: 用于运行需要持久存储和唯一网络标识符的应用。DaemonSet: 确保所有(或部分)节点运行一个 Pod 的副本。ReplicaSet: 确保指定数量的 Pod 副本始终可用。Node: 表示集群中的一个节点。 开发人员在使用 Kubernetes 时,通常会涉及到这些资源的创建和管理。通过这些资源,他们可以定义和配置应用的运行环境,实现自动化和弹性伸缩等特性。理解这些资源的作用和使用方式,是开发人员在 Kubernetes 平台上高效工作的基础。

【C++】多态 ④ ( 多态实现原理 | C++ 联编概念 | 链接属性 | 内部链接 | 外部链接 | 联编与链接 | 静态联编 | 动态联编 | 联编 与 virtual 关键字 )

文章目录 一、C++ 联编概念1、联编引入2、链接属性 ( 内部链接 | 外部链接 )3、联编 ( C++ 语言 ) 与 链接 ( C 语言 )4、静态联编5、动态联编 二、多态实现原理 - 联编 与 virtual 关键字 一、C++ 联编概念 1、联编引入 " 联编 " Linkage 指的是 将 程序模块 和 代码 互相关联的过程 , 将不同源文件中的 同名函数 或 变量 进行链接 ; 在 C++ 语言中 , 每个 函数 或 变量 都有一个 链接属性 , 该链接属性决定了该 函数 或 变量 是否可以在其他源文件中使用 ; 联编 是通过 声明函数或变量 的 链接属性 进行控制 ; 如果一个 函数或变量 具有外部链接属性 , 则可以在其他源文件中使用该函数或变量 ;如果一个 函数或变量 具有内部链接属性 , 则只能在其所在的源文件中使用该函数或变量。 2、链接属性 ( 内部链接 | 外部链接 ) C++ 中的 链接属性 有两种 : 内部链接 和 外部链接 ;

Vue 3响应式对象: ref和reactive

目录 什么是响应式对象? Ref Reactive Ref vs Reactive 适用场景: 访问方式: 引用传递: 性能开销: 响应式对象优点 响应式对象缺点 总结 Vue 3作为一种流行的JavaScript框架,提供了响应式编程的能力,使得前端开发更加便捷和高效。其中,ref和reactive是Vue 3中用于创建响应式数据的两个重要工具。 什么是响应式对象? 在介绍ref和reactive之前,我们先了解一下什么是响应式对象。简单来说,响应式对象是指当数据发生改变时,相关的视图会自动更新。这意味着我们只需要关注数据的变化,而无需手动去更新视图。Vue 3通过使用ref和reactive来实现响应式。 Ref ref是Vue 3中用于创建基本类型的响应式数据的函数。它接收一个初始值作为参数,并返回一个包装后的响应式对象。使用ref创建的响应式对象可以像普通变量一样进行读取和修改。 import { ref } from 'vue'; const count = ref(0); console.log(count.value); // 输出 0 count.value++; // 修改响应式数据 console.log(count.value); // 输出 1 在上面的例子中,我们使用ref创建了一个名为count的响应式对象,并初始化为0。我们可以通过访问.value属性来读取和修改该响应式对象的值。 Reactive reactive是Vue 3中用于创建复杂类型(如对象和数组)的响应式数据的函数。它接收一个普通对象或数组作为参数,并返回一个包装后的响应式对象。 import { reactive } from 'vue'; const state = reactive({ name: 'John', age: 25 }); console.log(state.name); // 输出 'John' state.age++; // 修改响应式数据 console.

微信扫码授权登录-王者荣耀

注:以下分析仅供学习交流,禁做其它用途 朋友的王者买了新皮肤想体验一把,但是怎么把他的账号登录到我的手机上呢? 点击微信登录会拉起微信,我需要登上别人的微信才行(别人的微信怎么可能随便让你登录)。 于是开始研究能不能扫码登录。果然,卸载了微信出现扫码登录,不能卸载能不能做到?于是研究这个二维码怎么生成的。 https://open.weixin.qq.com/connect/app/qrconnect?appid=wx95a3a4d7c627e07d&bundleid=com.tencent.tmgp.sgame&scope=snsapi_userinfo 这个接口一直轮询会返回授权code 有了这个code就可以登录了 wx95a3a4d7c627e07d://oauth?code=081TjQml2I4Uo94DIDol203wBM2TjQmE&state=weixin 那写个apk来组装Intent 拉起游戏把code传参进去就可以登录了

看完电视剧《问心》的一些思考

宝子们,最近好久没有写文章了,差不多有两个月左右都没有看视频学习了吧。我也不知道这两个月都在忙些啥,日常每天感觉都有干不完的需求,差不多天天点到九十点,估计还得再忙2个月左右吧,下完班实在是卷不动了,心里虽有想法千千万可以使目前的工作做的更好,奈何感觉一天的时间不够用,索性给自己放松了一段时间,晚上下班后没有卷了,下班后就在家看看视频,刷刷抖音,最近看朋友推荐了一个电视剧《问心》,挤了点时间把它给看完了,里面有些情节不错,虽是电视剧,确也跟我们的生活有那么一丝丝的联系吧。 一、工作中的态度、责任感 电视剧里面的男主角林逸是一名医生,在菜市场旁边遇到一个路人捂着胸口蹲在路上,上前把脉发现有可能是急性心梗,然后不顾路人自己的意见,硬是拉着他到医院去做检查,只可惜这个病人有点固执,最终为自己的固执买了单。但是,林逸表现出来的那种发现患者不顾一切的想要带到医院检查的这种心情以及做法,在我们的工作中其实也会有类似的一些经历,只是不知道各位都是如何去处理的:发现一个bug,开发说不是问题,这个时候你还会坚持吗?这个可以去看下前两集。 二、流程的重要性 有一次有一个病患情况比较紧急,从流程上来说应该要先做个CT检查确诊,但是时间上可能有点来不及,然后就直接给患者做了手术。当然,最后也受到了一定的惩罚。当然,这种情景一般只会出现在电视剧中,现实生活中谁会赌上自己的职业生涯去这么干。不出事情还好,一旦出了事情,那后果就很难说。你是不是觉得目前工作中的流程很繁琐,有些环节没什么意义?或者说,有些环节你很不喜欢。存在即合理,不按规矩办事,一旦出现问题,就会产生不良后果。 剩下的还有很多的剧情,有一些情感方面的,一个头顶悬着一把剑的人,最终还是遵从自己的内心。还有一些职场中勾心斗角小肚鸡肠的,感兴趣的可以自己去看看这部电视剧。 好了,接下来又准备开始卷了,敬请期待吧。

Linux网络编程入门小例子

如果你想进入Linux神奇的网络编程世界,请跟笔者来,在学习之前,笔者只需要你拥有一定的C语言编程知识,就足够了。笔者会讲述编写网络程序需要的基本知识。 所谓网络,在软件人员的观点来看,就是很多的用物理链路(比如,以太网,无线网络)连在一起的计算机,并且安装有网络程序。就像打电话,我们需要知道对方的号码一样,网络程序也需要知道要和那台计算机通讯,在这里,就是计算机的网络接口所拥有的IP地址。其实,一个完整的网络程序拥有两个独立的程序,他们分别运行在两个计算机上,一个是网络通讯的服务器端,一个是网络通讯的客户端,就像打电话,需要一个打电话的,还要一个接电话的是一样的,所以,我们需要编写两个程序,才是完整的网络通讯程序,我们熟悉的OutLook,FOXMAIL等都是网络程序中的客户端程序,而Apache,QMail等便是服务器端程序。只是往往,网络程序的客户端和服务器端之间有一定的通讯交互协议,比如SMTP,POP3,HTTP,FTP等,对于我们网络程序的编写者来说,他们就规定了通用的交互协议,这些协议规定了客户端,服务器端应该完成的工作,所以,编写好网络程序还需要理解好协议,不过,一般说来,我们用不着自己写协议,有很多的协议,我们可以使用的,都有RFC文档来说明了,你可以在网络上找到各种协议的RFC. 当然,我们现在将要开始编写的第一个网络程序,虽然非常简单,但是却可以很清楚的说明大部分编写网络程序需要的基本概念,好了先让我们看看网络程序的TCP服务器端的编写步骤: 1. 首先,你需要创建一个用于通讯的套接口,一般使用socket调用来实现。这等于你有了一个用于通讯的电话:) 2. 然后,你需要给你的套接口设定端口,相当于,你有了电话号码。这一步 一般通过设置网络套接口地址和调用bind函数来实现。 3. 调用listen函数使你的套接口成为一个监听套接字。 以上三个步骤是TCP服务器的常用步骤。 4. 调用accept函数来启动你的套接字,这时你的程序就可以等待客户端的连接了。 5. 处理客户端的连接请求。 6. 终止连接。 现在让我们来看看网络程序客户端的编程步骤: 1. 和服务器的步骤一样。 2. 通过设置套接口地址结构,我们说明,客户端要与之通讯的服务器的IP地址和端口。 3. 调用connect函数来连接服务器。 4. 发送或者接收数据,一般使用send和recv函数调用来实现。 5. 终止连接。 以上的步骤,是比较普遍的,我们可以从中看出,编写网络程序是很有意思的,同时,也不是非常复杂,当然,这不包括,高难度的东西:-),下次,我会给出一个简单的服务器和一个客户机程序。 今天,我给出的代码包括一个服务器,和一个客户机程序,但是省略了很多代码, 比如说错误处理代码,这样做主要是为了使网络编程的主线清楚,所以,这两个程序谈不上网络安全性,和稳定性,这些是以后的话题。但是对于基本理解 网络编程已经足够了。我会在下次给出一个完整可运行的程序。下面我会详细 解释程序的步骤: 先要包括一部分网络编程必须的头部文件,这是服务端程序: tcp_server.c: #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <errno.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #define MAXLINE 4096 #define PORT 5001 int main(int argc,char *argv[]) { //定义两个socket套接字,一个用于监听,一个用于通讯 int listensock, connsock, n; struct sockaddr_in serveraddr; //定义网络套接字地址结构 char buff[4096]; const char sendbuff[] = "

万字详解秒杀系统!!

大家好,我是捡田螺的小男孩~ 今天推荐冰河老哥一篇干货 很多小伙伴反馈说,高并发专题学了那么久,但是,在真正做项目时,仍然不知道如何下手处理高并发业务场景!甚至很多小伙伴仍然停留在只是简单的提供接口(CRUD)阶段,不知道学习的并发知识如何运用到实际项目中,就更别提如何构建高并发系统了! 究竟什么样的系统算是高并发系统?今天,我们就一起解密高并发业务场景下典型的秒杀系统的架构,结合高并发专题下的其他文章,学以致用。 电商系统架构 在电商领域,存在着典型的秒杀业务场景,那何谓秒杀场景呢。简单的来说就是一件商品的购买人数远远大于这件商品的库存,而且这件商品在很短的时间内就会被抢购一空。 比如每年的618、双11大促,小米新品促销等业务场景,就是典型的秒杀业务场景。 我们可以将电商系统的架构简化成下图所示。 由图所示,我们可以简单的将电商系统的核心层分为:负载均衡层、应用层和持久层。接下来,我们就预估下每一层的并发量。 假如负载均衡层使用的是高性能的Nginx,则我们可以预估Nginx最大的并发度为:10W+,这里是以万为单位。 假设应用层我们使用的是Tomcat,而Tomcat的最大并发度可以预估为800左右,这里是以百为单位。 假设持久层的缓存使用的是Redis,数据库使用的是MySQL,MySQL的最大并发度可以预估为1000左右,以千为单位。Redis的最大并发度可以预估为5W左右,以万为单位。 所以,负载均衡层、应用层和持久层各自的并发度是不同的,那么,为了提升系统的总体并发度和缓存,我们通常可以采取哪些方案呢? (1)系统扩容 系统扩容包括垂直扩容和水平扩容,增加设备和机器配置,绝大多数的场景有效。 (2)缓存 本地缓存或者集中式缓存,减少网络IO,基于内存读取数据。大部分场景有效。 (3)读写分离 采用读写分离,分而治之,增加机器的并行处理能力。 秒杀系统的特点 对于秒杀系统来说,我们可以从业务和技术两个角度来阐述其自身存在的一些特点。 秒杀系统的业务特点 这里,我们可以使用12306网站来举例,每年春运时,12306网站的访问量是非常大的,但是网站平时的访问量却是比较平缓的,也就是说,每年春运时节,12306网站的访问量会出现瞬时突增的现象。 再比如,小米秒杀系统,在上午10点开售商品,10点前的访问量比较平缓,10点时同样会出现并发量瞬时突增的现象。 所以,秒杀系统的流量和并发量我们可以使用下图来表示。 由图可以看出,秒杀系统的并发量存在瞬时凸峰的特点,也叫做流量突刺现象。 我们可以将秒杀系统的特点总结如下。 (1)限时、限量、限价 在规定的时间内进行;秒杀活动中商品的数量有限;商品的价格会远远低于原来的价格,也就是说,在秒杀活动中,商品会以远远低于原来的价格出售。 例如,秒杀活动的时间仅限于某天上午10点到10点半,商品数量只有10万件,售完为止,而且商品的价格非常低,例如:1元购等业务场景。 限时、限量和限价可以单独存在,也可以组合存在。 (2)活动预热 需要提前配置活动;活动还未开始时,用户可以查看活动的相关信息;秒杀活动开始前,对活动进行大力宣传。 (3)持续时间短 购买的人数数量庞大;商品会迅速售完。 在系统流量呈现上,就会出现一个突刺现象,此时的并发访问量是非常高的,大部分秒杀场景下,商品会在极短的时间内售完。 秒杀系统的技术特点 我们可以将秒杀系统的技术特点总结如下。 (1)瞬时并发量非常高 大量用户会在同一时间抢购商品;瞬间并发峰值非常高。 (2)读多写少 系统中商品页的访问量巨大;商品的可购买数量非常少;库存的查询访问数量远远大于商品的购买数量。 在商品页中往往会加入一些限流措施,例如早期的秒杀系统商品页会加入验证码来平滑前端对系统的访问流量,近期的秒杀系统商品详情页会在用户打开页面时,提示用户登录系统。这都是对系统的访问进行限流的一些措施。 (3)流程简单 秒杀系统的业务流程一般比较简单;总体上来说,秒杀系统的业务流程可以概括为:下单减库存。 秒杀三阶段 通常,从秒杀开始到结束,往往会经历三个阶段: 准备阶段:这个阶段也叫作系统预热阶段,此时会提前预热秒杀系统的业务数据,往往这个时候,用户会不断刷新秒杀页面,来查看秒杀活动是否已经开始。在一定程度上,通过用户不断刷新页面的操作,可以将一些数据存储到Redis中进行预热。 秒杀阶段:这个阶段主要是秒杀活动的过程,会产生瞬时的高并发流量,对系统资源会造成巨大的冲击,所以,在秒杀阶段一定要做好系统防护。 结算阶段: 完成秒杀后的数据处理工作,比如数据的一致性问题处理,异常情况处理,商品的回仓处理等。 针对这种短时间内大流量的系统来说,就不太适合使用系统扩容了,因为即使系统扩容了,也就是在很短的时间内会使用到扩容后的系统,大部分时间内,系统无需扩容即可正常访问。 那么,我们可以采取哪些方案来提升系统的秒杀性能呢? 秒杀系统方案 针对秒杀系统的特点,我们可以采取如下的措施来提升系统的性能。 (1)异步解耦 将整体流程进行拆解,核心流程通过队列方式进行控制。 (2)限流防刷 控制网站整体流量,提高请求的门槛,避免系统资源耗尽。 (3)资源控制 将整体流程中的资源调度进行控制,扬长避短。 由于应用层能够承载的并发量比缓存的并发量少很多。所以,在高并发系统中,我们可以直接使用OpenResty由负载均衡层访问缓存,避免了调用应用层的性能损耗。 大家可以到https://openresty.org/cn/来了解有关OpenResty更多的知识。同时,由于秒杀系统中,商品数量比较少,我们也可以使用动态渲染技术,CDN技术来加速网站的访问性能。 如果在秒杀活动开始时,并发量太高时,我们可以将用户的请求放入队列中进行处理,并为用户弹出排队页面。 注:图片来自魅族 秒杀系统时序图 网上很多的秒杀系统和对秒杀系统的解决方案,并不是真正的秒杀系统,他们采用的只是同步处理请求的方案,一旦并发量真的上来了,他们所谓的秒杀系统的性能会急剧下降。我们先来看一下秒杀系统在同步下单时的时序图。 同步下单流程 1.用户发起秒杀请求

Vue 单页、路由

目录 单页、路由的基本使用路由模式路由跳转路由传参路由传参 参数不刷新的问题嵌套路由路由守卫 单页应用:一个页面即一个简单应用,组件化开发 传统的页面调转是浏览器请求新页面,单页是把原本的多个页面以组件的形式集成在一个页面中,页面跳转时由vue路由到目标页面,因为目标页面是当前页面的一部分,切换到指定部分即可,浏览器不用发起新请求。 单页、路由的基本使用 #下载vue的路由插件 npm install vue-router <div id="app"></div> <!-- 引入vue.js --> <script src="js/vue.js"></script> <!-- 引入vue的路由插件。上线时均要换为min版 --> <script src="js/vue-router.js"></script> <script> // 首页 var Index={ template:` <div> <p>this is the index page</p> <p><a href="#/login">login</a></p> <!-- 注意url写法,#/开头 --> <p><a href="#/register">register</a></p> </div> `, } // 登录页面 var Login={ template:` <div> <p>this is the login page</p> <p><a href="#/index">index</a></p> <p><a href="#/register">register</a></p> </div> ` } // 注册页面 var Register={ template:` <div> <p>this is the register page</p> <p><a href="

Tensorflow2 中模型训练标签顺序和预测结果标签顺序不一致问题解决办法

本篇文章将详细介绍Tensorflow2.x中模型训练标签顺序和预测结果标签顺序不一致问题,这个问题如果考虑不周,或者标签顺序没有控制好的情况下会出现预测结果精度极其不准确的情况。 训练数据集的结构:数据集有超过10的类别数,这里包含16类数据,每个类别放置到一个文件夹中,文件夹名称按照其类别命名为1,2,3……16。文件夹结构如下图所示: 这组数据在系统中的排序是1,2,3,4,……顺序排序的。 一、Tensorflow2.数据读取的顺序 使用Tensorflow读取数据,代码如下: data_all = tf.keras.preprocessing.image_dataset_from_directory( data_dir, labels='inferred', batch_size=batch_size, image_size=(img_height, img_width), shuffle=False # 关闭洗牌以保持与文件夹中图像的顺序一致 ) 按照有的说明,tf.keras.preprocessing.image_dataset_from_directory()函数是按照文件夹中的排序读取的数据,但实际上并不是。我们来查看一下这个函数读取的数据是什么顺序,这里直接使用一下一行代码: class_names = data_all.class_names print("类别标签:", class_names) 看看输出结果是什么: 类别标签: ['1', '10', '11', '12', '13', '14', '15', '16', '2', '3', '4', '5', '6', '7', '8', '9'] 这里我们可以看到,以上函数读取的数据顺序和文件夹中的顺序并不一致,因此,我们在进行精度评的时候一定要保持这个标签的顺序一致。 二、Tensorflow2.数据预测结果的顺序 Tensorflow2.训练的模型预测出来的结果是按照0,1,2,……编码顺序编码的,也就是说,训练数据集中第1类预测出来的标签代码实0,第2类是1,第3类是2. 在这里我们进行评估时,如果是使用以下代码进行训练和评估时,训练集和测试集数据顺序一致,所以不会出现什么问题。 train_ds = tf.keras.preprocessing.image_dataset_from_directory( data_dir, validation_split=0.7, subset='training', seed=123, image_size=(img_height, img_width), batch_size=batch_size) test_ds = tf.keras.preprocessing.image_dataset_from_directory( data_dir, validation_split=0.7, subset='validation', seed=123, image_size=(img_height, img_width), batch_size=batch_size) 不过预测出来的标签和我们的类别不一致,这时候我们需要将两者变换为一致,我们可以通过建立一个类别对应关系的字典来进行变换,使预测的标签值变换为实际类别代码如下: label_dict={'0': 1, '1': 10, '2': 11, '3': 12, '4': 13, '5': 14, '6': 15, '7': 16, '8': 2, '9': 3, '10': 4, '11': 5, '12': 6,'13': 7, '14': 8,'15': 9} print(label_dict) # 将原始标签映射到调整后的标签 adjusted_labels = [label_dict[str(label)] for label in original_labels] df[adjusted_name] = adjusted_labels 通过以上代码,可以将预测的标签值变换为实际类别ID.

Hadoop 配置 Kerberos 认证

1、安装 Kerberos 服务器和客户端 1.1 规划 服务端: bigdata3 客户端(Hadoop集群): bigdata0 bigdata1 bigdata2 192.168.50.7 bigdata0.example.com bigdata0 192.168.50.8 bigdata1.example.com bigdata1 192.168.50.9 bigdata2.example.com bigdata2 192.168.50.10 bigdata3.example.com bigdata3 1.2 安装 Kerberos 服务器 yum install -y krb5-libs krb5-server krb5-workstation 配置: /etc/krb5.conf [logging] default = FILE:/var/log/krb5libs.log kdc = FILE:/var/log/krb5kdc.log admin_server = FILE:/var/log/kadmind.log [libdefaults] default_realm = EXAMPLE.COM dns_lookup_realm = false dns_lookup_kdc = false ticket_lifetime = 24h renew_lifetime = 7d forwardable = true [realms] EXAMPLE.COM = { kdc = bigdata3.