字符串与数组的异同

Java 中的字符串(String)和数组(Array)是两种不同类型的数据结构,它们有一些相似之处,同时也有一些显著的区别。 相同之处: 存储多个元素: 字符串和数组都用于存储多个元素。 使用索引: 在字符串和数组中,可以使用索引来访问和操作单个元素。在 Java 中,索引从 0 开始。 不同之处: 数据类型: 字符串(String): 是 Java 中的一种对象类型,属于 java.lang 包。字符串是不可变的,一旦创建就不能被修改。字符串的内容在创建后不可更改,任何对字符串的操作都会返回一个新的字符串。数组(Array): 是 Java 中的一种数据结构,可以容纳多个相同类型的元素。数组可以是基本数据类型的数组,也可以是对象类型的数组。数组的长度在创建后无法更改。 可变性: 字符串(String): 不可变。对字符串进行拼接、替换等操作会生成一个新的字符串,原字符串保持不变。数组(Array): 长度固定。一旦创建,数组的长度不能更改。 方法和属性: 字符串(String): 提供了多种方法来操作字符串,如 length()、charAt(index)、substring(beginIndex, endIndex) 等。字符串类还有一些实用的静态方法,如 valueOf()、format() 等。数组(Array): 数组有一些常见的属性,如 length 表示数组的长度。数组提供了基本的方法,如 clone()、equals(),以及一些静态方法,如 sort()、binarySearch()。 语法: 字符串(String): 字符串字面量可以用双引号括起来,如 "Hello, World!"。数组(Array): 数组的声明和初始化需要使用中括号 [],如 int[] numbers = {1, 2, 3, 4, 5};。 在使用时,选择字符串还是数组取决于具体的需求。如果需要处理文本、字符串拼接、字符串操作等,使用字符串更方便。如果需要存储一组相同类型的元素,并且可能需要修改它们的值,那么使用数组是更合适的选择。

数据结构和算法详解

一、线性结构详解 数据结构算法--线性结构详解-CSDN博客 二、查找详解 数据结构算法--查找详解-CSDN博客 三、排序详解 数据结构算法--排序详解-CSDN博客 四、动态规划详解 数据结构算法--动态规划详解-CSDN博客 五、递归、分治、贪心、回溯和枚举详解 数据结构算法--递归、分治、贪心、回溯和枚举详解-CSDN博客 六、图详解 数据结构算法--图详解-CSDN博客

数据结构算法--图详解

目录 1. 图定义 2. 图存储 3. 图遍历 深度优先遍历(DFS) 广度优先遍历(BFS) leecode举例 4. 常见图算法 最小生成树 最短路径 随机游走 社区发现 1. 图定义 图:图G由顶点集合V和边集合E组成,记为。 图分类:有向图和无向图。 子图:,如果,,则G’为G的子图。 有向完全图:n(n - 1)条边的有向图。 无向完全图:n(n - 1) / 2条边的无向图。 网:图的每条边带有权值。 邻接点:无向图,一条边的两点互为邻接点。 路径:顶点v到顶点v'的边的权值和为路径长度。 连通:无向图G,如果顶点v到顶点v'存在路径,则两顶点连通。 G是一个连通图, G中的极大连通子图为连通分量。 强连通图:有向图G,如果顶点v到顶点v'存在路径,则两顶点强连通。强连通图只有一个连通分量。 生成树:无向图 G,存在一个极小连通子图,如果其包含图的所有n个顶点,有且仅有n - 1条边,则称该连通子图为G的生成树。其中权值路径最小的为最小生成树。 有向树:对于有向图G,存在一个v的入度为0,其他v'的入度均为1的子图,则称该子图为G的有向树(树型图),即有向图的生成树。 2. 图存储 邻接矩阵 定义:n阶矩阵,矩阵值对应每条边权重。优点:便于计算顶点之间是否有边,便于计算顶点的度。缺点:不便于增删顶点;不便于统计所有边数目;空间复杂度高。 无向图举例: [[0, 6, 1, 5, 0, 0], [6, 0, 5, 0, 3, 0], [1, 5, 0, 5, 6, 4], [5, 0, 5, 0, 0, 2], [0, 3, 6, 0, 0, 6], [0, 0, 4, 2, 6, 0]] 邻接表 定义:链式存储。优缺点和上述邻接矩阵相反。

SQL性能分析

SQL性能分析 1、SQL执行频率 ​ MySQL 客户端连接成功后,通过 show [session|global] status 命令可以提供服务器状态信 息。通过如下指令,可以查看当前数据库的INSERT、UPDATE、DELETE、SELECT的访问频次: -- session 是查看当前会话 ; -- global 是查询全局数据 ; SHOW GLOBAL STATUS LIKE 'Com_______'; Com_delete: 删除次数 Com_insert: 插入次数 Com_select: 查询次数 Com_update: 更新次数 ​ 通过上述指令,我们可以查看到当前数据库到底是以查询为主,还是以增删改为主,从而为数据 库优化提供参考依据。 如果是以增删改为主,我们可以考虑不对其进行索引的优化。 如果是以 查询为主,那么就要考虑对数据库的索引进行优化了。 ​ 那么通过查询SQL的执行频次,我们就能够知道当前数据库到底是增删改为主,还是查询为主。 那假 如说是以查询为主,我们又该如何定位针对于那些查询语句进行优化呢? 次数我们可以借助于慢查询 日志。 2、MySQL中的慢查询日志 ​ 慢查询日志记录了所有执行时间超过指定参数(long_query_time,单位:秒,默认10秒)的所有SQL语句的日志。通过慢查询日志,就可以定位出执行效率比较低的SQL,从而有针对性的进行优化。 ​ MySQL的慢查询日志默认没有开启,我们可以查看一下系统变量 slow_query_log。 ​ 如果要开启慢查询日志,需要在MySQL的配置文件(/etc/my.cnf)中配置如下信息: # 开启MySQL慢日志查询开关 slow_query_log=1 # 设置慢日志的时间为2秒,SQL语句执行时间超过2秒,就会视为慢查询,记录慢查询日志 long_query_time=2 ​ 配置完毕之后,通过指令systemctl restart mysqld重新启动MySQL服务器进行测试,查看慢日志文件中记录的信息/var/lib/mysql/localhost-slow.log。 在慢查询日志中,只会记录执行时间超多我们预设时间(2s)的SQL,执行较快的SQL是不会记录的。 3、profile详情 ​ show profiles 能够在做SQL优化时帮助我们了解时间都耗费到哪里去了。通过have_profiling参数,能够看到当前MySQL是否支持profile操作: select @@have_profiling ; 可以通过set语句在session/global级别开启profiling:

探索sklearn中SVM模型的原理及使用案例

大家好,支持向量机(Support Vector Machines,SVM)是一种经典的机器学习算法,被广泛应用于分类和回归任务中。在sklearn库中,SVM模型提供了简单易用的API,使得开发者可以方便地应用SVM算法解决实际问题。本文将介绍SVM的原理和在sklearn中的使用案例,帮助大家更好地理解和应用该模型。 一、SVM的原理 SVM是一种监督学习算法,其核心思想是找到一个最优的超平面(或曲面),将不同类别的样本点尽可能地分开。这个超平面被称为分隔超平面,而离分隔超平面最近的一些样本点被称为支持向量。SVM的目标是最大化支持向量到分隔面的距离,使得分类边界具有最大的鲁棒性。 具体来说,假设训练样本集为: {(x1, y1),(x2, y2),...(xn, yn)} 其中xi表示特征向量,yi表示对应的目标值。 我们的目标是找到一个超平面,使得样本点到该超平面的距离最小。为了实现这一目标,SVM回归引入了一个松弛变量,用于允许一些样本点位于超平面的误差范围内。通过优化算法,求解超平面的参数和松弛变量的值,从而得到回归模型。对于线性可分的情况,可以通过以下步骤来构建SVM模型: 1.特征向量的标准化:由于SVM对特征的尺度敏感,需要对特征进行标准化,保证每个特征都在相似的尺度范围内。 2.确定分隔超平面:SVM为了找到一个最优的分隔超平面,需要选择一个适当的核函数,并通过优化算法来求解超平面的参数。常见的核函数有线性核、多项式核和高斯核等。 3.求解目标函数:SVM的优化目标函数是一个凸二次规划问题,可以通过凸优化算法(如序列最小优化算法和SMO算法)来求解。 4.预测新数据点的类别:利用求解得到的超平面参数和核函数,可以对新的数据点进行分类预测,根据其在分隔超平面的一侧来判断其类别。 二、SVM分类使用案例 本节将通过一个实际的使用案例来展示sklearn中SVM模型的使用方法,使用一个经典的鸢尾花数据集进行分类任务的演示。 # 1. 导入所需的库 from sklearn import datasets from sklearn.model_selection import train_test_split from sklearn.svm import SVC from sklearn.metrics import accuracy_score # 2. 加载鸢尾花数据集 iris = datasets.load_iris() X = iris.data y = iris.target # 3. 划分训练集和测试集 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) # 4. 构建SVM模型 svm = SVC(kernel='linear') # 5. 在训练集上拟合模型 svm.

支持华为GaussDB数据库的免费开源ERP:人力资源管理解决方案概述

开源智造所推出的Odoo SuperPeople数字化解决方案将HR和薪资数据与财务、项目规划、预算和采购流程连接起来,消除了多套系统给企业带来的信息孤岛问题。 ——复星集团 人力资源中心 高经理 一种更具吸引力、更有洞察力的人员管理方式 什么是开源智造·Odoo的人力资源管理解决方案? 开源智造·Odoo SuperPeople 人力资源管理解决方案提供了一套领先同行且功能应用完整的模组,使整个组织的每个人都能更轻松、更高效地交付 HR 服务。借助管理人力资源、薪资和财务的单一工具,组织可以消除第三方集成,提高数据准确性,创造更具吸引力的员工体验,并做出更明智的决策,使员工绩效与业务绩效紧密结合。 人力资源成本与财务的紧密整合 通过将人力资源、薪资和财务数据集中在一个地方,您的公司可以了解员工绩效如何影响财务绩效。 降低人力资源管理成本 使员工和经理能够随时安全地完成常见的 HR 任务,例如更改地址、考勤或查看休假余额。 推动与员工更深入的互动 通过积极的目标设定将员工与他们的工作联系起来。认可、审查和奖励成就,以提高参与度和生产力。 开源智造·Odoo人力资源管理的优势 提升薪酬核算与财务总账集成的效率。在几分钟内运行工资单,无需导入或操作第三方文档,并实时过账到您的总账。 改善 HR 服务交付。使经理和员工能够更新他们的个人资料,管理他们的团队,并安全地查看他们自己的人力资源信息。 提高员工绩效。员工绩效指标创建在 Odoo 数据的基础上,并由其更新,可实现更有效、更具吸引力的绩效评估。 开源智造·Odoo人力资源管理功能概述 人力资源管理 通过在整个套件中共享劳动力信息,人力资源主管可以自动执行 HR 流程,以减少在常见任务上花费的管理时间,并轻松传递信息以供审批。仪表板使 HR 能够监控关键 KPI,并成为高级领导者和招聘经理更具战略意义的业务合作伙伴。 员工名录 帮助员工在整个组织中创建联系和协作。 有效的数据采集 使用准确的数据和更改原因创建审计跟踪,以更快地解决 HR 数据收集问题。 访问控制 对于用户权限进行深入的定制,确保不会出现数据越界,有效保护员工隐私数据。 薪酬核算 开源智造·OdooSuperPeople Payroll 为公司提供高效的端到端工资单处理和管理,以支付美国工人的工资。全方位服务解决方案会随着工资计算的变化而保持最新状态,符合美国所有州和地方司法管辖区的要求,并自动提交工资税。实时过账到总账可保持账户平衡、财务报告准确,并使公司控制其工资支出。 绩效管理 开源智造·Odoo SuperPeople 绩效管理提供了一个轻松管理绩效评估流程的中心位置,不仅可以提高效率,还可以通过目标创建、进度监控和成就认可来保持员工的参与度。 考勤管理 排班、考勤、薪酬。 开源智造·Odoo SuperPeople 考勤管理提供单一解决方案,可简化排班,轻松捕获员工队伍的时间和出勤情况,并计算薪酬。 休假管理 自动执行员工请假和经理批准请求的流程。一旦请求获得批准,休假余额就会自动更新,公司可以设置控制措施来执行政策,这样员工就不会请太多假,或者公司不会在员工离职时造成不必要的损失。 薪酬和福利跟踪 跟踪员工薪酬和福利信息,以便进行报告和分析。HR 管理员和经理可以获得一个可视化的时间表,以查看在整个员工生命周期中薪酬何时发生变化。 人资规划 结合开源智造·Odoo SuperPeople Planning and Budgeting,公司可以使用实际的工资单、费用和员工人数信息自动对未来的劳动力需求进行建模,从而制定预算和招聘计划。 报告与分析 HR Analytics 为 HR 和其他授权用户提供基于角色的仪表板,以监控员工绩效。借助 15 个行业领先的 KPI,人力资源主管可以分析员工人数、离职趋势、人口统计数据、每位在职员工的收入、每位在职员工的费用和每位在职员工的利润。按部门、员工类别或组、位置或子公司向下钻取任何这些指标。这些强大的可视化分析有助于打破部门和数据障碍,以改善沟通,从而更快、更自信地做出员工决策和规划。

sizeof原理概要

经常搞混sizeof在计算指针和数组时,到底计算的是什么,故仔细研究了一下,并记录下来; sizeof概念简单介绍: `sizeof`: 是一个在编译时计算的运算符,它给出了其操作数的大小(以字节为单位)。 `sizeof`:用于数据类型(比如 `int`, `float`, `char` 等)或者具体的变量、数组、指针等。 sizeof计算指针和数组的区别 当 `sizeof` 用在指针上时,它给出的是指针本身的大小,而不是指针所指向的数据的大小。指针只是存储内存地址,所以 `sizeof` 对于所有类型的指针(不论它们指向的数据是什么类型的)都返回相同的大小,该大小取决于使用的机器(32位系统上通常是4字节,64位系统上通常是8字节)。 当 `sizeof` 用在数组上时,它给出的是整个数组占用的空间大小。对于字符串字面量(比如 `"abcd"`),`sizeof` 会返回整个数组的大小,包括结尾的空字符(null terminator)。 下面是几个例子来说明 `sizeof` 的用法和它的结果: ```c #include <stdio.h> int main() { char a[] = "abcdka"; // a是一个数组 char *p = "abcdka"; // p是一个指向字符串字面量的指针 // sizeof(a)将返回数组的大小,包括结尾的空字符 printf("Size of array: %zu bytes\n", sizeof(a)); // sizeof(p)将返回指针的大小,而不是它指向的字符串的大小 printf("Size of pointer: %zu bytes\n", sizeof(p)); // sizeof(*p)将返回p指向的类型的大小,即char的大小 printf("Size of char: %zu bytes\n", sizeof(*p)); return 0; } ``` 如果在64位系统上运行,输出可能是:

Angular - 笔记

文章目录 语法属性绑定引用模板变量组件绑定父组件传子组件 @input子组件传父组件 @outputEventEmitter @ViewChild@ViewChildren获取子组件对象列表 管道常用模块 函数localStorage实现数据持久化简介使用 参考文档 语法 属性绑定 Angular 的双向绑定语法是方括号和圆括号的组合 [()]。[] 进行属性绑定,() 进行事件绑定。 1. 语法 // 在属性上用{{}} <p title="{{title}}"> // 使用[]做属性绑定 <p [title]="title"> 举例: //html文件 <p>属性绑定</p> <div [id]="'apple'">Apple</div> <div [id]="lemon">{{lemon}}</div> <div id="{{lemon}}">{{lemon}}</div> <div [class]="'item'">绑定Class - 1</div> <div [class]="itemClass">绑定Class - 2</div> <h3 [class.h3-dom]="h3Dome">class.h3-dom根据true决定是否显示</h3> <h3 [class.h3-dom]="'true'">class.h3-dom根据true决定是否显示</h3> // 也可以渲染成功 <h3 [class]="'h3-dom font w string'">多类名绑定</h3> <a [title]="product.name + ' details'"> {{ product.name }} </a> // ts文件 lemon : string = 'lemon' itemClass : string ='item-Class'; h3Dome : boolean = true; product = {name: '张三'}; ngMoudle // home.

ubuntu打开epub格式的文件

Koodo Reader 是一个开源免费的电子书阅读器,支持多达15种主流电子书格式, 内置笔记、高亮、翻译功能,助力高效书籍阅读和学习。 官网地址 拖拽到此处即可添加图书 支持滚轮和点击翻页 菜单在这里 可以记笔记 查看笔记

ssh命令详解

名称 ssh — OpenSSH SSH客户端(远程登录程序) 概要 ssh [-1246AaCfGgKkMNnqsTtVvXxYy] [-b bind_address] [-c cipher_spec] [-D [bind_address:]port] [-E log_file] [-e escape_char] [-F configfile] [-I pkcs11] [-i identity_file] [-J [user@]host[:port]] [-L address] [-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port] [-Q query_option] [-R address] [-S ctl_path] [-W host:port] [-w local_tun[:remote_tun]] [user@]hostname [command] 描述 ssh(SSH客户端)是一个用于登录到远程计算机并在远程计算机上执行命令的程序。它旨在提供在不安全网络上的两个不受信任主机之间的安全加密通信。还可以通过安全通道转发X11连接、任意TCP端口和UNIX域套接字。 ssh连接并登录到指定的主机名(可选用户名称)。用户必须通过以下几种方法之一证明自己的身份(请参阅下文)。 如果指定了命令,则在远程主机上执行该命令,而不是登录shell。 以下是选项: -1 强制ssh尝试仅使用协议版本1。 -2 强制ssh尝试仅使用协议版本2。 -4 强制ssh仅使用IPv4地址。 -6 强制ssh仅使用IPv6地址。 -A 启用身份验证代理连接的转发。这也可以在配置文件中的每个主机上指定。 应谨慎启用代理转发。具有绕过远程主机上文件权限(用于代理的UNIX域套接字)的能力的用户可以通过转发的连接访问本地代理。攻击者无法从代理获取密钥材料,但他们可以执行使用加载到代理中的标识进行身份验证的操作。 -a 禁用身份验证代理连接的转发。 -b bind_address

六、基于深度学习关键点的指针式表计识别

基于深度学习关键点的指针式表计识别 提示:网上有太多的方案都是分割思路,思路很好,但是在制作数据的时候太费时间,据统计:分割数据标注一张需要180s-360s;而关键点标注控制在30s-90s。 温馨提示:更多技术交流请留言 文章目录 基于深度学习关键点的指针式表计识别具体实现流程一、 yolov8表计检测二、表盘关键点检测和指针检测三、表计矫正以及坐标的变换三、拟合出表盘的弧形结构,并计算比值三、根据比值、量程计算出读数总结 具体实现流程 提示:算法是基于unet语义分割模型和openpose姿态估计模型模改成多任务学习模型,包括关键点检测+指针分割两个并行任务,是整个算法的核心中的核心。 yolov8表计检测表盘关键点检测和指针检测表计矫正以及坐标的变换拟合出表盘弧形结构,并计算比值根据比值、量程计算出读数 提示:以下是本篇文章正文内容,下面案例可供参考 一、 yolov8表计检测 目标检测就不用多说。该步骤最主要有两个任务,第一,将图像中的表计检测出来;第二,并将每个表计进行分类,为了后面能根据类别配置表盘中的量程。 二、表盘关键点检测和指针检测 该部分是整个算法的核心,需要将关键点检测和分割整合为一个多任务学习模型。关键点检测参考openpose,分割网络参考unet等主流网络即可。这套算法相较百度的算法(分割刻度和指针)数据标注任务量减轻60%以上,更加的省事,便于优化。 下图是百度的方案: 想知道我的方案吗?那你想象成将刻度变为关键点即可,指针分割道理是一样的。 三、表计矫正以及坐标的变换 将倾斜的表计采用透视变换矫正,并对坐标进行变换。 三、拟合出表盘的弧形结构,并计算比值 根据矫正后的表计所得关键点,并拟合出表盘结构,并最终得到比值。 三、根据比值、量程计算出读数 最后根据比值、量程计算出具体读数,下图给出的是百分比,没时间转化了,将就用这个图了。 总结 本方案实现: 环境:pytorch、python=3.7、c++ 数据标注时间:本方案60s VS 百度方案360s 提示:所以你还愿意采用标注1张图片需要6分钟的方案吗? 一套可靠的方案,让开发、优化、部署、落地都省事。

毕业神刊之激光与光电子学进展

时间线 一个月就录用了,审稿速度也蛮快的 阶段名称处理人提交时间估计完成时间实际完成时间意见编辑部2023-12-112023-12-112023-12-11初审编辑部2023-12-132023-12-272023-12-13外审外审专家2023-12-132024-01-062023-12-30外审外审专家2023-12-132024-01-062023-12-15退修编辑部2024-01-022024-01-122024-01-09送终审编辑部2024-01-102024-01-172024-01-14已录用编辑部2024-01-152024-01-292024-01-15科云系统编校排版编辑部2024-01-152024-08-02 官网链接 https://www.opticsjournal.net/j/lop.html 常见QA Q:影响因子? A:《激光与光电子学进展》(以下简称《进展》)2021年 最新影响因子1.509; Q:收录情况? A:中文核心、中文科技核心、CSCD; Q:收稿方向? A:接收激光类和光电子类的文章,且重点接收综述类文章。 Q:“先进成像”专题半月? A:《进展》于2019年改版为半月刊,即一个月出版两期,每期35篇左右; 《进展》将于2020年开始,出版“先进成像”专题半月刊,即每月下半月全部出版“先进成像”方向的文章。“先进成像”半月刊以光学图像和辐射图像的获取、处理以及光电成像过程所涉及的相关理论和技术为主,重点关注光电成像器件的设计与集成、光电成像系统的设计与构建,光电成像器件与系统的测试评估等内容,并发表在光学信息处理、机器视觉、图像处理、生物医学、遥感成像、X射线光学等多个领域中与成像技术相关的研究成果,包括成像方法、成像器件、成像系统、成像算法、成像应用等方向。 其他方向文章在每月上半月的半月刊中出版。 Q:投稿方式: A:只接收网络投稿,不接收邮件投稿; Q:重复率: A:外审前会进行一次查重,研究论文要求在10%以下,综述要求在20%以下; 同时根据最新学术出版道德公约要求,本刊论文在正式出版前会再次进行学术不端检测查重,若发现问题将作撤稿处理; Q:审稿制度: A:单盲审制度,需要两个有效外审专家意见,通过主编终审后,稿件才算录用; Q : 送审给专家的时间: A:外审3周,复审2周,超时的文章编辑会主动进行催审,如专家因为忙或者其他原因不接受审稿,编辑会加送新的专家(因此有些时候您会看到外审人数超过2,如看到外审人数减少,即是有专家拒审,这种情况编辑会再加送新的专家); Q:平均审稿周期、平均发表周期等: A:平均外审周期为20天,录用周期为1个月,论文发表周期(从收稿到纸质出版)为6个月; Q:修改作者和单位: A:为避免学术不端问题,投稿前一定要确认好文章的署名和单位的排序,投稿以后原则上不接受修改作者和单位(官方单位名变更等特殊情况须在征得编辑部同意后,出具证明); Q:审稿费金额和支付方式: A:200元/篇,支付方式见收稿通知邮件; Q : 录用率和发表体量: A:录用率在50%左右,进展90篇/月; Q : 论文网络出版时间、正式出版时间及CNKI收录时间: A:网络优先出版:录用一周后可以在官网上看到您最后一次提交的稿件内容(多了doi号和页码等出版信息),是暂时版本,后续正式版本出来后会替换掉原来的暂时版本;正式版本出版时间为:从19年开始一年出版24期,一个月两期,您可自行计算,例如,第13期,就是7月份出版;正式出版后的终稿会替代之前的网络预出版版本,CNKI的收录会在正式出版后延后3个月左右; Q : 看清样时间: A:论文发表的前1~2个月为看清样时间,编辑会发邮件通知第一作者和通信联系人; Q:样刊寄送与稿费: A:自2021年开始,统一由科云系统收集样刊和稿费信息。请在文章出版月当月前提前填写样刊收件地址信息及稿费相关信息。 样刊寄送时间为出版当月下旬,由邮局挂号信寄出,请及时关注收发室或信箱。如有其他问题,请与发行人员:阮编辑021-69918416;clp_fx@siom.ac.cn联系。稿费是出版当月月底由财务统一安排,若有疑问,请联系财务老师:021-69918253 Q:发票什么时候寄? A:从2019年2月起,本刊改开电子发票。当系统内“支付情况”栏的状态转为“已开发票”且已显示开票日期后,发票会在显示开票日期的两天内以邮件方式发送到您填写的收件邮箱内。注:稿件处理费发票信息在玛格系统中填写,版面费发票信息在科云系统中填写,届时请注意查看邮件要求。此条看后还未解决请咨询财务02169918253。 如有特殊情况,急需发票,可与财务:021-69918253联系,沟通解决。 Q:版权协议和脱密证明问题? A:稿件投稿后立即需要办理版权协议和脱密证明,需要所有作者签字,第一单位盖章,需要原件; Q:稿件重投和申诉? A:稿件退稿修改后允许重投1次,重投需要对应相应外审意见的修改说明,稿件外审意见本人不接受,可以申诉一次,同样需要相应的解释说明。 Q:版面费金额和支付方式: A:排版以后论文500元/页,快报论文800元

axios发送post请求之后端怎么接收不到数据或者接收到的对象属性全是null

一:基本情况介绍: 前端:这是向后端提交数据的方法,使用addAddress方法,参数是this.addressAdd整个对象,代码中还将token添加到请求头中 submitAddressForm () { // 添加地址数据 this.$refs.form.validate(valid => { if (valid) { // 构造请求头对象 const headers = { token: `${this.token}` } console.log(this.addressAdd) addAddress(this.addressAdd, headers) .then((response) => { console.log(response.data) if (response.data.code === 1) { this.$message.success('地址添加成功!') } else { this.$message.error('添加失败') } this.dialogVisible = false selectAll(headers).then((response) => { this.addressBook = response.data.data console.log(this.addressBook) }) }) } else { console.log('请填写正确的表单信息') this.$message.error('请填写正确的表单信息') } }) }, 下面这是addressAdd对象 后端:下面这是后端接收数据的代码,实体类也在下面: /** * 添加收货地址 */ @PostMapping("/add") @ApiOperation("添加收货地址") public Result insert(@RequestBody AddressBookAddDTO addressBookAddDTO){ log.

手把手图解教你Java SPI源码分析

原创/朱季谦 我在《Java SPI机制总结系列之开发入门实例》一文当中,分享了Java SPI的玩法,但是这只是基于表面的应用。若要明白其中的原理实现,还需深入到底层源码,分析一番。 这里再重温一下SPI机制的概念:SPI,是Service Provider Interface的缩写,即服务提供者接口,单从字面上看,可以这样理解,该机制提供了一种可根据接口类型去动态加载出接口实现类对象的功能。打一个比喻,该机制就类似Spring容器,通过IOC将对象的创建交给Spring容器处理,若需要获取某个类的对象,就从Spring容器里取出使用即可。同理,在SPI机制当中,提供了一个类似Spring容器的角色,叫【服务提供者】,在代码运行过程中,若要使用到实现了某个接口的服务实现类对象,只需要将对应的接口类型交给服务提供者,服务提供者将会动态加载出所有实现了该接口的服务实现类对象,最后给到服务使用者使用。 接着前文的分享,可从以下三个步骤目录去深入分析Java SPI机制源码实现—— 创建服务提供者ServiceLoader对象,其内部生成一个可延迟加载接口对应实现类对象的迭代器LazyIterator,主要作用是读取并解析META-INF/services/目录下的配置文件中service类名字,进而通过反射加载生成service类对象。调用serviceLoader.iterator()返回一个内部实际是调用LazyIterator迭代器的匿名迭代器对象。遍历迭代器,逐行解析接口全类名所对应配置文件中的service实现类的名字,通过反射生成对象缓存到链表,最后返回。 //step 1 创建ServiceLoader对象,其内部生成一个可延迟加载接口对应实现类对象的迭代器LazyIterator,主要作用是读取并解析META-INF/services/目录下的配置文件中service类名字,进而通过反射加载生成service类对象。 ServiceLoader<UserService> serviceLoader = ServiceLoader.load(UserService.class); //step 2 调用serviceLoader.iterator()返回一个内部实际是调用LazyIterator迭代器的匿名迭代器对象。 Iterator<UserService> serviceIterator = serviceLoader.iterator(); //step 3 遍历迭代器,逐行解析接口全类名所对应配置文件中的service实现类的名字,通过反射生成对象缓存到链表,最后返回。 UserService service = serviceIterator.next(); service.getName(); } } 整个过程这里先做一个全面概括——ServiceLoader类会延迟加载UserService接口全名对应的META-INF/services/目录下的配置文件com.zhu.service.UserService。当找到对应接口全名文件后,会逐行读取文件里Class类名的字符串,假如存储的是“com.zhu.service.impl.AUserServiceImpl”和“com.zhu.service.impl.BUserServiceImpl”这两个类名,那么就会逐行取出,再通过反射【“Class类名”.newInstance()】,就可以创建出UserService接口对应的服务提供者对象。这些对象会以结构为<实现类名, 实现类对象>的Map形式,存储到LinkedHashMap链表里。该链表将由迭代器循环遍历,取出每一个实现类对象。 画一个流程图说明,大概如下—— 接下来,基于该全貌流程图,分别对源码作分析。 一、创建服务提供者ServiceLoader对象,其内部生成一个可延迟加载接口对应实现类对象的迭代器LazyIterator,主要作用是读取并解析META-INF/services/目录下的配置文件中service类名字,进而通过反射加载生成service类对象。 先看第一部分代码—— ServiceLoader<UserService> serviceLoader = ServiceLoader.load(UserService.class); 进入到ServiceLoader.load(UserService.class)方法里,里面基于当前线程通Thread.currentThread().getContextClassLoader()创建一个当前上下文的类加载器ClassLoader,该加载器在这里主要是用来加载META-INF.services目录下的文件。 在load方法里,将UserService.class和类加载器ClassLoader当作参数,交给ServiceLoader中的另一个重载方法ServiceLoader.load(service, cl)去做进一步具体实现。 public static <S> ServiceLoader<S> load(Class<S> service) { ClassLoader cl = Thread.currentThread().getContextClassLoader(); return ServiceLoader.load(service, cl); } 进入到ServiceLoader.load(service, cl),该方法里创建了一个ServiceLoader对象,该对象默认执行了参数值分别为UserService.class和ClassLoader的带参构造方法。 public static <S> ServiceLoader<S> load(Class<S> service, ClassLoader loader) { return new ServiceLoader<>(service, loader); } 根据字面意义,可以看出,ServiceLoader是一个专门负责加载服务的对象,在SPI机制里,它充当专门提供接口实现服务对象的角色。

通过本质看现象:关于Integer受内部初始化赋值范围限制而出现的有趣现象

文/朱季谦 这是我很多年前的第一篇技术博客,当时作为一名技术小菜鸟,总体而言显得很拙见,但也算是成长路上的一个小脚印,希望能在以后的日子里,可以对JAVA技术有一个更加深入的思考与认识。 前几天我在逛论坛的时候,偶然看到有人讨论这样一个现象,定义四个Integer类型的变量,分别初始化赋值为a=100,b=100,c=1000,d=1000,然后用println分别打印输出a==b和c==d的boolean值。这时就会出现一个很有趣的现象,a==b会被判断为ture,而c==d被判断为false。我觉得这个问题有点意思,就自己在eclipse上玩了一遍,运行截图如下: 问题便来了,同样类型的数值,为何a==b是正确的,而c==d则被判断为错误。在我们现实生活中,人们总说要透过现象去看本质,但若能反过来通过本质来分析现象,我想,同样可以深入理解很多东西。就像你能读懂一个人,就会很容易理解这个人的所作所为。打一个比方,你要弄懂一个人为何要犯罪,首先得了解他做这件事的心理,这就是通过本质回过头去看现象。 这道题,如果能通过本质来看现象,就会茅塞顿开。 Integer的本质是什么,当然是它的源码咯。 在我们定义Integer a=100时,编译器会转成Integer.valueOf(100),即内部实现是Integer a= Integer.valueOf(100),而在Integer的源码里valueOf方法如下: public static Integer valueOf(int i) { if (i >= IntegerCache.low && i <= IntegerCache.high) return IntegerCache.cache[i + (-IntegerCache.low)]; return new Integer(i); } 通过Integer的内部代码,可以看到有一个范围,即IntegerCache.low和IntegerCache.high。通常情况两者默认初始化为IntegerCache.high=127,IntegerCache.low=-128,同时,Integer内部还有一个静态static代码块,它会在类被加载时被执行,该代码块如下: static { int h = 127; String integerCacheHighPropValue = sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high"); if (integerCacheHighPropValue != null) { try { int i = parseInt(integerCacheHighPropValue); i = Math.max(i, 127); h = Math.min(i, Integer.MAX_VALUE - (-low) -1); } catch( NumberFormatException nfe) { } } high = h; cache = new Integer[(high - low) + 1]; int j = low; for(int k = 0; k < cache.

Java SPI机制总结系列之开发入门实例

原创/朱季谦 在该文章正式开始前,先对 Java SPI是什么做一个简单的介绍。 SPI,是Service Provider Interface的缩写,即服务提供者接口,单从字面上看比较抽象,你可以理解成,该机制就像Spring容器一样,通过IOC将对象的创建交给了Spring容器处理,若需要获取某个类的对象,就从Spring容器里取出使用即可。同理,在SPI机制当中,提供了一个类似Spring容器的角色,叫【服务提供者】,在代码运行过程中,若要使用到实现了某个接口的服务实现类对象,只需要将对应的接口类型交给服务提供者。服务提供者将会动态加载实现了该接口的所有服务实现类对象。 服务提供者的角色用下图来表示。 举一个例子来说明。 假如,假如Maven项目里有这样一个interface接口,接口全名“com.zhu.service.UserService”—— package com.zhu.service; public interface UserService { void getName(); } 创建一个“com.zhu.service.impl.AUserServiceImpl”实现类—— public class AUserServiceImpl implements UserService { @Override public void getName() { System.out.println("这是A用户姓名"); } } 接着在resource资源里,创建一个META-INF.services目录,在该目录里,创建一个文件名与接口com.zhu.service.UserService一致的文件—— 该com.zhu.service.UserService文件里写下com.zhu.service.impl.UserServiceImpl类名字—— 这时候,就可以基于Java SPI动态加载到接口的实现类并执行了,我们写一个简单的测试类做验证—— public class Test { public static void main(String[] args) { ServiceLoader<UserService> serviceLoader = ServiceLoader.load(UserService.class); Iterator<UserService> serviceIterator = serviceLoader.iterator(); while (serviceIterator.hasNext()) { UserService service = serviceIterator.next(); service.getName(); } } } } 执行该代码,ServiceLoader会加载到META-INF.services目录下的配置文件,找到对应接口全名文件,读取文件里的类名,再通过反射就可以进行实现类的实例化。既然能找到实现类的对象,那么不就可以基于父类引用指向子类对象,进而调用到实现类的getName()方法。该方法里执行打印语句 System.

Linux:/proc/kmsg 与 /proc/sys/kernel/printk_xxx

目录 前言一、/proc/kmsg1、简介2、如何修改内核日志缓冲区3、dmesgklogctl 函数(来源于 man 手册) 4、扩展阅读 二、 /proc/sys/kernel/printk_xxx三、/dev/kmsg 前言 本篇文章将为大家介绍与 Linux 内核日志相关的一些控制文件,共同学习! 一、/proc/kmsg 1、简介 /proc/kmsg 是一个特殊的文件,它提供了内核消息缓冲区的访问,这个缓冲区包含了内核产生的所有消息,包括各种调试和错误信息,如内核的启动打印。/proc/kmsg 文件通常只能被 root 用户或具有相应权限的用户读取。这个文件通常被用于调试和故障排除,因为它可以提供关于内核发生事件的详细信息。 注意:这是一个缓冲区,所以其内的数据是会被刷新覆盖的!!! 一般情况下,你可以使用以下方式来使用 /proc/kmsg 文件: 1、读取内核消息:你可以使用命令行工具如 `cat` 或 `dmesg` 来查看和读取`/proc/kmsg`文件 中的内核消息。例如,使用以下命令可以显示最近的内核消息: cat /proc/kmsg 这样做可以帮助你查看内核启动时的各种信息、硬件错误、系统调试等。 需要注意的是,`/proc/kmsg` 文件一般只能被 root 用户或具有相应权限的用户访问,因此在使用 时请确保你有足够的权限。此外,了解内核消息的解释和上下文对正确理解和利用 `/proc/kmsg` 中 的信息非常重要。 2、如何修改内核日志缓冲区 有时候我们发现,dmesg看到的日志信息缺少了很多,或者存储的很少,这个是因为内核日志缓冲区设置的较小,无法存储更多的内容,可以适当调整该缓冲区的大小。 建议不要调整的过大,正常的产品使用128KB即可,若是自己调试排查问题可以设置的大一点,比如2MB,根据自己的物理内存资源合理设置。 3、dmesg /proc/kmsg 文件和 dmesg 命令之间有着紧密的关系。 /proc/kmsg 文件提供了对内核消息缓冲区的直接访问,通过读取该文件可以查看最近的内核消息。dmesg 命令是一个通用命令行工具,主要用于显示和控制内核环缓冲区。使用 dmesg 命令可以更方便地查看内核日志消息,包括从开机到当前时间内的所有内核日志消息。 实际上,dmesg 命令背后的实现原理也是通过读取 /proc/kmsg 文件来获取内核消息的。当我们在终端中执行 dmesg 命令时,它会读取 /proc/kmsg 文件的内容并将其显示在终端上。 因此,可以说 /proc/kmsg 文件是 dmesg 命令的底层实现之一。在使用 dmesg 命令的时候,实际上是在调用 /proc/kmsg 文件提供的接口来获取内核日志。

【AI的未来 - AI Agent系列】【MetaGPT】2. 实现自己的第一个Agent

在MetaGPT中定义的一个agent运行示例如下: 一个agent在启动后他会观察自己能获取到的信息,加入自己的记忆中下一步进行思考,决定下一步的行动,也就是从Action1,Action2,Action3中选择执行的Action决定行动后,紧接着就执行对应行动,得到这个环节的结果 以Task3 作业为例,来看下使用MetaGPT 实现Agent的思路。Task3任务如下: 经过上面的学习,我想你已经对 MetaGPT 的框架有了基本了解,现在我希望你能够自己编写这样一个 agent 这个 Agent 拥有三个动作 打印1 打印2 打印3(初始化时 init_action([print,print,print]))重写有关方法(请不要使用act_by_order,我希望你能独立实现)使得 Agent 顺序执行上面三个动作当上述三个动作执行完毕后,为 Agent 生成新的动作 打印4 打印5 打印6 并顺序执行,(之前我们初始化了三个 print 动作,执行完毕后,重新 init_action([…,…,…]),然后顺序执行这个新生成的动作列表) 实现思路 用最通俗的话来总结: 要实现一个Agent,其实就是定义一个Role。该Role应该包含自己的Action。在Role的初始化中初始化ActionsRole重写_act函数或_react函数,Role run的时候会调用该函数 _react函数重写,一般是先思考_think下一步用哪个action,然后再_act Action重写run函数,这里面决定了我们对传入的内容到底要做什么样的处理,例如调用大模型得到结果 Task3 - 完整代码及注释 先看执行结果:顺序打印1-6,然后结束 完整代码及细节注释 # 加载 .env 到环境变量 from dotenv import load_dotenv, find_dotenv _ = load_dotenv(find_dotenv()) from metagpt.actions import Action from metagpt.logs import logger import asyncio from metagpt.roles import Role from metagpt.schema import Message ## 1.