一、题目 1、题目描述 电子游戏“辐射4”中,任务 “通向自由” 要求玩家到达名为 “Freedom Trail Ring” 的金属表盘,并使用表盘拼写特定关键词才能开门。
给定一个字符串 ring ,表示刻在外环上的编码;给定另一个字符串 key ,表示需要拼写的关键词。您需要算出能够拼写关键词中所有字符的最少步数。
最初,ring 的第一个字符与 12:00 方向对齐。您需要顺时针或逆时针旋转 ring 以使 key 的一个字符在 12:00 方向对齐,然后按下中心按钮,以此逐个拼写完 key 中的所有字符。
旋转 ring 拼出 key 字符 key[i] 的阶段中:
您可以将 ring 顺时针或逆时针旋转 一个位置 ,计为1步。旋转的最终目的是将字符串 ring 的一个字符与 12:00 方向对齐,并且这个字符必须等于字符 key[i] 。如果字符 key[i] 已经对齐到12:00方向,您需要按下中心按钮进行拼写,这也将算作 1 步。按完之后,您可以开始拼写 key 的下一个字符(下一阶段), 直至完成所有拼写。 2、接口描述 class Solution { public: int findRotateSteps(string ring, string key) { } }; 3、原题链接 514. 自由之路
二、解题报告 1、思路分析 今天看到题就觉得是一个最短路问题,为什么这样想呢?
文章目录 0 前言1 课题背景2 Dlib人脸识别2.1 简介2.2 Dlib优点2.3 相关代码2.4 人脸数据库2.5 人脸录入加识别效果 3 疲劳检测算法3.1 眼睛检测算法3.2 打哈欠检测算法3.3 点头检测算法 4 PyQt54.1 简介4.2相关界面代码 5 最后 0 前言 🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。
为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天要分享的是
🚩 机器视觉 opencv 深度学习 驾驶人脸疲劳检测系统
🥇学长这里给一个题目综合评分(每项满分5分)
难度系数:3分工作量:3分创新点:4分 1 课题背景 为了有效监测驾驶员是否疲劳驾驶、避免交通事故的发⽣,本项目利⽤⼈脸特征点进⾏实时疲劳驾驶检测的新⽅法。对驾驶员驾驶时的⾯部图像进⾏实时监控,⾸先检测⼈脸,并利⽤ERT算法定位⼈脸特征点;然后根据⼈脸眼睛区域的特征点坐标信息计算眼睛纵横⽐EAR来描述眼睛张开程度,根据合适的EAR阈值可判断睁眼或闭眼状态;最后基于EAR实测值和EAR阈值对监控视频计算闭眼时间⽐例(PERCLOS)值度量驾驶员主观疲劳程度,将其与设定的疲劳度阈值进⾏⽐较即可判定是否疲劳驾驶。
2 Dlib人脸识别 2.1 简介 Dlib是一个基于c++开发的开源数据工具库,其中包含了不少的机器学习的成熟算法与模型,相对于tensorflow和PyTorch,它用于图像处理以及人脸面部特征提取、分类及对比这几个方面比较具有通用性和优越性,因此,Dlib正在越来越广泛地应用在人脸识别技术领域。
Dlib具有独立使用的可移植代码。Dlib中的代码使用c++语言进行开发而成,使用独立封装,在不借助第三方数据库的情况下,可以直接移植到自己所需要设计的项目中进行使用。
2.2 Dlib优点 Dlib拥有全面的文档说明。作为一个开源的人脸数据库训练集,Dlib中有很多功能齐全的程序和文件,从人性化的角度而言的,Dlib在这一点上做的是非常不错的,因为它为每一个程序文档和文件都做了相对应的注释,这样开发者就可以迅速准确的调集程序文档来完成自己所需要的项目功能。
Dlib涵盖了支持功能完备的深度学习以及图像处理的各类算法。Dlib为开发者提供了机器深度学习的各类成熟的完备算法,并且在图像处理方面也为开发者带来了能够解决大多数实质问题的优良算法。例如基于SVM的递归和分类算法,以及专门用于面对大规模分类和递归的降维算法。当然还有能够对未知函数进行预分类和预测的相关向量机,其分类和预测训练是基于贝叶斯框架。
2.3 相关代码 import` `matplotlib.pyplot as plt import` `dlib import` `numpy as np import` `glob import` `re #正脸检测器 detector``=``dlib.get_frontal_face_detector() #脸部关键形态检测器 sp``=``dlib.shape_predictor(r``"D:LBJAVAscriptshape_predictor_68_face_landmarks.dat"``) #人脸识别模型 facerec ``=` `dlib.face_recognition_model_v1(r``"D:LBJAVAscriptdlib_face_recognition_resnet_model_v1.dat"``) #候选人脸部描述向量集 descriptors``=``[] photo_locations``=``[] for` `photo ``in` `glob.
通讯原理 简介UART (Universal Asynchronous Receiver/Transmitter)设置中断发送/接收 RS485RS232I2CI2STCP/IPCANSPI 简介 UART (Universal Asynchronous Receiver/Transmitter) 通用异步收发传输器(Universal Asynchronous Receiver/Transmitter,通常称为UART)
在异步通信中,发送端和接收端不需要同时处于激活状态,而是通过起始位和停止位来标识数据帧的开始和结束。
设置 属性描述波特率:通常用bps(bits per second) 例如,如果波特率为9600bps,则每秒钟可以传输9600个比特位的数据。
常见的波特率有2400、4800、9600、19200、38400、57600、115200……它们都可是2400的整数倍 校验位:奇偶校验位只能检测数据传输过程中的错误和丢失,而不能保证数据的完整性和正确性。
因此,在使用UART通信时,还需要采取其他措施来确保数据传输的正确性和可靠性。数据位:5、6、7、8 可以是5~8位逻辑”0”或”1”。如ASCII码(7位),扩展BCD码(8位)
停止位:1、 1.5、 2 停止位用于表示数据帧的结束。停止位可以是1个或2个比特位 奇偶校验位:只能检测数据传输过程中的错误和丢失,而不能保证数据的完整性和正确性。 中断发送/接收 属性描述中断发送:UART发送器是空闲状态,此时往发送器里面写入第一个字节,该字节传输完毕后产生TX完毕中断,在TX完毕中断的服务函数中再填入后续字节并产生下一个中断,最后直到把需要传输的字节都传完为止。中断接收:UART接收器收到字节后会产生RX收到中断,在RX收到中断服务函数中读取收到的字节,每次中断时都读取收到的字节。 RS485 RS232 I2C I2S TCP/IP CAN SPI
文章目录 Web Apis1.Web Apis和Js基础关联性1.1 JS的组成1.2 JS基础阶段以及WebAPls阶段 2.Api和Web Api2.1 Api2.2Web Api2.3Api和Web Api小结 DOM1.DOM简介1.1什么是DOM1.2 DOM树 2.获取元素2.1如何获取页面元素2.2根据ID获取2.3根据标签名获取2.4通过HTML5新增的方法获取2.5获取特殊元素(body,html) 3.事件基础3.1 事件概述3.3执行事件的步骤 4.操作元素4.1改变元素内容4.2常用元素的属性操作4.3表单属性操作4.4样式属性操作4.5操作元素小结4.6排他思想4.7自定义属性元素4.8 H5自定义属性 5.节点操作5.1为什么学节点操作5.2节点概述5.3节点层级5.4创建节点5.4添加节点5.5删除节点5.6复制节点(克隆节点)5.7三种动态创建元素区别 6.DOM重点核心 事件高级1.注册事件(绑定事件)1.1注册事件概述1.2 addEventListener 事件监听方式1.3 attachEvent 事件监听方式 (了解)1.4注册事件兼容性解决方案 (了解) 2.删除事件(解绑事件)2.1删除事件的方式2.2删除事件兼容性解决方案 3.DOM事件流4.事件对象4.1什么是事件对象4.2事件对象的使用语法4.3事件对象的兼容性方案4.4事件对象的常见属性和方法 5.阻止事件冒泡5.1阻止事件冒泡的两种方式5.2阻止事件冒泡的兼容性解决方案 6.事件委托(代理、委派)7.常用的鼠标事件7.1常用的鼠标事件7.2鼠标事件对象 8.常用的键盘事件8.1常用键盘事件8.2键盘事件对象 Web Apis 1.Web Apis和Js基础关联性 1.1 JS的组成 1.2 JS基础阶段以及WebAPls阶段 JS基础阶段
我们学习的是ECMAScript标准规定的基本语法
要求同学们掌握JS基础语法
只学习基本语法,做不了常用的网页交互效果
目的是为了 JS 后面的课程打基础、做铺垫
Web APls阶段
Web APIs是W3C组织的标准
Web APIs 我们主要学习 DOM 和 BOM
Web APIs 是我们 JS 所独有的部分
我们主要学习页面交互功能
需要使用Js基础的课程内容做基础
JS基础学习ECMAScript基础语法为后面作铺垫,webAPIs是Js的应用,大量使用Js基础语法做交互效果
2.Api和Web Api 2.1 Api API(Application Programming Interface,应用程序编程接口是一些预先定义的函数,目的是提供应用程序
文章目录 ES61.let和const1.1let声明的变量只在他所在的代码块有效1.2变量不能重复声明1.3不存在变量提升1.4const声明变量1.5作用: 2.模板字符串3.函数之默认值、剩余参数3.1带参数默认值的函数3.2默认的表达式也可以是一个函数3.3剩余参数 4.扩展运算符,箭头函数4.1扩展运算符4.2箭头函数 5.解构赋值5.1完全解构5.2不完全解构5.3重命名5.4数组解构 6.扩展的对象的功能7.Symbol数据类型8.Set和Map数据解构8.1.Set 8.2Map9.数组的扩展方法10.迭代器 Iterator11.生成器 Generator(不太理解)12.async(不太理解)13.类的用法14.类的继承 ES6 阮一峰ES6文档:https://es6.ruanyifeng.com/#README
文档写的很好,看视频反而有的看不懂
1.let和const 总结:默认情况下用const,如果变量后面需要被修改再用let
1.1let声明的变量只在他所在的代码块有效 { let a = 10; var b = 1; } a // ReferenceError: a is not defined. let声明 b // 1 1.2变量不能重复声明 下面这样会报错,而var就不会
let a = 1; let a = 2; 1.3不存在变量提升 这样写会报错
console.log(c); let c = 3; 但是如果用var 的话,就相当于是
var c; console.log(c); c = 3; 1.4const声明变量 const也不能重复声明,也是块级作用域,也不存在变量提升,但是和let不同的是,const赋值之后,不能再修改,还有就是for循环不能用const
比如我这么写,var和let都不会报错,但是const会报错
const d = 1; d = 2; console.
网络搭建与应用赛项公开赛卷——网络环境要求 1
图 1 网络拓扑图
1 / 8
表 1.网络设备连接表
A 设备连接至 B 设备 设备名称 接口 设备名称 接口 SW-1
E1/0/23
SW-2
E1/0/23
SW-1
E1/0/24
SW-3
E1/0/27
SW-2
E1/0/24
SW-3
E1/0/28
SW-1
E1/0/22
DCWS
E1/0/23
SW-2
E1/0/22
DCWS
E1/0/24
SW-1
E1/0/21
FW-1
G0/3
SW-2
E1/0/21
FW-1 G0/4
FW-1
E0/1
SW-2 模拟 Internet 交换机 E1/0/17
FW-2
E0/1
SW-2 模拟 Internet 交换机 E1/0/18
SW-1
E1/0/1
PC1
NIC
SW-2
E1/0/1
云平台 管理口 SW-2
Golang以其并发性Goroutines而闻名。不仅是并发,还有更多。
因此,在这种情况下,我们必须确保多个goroutines不应该同时试图修改资源,从而导致冲突。
为了确保资源一次只能被一个goroutine访问,我们可以使用一个叫做sync.Mutex的东西。
This concept is called mutual exclusion, and the conventional name for the data structure that provides it is mutex. — Go dev
无Mutex的用例 让我们有一个简单的用例来理解Mutex在goroutines中的使用。
例如,如果我们需要通过一个goroutine增加一个变量的值,并通过另一个goroutine减少同一个变量的值。
package main import ( "fmt" "sync" "time" ) func main() { const loop = 100 var wg sync.WaitGroup wg.Add(loop * 2) // declaring a shared value var n int = 0 for i := 0; i < loop; i++ { go func() { time.
日志级别及优先级排序 :
OFF(关闭) > fatal(致命错误) > error (错误) > warn (警告) > info(普通信息) > debug(调试信息) > TRACE > ALL(所有日志) 程序会打印 >= 所设置级别的日志,故设置的日志等级越高,打印出来的日志就越少。
一般官网建议就使用DEBUG、INFO、WARN、ERROR这四个,日志的等级越高,打出的日志越少。
[Ref] SpringBoot—整合log4j2入门和log4j2.xml配置详解
1.创建步骤
2. 编码添加
2.1 这是自动生成的启动函数
package com.example.comxjctest4; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } 2.2 添加一个controler
package com.example.comxjctest4; import org.springframework.web.bind.annotation.Mapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class CTest { @RequestMapping("/h") public String h(){ return "h"; } } 3 要点记录
@SpringBootApplication 这个注解保证了会对你创建再工程下的类进行扫描。扫描后的类有回用户被框架管理的功能。 @RestController 这个注解表示是该类会被当做controller处理 @RequestMapping("/h") 这个注解表示映射的http地址栏中的地址
文章目录 Git概述什么是GitGit历史Git是什么 为什么要使用Git什么是版本控制系统 Git和SVN对比SVN集中式SVN优缺点 Git分布式Git优缺点 Git工作流程四个工作区域工作流程 Git下载与安装下载window版下载64位软件包安装Git Git基础环境配置设置用户信息查看配置信息 文件的两种状态untracked未跟踪tracked已跟踪 文件加入暂存区文件加入暂存区命令文件取消暂存区命令 文件提交与删除文件提交命令修改commit记录使用--amend参数进行Commit Git基础_删除文件挽救已被删除的文件或目录 将文件添加至忽略列忽略规则 日志记录操作查看日志获取执行过的命令 比较文件差异git diff命令格式实战演习 还原文件情况I情况II情况III Git概述 什么是Git Git历史 很多人都知道,林纳斯·托瓦兹在1991年创建了开源的Linux,从此,Linux系统不断发展,已经成为最大的服务器系统软件了。
Git是什么 Git是一种代码托管技术。在开发中,Git是一种代码托管技术,很多代码托管平台也是基于Git来实现的。Git可以帮我们做到很多的事情,比如代码的版本控制,分支管理等。
注意:
我们可以把Git理解成是一个开源的分布式版本控制系统,用于敏捷高效地处理任何或小或大的项目。正是因为有了Git的存在,现在很多工作才可以变得相对轻松。
为什么要使用Git 什么是版本控制系统 你可以把一个版本控制系统(缩写VCS)理解为一个“数据库”,在需要的时候,它可以帮你完整地保存一个项目的快照。当你需要查看一个之前的快照(称之为“版本” )时,版本控制系统可以显示出当前版本与上一个版本之间的所有改动的细节。
想法:
因为我们怕在原来的基础改错了东西,没法恢复,所以,我们可能会有多个毕业论文的文件。而我们写代码的时候本身就是「多人协作」的,修改是无法避免的,我们不希望有多个文件的产生,又希望能够记录每次更改的内容。“
这个软件用起来就应该像这个样子,能记录每次文件的改动:
版本文件名用户说明日期1service.doc张三删除了软件服务条款57/12 10:382service.doc张三增加了License人数限制7/12 18:093service.doc李四财务部门调整了合同金额7/13 9:514service.doc张三延长了免费升级周期7/14 15:17 注意:
结束了手动管理多个“版本”的史前时代,进入到版本控制的20世纪。
Git和SVN对比 SVN集中式 集中式版本控制系统需要找一个服务器作为大本营,所有的代码都需要提交到服务器上进行统一的管理。当你需要对代码进行改动时,需要先从服务器上下载一份拷贝,修改完成之后,还需要上传回服务器。
SVN优缺点 优点:
管理员也可以轻松掌控每个开发者的权限。代码一致性非常高。适合开发人数不多的项目开发。 缺点:
服务器压力太大,数据库容量暴增。如果不能连接到服务器上,基本上不可以工作,看上面第二步,如果服务器不能连接上,就不能提交,还原,对比等等。 Git分布式 在分布式版本控制系统中,大家都拥有一个完整的版本库,不需要联网也可以提交修改,所以中心服务器就显得不那么重要了。
注意:
Git记录版本历史==只关心文件数据的整体是否发生变化。==Git 不保存文件内容前后变化的差异数据。
Git优缺点 优点:
适合分布式开发,强调个体。公共服务器压力和数据量都不会太大。速度快、灵活。任意两个开发者之间可以很容易的解决冲突。离线工作。 缺点:
学习周期相对而言比较长。不符合常规思维。易学难精,80/20 Git工作流程 四个工作区域 Workspace: 工作区,就是你平时存放项目代码的地方
Index / Stage: 暂存区,用于临时存放你的改动,事实上它只是一个文件,保存即将提交到文件列表信息
Repository: 仓库区(或版本库),就是安全存放数据的位置,这里面有你提交到所有版本的数据。其中HEAD指向最新放入仓库的版本
Remote: 远程仓库,托管代码的服务器,可以简单的认为是你项目组中的一台电脑用于远程数据交换
Dockerfile完全指南 什么是Dockerfile 概述 Dockerfile是一个文本格式的配置文件,用户可以使用Dockerfile快速创建自定义的镜像。
基本结构 Dockerfile由一行行命令语句组成,并且支持以 # 开头的注释行。一般而言,Dockerfile分为四部分:基础镜像信息、维护者信息、镜像操作指令和容器启动时执行指令。
例如:
## Dockerfile文件格式 # 1、第一行必须指定 基础镜像信息 FROM java:8 # 2、维护者信息 MAINTAINER oldGj_ oldGj_@163.com # 3、镜像操作指令 RUN echo "wget https://dlcdn.apache.org/tomcat/tomcat-9/v9.0.55/bin/apache-tomcat-9.0.55.tar.gz" run tar -zxvf apache-tomcat-9.0.55.tar.gz -C /usr/local # 4、容器启动执行指令 CMD /usr/local/tomcat/bin/catalina.sh Dockerfile 四部分说明:
一开始必须要指明所基于的镜像名称, 关键字是FROM, 这是必须的.接下来是维护者信息关键字是MAINTAINER, 非必须, 但良好的习惯有利于后期的职责明确.后面是镜像操作指令, 如RUN等, 每执行一条RUN命令,镜像添加新的一层.最后是CMD指令,来指明运行容器时的操作命令. 构建镜像 简单示例
在一个空白的文本文件, 命名为Dockerfile
vim Dockerfile 示例1
Dockerfile文件内容:
#基础镜像 FROM centos #维护者 MAINTAINER oldGj_<oldGj_@163.com> #运行命令 RUN "yum install wget" #启动容器运行命令 CMD echo "hello Dockerfile"
在2024年,许多技术话题都备受关注,其中一些最火的话题包括:
1.生成式人工智能:生成式人工智能是当前最热门的技术话题之一。它使机器能够创造类似于人类创作的内容,从而给各个行业带来了革命性的变化。生成式人工智能的应用广泛,包括文本生成、图像合成、音乐作曲等。掌握生成式人工智能技术的人可以在人工智能研究、数据科学和创意产业等领域从事令人兴奋的工作。
2.网络安全技术:随着网络安全威胁的不断演变,网络安全技术也在不断发展。在2024年,新型内生安全技术将逐步迈入成熟落地阶段,例如拟态防御、可信计算等。此外,随着5G、物联网、云等新兴技术的普及,网络安全挑战也不断增加,需要不断加强安全防御措施。
3.大模型技术:大模型原生应用也是当前备受关注的技术话题。随着大模型技术的飞速发展,AIGC、AI Agent和具象智能等领域正在迅速扩张。这些领域的发展也面临着诸多挑战,例如AIGC需要解决内容的原创性、准确性和版权问题,AI Agent需要提升交互的自然性和人性化,具象智能需要更高效地将AI技术与物理世界结合。
4.工业物联网:工业物联网是推动数字化转型的关键技术之一。在2024年,工业物联网市场的增长趋势依然明显。据预测,到2026年,全球5G工业物联网市场规模预计将达到157亿美元,复合年增长率高达79.1%。此外,工业物联网还为工厂的智能化升级提供了海量数据,推动了5G行业应用的快速发展。
这些技术话题在2024年备受关注,它们的发展和应用对数字化转型和未来发展具有重要意义。不断学习和掌握这些新技术,将为个人和企业在未来的竞争中提供优势。
Git是一种版本控制系统,用于管理和跟踪文件的修改历史。它通过记录文件的更改内容并保存为快照来进行工作。下面是Git的基本概念和使用方式:
仓库(Repository):Git使用仓库来存储文件的版本历史记录。一个仓库可以包含一个或多个文件。
提交(Commit):提交是指保存文件更改的操作。每次执行提交都会创建一个新的快照,并将其添加到版本历史记录中。
分支(Branch):分支是指基于当前版本创建的一个可独立进行工作的副本。通过使用分支,可以同时进行多个任务或功能的开发,并在完成后将其合并到主分支。
合并(Merge):合并是指将一个分支的更改内容合并到另一个分支中。当完成一个分支上的工作后,可以将其合并到主分支或其他分支中。
远程仓库(Remote Repository):远程仓库是指存储在网络上的Git仓库,可以与其他开发人员共享代码并进行协作。
拉取(Pull):拉取是指从远程仓库获取最新的代码更新并合并到本地仓库中。
推送(Push):推送是指将本地仓库的更改上传到远程仓库中,以便与其他开发人员共享。
使用Git的基本步骤如下:
创建仓库:使用 git init 命令在本地文件夹中创建一个新的仓库。
添加文件:使用 git add 命令将文件添加到暂存区。
提交更改:使用 git commit 命令提交更改并添加注释。
创建分支:使用 git branch 命令创建一个新的分支。
切换分支:使用 git checkout 命令切换到一个分支。
合并分支:使用 git merge 命令将一个分支的更改合并到当前分支中。
拉取代码:使用 git pull 命令从远程仓库获取最新的代码更新。
推送代码:使用 git push 命令将本地仓库的更改推送到远程仓库。
以上是Git的基本概念和使用方式,它可以帮助开发人员更好地管理和跟踪文件的修改历史,同时方便团队协作。
文章目录 前言Spacer组件的参数说明Spacer组件的使用 总结 前言 Spacer组件是让两组件之间留有空白间隔
Spacer组件的参数说明 Spacer只有一个修饰符,修饰留空白的大小和比例,颜色
Spacer(modifier: Modifier) Spacer组件的使用 Row { Box(modifier = Modifier .size(100.dp) .background(Color.Red)) Spacer(modifier = Modifier.width(20.dp)) Box(modifier = Modifier .size(100.dp) .background(Color.Magenta)) Spacer(modifier = Modifier.weight(1f)) Box(modifier = Modifier .size(100.dp) .background(Color.Black)) } 总结 Spacer组件是让两组件之间留有空白间隔的组件
文章目录 1 项目简介2 实现效果2.1 界面展示 3 设计方案3.1 概述3.2 系统流程3.2.1 添加信息流程3.2.2 操作流程3.2.3删除信息流程 3.3 系统结构设计 4 项目获取 1 项目简介 Hi,各位同学好呀,这里是M学姐!
今天向大家分享一个今年(2022)最新完成的毕业设计项目作品,【基于SSM的药品管理系统】
学姐根据实现的难度和等级对项目进行评分(最低0分,满分5分)
难度系数:3分
工作量:5分
创新点:3分
界面美化:5分
界面美化的补充说明:使用vue的基本都能达到5分
本项目完成于2022年6月份,包含内容 : 源码 + 论文 + 答辩PPT
项目获取:https://gitee.com/kaaxuu/warehouse-six-warehouse/blob/master/vue/README.md
2 实现效果 视频地址:https://www.bilibili.com/video/BV1TY4y177qF
2.1 界面展示 管理员登录页面 前台首页功能界面 在线咨询管理界面 药品入库管理界面 3 设计方案 3.1 概述 本系统采用的数据库是Mysql,使用SSM框架开发,运行环境使用Tomcat服务器,ECLIPSE 是本系统的开发平台。在设计过程中,充分保证了系统代码的良好可读性、实用性、易扩展性、通用性、便于后期维护、操作方便以及页面简洁等特点。
3.2 系统流程 3.2.1 添加信息流程 添加信息,编号系统使用自动编号模式,没有用户填写,用户添加信息输入信息,系统将自动确认的信息和数据,验证的成功是有效的信息添加到数据库,信息无效,重新输入信息。
3.2.2 操作流程 用户想进入系统,首先进入系统登录界面,通过正确的用户名、密码,选择登录类型登录,系统会检查登录信息,信息正确,然后输入相应的功能界面,提示信息错误,登录失败。
3.2.3删除信息流程 用户选择要删除的信息并单击Delete按钮。系统提示是否删除信息。如果用户想要删除信息,系统将删除信息。系统数据库删除信息。
3.3 系统结构设计 使用药品管理系统的分为管理员和用户、员工三个权限模块。
管理员所能使用的功能主要有:首页、个人中心、用户管理、员工管理、药品类别管理、药品信息管理、药品入库管理、药品出库管理、在线咨询管理、留言板管理、系统管理、订单管理等。用户可以实现;首页、个人中心、在线咨询管理、我的收藏管理、订单管理等。员工可以实现;首页、个人中心、药品信息管理、药品入库管理、药品出库管理、在线咨询管理等。 4 项目获取 本项目完成于2022年6月份,包含内容 : 源码 + 论文 + 答辩PPT
题目: 某部门在开发一个代码分析工具,需要分析代码模块之间的依赖关系,用来确定模块的初始化顺序、是否有循环依赖等问题。“批量初始化”是指次可以初始化一个或多个模块。例如模块1依赖模块2模块3也依赖模块2,但模块1和3没有依赖关系。则必须先“批量初始化“模块2,再”批量初始化”模块1和3。现给定一组模块间的依赖关系,请计算需要”批量初始化”的次数。
每一个模块,包含自己的id,和其父亲id。
时间限制: C/C++ 1000ms,其他语言: 2000ms
内存限制:C/C++ 256MB,其他语言:512MB
输入
(1)第1行只有一个数字,表示模块总数N。
(2)随后的N行依次表示模块1到N的依赖数据。每行的第1个数据表示 依赖的模块数量 (不会超过N),之后的数字表示当前模块依赖的模块ID序列,该序列不会重复出现相同的数字,模块ID的取值一定在[1,N]之内。
(3)模块总数N取值范围 1<=N<=1000。
(4)每一行里面的数字按1个空格分隔
输出
输出”批量初始化次数”;
若有循环依赖无法完成初始化,则输出-1;
样例
输入:
5
3 2 3 4
1 5
1 5
1 5
0
输出: 3
解释:共5个模块。模块1依赖模块2、3、4;模块2依赖模块5;模块3依赖模块5;模块4依赖模块5;模块5没有依赖任何模块批量初始化顺序为(5)-2,3,4-1,共需”批量初始化"3次。
解题思路: 我们的目标是计算出“批量初始化”的次数,即我们需要找出所有模块的依赖关系,然后确定哪些模块可以同时初始化,最后计算出需要初始化的次数。
1、读取模块总数 N: 这是问题的第一行输入。
2、读取依赖关系: 接下来的 N 行中,每行表示一个模块及其依赖的模块ID。
3、构建依赖图: 使用一个图(可以用邻接表表示)来存储模块之间的依赖关系。
4、计算入度: 对于图中的每个节点,计算其入度(即有多少模块依赖于它)。
5、拓扑排序: 使用入度为0的节点开始,进行拓扑排序。在排序过程中,每次选择一个入度为0的节点,将其加入结果列表,并减少其所有依赖节点的入度。
6、检查循环依赖: 如果在拓扑排序过程中发现有节点的入度仍然不为0,说明存在循环依赖,无法完成初始化,返回-1。
7、计算批量初始化次数: 如果所有节点都被加入结果列表,那么返回结果列表的长度(即批量初始化的次数)。
C++程序实现 #include <iostream> #include <vector> #include <queue> using namespace std; // 添加依赖关系 void addEdge(vector<vector<int>> &graph, int u, int v) { graph[u].
文章目录 前言Box 组件的参数说明Box 组件的使用Surface 的参数说明Surface 的使用 总结 前言 Box组件是 按子组件依次叠加 的布局组件,相当传统View中的 FrameLayout
Box 组件的参数说明 @Composable inline fun Box( modifier: Modifier = Modifier, //修饰符 contentAlignment: Alignment = Alignment.TopStart, //内容对齐方式 propagateMinConstraints: Boolean = false, //是否将最小尺寸值设置给子 View ,默认为false content: @Composable BoxScope.() -> Unit //Box作用域 ) Box 组件的使用 Box{ Box(modifier = Modifier .size(150.dp) .background(Color.Green)) Box(modifier = Modifier .size(80.dp) .background(Color.Red)) Text(text = "Hello") } Surface 的参数说明 Surface组件是将多个组件摆放平面上,可以设置平面边框,圆角,颜色等。
@Composable @NonRestartableComposable fun Surface( modifier: Modifier = Modifier, //修饰符 shape: Shape = RectangleShape, //设置布局形状 color: Color = MaterialTheme.
Docker 的基本概念和优势,以及在应用程序开发中的实际应用? Docker 是一个开源的容器化平台,使用容器技术来轻松打包、分发和运行应用程序。它基于 Linux 内核的 cgroups 和 namespace 等功能,可以实现资源的隔离和管理。Docker 的基本概念包括镜像、容器和仓库。
镜像是一个只读的模板,包含了运行应用程序所需的文件系统和参数。镜像可以用来创建容器,每个容器都是镜像的一个可执行实例,可以在其中运行应用程序。容器是轻量级和独立的,可以快速启动和停止,并且可以隔离运行环境,避免应用程序之间的冲突。
Docker 仓库是用来存储和分享镜像的地方。Docker 官方仓库是 Docker Hub,其中包含了大量的公共镜像,用户可以从中选择和下载。
Docker 的优势在于: 1、轻量级和快速:Docker 使用容器技术,相比于虚拟机更加轻量级,可以快速启动和停止。
2、可移植性:Docker 镜像包含了应用程序及其依赖的所有文件和配置,因此可以在不同的环境中部署和运行,保持一致的运行环境。
3、隔离性:每个 Docker 容器都是相互隔离的,可以避免应用程序之间的冲突。
4、可扩展性:可以通过创建多个容器来水平扩展应用程序,提高系统的并发能力。
在应用程序开发中,Docker 可以用于实现以下功能: 1、开发环境一致性:通过 Docker,可以将开发环境的配置和依赖打包成镜像,确保团队成员拥有相同的开发环境。
2、持续集成和持续部署:可以使用 Docker 来构建持续集成和持续部署的流水线,快速部署和测试新的版本。
3、微服务架构:Docker 的轻量级和可扩展性使其成为构建微服务架构的理想选择,每个微服务都可以打包成一个独立的容器。
Docker 是一个开源的容器化平台,使用容器技术来轻松打包、分发和运行应用程序。它基于 Linux 内核的 cgroups 和 namespace 等功能,可以实现资源的隔离和管理。Docker 的基本概念包括镜像、容器和仓库。
4、多租户环境:Docker 可以在同一台物理机上运行多个容器,实现多租户的隔离和管理。
总的来说,Docker 可以使开发、测试和部署应用程序变得更加灵活、可靠和高效。
项目说明
随着公司的快速发展,企业人员和经营规模不断壮大,公司对内部招采管理的提升提出了更高的要求。在企业里建立一个公平、公开、公正的采购环境,最大限度控制采购成本至关重要。符合国家电子招投标法律法规及相关规范,以及审计监督要求;通过电子化平台提高招投标工作的公开性和透明性;通过电子化招投标,使得招标采购的质量更高、速度更快。过招投标文件电子化,节约招标成本,提升企业的资金节约率。
开发类型
电子招标采购软件
解决方案
招标面向的对象为供应商库中所有符合招标要求的供应商,当库中的供应商有一定积累的时候,会节省大量引入新供应商的时间。系统自动从供应商库中筛选符合招标要求的供应商,改变以往邀标的业务模式。招采工作完成对供应商进行评分,对不合格供应商进行拉黑;供应商报名、缴费以及投标、答疑等过程通过系统自助完成。以往线下存档资料管理困难,回溯项目过程不清晰,回溯过程复杂,现在通过线上存档的方式,存档方便,可以快捷高效的对以往招采项目进行回溯。
一、立项管理
1、招标立项申请
功能点:招标类项目立项申请入口,用户可以保存为草稿,提交。
2、非招标立项申请
功能点:非招标立项申请入口、用户可以保存为草稿、提交。
3、采购立项列表
功能点:对草稿进行编辑,驳回的立项编辑,在途流程查看。
二、项目管理
1、采购计划管理
功能点:采购计划新增、编辑、删除
2、采购过程管理
功能点:查询、维护基准价、组建评审小组、项目答疑澄清、文件费保证金审核、供应商报价维护、查看评审明细。
3、招标代理机构抽取
功能点:招标代理机构抽取
4、造价机构抽取
功能点:造价机构抽取
5、线下项目管理
功能点:新增、导入、删除、编辑。
三、采购公告管理
1、项目公告查询
功能点:招标类公告创建、非招标类公告创建、查看、编辑、提交审核、停用。
四、评审管理
1、项目评审
功能点:查询、评审人员提交评分。
五、考核管理
1、项目考核分派
功能点:查询、查看详情、发布考核、指派考核负责人。
2、项目考核查询
功能点:查询、查看详情、分配考核人。
3、项目考核
功能点:查询、查看详情、提交考核评分。
六、供应商企业中心
1、投诉建议
功能点:提交投诉建议
2、企业信息
功能点:修改企业信息
3、项目管理
功能点:查看公告、查看项目、下载标书、缴纳文件费、缴纳保证金、上传标书文件。
七、招标代理机构企业中心
1、基本信息
功能点:修改企业信息
2、项目管理
功能点:查看项目详情及状态
3、公告管理
功能点:招标类公告创建、非招标类公告创建、查看、编辑、提交审核、停用。
链接:https://pan.baidu.com/s/1E4x2TX_9SYhxM9sWfnehMg?pwd=1688
提取码:1688
ARM中断寄存器详解 S3C2440的中断寄存器:
1.中断分两大类:内部中断和外部中断。
2.外部中断。24个外部中断占用GPF0-GPF7(EINT0-EINT7),GPG0-GPG15(EINT8-EINT23)。用这些脚做中断输入,则必须配置引脚为中断,并且不要上拉。具体参考datesheet数据手册。
寄存器:EXTINT0-EXTINT2:三个寄存器设定EINT0-EINT23的触发方式。
EINTFLT0-EINTFLT3:控制滤波时钟和滤波宽度。
EINTPEND:这个是中断挂起寄存器,清除时要写1,后面还有几个是写1清除。当一个外部中断(EINT4-EINT23)发生后,那么相应的位会被置1。为什么没有EINT0-EINT3,呵呵,看看SRCPND就知道了,里面没有EINT4-EINT23的位子,所以有了EINTPEND。
EINTMASK:这个简单,是屏蔽中断用的,也就是说位为1时,此次中断无效。
3.内部中断。内部中断有8个寄存器,下面逐一来看。
寄存器:
SUBSRCPND:当一个中断发生后,那么相应的位会被置1,表示一个中断发生了。
INTSUBMSK:与上一个是一伙的,中断屏蔽寄存器,具体屏蔽什么,自己看手册去吧。
INTMOD:中断的方式。一个中断可以是普通中断,也可以是快中断,在这里设置,但只能有一个快中断。
PRIORITY :优先级寄存器,不说了。
SRCPND :当一个中断发生后,那么相应的位会被置1,表示一个或一类中断发生了。
INTMSK :中断屏蔽寄存器。
INTPND :中断发生后,SRCPND中会有位置1,可能好几个(因为同时可能发生几个中断),这些中断会由优先级仲裁器选出一个最紧迫的,然后吧把INTPND中相应位置1,所以同一时间只有一位是1。也就是说前面的寄存器置1是表示发生了,只有INTPND置1,CPU才会处理。
INTOFFSET :用来表示INTPND中哪一位置1了,好让你查询,普通中断跳转时查询用。清除INTPND、SRCPND时自动清除。
4.各寄存器关系:
下面看图说明:
5.中断过程。
a 如果是不带子中断的内部中断:发生后SRCPND相应位置1,如果没有被INTMSK屏蔽,那么等待进一步处理。
b 如果是带子中断的内部中断:发生后SUBSRCPND相应位置1,如果没有被INTSUBMSK屏蔽,那么SRCPND相应位置1,等待进一步处理,几个SUBSRCPND可能对应同一个SRCPND,对应表如下:
SRCPND SUBSRCPND
INT_UART0 INT_RXD0,INT_TXD0,INT_ERR0
INT_UART1 INT_RXD1,INT_TXD1,INT_ERR1
INT_UART2 INT_RXD2,INT_TXD2,INT_ERR2
INT_ADC INT_ADC_S, INT_TC
INT_CAM INT_CAM_C, INT_CAM_P
INT_WDT_AC97 INT_WDT, INT_AC97
c 如果是外部中断:EINT0-EINT3发生后SRCPND相应位置1,如果没有被INTMSK屏蔽,那么等待进一步处理。EINT4-EINT23发生后EINTPEND相应位置1,如果没有被EINTMASK屏蔽,那么SRCPND相应位EINT4-7 或EINT8-23置1,如果没有被INTMSK屏蔽,等待进一步处理,几个EINTPEND对应同一个SRCPND,对应表如下:
SRCPND EINTPEND
EINT0 EINT0
EINT1 EINT1
EINT2 EINT2
EINT3 EINT3
EINT4-7 EINT4-EINT4
EINT8-23 EINT8-EINT23
三种中断都等待进一步处理了。接下来从SRCPND往下看,看INTMSK。如果中断被屏蔽了,就不用说了(注意:快中断也能被屏蔽)。如果没有被屏蔽,那么会进一步到INTMOD。如果是快中断,那么直接出来,进入FIQ(即CPU进入快中断模式处理)。如果是普通中断,那么SRCPND可以有多为置1(FIQ只能有一个),这时就会经过PRIORITY选出一个优先级高的,然后把根据选出的中断把INTPND相应位置1(注意:只能选出一个),进入IRQ,让CPU处理。
6.中断的开启。
a.如果是不带子中断的内部中断,只需设置INTMSK,让它不屏蔽中断就可以了。
类加载器 类加载器主要就是为了负责将.class文件加载到内存中
类加载过程:
1.创建类的实例(对象)
2.调用类的类方法的时候
3.访问类或者接口的类变量,或者为该类变量赋值
4.使用反射方式来强制创建某个类或者\接口对应的java.lang.Class对象
5.初始化某个子类的时候
6.直接使用java.exe命令来运行某个主类
类用到就在在没用到就不加载
加载----->验证----->准备----->解析----->初始化
加载:
通过包名和类名的形式,或者这个类,然后准备使用流的形式进行传输,之后再将这个字节流加载到内存中,再内存中会生成一个这个类的class对象
验证:
验证class文件字节流中是否包含符合当前虚拟机的要求规范,并且没有安全隐患
准备:
负责为类的变量(被static修饰的变量)分配到内存中并且设置默认初始化值
解析:
将类的二进制数据流的符合应用替换为直接引用,(可以这样理解就是一个类再加载的时候,里面如果有引用类型,初次是识别不到的就占时使用符号进行替换,然后再解析的这一步中将之前的符号找到对应的对象在替换为直接引用)
初始化:
通过程序制定的主管计划区初始化变量和其他的资源—也就是给静态变量进行赋值给其他变量进行初始化
类加载分类
名称解释说明启动类加载器(Bootstrap ClassLoader)虚拟机内置的类加载器平台类加载器(Platfrm ClassLoader)负责加载JDK中一些特殊的模块系统类加载器(System ClassLoader)负责加载用户类路径上所指定的类库 //获取系统内加载器 ClassLoader loaderOne = classLoader.getSystemClassLoader(); //获取平台类加载器 ClassLoader loaderTwo = loaderOne.getParent(); //获取启类动加载器 ClassLoader loaderThree = loaderTwo.getParent(); 方法解释说明static ClassLoader getSystemClassLoader()获取系统类加载器InputStream getResourceAsStream(String name)加载某一个资源文件(利用加载器如加载一个指定的文件,参数指的是文件路径) ClassLoader loaderOne = classLoader.getSystemClassLoader(); //利用加载器去加载一个指定的文件 //参数:文件路径--这个文件是相对路径需要放在src路径下面 //返回值:字节流 InputStream is = loaderOne.getResourceAsStream("prop.properties") Properties prop = new Properties(); prop.load(is); is.close();
问题描述: 使用华为obs的sdk创建client,在mac和Windows环境本地调试完成,发到测试环境的Linux服务器却非常慢,定位到具体代码是:
java.security.SecureRandom.next(SecureRandom.java:505) 问题原因:
SecureRandom类使用了多种熵源来生成随机数,包括操作系统提供的随机性源、硬件随机数生成器和其他可用的随机性源。这种多样化的熵源提供了更高的随机性和抵抗性,使得生成的随机数更难以预测和破解。
SecureRandom支持多种随机数生成算法,包括伪随机数生成器(PRNG)和真随机数生成器(TRNG)。PRNG算法基于确定性算法产生随机数序列,而TRNG算法则利用物理过程生成真正的随机数。在 Linux 或 Unix 平台上运行的Java程序默认使用的是/dev/random文件作为熵源,如果/dev/random 在熵不足时就会阻塞。
/dev/random生成的随机数是基于环境噪声和硬件事件的熵源。它会收集在Linux操作系统中,/dev/random是一个特殊的设备文件,用于生成随机数。它是由操作系统内核提供的一个随机数生成器。/dev/random生成的随机数是基于环境噪声和硬件事件的熵源。它会收集来自硬件设备(如鼠标移动、键盘敲击、磁盘活动等)和操作系统事件(如进程调度、网络活动等)的随机性信息,并将这些信息转化为随机数。
问题已经定位到了,/dev/random 熵源不足,解决问题的思路也就有了
不使用/dev/random 作为熵源增加/dev/random熵源的数量 解决方案: 创建对象时直接指定策略(因为我是使用的sdk,这种没有测试,如果是自己的源码可以使用这种方式试一下,最方便) SecureRandom secureRandom = SecureRandom.getInstance("NativePRNGNonBlocking") 修改jre的配置vim /jdk1.8.0_251/jre/lib/security/java.security securerandom.strongAlgorithms=NativePRNGNonBlocking 网上还有资料让加启动参数,我经过测试并没有用,改完上面配置文件后,才生效。下面是让指定的启动参数,如果上述配置不生效可以试一下这个启动参数 -Djava.security.egd=file:/dev/./urandom 增加熵源 安装rngd软件包 # yum install rng-tools 配置,启用并启动rngd服务 如果不存在,请创建目录/etc/systemd/system /并放置/usr/lib/systemd/system/rngd.service的副本,编辑文件并修改[Service]部分,如下所示:
[Service] ExecStart=/sbin/rngd -f -r /dev/urandom -o /dev/random 运行以下命令以启用rngd服务,使其在引导时启动:
# systemctl daemon-reload
# systemctl enable rngd.service 启动rngd服务:
# systemctl start rngd.service 显示新的熵水平 cat /proc/sys/kernel/random/entropy_avail
cat /proc/sys/kernel/random/read_wakeup_threshold
龙芯 3A6000 处理器完全自主设计、性能优异,代表了我国自主桌面 CPU 设计领域的最新里程碑成果。龙芯 3A6000 处理器的推出,说明国产 CPU 在自主可控程度和产品性能上已双双达到新高度,也证明了国内有能力在自研 CPU 架构上做出一流的产品。
龙芯 3A6000 处理器采用龙芯自主指令系统龙架构(LoongArch),是龙芯第四代微架构的首款产品,主频达到 2.5GHz,集成 4 个最新研发的高性能 LA664 处理器核,支持同时多线程技术(SMT2),全芯片共 8 个逻辑核。集成安全可信模块,可提供安全启动方案和国密(SM2、SM3、SM4 等)应用支持。
根据中国电子技术标准化研究院赛西实验室测试结果,龙芯 3A6000 在 2.5GHz 频率下,SPEC CPU 2006 base 单线程定/浮点分值分别达到 43.1/54.6 分,多进程定/浮点分值分别达到155/140 分;SPEC CPU 2017 base 单线程(rate1)定/浮点分值分别达到 5.05/7.78 分,单进程多线程(speed)定/浮点分值分别达到 6.66/18.1 分,多进程(rate8)定/浮点分值分别达到 21.3/21.0 分;Stream 实测带宽超过 42GB/s;Unixbench 实测分值超 7400 分。综合相关测试结果,龙芯 3A6000 处理器总体性能与 Intel 公司 2020 年上市的第 10 代酷睿四核处理器相当。
龙芯 3A6000 与龙芯 3A5000 等龙架构处理器软件兼容。统信、麒麟等操作系统企业在持续兼容的基础上均对龙芯 3A6000 新特性进行全面支持。龙芯 3A6000 完善了对软硬协同的二进制翻译的支持,可提高二进制翻译效率,运行更多种类的跨平台应用,满足各类大型复杂桌面应用场景。
龙架构已建成与 X86、ARM 并列的 Linux 基础软件体系,得到与指令系统相关的主要国际软件开源社区的支持,得到国内统信、麒麟、欧拉、龙蜥、开源鸿蒙等操作系统,以及 WPS、微信、QQ、钉钉、腾讯会议等基础应用的支持。
(同一数据库表数据转移)源码 import pyodbc # 连接数据库 server = 'DESKTOP-HAI1BEH' database = 'T1' driver = '{ODBC Driver 17 for SQL Server}' conn = pyodbc.connect(f'DRIVER={driver};SERVER={server};DATABASE={database};Trusted_Connection=yes;') # 查询数据 cursor = conn.cursor() cursor.execute('select top 3 * from emp') # 获取查询结果 results = cursor.fetchall() for result in results: # 插入方法1 # cursor.execute('insert into emp_copy (id,name,password,date) values(?,?,?,?)',result.id,result.name,result.password,result.date) # 插入方法2 cursor.execute(f"insert into emp_copy (id,name,password,date) values('{result[0]}','{result[1]}','{result[2]}','{result[3]}')") conn.commit() print("数据插入成功!") # 关闭游标和连接 cursor.close() conn.close() (不同数据库表数据转移)源码 import pyodbc # 连接源数据库 source_conn_str = 'DRIVER={ODBC Driver 17 for SQL Server};SERVER=DESKTOP-HAI1BEH;DATABASE=T1;UID=sa;PWD=pwd_Admin' source_conn = pyodbc.
文章目录 场景官方插件源码解析项目细节小结 场景 在许多业务场景下,需要对tkMapper的功能进行增强,需要用到批量新增和批量更新(这里是唯一主键去更新的),许多论文博客自己写的看起来并不行,我们这里就采用官方的模式,一次跑通
官方插件 这里是我通过中央仓库发现的一个宝库,平常对额外功能的增强需要自己常在中央仓库去逛逛看。
依赖地址:
<dependency> <groupId>tk.mybatis</groupId> <artifactId>mapper-spring-boot-starter</artifactId> <version>4.2.3</version> </dependency> <dependency> <groupId>tk.mybatis</groupId> <artifactId>mapper-extra</artifactId> <version>4.2.3</version> </dependency> starter是启动器,extra则是扩展插件,里面就有我们所需的功能
源码解析 我们来看看官方作者的实现方式到底是什么,看看这个具体的provider的实现原理,其实底层就是foreach
package tk.mybatis.mapper.additional.update.batch; import java.util.List; import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.UpdateProvider; import tk.mybatis.mapper.annotation.RegisterMapper; @RegisterMapper public interface BatchUpdateMapper<T> { @UpdateProvider( type = BatchUpdateProvider.class, method = "dynamicSQL" ) void batchUpdate(@Param("list") List<? extends T> recordList); } package tk.mybatis.mapper.additional.update.batch; import org.apache.ibatis.mapping.MappedStatement; import tk.mybatis.mapper.mapperhelper.MapperHelper; import tk.mybatis.mapper.mapperhelper.MapperTemplate; import tk.mybatis.mapper.mapperhelper.SqlHelper; public class BatchUpdateProvider extends MapperTemplate { public BatchUpdateProvider(Class<?> mapperClass, MapperHelper mapperHelper) { super(mapperClass, mapperHelper); } public String batchUpdate(MappedStatement ms) { Class<?
文章目录 场景例子工程引用pom文件(打包关键)打包后观察 场景 许多时候我们在对接三方的时候,需要下载官方的推荐的SDK,但springboot项目怎么引入额外的三方jar包了,自已通过maven本地坐标的方式尝也不行,这里就还有另外一种办法
例子 例如:
我在resources下创建了lib目录,上传的官方推荐的SDK的jar包
工程引用 这里+号添加进来项目就能正常编辑
pom文件(打包关键) 依赖
<dependency> <groupId>com.taobao</groupId> <artifactId>taobao-sdk-NEW_JAVA</artifactId> <version>1.0.0</version> <scope>system</scope> <systemPath>${project.basedir}/src/main/resources/lib/taobao-sdk-NEW_JAVA.jar</systemPath> </dependency> 插件
<!--需添加下面插件,否则java -jar命令启动报SrpingApplication类找不到错误--> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <fork>true</fork> <includeSystemScope>true</includeSystemScope> </configuration> </plugin> 打包后观察 可以观察在BOOT-INF\lib 中可以找到我们的三方jar包
二分查找是一种非常高效的查找算法,时间复杂度为 O(logn) ,也就是 n = 1000 万 时只要 l o g 2 1 0 7 = 24 log _ 2 10^7 = 24 log2107=24 次,但必须是有序的数组,不能是链表,也不能是无序的数组,代码如下,其中 target 是查找的数据,输出的是 target 在数组 a 中的下标或者是 -1:
#include <bits/stdc++.h> using namespace std; int a[10005]; int twofenfind(int a[],int left,int right,int x) { if(left>right) return -1; int mid=left+(right-left)/2; if(a[mid]==x) return mid; if(a[mid]>x) return twofenfind(a,left,mid-1,x); return twofenfind(a,mid+1,right,x); } int main() { int target,n; cin>>target>>n; for(int i=1; i<=n; i++) cin>>a[i]; cout<<twofenfind(a,1,n,target); return 0; }
垃圾回收(Garbage Collection,简称GC)是编程语言中提供的自动的内存管理机制,自动释放不需要的对象,让出存储器资源,无需程序员手动执行。
Golang中的垃圾回收主要应用三色标记法,GC过程和其他用户goroutine可并发运行,但需要一定时间的STW(stop the world),STW的过程中,CPU不执行用户代码,全部用于垃圾回收,这个过程的影响很大,Golang进行了多次的迭代优化来解决这个问题。
一、Go V1.3之前的标记-清除(mark and sweep)算法 此算法主要有两个主要的步骤:
标记(Mark phase)清除(Sweep phase) 第一步,暂停程序业务逻辑。
操作非常简单,但是有一点需要额外注意:mark and sweep算法在执行的时候,需要程序暂停!即 STW(stop the world)。也就是说,这段时间程序会卡在哪儿。
第二步, 开始标记,程序找出它所有可达的对象,并做上标记。如下图所示:
第三步, 标记完了之后,然后开始清除未标记的对象. 结果如下.
对象5,6不可达,被GC所清除 第四步, 停止暂停,让程序继续跑。然后循环重复这个过程,直到process程序生命周期结束。
二、标记-清扫(mark and sweep)的缺点 STW,stop the world;让程序暂停,程序出现卡顿 (重要问题)。标记需要扫描整个heap清除数据会产生heap碎片 所以Go V1.3版本之前就是以上来实施的, 流程是
Go V1.3 做了简单的优化,将STW提前, 减少STW暂停的时间范围.如下所示
这里面最重要的问题就是:mark-and-sweep 算法会暂停整个程序 。
Go是如何面对并这个问题的呢?接下来G V1.5版本 就用三色并发标记法来优化这个问题.
三、Go V1.5的三色并发标记法 三色标记法 实际上就是通过三个阶段的标记来确定清楚的对象都有哪些. 我们来看一下具体的过程.
第一步 , 就是只要是新创建的对象,默认的颜色都是标记为“白色”.
这里面需要注意的是, 所谓“程序”, 则是一些对象的跟节点集合.
所以上图,可以转换如下的方式来表示.
第二步, 每次GC回收开始, 然后从根节点开始遍历所有对象,把遍历到的对象从白色集合放入“灰色”集合。
第三步, 遍历灰色集合,将灰色对象引用的对象从白色集合放入灰色集合,之后将此灰色对象放入黑色集合
第四步, 重复第三步, 直到灰色中无任何对象.
第五步: 回收所有的白色标记表的对象.
以下树为带parentId结构,不带的不适用。 1、保存选中节点的数据 首先介绍一下el-tree
<el-tree :data="treeData" show-checkbox node-key="id" :props="defaultProps" ref="tree" @check-change="getSelectedNodes" style="background-color: rgba(0, 0, 0, 0)" > :props里面存数据的对应结构
function getSelectedNodes() { data.selectedNodes = data.tree.getCheckedNodes(); console.log('选中的节点数据', data.selectedNodes); }j 2、保存选中节点的叶子节点数据 function getSelectedNodes() { data.selectedNodes = data.tree.getCheckedNodes(); const Nodes = data.tree.getCheckedNodes(); let array = []; let isLeaf = false; data.selectedNodes.map((item) => { Nodes.map((i) => { if (item.id === i.parentId) { isLeaf = true; } }); if (isLeaf === true) { array.push(item); isLeaf = false; } }); data.
关系型的结构化存储存在一定的弊端,因为它需要预先定义好所有的列以及列对应的类型。但是业务在发展过程中,或许需要扩展单个列的描述功能,这时,如果能用好 JSON 数据类型,那就能打通关系型和非关系型数据的存储之间的界限,为业务提供更好的架构选择。
当然,很多同学在用 JSON 数据类型时会遇到各种各样的问题,其中最容易犯的误区就是将类型 JSON 简单理解成字符串类型。但当你看完这篇文章后,会真正认识到 JSON 数据类型的威力,从而在实际工作中更好地存储非结构化的数据。
JSON 数据类型 JSON(JavaScript Object Notation)主要用于互联网应用服务之间的数据交换。MySQL 支持 RFC 7159 定义的 JSON 规范,主要有 JSON 对象 和 JSON 数组 两种类型。下面就是 JSON 对象,主要用来存储图片的相关信息:
{ "Image": { "Width": 800, "Height": 600, "Title": "View from 15th Floor", "Thumbnail": { "Url": "http://www.example.com/image/481989943", "Height": 125, "Width": 100 }, "IDs": [116, 943, 234, 38793] } } 从中你可以看到, JSON 类型可以很好地描述数据的相关内容,比如这张图片的宽度、高度、标题等(这里使用到的类型有整型、字符串类型)。
JSON 对象除了支持字符串、整型、日期类型,JSON 内嵌的字段也支持数组类型,如上代码中的 IDs 字段。
另一种 JSON 数据类型是数组类型,如:
[ { "
目录
一、打开文件
二、读取文件内容
三、写入文件内容
四、追加内容到文件末尾
五、文件路径
六、错误处理
七、关闭文件
八、文件读写的高级功能
总结
在Python中,文件读写是一项常见的操作。通过文件读写,我们可以保存数据,加载数据,读取文件内容等等。本文将带您了解Python中的文件读写,并帮助您理解其中的一些重要概念。
一、打开文件 在Python中,要打开一个文件,我们需要使用内置的open()函数。open()函数需要两个参数:文件名和打开模式。打开模式决定了我们要如何与文件交互。
以下是几个常见的打开模式:
'r':只读模式。打开一个用于读取的文件。该文件必须存在。'w':写入模式。打开一个用于写入的文件。如果文件不存在,则会创建一个新文件。如果文件已经存在,则会覆盖该文件的内容。'a':追加模式。打开一个用于写入的文件。如果文件不存在,则会创建一个新文件。如果文件已经存在,则会在文件的末尾追加内容。'x':独占创建模式。创建一个新文件用于写入。如果文件已经存在,则会引发异常。'b':二进制模式。该模式以二进制方式打开文件。't':文本模式(默认模式)。该模式以文本方式打开文件。 下面是一个简单的例子,演示如何以只读模式打开一个文件:
file = open('example.txt', 'r') 这将打开名为example.txt的文件,并将其保存在名为file的对象中。请注意,为了防止资源泄漏,我们在完成文件操作后需要关闭文件。可以使用close()方法或使用with语句来自动关闭文件。
二、读取文件内容 一旦打开了文件,我们就可以使用read()方法来读取文件的内容。例如:
file = open('example.txt', 'r') content = file.read() print(content) 这将读取example.txt文件的内容,并将其打印到控制台中。请注意,read()方法将读取文件的全部内容,并将其作为一个字符串返回。如果文件很大,则可能会占用大量内存。在这种情况下,我们可以使用readlines()方法逐行读取文件内容:
file = open('example.txt', 'r') lines = file.readlines() for line in lines: print(line) 这将逐行读取example.txt文件的内容,并将其打印到控制台中。readlines()方法返回一个包含所有行的列表,每行都是字符串类型。
三、写入文件内容 要写入文件内容,我们可以使用write()方法。例如:
file = open('example.txt', 'w') file.write('Hello, world!') file.close() 这将创建一个名为example.txt的新文件(如果该文件不存在),并在其中写入字符串"Hello, world!"。请注意,write()方法不会自动添加换行符,因此如果您需要在每行之间添加换行符,则需要在字符串末尾添加换行符('\n')。此外,在完成写入后,我们需要调用close()方法来关闭文件。
四、追加内容到文件末尾 如果您想将内容追加到文件的末尾而不是覆盖整个文件的内容,则可以使用'a'模式打开文件,并使用write()方法将内容写入文件中:
file = open('example.txt', 'a') file.write('Hello, again!') file.close() 这将向example.txt文件的末尾添加字符串"Hello, again!"。请注意,如果example.txt不存在,则会创建一个新文件。
五、文件路径 在打开文件时,我们可以使用绝对路径或相对路径指定文件的位置。绝对路径是从根目录开始的完整文件路径,而相对路径是从当前工作目录开始的文件路径。
实体类一键生成DDL语句 效果动态图场景环境实体类工具类+测试运行效果美化下DDL原理总结 效果动态图 实体类一键生成DDL展示
场景 在大多情况,我们都是用数据库中的表生成我们用的实体类对象,但是有的时候,我们习惯使用UML或者拿到新的项目,只有实体类,没有DDL语句,那么这种情况下,我们除了使用三方工具,三方插件,其实利用简单的反射和注释提取就能轻轻松松完成实体类逆向生成建表语句这个功能。
环境 springboot+jdk8
实体类 package com.**.manager.domain.entity; import lombok.Data; import javax.persistence.*; import java.util.Date; /** * 运营收入实体类 * * @author liaoqian * @since 2023/8/8 */ @Data @Table(name = "t_operating_income") public class OperatingIncomeEntity { /** * 主键 */ @Id @Column(name = "operating_income_id") @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer operatingIncomeId; /** * 收入日期 */ @Column(name = "income_date") private String incomeDate; /** * 组织id */ @Column(name = "unit_id") private Integer unitId; /** * 组织编码 */ @Column(name = "
"
BSPA-202675 [SD6490][Nazare] - Screen is not waking up after alarm expiry
#Description: Screen is not waking up after alarm expiry
#Solution: Add USE_FULL_SCREEN_INTENT permission and set notification category to CATEGORY_ALARM
#Commit Reason: S/W bug fixed.
#Function Area: F_Others
#Function Tag: Others_Others
"
修改的code如下:
packages/apps/DeskClock/src/com/android/deskclock/alarms/AlarmNotifications.java
packages/apps/DeskClock/AndroidManifest.xml
diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 03258fd..99a17a5 100755 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -33,6 +33,8 @@ <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="org.codeaurora.permission.POWER_OFF_ALARM" /> <uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> + <!
文章目录 play按钮重置游戏提高等级游戏完成 我们会添加一个Play按钮,用于根据需要启动游戏以及在游戏结束后重启游戏,还会修改这个游戏,使其随玩家等级提高而加快节奏。 play按钮 添加一个Play按钮,它在游戏开始前出现,并在游戏结束后再次出现,让玩家能够开始新游戏
让游戏一开始处于非活动状态,并提示玩家单击Play按钮来开始游戏
game_stats.py
def __init__(self, ai_game): """初始化统计信息。""" self.settings = ai_game.settings self.reset_stats() # 让游戏一开始处于非活动状态。 self.game_active = False 于Pygame没有内置创建按钮的方法,我们将编写一个Button类,用于创建带标签的实心矩形
创建方法draw_button() ,用于将这个按钮显示到屏幕
import pygame.font class Button: def __init__(self, ai_game, msg): """初始化按钮的属性。""" self.screen = ai_game.screen self.screen_rect = self.screen.get_rect() # 设置按钮的尺寸和其他属性。 self.width, self.height = 200, 50 self.button_color = (0, 255, 0) self.text_color = (255, 255, 255) self.font = pygame.font.SysFont(None, 48) # 创建按钮的rect对象,并使其居中。 self.rect = pygame.Rect(0, 0, self.width, self.height) self.rect.center = self.
一、前提条件 磁盘扩展与合并必须是相邻分区空间,且两个磁盘类型需要相同。以磁盘分区为 C 盘和 D 盘为例,如果您希望增加 C 盘容量,可以先将 D 盘合并到 C 盘,然后重新创建磁盘分区,分配 C 盘和 D 盘的空间大小。
访问微软官网,了解更多关于磁盘管理的相关操作。
二、具体操作 将 D 盘数据合并到 C 盘会清除 D 盘所有数据,因此在合并前请先做好 D 盘的数据备份,否则会造成数据丢失。若您的软件安装在 D 盘,那么合并后需要重新安装该软件。
将 D 盘中的数据备份到 C 盘或外部存储设备,如移动硬盘等。右键单击桌面 Windows图标,点击磁盘管理。 在弹出的磁盘管理窗口中,右键单击 D 盘选择删除卷,在弹窗中点击是。 若删除卷按钮置灰无法点击,您可以参考知识:《华为计算机磁盘“格式化”、“删除卷”按钮为灰色》。
删除卷后会出现一个未分配的空间,右键单击 C 盘选择扩展卷,在弹出的扩展卷向导对话框中,根据提示完成扩展。完成后 D 盘空间将合并到 C 盘。 在磁盘管理窗口中,右键单击 C 盘选择压缩卷,在输入压缩空间量选项里输入您要压缩的空间(即分配给新盘符的空间,1GB=1024MB),然后点击压缩。 右键单击未分配的空白分区,选择新建简单卷,根据向导设置简单卷大小、分配给简单卷的驱动器号(如“D”)等,完成后, C 盘和 D 盘空间将会被重新分配。
查询你执行update 语句之前的数据 精确到什么时间
select * from A as of timestamp to_timestamp('2019-07-4 20:00:00', 'yyyy-mm-dd hh24:mi:ss'); 开启可移动数据命令,执行完就可以回滚数据
alter table A enable row movement; 正式回滚 update 语句前的数据
flashback table A to timestamp to_timestamp('2019-07-4 20:00:00', 'yyyy-mm-dd hh24:mi:ss');
微服务(Microservices) 是一种软件架构风格,它将一个大型的应用程序拆分为一组小型、独立的服务,这些服务可以独立开发、部署、扩展和维护。每个微服务都专注于执行一组明确定义的任务,并通过轻量级的通信机制(通常是HTTP API)与其他服务进行交互。微服务架构旨在提高应用的灵活性、可维护性和可伸缩性。
以下是微服务架构的一些关键特点:
服务拆分: 应用被拆分为多个小型服务,每个服务负责特定的业务功能。这种拆分可以提高代码的可维护性和团队的独立开发能力。
独立部署: 微服务可以独立部署,这意味着更新或修改一个服务不会影响其他服务。每个服务都可以按照自己的节奏进行开发、测试和部署。
松散耦合: 微服务通过明确定义的接口进行通信,彼此之间是松散耦合的。这意味着一个服务的变化不太可能对其他服务产生重大影响。
技术多样性: 每个微服务可以使用适合其需求的技术栈。这样,团队可以选择最适合他们需求的编程语言、框架和工具。
独立扩展: 每个微服务都可以独立扩展,允许根据需要增加或减少服务的实例,以应对不同服务的不同负载。
去中心化管理: 微服务架构通常采用去中心化的管理方法,避免单点故障,提高系统的弹性和可靠性。
分布式数据管理: 由于每个微服务都可以拥有自己的数据库或数据存储,因此需要考虑分布式数据管理的挑战,如数据一致性和事务处理。
优点: 模块化和独立性: 微服务架构将应用程序拆分为小的、独立的服务,使得每个服务都可以独立开发、测试、部署和扩展。
灵活性: 因为每个微服务都是独立的,团队可以使用不同的技术栈,这提供了更大的灵活性和选择权。
独立部署: 微服务可以独立部署,这使得发布和更新变得更为灵活,不会影响整个应用程序。
可伸缩性: 微服务允许对具体服务进行独立的水平扩展,以应对不同服务的不同负载。
快速交付: 小团队可以独立地开发和交付微服务,这有助于缩短开发周期。
技术多样性: 不同服务可以使用适合其需求的最佳技术,而无需受制于整个应用的技术栈。
容错性: 单个微服务的故障不会影响整个应用程序,系统具有更好的容错性。
缺点: 复杂性: 微服务架构引入了分布式系统的复杂性,包括服务发现、服务间通信、分布式事务等问题。
运维复杂性: 管理多个独立部署的微服务,监控、日志、调试等方面的运维任务变得更加复杂。
分布式系统的挑战: 分布式系统带来了一系列挑战,如数据一致性、网络延迟、服务间通信等问题。
团队沟通: 微服务架构可能导致服务之间的接口和依赖关系变得复杂,增加了团队之间的沟通和协调的难度。
数据管理: 分布式数据管理可能涉及到一致性、事务处理、数据一致性等方面的挑战。
初始开发成本: 初始将单体应用拆分为微服务架构可能需要较大的工作量和投入。
性能开销: 由于服务间通信,可能引入一些性能开销,特别是在高负载情况下。
SpringCloud Spring Cloud 是基于 Spring Framework 的微服务架构开发工具集,提供了一系列的开发工具和框架,用于快速构建分布式系统中的微服务应用。Spring Cloud 通过各种组件和模块来解决微服务架构中的一系列共性问题,包括服务发现、配置管理、负载均衡、熔断器、API 网关等。
Spring Cloud 的一些主要模块和功能:
Spring Cloud Netflix:
Eureka: 服务注册与发现组件,允许微服务注册并发现其他服务的存在。Ribbon: 客户端负载均衡器,用于在多个服务提供者之间进行负载均衡。Hystrix: 用于处理服务之间的故障和延迟的容错库,提供断路器模式、降级、快速失败等功能。 Spring Cloud Config:
<UserControl x:Class="NavTest.Views.Page5" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:cv="clr-namespace:NavTest.Components" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:hc="https://handyorg.github.io/handycontrol" xmlns:i="http://schemas.microsoft.com/xaml/behaviors" xmlns:local="clr-namespace:NavTest.Views" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mv="clr-namespace:NavTest.ViewModels" d:DataContext="{d:DesignInstance mv:Page5ViewModel}" d:DesignHeight="450" d:DesignWidth="800" mc:Ignorable="d"> <UserControl.Resources> <cv:SingleParamConverter x:Key="SingleParamConverter" /> <cv:MultiParamConverter x:Key="MultiParamConverter" /> </UserControl.Resources> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition /> <ColumnDefinition /> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition /> <RowDefinition /> </Grid.RowDefinitions> <DataGrid Margin="10" AutoGenerateColumns="False" ItemsSource="{Binding Stu}"> <DataGrid.Columns> <DataGridTextColumn Binding="{Binding Id}" Header="Id" /> <DataGridTextColumn Binding="{Binding Name}" Header="Name" /> <DataGridTextColumn Binding="{Binding Age}" Header="Age" /> <DataGridTextColumn Binding="{Binding Description}" Header="Description" /> <DataGridTemplateColumn> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <Button Width="60" HorizontalAlignment="Center" Command="
机器学习实际应用时的工程问题与面临的挑战
一、实现细节问题
1.1 训练样本
训练样本与标注对各类机器学习算法和模型的精度影响
训练样本的选择对各类机器学习算法和模型的影响
训练样本的优化
如何进行数据增强?
如何进行数据清洗?
样本的标注对各类机器学习算法精度的影响
样本的对齐
各个类的训练样本不均衡问题怎么解决
1.2 特征预处理
如果特征向量各分量的取值范围相差很大,会影响算法的精度与训练时的收敛
特征预处理方法
将特征向量归一化到单位长度
归一化可以通过学习实现
1.3 模型选择
没有免费的午餐定理
如何选择合适的算法和参数?
剃刀原理
剃刀原理在机器学习中的应用
1.4 过拟合问题
二、安全性问题
2.1 对抗样本
神经网络拟合出的目标函数不连续
如何找到扰动图像(如何找到一些能够使得机器学习模型产生错误的输出或行为的扰动图像)
什么是对抗样本攻击?
对抗样本攻击是一种在机器学习中的一种安全性问题,它是指利用一些经过特殊设计或修改的数据,来使得机器学习模型产生错误的输出或行为,从而达到攻击或干扰的目的。对抗样本攻击的原因是机器学习模型的泛化能力有限,对于一些看似微小的数据变化,可能会导致模型的输出发生巨大的变化。对抗样本攻击的影响是很严重的,它可能会威胁到机器学习模型的安全性和可靠性,甚至危害到人类的利益和社会的稳定。对抗样本攻击的应用领域很广泛,例如图像识别、自然语言处理、语音识别、生物识别、自动驾驶等。
人工生成对抗样本的方法
2.2 形成原因分析
线性模型拟合数据时哪些情况容易出现对抗样本问题
数据维度过高导致线性模型对抗样本问题
激活函数与对抗样本问题
激活函数是神经网络中的一个重要的组成部分,它决定了神经元的输出和非线性特性。激活函数的选择会影响神经网络的性能和效果,例如准确性、收敛速度、泛化能力等。一些常用的激活函数有线性函数、Sigmoid函数、双曲正切函数、整流线性单元(ReLU)、Leaky ReLU、参数化整流线性单元(PReLU)、指数线性单元(ELU)、斜坡函数(Ramp)等。其中,一些激活函数是不连续的,例如ReLU、Leaky ReLU、PReLU、Ramp等,它们在某些点上的导数为0或无穷大,导致神经网络的输出也不连续。
激活函数与对抗样本问题的关系有以下几个方面:
激活函数的非线性程度:激活函数的非线性程度是指激活函数的输出与输入的非线性关系的强度,它可以用激活函数的导数的变化率来衡量。激活函数的非线性程度会影响神经网络的对抗样本的抵抗能力,一般来说,激活函数的非线性程度越高,神经网络的对抗样本的抵抗能力越强,反之亦然。这是因为,激活函数的非线性程度越高,意味着神经网络的输出对输入的微小变化越不敏感,从而使得对抗样本的生成更困难。例如,Sigmoid函数的非线性程度较高,它的导数在中间区域变化较快,在两端区域变化较慢,这使得Sigmoid函数对输入的微小变化不太敏感,从而使得神经网络的对抗样本的抵抗能力较强。相反,线性函数的非线性程度较低,它的导数在任何区域都是恒定的,这使得线性函数对输入的微小变化非常敏感,从而使得神经网络的对抗样本的抵抗能力较弱。
激活函数的连续性:激活函数的连续性是指激活函数的输出是否在整个输入域内都是连续的,即是否存在任何断点或跳跃。激活函数的连续性会影响神经网络的对抗样本的抵抗能力,一般来说,激活函数的连续性越高,神经网络的对抗样本的抵抗能力越强,反之亦然。这是因为,激活函数的连续性越高,意味着神经网络的输出对输入的微小变化越平滑,从而使得对抗样本的生成更困难。例如,Sigmoid函数和双曲正切函数的连续性较高,它们的输出在整个输入域内都是连续的,没有任何断点或跳跃,这使得Sigmoid函数和双曲正切函数对输入的微小变化比较平滑,从而使得神经网络的对抗样本的抵抗能力较强。相反,ReLU函数和Ramp函数的连续性较低,它们的输出在某些点上存在断点或跳跃,这使得ReLU函数和Ramp函数对输入的微小变化比较突变,从而使得神经网络的对抗样本的抵抗能力较弱。
激活函数的饱和性:激活函数的饱和性是指激活函数的输出是否在某些区域内趋于恒定,即是否存在任何饱和区域。激活函数的饱和性会影响神经网络的对抗样本的抵抗能力,一般来说,激活函数的饱和性越低,神经网络的对抗样本的抵抗能力越强,反之亦然。这是因为,激活函数的饱和性越低,意味着神经网络的输出对输入的变化越敏感,从而使得对抗样本的生成更困难。例如,ReLU函数和Ramp函数的饱和性较低,它们的输出在任何区域都是线性增长的,没有任何饱和区域,这使得ReLU函数和Ramp函数对输入的变化比较敏感,从而使得神经网络的对抗样本的抵抗能力较强。相反,Sigmoid函数和双曲正切函数的饱和性较高,它们的输出在两端区域都趋于恒定,存在饱和区域,这使得Sigmoid函数和双曲正切函数对输入的变化比较不敏感,从而使得神经网络的对抗样本的抵抗能力较弱。
通过哪种方式生成的样本导致大量的神经网络模型出现错分类
三、实现成本问题
3.1 训练样本量
样本的收集和标注问题
小样本深度学习技术
哪些情况适用于半监督学习
3.2 计算与存储成本
四、深度模型优化
深度模型优化的方法
减少存储空间和计算量的方法是对神经网络的模型进行压缩。有哪些实现手段?
剪枝与编码 二值化网络 卷积核分离简述:
4.1 剪枝与编码
剪枝与编码是一种对神经网络模型进行压缩的方法,它包括以下两个步骤:
剪枝:剪枝是指通过删除一些不重要或冗余的模型参数,例如权重、偏置、节点、层等,以减少模型的结构和规模。剪枝的目的是去除模型中的无用或有害的信息,提高模型的性能和精度。剪枝的方法有很多,例如最小化损失函数、最大化信息量、最小化梯度等。剪枝的结果是一个稀疏的模型,即模型中有很多的零值或接近零的值。
编码:编码是指对剪枝后的模型参数进行编码,以减少模型的存储空间和计算量。编码的目的是利用模型的稀疏性,压缩模型的大小和复杂度。编码的方法有很多,例如哈夫曼编码、熵编码、矩阵分解、张量分解等。编码的结果是一个紧凑的模型,即模型中的参数用更少的位数或更简单的形式来表示。
剪枝与编码的优点是可以显著地减少模型的存储空间和计算量,而不影响模型的性能和精度。剪枝与编码的缺点是可能导致模型的不稳定和不可逆。
Deep Compression深度模型压缩技术
第3章 神经网络入门 本章包括以下内容: 神经网络的核心组件 Keras 简介 建立深度学习工作站 使用神经网络解决基本的分类问题与回归问题 本章的目的是让你开始用神经网络来解决实际问题。你将进一步巩固在第 2 章第一个示例中学到的知识,还会将学到的知识应用于三个新问题,这三个问题涵盖神经网络最常见的三种使用场景:二分类问题、多分类问题和标量回归问题。 本章将进一步介绍神经网络的核心组件,即层、网络、目标函数和优化器;还会简要介绍Keras,它是贯穿本书的 Python 深度学习库。你还将建立深度学习工作站,安装好 TensorFlow和Keras,并支持GPU。
最后,我们将用三个介绍性示例深入讲解如何使用神经网络解决实际问题,这三个示例分别是:
将电影评论划分为正面或负面(二分类问题) 将新闻按主题分类(多分类问题) 根据房地产数据估算房屋价格(回归问题) 学完本章,你将能够使用神经网络解决简单的机器问题,比如对向量数据的分类问题和回归问题。然后,你就可以从第 4 章开始建立对机器学习更加具有原则性、理论性的理解。
3.1 神经网络剖析 前面几章介绍过,训练神经网络主要围绕以下四个方面。
层,多个层组合成网络(或模型)。 输入数据和相应的目标。 损失函数,即用于学习的反馈信号。 优化器,决定学习过程如何进行。 你可以将这四者的关系可视化,如图 3-1 所示:多个层链接在一起组成了网络,将输入数据映射为预测值。然后损失函数将这些预测值与目标进行比较,得到损失值,用于衡量网络预测值与预期结果的匹配程度。优化器使用这个损失值来更新网络的权重。
我们来进一步研究层、网络、损失函数和优化器。
3.1.1 层:深度学习的基础组件 我们在第 2 章中介绍过,神经网络的基本数据结构是层。层是一个数据处理模块,将一个或多个输入张量转换为一个或多个输出张量。有些层是无状态的,但大多数的层是有状态的,即层的权重。权重是利用随机梯度下降学到的一个或多个张量,其中包含网络的知识。
不同的张量格式与不同的数据处理类型需要用到不同的层。
例如,
(1)简单的向量数据保存在形状为 (samples, features) 的 2D 张量中,通常用密集连接层[densely connected layer,也叫全连接层(fully connected layer)或密集层(dense layer),对应于 Keras 的 Dense 类]来处理。
(2)序列数据保存在形状为 (samples, timesteps, features) 的 3D 张量中,通常用循环层(recurrent layer,比如 Keras 的 LSTM 层)来处理。
(3)图像数据保存在 4D 张量中,通常用二维卷积层(Keras 的 Conv2D)来处理。
2024美赛A-F题思路+代码+模型+论文:2.2开赛第一时间更新,获取见文末名片
美赛流程以及经验分享
今天主要和大家分享一下我之前参加美赛的经验,主要分两部分来讲。一部分是美赛流程,另一部分是美赛经验。
一 美赛流程
比赛前:
首先是美赛报名。对于报名的具体细节,大家可以参考我当时报完名整理的博客《美赛报名步骤解说》,链接如下:https://blog.csdn.net/zr147258369/article/details/86483215?utm_source=app
其次是比赛准备。比赛每组三人,我个人建议一人负责论文写作,两人负责编程和建模,因为美赛编程要求不如国赛要求高。对于论文写作的人而言,首当其冲的肯定是英语写作能力的提升,建议可以阅读一些学术报告,掌握专业术语的表达。其次可以参考往年的优秀论文,确定论文框架,论文格式。对于编程和建模的人而言,需要提前了解美赛的题目类型,对于数学专业的学生,一般选择MCM(Mathematical Contest In Modeling 数学建模竞赛),对于其他专业的学生,选择ICM(Interdisciplinary Contest In Modeling 交叉学科建模),分析历年的题目,选择适合自己的类型,但具体还是根据题目出来后,团队对于题目的兴趣与思路决定。
MCM
ICM
A
连续型
D
运筹学/网络科学
B
离散型
E
环境科学
C
大数据
F
政策
最后是赛前心态。想要参加美赛的同学也一定了解了美赛的难度以及获奖比例,美赛共设置五个奖项,分别为Outstanding Winner,Finalist,Meritorious Winner,Honorable Mentions,Successfully Participation。 在国内,约定俗成地将这五个奖项分别对应为特等奖、特等奖候选奖、一等奖、二等奖,成功参与奖。获奖比例依次为0.5%,1%,13%,30%,55%。所以相对比国赛而言,美赛获奖的概率更高,难度也就稍低,所以一定不要胆怯,只要认真完成了,一定会有收获。
比赛中:
一旦题目公布后,下载题目,分析题目,选择题目。确定题目之后,负责论文写作的同学下载控制页,根据实际情况改动其表头及页眉队伍信息。(这项工作在题目确定后就完成,因为到后期的时候,快提交论文的前5个小时完全进不去网站)
确定题目之后,对题目进行翻译,(当然一般都选择网页翻译,但是对于一些不确定的地方一定要研读英文版题目)队伍成员深入讨论研究题目,确定思路和建模的大致框架。(研究讨论题目的过程,编写论文的同学一定要全程参与,要了解题目以及团队的思想,确保论文写作过程中描述精准,表达清楚)。确定模型框架之后,编写论文的同学可以在其他两位同学建模的过程中完成题目背景,问题重述等内容的编写。
建模过程中,需要注意的几点:
1 大胆的构造模型,不一定要像万有引力公式那样严密(短短四天时间,我们怎样也不可能达到科学家那样严密)。
2 建模构造的模型看起来要合乎逻辑,但不一定完全能应用于现实(可以将模型成立的背景写在假设中)。
3 尽量三个人一起讨论模型的大体框架。
编程过程主要还是考验负责编程的同学的能力了,我就不多加赘述了。
提交时,仔细核对论文提交和控制页提交的邮箱,按照要求格式完成提交。提交后,通过指导教师登陆(Advisor Login) 连接登录竞赛网页,查验 COMAP 是否收到了论文电子版。如果成功提交的话,48小时内登录后的界面的左下角会显示 "received";否则要联系美赛官方解决。
二 美赛经验分享
1 时间安排
第一天 前半天
分析题目,确定题目,完成控制页
第一天 后半天~第二天 前半天
第一问模型建立,编程解决;题目背景,问题重述等完成
第二天 后半天~第三天 前半天
第二三问模型建立,编程解决;第一问论文写作完成
第三天 后半天
01-Multiply算法背景
01.01-触觉传感器
触觉传感器是一种用于感知和测量物体接触力、形状、纹理和其他相关参数的传感器。它们模拟人类触觉系统,通过收集和解释物体与传感器之间的相互作用来获取信息。 工作原理:触觉传感器使用不同的原理来感知接触力和其他触觉信息。常见的触觉传感器技术包括压电传感器、电容传感器、电阻传感器、光学传感器和弹性元件等。
接触力测量:触觉传感器能够测量物体施加在其表面的接触力。这些传感器可以提供接触力的大小、方向和分布信息,从而帮助机器人或其他系统感知和控制接触过程。
形状感知:触觉传感器可以检测物体的形状和表面几何特征。通过测量物体与传感器之间的接触区域和接触点的变化,可以推断物体的形状和轮廓。
纹理感知:触觉传感器可以感知物体表面的纹理和细节。通过测量接触区域的微小变化和表面结构的特征,可以获取关于物体纹理的信息。
应用领域:触觉传感器在许多领域中有广泛的应用,包括机器人技术、自动化制造、医疗诊断、虚拟现实和游戏等。它们可用于机器人的抓取和操作、医疗设备的手术辅助、虚拟环境中的触觉反馈以及产品质量控制等。
发展趋势:随着科技的发展和研究的深入,触觉传感器正朝着更高精度、更小尺寸、更灵活和更智能化的方向发展。新的材料、传感技术和数据处理算法的不断涌现,为触觉传感器的进一步创新和应用提供了广阔的空间。
总之,触觉传感器是一项重要的技术,它们允许机器和系统感知和理解物体的触觉信息。通过感知接触力、形状、纹理等参数,触觉传感器为机器人和自动化系统提供了更多的感知能力和交互能力,推动了许多应用领域的创新和发展。
01.02-热感应传感器
热感应传感器是一种用于测量和检测热量变化的传感器。它们基于物体的温度差异来感知热量,并将其转化为电信号或其他形式的输出。 工作原理:热感应传感器利用热量在物体中的传导、辐射和对流等原理来测量温度变化。它们通常由热敏元件和信号处理电路组成。热敏元件可以是热电偶、热敏电阻、热敏电容或红外线传感器等。
测量原理:热感应传感器测量温度变化的方法因传感器类型而异。例如,热电偶通过测量两个不同金属接点之间的温度差异来产生电压信号。热敏电阻则基于电阻值随温度变化而变化,而红外线传感器可以检测物体辐射出的红外线,并将其转化为温度测量。
应用领域:热感应传感器在许多领域中有广泛应用。它们可用于温度监测和控制,如室内温度调节、工业过程控制、电子设备散热管理等。此外,热感应传感器还常用于红外热成像、医疗诊断、火灾探测、环境监测和热能转换等领域。
发展趋势:随着技术的进步,热感应传感器正朝着更高性能、更小尺寸、更低功耗和更多功能集成的方向发展。新的材料、微纳加工技术和先进的信号处理算法的引入,将进一步提高热感应传感器的性能和应用领域。
总之,热感应传感器是一种重要的测量工具,可用于测量和检测温度变化。它们在许多领域中发挥着重要作用,提供温度监测、控制和红外热成像等功能。随着技术的不断进步,热感应传感器将继续发展,为各行各业提供更多应用和创新的可能性。
02-Multiply算法简介
在积极探索3D世界并与之互动的过程中,人类发现增加多种感官传感器可以提供更多有用的线索。然而,当前的多模态大语言模型被动地吸收传感器数据作为输入,缺乏与3D环境中的对象主动交互并动态收集其多感官信息的能力。
为了开启这一领域的研究,作者提出了MultiPLY,它是多传感器嵌入LLM,通过部署嵌入代理来参与3D环境,它对以对象为中心的多传感器表示(例如,视觉、音频、触觉和热)进行编码,从而建立单词、动作和感知之间的相关性。MultiPLY可以执行一组不同的多感官隐含任务,包括多感官问答、隐含问答、任务分解、对象检索和工具使用等。
03-Multiply算法流程
上面的视频展示了MultiPLY算法的整体表框架。作者首先将场景编码为抽象的以对象为中心的特征表示,而对象的多感官细节只有在代理执行动作并与之交互时才会显现。除此之外,作者还设计了一组动作标记,表示代理与环境交互的动作。交互结果通过状态标记附加回LLM,从而生成后续的文本或操作标记。详细的步骤如下所述: 首先,将输入的场景图片送入Concept Graphs中获取3D场景图表示,同时将输入的环境声音转换为相应的语音特征表示。
然后,将这些特征输入到MultiPLY大模型中,通过理解用户的问题来调用相应的感官功能。例如:“甜甜圈可以吃了吗?”,为了回答这个问题,机器人需要根据外部的声音传感器和触觉传感器的反馈来做出相应的分析与应答。
最后,为了回答用户的问题,该大模型首先需要导航到甜甜圈所在的具体位置;并根据微波炉的声音进行判断;最后需要使用触觉传感器来做出相应的结论。
04-Multiply算法应用场景
04.01-声音&视觉感知
04.02-触觉&热红外&导航
04.03-利用工具&多传感器字幕生成
04.04-问答&目标检索
04.05-任务分解&物体重排
05-Multiply算法性能评估
05.01-主观效果性能评估
上图展示了该算法利用多种传感器在特定环境中完成的聊天、QA问答、导航、字幕生成等多个任务的样例。 上图展示了MultiPLY算法的定性效果。MultiPLY可以与具体环境中的物体进行交互,并收集多传感器信息。上图展示了机器人agent通过导航、语音理解、温度传感器等多个传感器来完成特定的任务。 05.02-客观指标性能评估
上表展示了该算法与多个SOTA算法在对象检索任务上面的实验结果。-I表示模型使用oracle操作令牌与环境进行交互。通过观察我们可以发现:与其它的SOTA算法相比,该算法获得了最高的检索准确率,碾压其它的SOTA算法。 上表展示了该算法与多个SOTA算法使用工具的结果。通过观察我们可以发现:基于绑定的方法在工具使用方面的性能非常差。这可能是因为它们将物体的感官数据视为一个整体,无法将材料等个体感官信息从表示中分离出来,更不用说推理如何将这种特性用作工具,以及如何在多感官信息集成时分析和推导物体的功能了。 上表展示了该算法与多个SOTA算法在多传感器字幕任务上面的生成效果。从表中,我们可以看到:基于3D的LLM总体上胜过2D VLM。LLaVA和3D-LLM将整体表示作为输入,因此无法与可以与模型交互以在表示之间切换的模型竞争。MultiPL Y胜过Pointbind LLM,可能是因为Pointbind绑定了不同模态的表示,使感官难以理清。
06-Multiply算法效果展示
图6.1-Multiply算法效果展示1
图6.2-Multiply算法效果展示2
已经很久没有写博客记录自己学到的一些东西了。但是在过去一年的时间中自己确实又学到了一些东西。一直攒着没有系统化成一篇篇的文章,所以今年的博客打算也是以去年学到的一系列内容为主。通过之前Vim系列教程的启发,我发现还是写一些系列文章对自己的帮助最大。它能最大化自己的学习成果,并强迫自己深入了解一些内容。所以今年我想还是以系列文章为主,如果中间有需要穿插一些bug处理或者语言特性相关的,可能也会有这方面的内容吧。
好了,废话就到这里,下面开始正式介绍PDF相关的内容
PDF简介 PDF的全称是 Portable document format(可移植文档格式),是描述打印页面的世界领先语言。最早于1990年代由Adobe Systems创造。早期是Adobe专有格式,直到2008年作为开放标准发布。后续经过一系列的发展,目前已经发展到了2.0版本,由于PDF完全向后兼容,并且大部分都是向前兼容的,因此,这里不打算固定在某个具体的版本,而是介绍一些PDF通用的标准和规则。
PDF的文档结构 PDF主要由四个部分构成,文件头、文件体、交叉引用表以及文件尾
文件头将文件标识为PDF并给出它的版本号,例如
%PDF-1.0 % PDF 版本号为 1.0 的文件头 文件体是PDF文档的主体内容,主要由对象组成,它规定了页面信息和页面内容元素等信息
交叉引用表给出了每个对象距离文件首部的地址偏移,这样在解析PDF的时候就不用从头到尾解析每个对象,而是根据需要通过交叉引用表来寻址到具体的对象地址,只单独解析某个对象,提高了解析效率
文件尾给出交叉引用表的位置并且以
%%EOF 作为结尾
PDF文件的逻辑结构 一个标准的PDF文档需要在文件体中包含下列元素对象:
根节点元素,类似于xml的根节点,它是整个文档的根节点对象Pages对象,它包含了PDF文档的页面信息,一般通过它来定义整个PDF文档有多少页Page 页面对象,它用来描述每个具体的页Page Content 对象,它来描述每个具体页中都有哪些对象,一般是一个字节流用来表示将在页面中显示哪些内容Page Resource 对象,它是内容的资源字典,供Content对象引用,资源包括字体、画刷、画笔等等trailer 字典,可以将它看作pdf文档对象的入口,通过它我们可以知道当前PDF文档的一些具体信息,例如根节点的位置,交叉引用表的大小 它们之间的关系如下图:
PDF版的Hello World 说了这么多,我们来试试来自己编辑一个hello world文档,首先建立一个文本文件,将后缀改为.PDF 。
我们先写上文件头:
%PDF-1.0 % PDF 版本号为 1.0 的文件头 主要对象 我们按照之前的分析的PDF文档中需要包含的对象,来逐一定义
首先给出Pages节点的定义
1 0 obj % 对象1 << /Type /Pages % 这是一个页面列表 /Count 1 % 只有一页 /Kids [2 0 R] % 页面对象编号列表。这里只是对象2 >> endobj % 对象1结束 对象的内容我们在后续会专门介绍,所以这里不需要额外关注它的语法,这里只需要知道
FTP是一种文件传输协议。有时我们把他形象的叫做文件交流集中地。FTP文件服务器的主要用途就是提供文件存储的空间,让用户可以上传或者下载所需要的文件。在企业中,往往会给客户提供一个特定的FTP空间,以方便跟可以进行一些大型文件的交流,如大到几百兆的设计图纸等等。同时,FTP还可以作为企业文件的备份服务器,如把数据库等关键应用在FTP服务器上实现异地备份等等。
可见,FTP服务器在企业中的应用是非常广泛的。真是因为其功能如此的强大,所以,很多黑客、病毒也开始关注他了。他们企图通过FTP服务器为跳板,作为他们传播木马、病毒的源头。同时,由于FTP服务器上存储着企业不少有价值的内容。在经济利益的诱惑下,FTP服务器也就成为了别人攻击的对象。
在考虑FTP服务器安全性工作的时候,第一步要考虑的就是谁可以访问FTP服务器。在Vsftpd服务器软件中,默认提供了三类用户。不同的用户对应着不同的权限与操作方式。
一类是Real帐户。这类用户是指在FTP服务上拥有帐号。当这类用户登录FTP服务器的时候,其默认的主目录就是其帐号命名的目录。但是,其还可以变更到其他目录中去。如系统的主目录等等。
第二类帐户实Guest用户。在FTP服务器中,我们往往会给不同的部门或者某个特定的用户设置一个帐户。但是,这个账户有个特点,就是其只能够访问自己的主目录。服务器通过这种方式来保障FTP服务上其他文件的安全性。这类帐户,在Vsftpd软件中就叫做Guest用户。拥有这类用户的帐户,只能够访问其主目录下的目录,而不得访问主目录以外的文件。
在组建FTP服务器的时候,我们就需要根据用户的类型,对用户进行归类。默认情况下,Vsftpd服务器会把建立的所有帐户都归属为Real用户。但是,这往往不符合企业安全的需要。因为这类用户不仅可以访问自己的主目录,而且,还可以访问其他用户的目录。这就给其他用户所在的空间 带来一定的安全隐患。所以,企业要根据实际情况,修改用户虽在的类别。
第一步:修改/etc/Vsftpd/vsftpd.conf文件 默认情况下,只启用了Real与Anonymous两类用户。若我们需要启用Guest类用户的时候,就需要把这个选项启用。修改/etc/Vsftpd/vsftpd.conf文件,把其中的chroot_list_enable=YES这项前面的注释符号去掉。去掉之后,系统就会自动启用Real类型的帐户。
第二步:修改/etc/vsftpd.conf文件。 若要把某个FTP服务器的帐户归属为Guest帐户,则就需要在这个文件中添加用户。通常情况下,FTP服务器上没有这个文件,需要用户手工的创建。利用VI命令创建这个文件之后,就可以把已经建立的FTP帐户加入到这个文件中。如此的话,某个帐户就属于Real类型的用户了。他们登录到FTP服务器后,只能够访问自己的主目录,而不能够更改主目录。
第三步:重新启动FTP服务器。 按照上述步骤配置完成后,需要重新启动FTP服务器,其配置才能够生效。我们可以重新启动服务器,也可以直接利用Restart命令来重新启动FTP服务。
在对用户尽心分类的时候,笔者有几个善意的提醒。
一是尽量采用Guest类型的用户,而减少Real类行的用户。一般我们在建立FTP帐户的时候,用户只需要访问自己的主目录下的文件即可。当给某个用户的权限过大时,会对其他用户文件的安全产生威胁。
在以下几种情况下,我们要禁止这些账户访问FTP服务器,以提高服务器的安全。
一是某些系统帐户。如ROOT帐户。这个账户默认情况下是Linxu系统的管理员帐户,其对系统具有最高的操作与管理权限。若允许用户以这个账户为账户名进行登陆的话,则用户不但可以访问Linux系统的所有资源,而且,还好可以进行系统配置。这对于FTP服务器来说,显然危害很大。所以,往往不允许用户以这个Root等系统帐户身份登陆到FTP服务器上来。
第二类是一些临时账户。有时候我们出于临时需要,为开一些临时账户。如需要跟某个客户进行图纸上的交流,而图纸本身又比较大时,FTP服务器就是一个很好的图纸中转工具。在这种情况下,就需要为客户设立一个临时账户。这些账户用完之后,一般就加入到了黑名单。等到下次需要再次用到的时候,再启用他。
在vstftpd服务器中,要把某些用户加入到黑名单,也非常的简单。在Vsftpd软件中,有一个/etc/vsftpd.user_lise配置文件。这个文件就是用来指定哪些账户不能够登陆到这个服务器。我们利用vi命令查看这个文件,通常情况下,一些系统账户已经加入到了这个黑名单中。FTP服务器管理员要及时的把一些临时的或者不再使用的帐户加入到这个黑名单中。从而才可以保证未经授权的账户访问FTP服务器。在配置后,往往不需要重新启动FTP服务,配置就会生效。
不过,一般情况下,不会影响当前会话。也就是说,管理员在管理FTP服务器的时候,发现有一个非法账户登陆到了FTP服务器。此时,管理员马上把这个账户拉入黑名单。但是,因为这个账户已经连接到FTP服务器上,所以,其当前的会话不会受到影响。当其退出当前会话,下次再进行连接的时候,就不允许其登陆FTP服务器了。所以,若要及时的把该账户禁用掉的话,就需要在设置好黑名单后,手工的关掉当前的会话。
对于一些以后不再需要使用的帐户时,管理员不需要把他加入黑名单,而是直接删除用户为好。同时,在删除用户的时候,要记得把用户对应的主目录也一并删除。不然主目录越来越多,会增加管理员管理的工作量。在黑名单中,只保留那些将来可能利用的账户或者不是用作FTP服务器登陆的账户。这不但可以减少服务器管理的工作量,而且,还可以提高FTP服务器的安全性。
在系统默认配置下,匿名类型的用户只可以下载文件,而不能够上传文件。虽然这不是我们推荐的配置,但是,有时候出于一些特殊的需要,确实要开启这个功能。如笔者以前在企业中,利用这个功能实现了对用户终端文件进行备份的功能。为了设置的方便,就在FTP服务器上开启了匿名访问,并且允许匿名访问账户网某个特定的文件夹中上传某个文件。
笔者再次重申一遍,一般情况下,是不建议用户开启匿名账户的文件上传功能。因为很难保证匿名账户上传的文件中,不含有一些破坏性的程序,如病毒或者木马等等。有时候,虽然开启了这个功能,但是往往会在IP上进行限制。如只允许企业内部IP可以进行匿名访问并上传文件,其他账户则不行。如此的话,可以防止外部用户未经授权匿名访问企业的FTP服务器。若用户具有合法的账户,就可以在外网中登陆到FTP服务器上。
总之,在FTP服务器安全管理上,主要关注三个方面的问题。一是未经授权的用户不能往FTP空间上上传文件;二是用户不得访问未经授权的目录,以及对这些目录的文件进行更改,包括删除与上传;三是FTP服务器本身的稳定性。以上三个问题中的前两部分内容,都可以通过上面的三个方法有效的解决
文章目录 分布式锁介绍1. 分布式锁的工作原理1.1 锁的基本概念1.2 工作机制 2. 分布式锁的实现方式2.1 基于数据库的分布式锁2.2 基于Redis的分布式锁2.3 基于ZooKeeper的分布式锁 3. 分布式锁的挑战3.1 死锁问题3.2 锁粒度问题粗粒度锁细粒度锁锁粒度的选择 3.3 锁的公平性问题1. 使用中心化的服务2. 时间戳排序3. 队列机制 4. 总结 分布式锁介绍 分布式锁是一种在分布式环境下,对共享资源提供访问限制的方法。其主要目的是防止多个进程同时操作同一资源,造成数据的不一致性。分布式锁通过在多个节点上运行的进程之间引入协调机制,来解决这个问题。
1. 分布式锁的工作原理 1.1 锁的基本概念 在开始之前,先简单了解一下锁的基本概念。锁是一种保护共享资源不被并发操作破坏的技术。当一个进程想要访问共享资源时,必须首先获取锁。如果其他进程已经持有锁,那么该进程必须等待,直到锁被释放。
1.2 工作机制 在分布式系统中,分布式锁的实现比单机环境更为复杂。因为在分布式环境下,不同的进程可能在不同的物理机器上运行。因此,我们需要一种跨越多台机器,能够实现共享状态的方式来实现分布式锁。常见的实现方式包括基于数据库、基于缓存(如Redis)或者是基于ZooKeeper等系统。
2. 分布式锁的实现方式 接下来,将详细介绍一些常见的分布式锁实现方式。
2.1 基于数据库的分布式锁 这种实现方式通常是在数据库中创建一个表,用于存储锁信息。当一个进程想要获取锁时,会在该表中插入一条记录。如果插入成功,则表示获取锁成功;如果因为主键冲突等原因插入失败,则表示获取锁失败。
CREATE TABLE `Locks` ( `key` varchar(64) NOT NULL, PRIMARY KEY (`key`) ) ENGINE=InnoDB; 2.2 基于Redis的分布式锁 Redis具有很好的性能和原子操作支持,因此也常被用于实现分布式锁。通过SETNX(Set if Not eXists)命令,我们可以尝试获取一个锁。如果该锁不存在,那么设置成功,获取锁;否则获取失败。
SET resource_name my_random_value NX PX 30000 2.3 基于ZooKeeper的分布式锁 ZooKeeper是一个开源的分布式协调服务,它提供了一种高效且可靠的分布式锁实现方式。通过创建短暂的顺序ZNode节点,可以让多个客户端争抢锁。只有序号最小的客户端才能获得锁。
public void lock() { if (!
在 Flutter 的 pubspec.yaml文件中,依赖的版本号前面的 ^符号用于指定版本范围,而没有 ^ 符号则表示精确指定版本
带 ^ 符号 在依赖版本前使用 ^ 符号,代表接受这个依赖的任何向上兼容的版本(主版本号相同,次版本号或补丁版本号更高的版本)
eg:^1.0.2包括 1.0.2、1.1.0等版本,但不包括 2.0.0
不带^符号 代表使用指定的三方库、插件版本
eg:6.0.0版本
1.创建用户 groupadd www -g 666 useradd www -s /sbin/nologin -M -u 666 -g 666 2.安装nginx yum install nginx -y 3.下载第三方软件仓库,解决一些依赖 rpm -Uvh https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm rpm -Uvh https://mirror.webtatic.com/yum/el7/webtatic-release.rpm #此时就是多出来几个仓库 [root@localhost ~]# ls /etc/yum.repos.d/ CentOS-Base.repo epel.repo epel.repo.rpmnew epel-testing.repo webtatic-archive.repo webtatic.repo webtatic-testing.repo 4.安装php7依赖 yum install -y php71w-cli php71w-common php71w-devel php71w-embedded php71w-gd php71w-mcrypt php71w-mbstring php71w-pdo php71w-xml php71w-fpm php71w-mysqlnd php71w-opcache php71w-pecl-memcached php71w-pecl-redis php71w-pecl-mongodb php71w-json php71w-pecl-apcu php71w-pecl-apcu-devel 5.修改权限 [root@localhost ~]# grep -E '^(user|group)' /etc/php-fpm.d/www.conf user = www group = www [root@localhost ~]# grep -E ^user /etc/nginx/nginx.
1. 引言 前序博客:
Bitcoin+STARK: ZeroSync & Khepri Robin Linus、Tino Steffens、Lukas George 等人成立了一个名为 ZeroSync 协会(ZeroSync Association)的瑞士非营利组织,该组织将牵头开发比特币证明系统。ZeroSync 于 2022 年获得了 Geometry Research 的资助,今年早些时候也获得了 StarkWare 的资助,此后成立了该基金会。该小组的工作是在以太坊生态系统之外使用 StarkWare 的 Cairo 编程语言的首次尝试。
ZeroSync 协会总部位于瑞士楚格州,由一个以多重签名钱包为代表的董事会进行管理,其密钥持有者在比特币或 ZKP 系统领域赢得了良好的声誉。作为安全措施和保护其隐私,密钥持有者的姓名不公开。
ZeroSync的使命为:
促进比特币生态系统中证明系统的使用,以提高可扩展性、可访问性和隐私性。 ZeroSync分为3大阶段:
1)Header Chain proof(原型已实现):类似于SPV轻节点,header state proof仅验证区块头、PoW和难度调整。此外,在所有区块头上使用Merkle树来增强header chain,从而为所有区块和交易提供简洁的包含证明。该state proof相对简单,轻量,计算成本低。将是ZeroSync第一个准备的生产级版本。
Header Chain Verifier demo:在浏览器内运行WebAssembly的miniSTARK verifier,来验证Bitcoin header chain的递归证明。当前仍处于原型开发阶段,仅能验证header chain,还不能验证交易。
2)“Assumevalid” state proof(原型已实现):模仿Bitcoin Core的“assumevalid”选项。其验证除交易签名之外的所有比特币共识规则。更确切地说:假设所有witness数据都是有效的。此外,此证明使用Utreexo来通过UTXO集合承诺来增强链。ZeroSync团队于2023年2月完成了这种“Assumevalid” state proof的初步原型。
3)Full state proof:验证所有比特币共识规则,包括所有witness数据。在“Assumevalid” state proof的基础上,还验证了所有的witness数据。就计算而言,这是最昂贵的证明,并且需要对Prover进行重大优化才能变得可行。它将是最后一个做好生产准备的。
ZeroSync的第一个主要应用程序将是通过Blockstream卫星从太空广播state proofs,让几乎在地球上任何地方的每个人都可立即同步比特币区块链。
ZeroSync核心开发者有:
Robin LinusLukas GeorgeTino SteffensMax GillettAndrew Milson 开源代码见:
球形空间产生器 题目描述 有一个球形空间产生器能够在N维空间中产生一个坚硬的球体。现在,你被困在了这个N维球体中,你只知道球面上N+1个点的坐标,你需要以最快的速度确定这个N维球体的球心坐标,以便于摧毁这个球形空间产生器。 输入描述 第一行是一个整数N(1≤N≤10)。 接下来的N+1行,每行有N个实数,表示球面上一点的N维坐标。每一个实数精确到小数点后6位,且其绝对值都不超过20000。 输出描述 有且只有一行,依次给出球心的N维坐标(N个实数),两个实数之间用一个空格隔开。每个实数精确到小数点后3位。数据保证有解。你的答案必须和标准输出一模一样才能够得分。 输入输出样例 示例1 输入 2 0.00.G -1.01.0 1.00.0 输出 0.5001.500 运行限制 语言 最大运行时间 最大运行内存 C++ 1s 128M C 1s 128M Python3 1s 128M Java 1s 128M
一、信息(题目的有用信息) 题目要求在N维空间中,给定N+1个点的坐标,这些点位于一个球面上,要求计算出这个N维球的球心坐标。
输入:第一行是维度N(1≤N≤10),接下来的N+1行,每行N个实数表示一个点的坐标。
输出:一行,包含N个实数,表示球心的坐标,每个实数精确到小数点后三位。
二、分析 每个信息的作用: 维度N决定了坐标点的数量和每个点的维度。N+1个点的坐标是计算球心所需的数据。 思考和分析过程: 在N维空间中,一个球体的定义是所有点到某一点(球心)的距离都相等。给定N+1个点,可以通过解方程组来找到满足所有这些点到球心距离相等的球心坐标。 算法思路: 构建方程组:对于每两个点,根据它们到球心的距离相等,可以得到一个方程。解方程组:这将是一个线性方程组,可以通过高斯消元法或者线性代数库求解。 三、算法设计 高斯消元法: 构建增广矩阵:根据N+1个点坐标构建N个方程。对增广矩阵进行行操作,使其上三角化。从最后一个方程开始回代求解每个变量。 四、代码实现(C++) #include <iostream> #include <vector> #include <cmath> #include <iomanip> using namespace std; // 高斯消元法求解线性方程组 vector<double> gaussianElimination(vector<vector<double>>& mat, int n) { for (int i = 0; i < n; i++) { // 寻找主元 int maxRow = i; for (int k = i + 1; k < n; k++) { if (abs(mat[k][i]) > abs(mat[maxRow][i])) { maxRow = k; } } // 交换行 swap(mat[i], mat[maxRow]); // 消元 for (int k = i + 1; k < n; k++) { double factor = mat[k][i] / mat[i][i]; for (int j = i; j <= n; j++) { mat[k][j] -= factor * mat[i][j]; } } } // 回代 vector<double> res(n); for (int i = n - 1; i >= 0; i--) { res[i] = mat[i][n] / mat[i][i]; for (int k = i - 1; k >= 0; k--) { mat[k][n] -= mat[k][i] * res[i]; } } return res; } // 主函数 int main() { int n; cin >> n; vector<vector<double>> points(n + 1, vector<double>(n)); // 读入点的坐标 for (int i = 0; i <= n; i++) { for (int j = 0; j < n; j++) { cin >> points[i][j]; } } // 构建增广矩阵 vector<vector<double>> mat(n, vector<double>(n + 1, 0)); for (int i = 1; i <= n; i++) { for (int j = 0; j < n; j++) { mat[i - 1][j] = 2 * (points[i][j] - points[0][j]); mat[i - 1][n] += points[i][j] * points[i][j] - points[0][j] * points[0][j]; } } // 高斯消元求解 vector<double> center = gaussianElimination(mat, n); // 输出结果 for (int i = 0; i < n; i++) { cout << fixed << setprecision(3) << center[i]; if (i < n - 1) cout << "
# 一、dns的主要信息 关于dns的名词解释:dns:
domain name service(域名解析服务)
关于客户端:
/etc/resolv.conf dns指向文件
A记录 ##ip地址叫做域名的Address 记录
SOA ##授权起始主机
关于服务端
bind安装包named服务名称/etc/named.conf主配置文件/var/named数据目录端口53 关于报错信息:
1.no servers could be reached服务无法访问(服务开启?火墙?网络?端口?)2.服务启动失败配置文件写错 journalctl -xe查询错误 3.dig查询状态NOERROR表示查询成功REFUSED服务拒绝访问SERVFAIL查询记录失败,(dns服务器无法到达上级,拒绝缓存)NXDOMAIN此域名A记录在dns中不存在 二、dns的安装及启用 安装
dnf install bind.x86_64 -y
启用
systemctl enable --now named
firewall-cmd --permanent --add-service=dns
firewall-cmd --reload
测试
在测试主机上(另一台主机)编辑文件
vim /etc/resolv.conf
客户端主机上运行
dig www.baidu.com
此时测试主机不能运行
客户端主机运行
netstat -antlupe | grep named
发现使用的53端口并没有对外开放
编辑配置文件
vim /etc/named.conf
重启服务
systemctl restart named
此时测试主机上有回应
但并拒绝服务,没有成为服务对象
继续编辑配置文件
重启服务
systemctl restart named
文章目录 内置对象1.什么是内置对象2.如何查阅MDN文档3.Math对象3.1Math概述3.2随机数方法random() 4.Date日期对象4.1Date概述4.2Date()的使用4.2日期格式化 5.Array数组对象5.1创建数组的两种方法5.2检测是否为数组的两种方法5.3添加或删除数组元素5.4数组排序5.5.数组索引5.6数组转换成字符串5.7其他 6.字符串对象6.1基本包装类型6.2字符串的不可变6.3根据字符返回位置6.4根据位置返回字符(重点)6.5字符串的操作方法(重点)6.6其他方法 简单数据类型和复杂数据类型1.堆和栈2.简单类型的内存分配3.复杂类型的内存分配4.简单类型的传参5.复杂数据类型的传参 内置对象 1.什么是内置对象 ①JavaScript中的对象分为3种:自定义对象、内置对象、浏览器对象
②前面两种对象是JS基础内容,属于ECMAScript;第三个浏览器对象属于我们JS独有的,我们JSAPI讲解
③内置对象就是指JS语言自带的一些对象,这些对象供开发者使用,并提供了一些常用的或是最基本而必要的功能(属性和方法)
④内置对象最大的优点就是帮助我们快速开发
⑤JavaScript提供了多个内置对象:Math、Date、Array、string等
2.如何查阅MDN文档 学习一个内置对象的使用,只要学会其常用成员的使用即可,我们可以通过查文档学习,可以通过MDN/W3C
来查询。
Mozilla开发者网络(MDN)提供了有关开放网络技术(OpenWeb)的信息,包括HTML、CSS和万维网及
HTML5应用的API。
MDN:https://developer.mozilla.org/zh-CN/
如何学习对象中的方法
1.查阅该方法的功能
2.查看里面参数的意义和类型
3.查看返回值的意义和类型
4.通过demo进行测试
3.Math对象 3.1Math概述 Math 对象不是构造函数,它具有数学常数和函数的属性和方法。跟数学相关的运算(求绝对值,取整、最大值
等)可以使用Math中的成员。
Math.PI//圆周率 Math.floor() //向下取整 Math.ceil() //向上取整 Math.round() //四舍五入版就近取整注意-3.5结果是-3 Math.abs ( ) //绝对值 Math.max()/Math.min() //求最大和最小值 //1.绝对值方法 console.log(Math.abs(1));//1 console.log(Math.abs(-1));//1 console.log(Math.abs('-1'));//隐式转换会把字符串型-1转换为数字型 console.log(Math.abs('pink'));//NaN //2.三个取整方法 //(1)Math.floon()地板向下取整往最小了取值 console.log(Math.floor(1.1));//1 console.log(Math.floor(1.9));//1 //(2)Math.ceil()ceil天花板向上取整往最大了取值 console.log(Math.ceil(1.1));//2 console.log(Math.ceil(1.9));//2 //(3)Math.round()四舍五入其他数字都是四舍五入,但是.5特殊它往大了取 console.log(Math.round(1.1));//1 console.log(Math.round(1.5));//2 console.log(Math.round(1.9));//2 console.log(Math.round(-1.1));//-1 console.log(Math.round(-1.5));//这个结果是-1 3.2随机数方法random() //1.Math对象随机数方法 random()返回一个随机的小数 //2.这个方法里面不跟参数 //3.代码验证 console.log(Math.random()); //4.我们想要得到两个数之间的随机整数并且包含这2个整数 // Math.floor(Math.random()*(max-min+1))+min; function getRandom(min,max){ return Math.
摘 要
一般来说,在房地产行业,房源信息采集,对企业来说至关重要,通过人工采集数据的方式进行数据收集,既耗时又费力,影响工作效率,还导致信息时效性变差,可靠性偏低,不利于数据分析和决策,而且不好去准确统计目前房地产的存量,往大的说,不利于国家进行房地产宏观调控,往小了说不利于企业和业主快速完成房源交易,降低了交易的频次。而快速获取一个好的房源信息要比找到一个客户更重要,因为一个好的房源信息背后隐藏很多潜在客户,而挖掘了一个客户却不一定就能签单。所以对于成功的房地产从业人员来说,高效的获取房源就是成功的关键,同时也可以实现房源信息汇总,可帮助企业和政府机构及时了解本地房源的最新情况。
基于Python scrapy框架的房源信息采集与可视化系统的出现适应了国家信息化建设的要求,使得房地产工作者和房地产政策制定人员更为高效准确的了解房源信息,节省了不少宝贵时间和大量的人力物力,也使房地产工作者更加方便,也利于企业实现将库存的目的,实现了资源高效利用,不仅盘活了房地产,提高了房源信息的开发和利用,而且实现了房地产降库存、提高房源流转,降低房地产的风险,也利于政府部门制定相应的政策提供数据依据。
本论文重点阐述了房源信息采集与可视化系统的开发过程,以实际运用为开发背景,运用了Python网络爬虫技术,充分保证系统的安全性和稳定性。本系统使用scrapy框架爬取北京链家房源信息,操作简单方便;可视化是通过echart来直接显示,在通过flask轻量化服务器部署展示。通过系统概述、系统分析、系统设计、数据库设计、系统实现这几个部分,详细的说明了系统的开发过程,最后并对整个开发过程进行了总结,该可视化系统主要功能包含北京地图、柱形图、复合柱形图、饼图、折线图等,最后都是通过图表形式部署展示这些房源信息的数据。
关键词:房源信息;信息采集;可视化;Python爬虫;scrapy
1.绪论
1.1 研究背景
随着科技技术的变革,人类社会环境发生了一次又一次的重大变化。各行各业都在科技的冲击下迅速发展,对于房地产来说,从传统的纸质记录房源信息到现在通过软件产品来记录,大大的提升了企业房地产数据采集的工作时间。对于企业来说除了记录房源信息记录外,企业还需要了解不同地区的房源售信息,基于这种情况开发了一个基于Python的房源信息数据采集与可视化系统。
本文基于Python技术和Excel、MySQL,针对北京房源信息数据方向建立了网络爬虫的房源信息数据采集与可视化系统。系统是为了通过大数据对房源信息进行分析,为了最终实现要求,本系统以PyCharm为开发平台。经过细心的调研和衡量,以Python技术为核心去编写后台和实现各业务接口,以echart作为数据的展示,flask轻量化服务器部署展示。
1.2 研究现状
很多时候,无论出于数据分析或产品需求,我们需要从某些网站,提取出我们感兴趣、有价值的内容,但是纵然是进化到21世纪的人类,依然只有两只手,一双眼,不可能去每一个网页去点去看,然后再复制粘贴。所以我们需要一种能自动获取网页内容并可以按照指定规则提取相应内容的程序,这就是爬虫。而爬虫数据获取的基础,经过这么多年的发展,除了面对surfaceweb(即表层Web,由网页沟通,网页之间通过超链接关联)的常用爬虫,各种面对垂直领域和特定主题的爬虫(focusedcrawler)成为热点。目前最常用的爬虫语言是Python爬虫,其中scrapy、beautifulsoup、selenium等常见框架。
这三种框架都有各自的特点:(1)Scrapy:很强大的爬虫框架,可以满足简单的页面爬取(比如可以明确获知url pattern的情况)。用这个框架可以轻松爬下来如亚马逊商品信息之类的数据,是目前房源信息采集常用的一种框架。(2)Beautiful Soup:名气大,整合了一些常用爬虫需求。缺点:不能加载JS。(3)selenium:这是一个调用浏览器的driver,通过这个库你可以直接调用浏览器完成某些操作,比如输入验证码。
1.3 目的和意义
本系统解决了房地产从业人员和房地产政策制定者所依赖的数据来源的问题,帮助他们获取更多更有价值的数据。同时,本房地产网站上极有价值的数据,利用现有技术在项目中实现了免登陆、高效率爬取数据,同时针对爬取的数据进行了初步的筛选过滤,去掉多余信息,除了可以节省本地空间之外还方便地产从业人员和房地产政策制定者对数据进行二次清洗、提炼,从而得到更有价值的信息。本系统还针对爬虫的作用机制以及设计模式进行了优化,采用scrapy的技术框架可以提高采集效率,同时因为采用了合适的设计模式,可以及时地将内存中的数据导入到数据库中,极大地减少了内存资源的占用,使爬虫程序在运行期间,尽可能少地占用计算机资源。在辅助flask轻量化的服务器,结合pyecharts库,实现数据大屏可视化展示,让房地产从业人员和房地产政策制定者更直观更细致了解数据信息。
2.系统概述
2.1 系统的相关技术和运行环境
本系统以pycharm、MySQL、SQL数据库语言作为工具。系统概述以系统分析、系统设计、数据库设计、系统实现这几个部分,详细的说明了系统的开发过程。下面对这几种技术和方法进行概述。
Pycharm Pycharm 是一种Python IDE,带有一整套可以帮助用户在使用Python语言开发时提高其效率的工具,比如调试、语法高亮、Project管理,代码跳转,只能提示,自动完成,单元测试、脚本控制。此外,该IDE提供了一些高级功能,用于支持Django框架下的专业Web开发,同时支持Google App Engine,更酷的是Pycharm支持IronPython。
MySQL
由于其体积小、速度快、总体拥有成本低,尤其是开放源码这一特点,许多中小型网站为了降低网站总体拥有成本而选择了MySQL作为网站数据库。MySQL是一个多用户、多线程的关系型数据库管理系统。 工作模式是基于客户机/服务器结构。目前它可以支持几乎所有的操作系统,同时也可以和php完美结合。
简单的来说 ,MySql是一个开放的、快速的、多线程的、多用户的SQL数据库服务器。
3.系统分析
3.1 系统需求分析
3.1.1 房源信息采集
采集房源信息,使用的就是scrapy框架,首先确定爬虫中起始的url构造成request对象通过爬虫中间件传递给调度器,调度器把request传递给下载器,下载器发送请求,获取response响应经过下载中间件反馈给爬虫,爬虫提取url地址,组装成request对象传递给调度器,重复步骤2,爬虫提取数据最后经过管道处理,保存数据,其基本流程如下图。
图3-1 scrapy框架数据采集流程图
3.1.2 房源信息保存
经过图3-1流程可以知道,在保存数据环节,本论文使用了三种存储方式,csv、MySQL和json三种格式,当然scrapy框架数据存储的时候,必须要先设定存储的优先级,这样才能保障存储优先顺序不会错乱。基本流程如下图。
图3-2 房源信息存储流程图
3.1.3 房源信息处理
存储完数据,要将数据可视化,必须对数据进行处理,处理成能够直接进行可视化的数据格式,本论文可视化是使用echart进行可视化,其默认的格式是json格式,所以要将数据转换成json格式的数据,为后面的可视化提供数据基础。
图3-3 房源信息数据处理流程图
3.1.4 房源信息可视化
在处理好数据之后,就将处理好的数据用echart里面的js文件,使用js技术处理成图表展示出来,为最后的可视化部署做准备。
图3-4 房源信息可视化
3.1.5 房源信息可视化部署
经过echart可视化之后,就利用flask部署,实现网页访问,展示可视化后的数据。
图3-5 房源信息部署流程图
3.2 系统需求分析
3.2.1 数据采集
Scrapy框架中的爬虫文件spider先确定采集的链接url,初始链接为‘https://bj.fang.lianjia.com/loupan/pg1’,反爬措施使用浏览器的标头,伪装成浏览器,爬取的数据为:房源名称、面积、房子类型、销售状态、地区、所在乡镇、地址、户型、卖点、单价、总价。
showModalBottomSheet( context: context, isDismissible: true, isScrollControlled: false, shape: RoundedRectangleBorder(borderRadius: BorderRadius.only(topLeft: Radius.circular(15), topRight: Radius.circular(15))), builder: (BuildContext context) { return ListView.builder( itemBuilder: (context, index) { return ListTile( title: Text('老孟$index'), ); }, itemExtent: 50, itemCount: 50, ); }); flutter面试题相关:flutter面试题 - 简书
Flutter 大厂面试真题(含答案)_前端知识库
问题描述 有n(2≤n≤10)个玩家玩游戏,他们按1到n编号。第i(1≤i≤n)个玩家有ti个喜欢的玩家,给出第i个玩家喜欢的玩家的编号列表。 最初1号玩家拿着一朵花,游戏进行k(0≤k≤1018)个回合,每个回合拿着花的人会把花等概率地送给自己喜欢的人之一,k回合游戏后拿着花的人获胜。分别求n个人获胜的概率,对10⁹+7取模。 输入格式 第一行,包括两个正整数n,k,分别表示玩家人数和游戏轮数。 以下n行,每行首先有一个非负整数ti(1≤ti≤n),表示第i个玩家有ti个喜欢的人。然后输入ti个互不相同的正整数,表示第i个玩家喜欢的人的编号。 输出格式 共n行,每行一个正整数pi(1≤i≤n)表示k次游戏后第i个人拿着花的概率,对10⁹+7取模。 令M=10⁹+7,可以证明所求概率可以写成既约分数号的形式,其中P,q均为整数且q≠0(modM)。应输出整数p×q-¹(mod M)。 样例输入 41 224 12 224 11 样例输出 0 500060004 0 500000004 说明 1轮游戏后,花在第1个人和第3个人手中的概率为0,在第2个人和第4个人手中的概率是。 评测数据规模 2≤n≤10,0≤k≤10l⁸。 运行限制 语言 最大运行时间 最大运行内存 C++ 1s 256M C 1s 256M Java 2s 256M Python3 3s 256M
官方答案: C++代码: #include <bits/stdc++.h> using namespace std; const int N=1e5+5; using LL=long long; const int mod=1e9+7; int n; LL k; struct asdf{ int n,m; LL a[11][11]; asdf(int x=10,int y=10,int t=0) { n=x; m=y; memset(a,0,sizeof(a)); if (t) for (int i=0;i<min(m,n);++i) a[i][i]=1; } asdf operator * (asdf b) { asdf ans; memset(ans.
Gitlab7.14 中文版安装教程 注: 本教程由羞涩梦整理同步发布,本人技术分享站点:blog.hukanfa.com转发本文请备注原文链接,本文内容整理日期:2024-01-28csdn 博客名称:五维空间-影子,欢迎关注 1 简要说明 说明
为何写本文 1、本人所在公司目前在用的gilab版本为7.14.3,鉴于版本比较老打算迁移到新版。 2、旧版乃前人所部署,部署方式也比较传统:通过手动一步步搭环境和组件,还是比较繁琐 3、本人一般用docker方式部署gitlab,借此机会通过手动方式实现下gilab部署也是有必要的 gitlab简介 1、Ruby on Rails 开发的开源应用程序,实现一个自托管的Git项目仓库,可通过Web界面进行访问公开的或者私人项目 2、与Github类似的功能,能够浏览源代码,管理缺陷和注释, 3、可以管理团队对仓库的访问,它非常易于浏览提交过的版本并提供一个文件历史库 本次部署gitlab所用到的环境和依赖版本说明 # 以下依赖版本可根据需求选择,可以使用较新版本代替 * 系统版本:Centos 7 * gitlab:7-14中文版|英文版 * ruby:2.2.0 * mysql:5.7 * nginx:1.8.0 * git: 2.8.2 * redis:yum 版本 特别说明:由于旧版距今很多年,重新部署还是有很多坑。也许你按照文档走还会碰到新的问题,希望能克服!
2 前期部署 2.1 基本配置 操作如下
关闭防火墙相关 # 永久 sed -i 's/^SELINUX=enforcing/SELINUX=disabled/g' /etc/sysconfig/selinux # 临时 setenforce 0 systemctl stop firewalld systemctl disable firewalld 安装epel源 # 方式一 yum -y install epel* # 方式二(推荐) wget https://dl.
要做接口测试,我们得搭建一套本地可以运行的接口环境。这次我选择了一个搭建容易,适合学习的系统——学生管理系统。
Python安装 这套管理系统是Python代码写的,因此需要Python环境。
安装挺无脑的,按照我提供的安装包和方法装好即可。
Postman安装 Postman是一款接口测试工具。同样是无脑安装,按照我提供的安装包和方法装好即可。
Pycharm安装
Pycharm是python语言编辑工具。无脑安装+3,不说啦~
项目部署 01 项目解压后,用Pycharm打开项目
02 在Pycharm的命令行窗口键入命令,安装项目依赖的模块
pip3 install -r requirements.txt -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com 03 在Pycharm的命令行窗口键入命令,启动项目 python run_server.py tips:因避免2端口占用,我已修改项目的默认端口为8099,IP是本机127.0.0.1(可以在run_server.py中自行修改) 因我在py文件中修改过默认端口,可能会和后面要讲的接口文档里的URL不一致,但也无伤大雅~
如果运行时报下面的错(Django版本不兼容导致的)
Unhandled exception in thread started by <function check_errors.<locals>.wrapper at 0x0000024D934BDD08> Traceback (most recent call last): …… File "C:\Python37\lib\site-packages\django\contrib\admin\widgets.py", line 152 '%s=%s' % (k, v) for k, v in params.items(), ^ SyntaxError: Generator expression must be parenthesized 则需跳转到报错路径下,将这个逗号去掉,然后重新键入python run_server.py命令启动项目。
04 阅读项目内的接口API文档或接口清单,拿到接口
05 在浏览器输入:IP:端口/api/departments/如果能获取到数据,证明服务启动成功。
补充说明 apt-key命令 用于管理Debian Linux系统中的软件包密钥。每个发布的deb包,都是通过密钥认证
的,apt-key用来管理密钥。
语法 apt-key(参数) 参数 操作指令:APT密钥操作指令。
实例 apt-key list # 列出已保存在系统中key。 apt-key add keyname # 把下载的key添加到本地trusted数据库中。 apt-key del keyname # 从本地trusted数据库删除key。 apt-key update # 更新本地trusted数据库,删除过期没用的key。
目录 Leetcode695. 岛屿的最大面积Leetcode1020. 飞地的数量Leetcode130. 被围绕的区域Leetcode417. 太平洋大西洋水流问题Leetcode827.最大人工岛 Leetcode695. 岛屿的最大面积 文章链接:代码随想录
题目链接:695. 岛屿的最大面积
思路:dfs
class Solution { public: int count; int dir[4][2] = {1, 0, -1, 0, 0, 1, 0, -1}; void dfs(vector<vector<int>>& grid, vector<vector<bool>>& visited, int x, int y){ for (int i = 0; i < 4; i++){ int nex = x + dir[i][0]; int ney = y + dir[i][1]; if (nex < 0 || nex >= grid.size() || ney < 0 || ney >= grid[0].
目录
前言
设计思路
一、课题背景与意义
二、算法理论原理
三、模型训练
3.1 数据集
3.2 实验环境搭建
3.3 实验及结果分析
最后
前言 📅大四是整个大学期间最忙碌的时光,一边要忙着备考或实习为毕业后面临的就业升学做准备,一边要为毕业设计耗费大量精力。近几年各个学校要求的毕设项目越来越难,有不少课题是研究生级别难度的,对本科同学来说是充满挑战。为帮助大家顺利通过和节省时间与精力投入到更重要的就业和考试中去,学长分享优质的选题经验和毕设项目与技术思路。
🚀对毕设有任何疑问都可以问学长哦!
选题指导:
最新最全计算机专业毕设选题精选推荐汇总
大家好,这里是海浪学长毕设专题,本次分享的课题是
🎯基于OCR的火车票信息识别
设计思路 一、课题背景与意义 目前国内火车站已全面实现购票实名制验证和上车前火车票机器验票。然而,火车票机器验票仅能验证票的合法性,需要通过人工方法确认持票人是否与身份证和票相符,这浪费了大量人力成本。同时,火车票机器验票具有劳动强度高和识别率低的缺点。通过将卷积神经网络与推荐方法相结合,提高了图像特征提取的准确度,但性能却明显下降。因此,如何改进图像识别技术算法,提高识别正确率的同时不影响性能,成为当前研究的热点。
二、算法理论原理 对于火车票的重点识别项目,主要步骤包括以下几个方面:
图像预处理:对火车票图像进行预处理,包括去噪、图像增强、调整图像大小等操作,以便更好地提取票面信息。
票面字符提取:使用图像处理和光学字符识别(OCR)技术,将火车票图像中的字符提取出来,包括车次、日期、出发站、到达站等关键信息。
关键字符筛选:根据预先定义的规则和模式,对提取到的字符进行筛选,选择出与火车票识别相关的关键字符,如车次号码、日期等。
火车票核心特征项提取:从关键字符中提取出火车票的核心特征项,如出发站、到达站、车次号码、座位号等。
火车票识别扩张:通过对核心特征项进行进一步的识别和解析,可以扩展识别结果,如识别出具体的城市名称、车次类型、车票类型等详细信息。
这些步骤结合了图像处理、字符识别和规则匹配等技术,可以实现对火车票的准确识别和信息提取。通过这些步骤,可以有效地获取火车票的关键信息,提高识别的准确性和效率。为减少计算量并提高运算速度,可以通过准确确定身份证号码所在区域来进行局部自适应阈值分割。身份证号码所在区域可以用一个矩形RECT((Lx, Ly), (Rx, Ry))表示,其中(Lx, Ly)为矩形的左上角坐标,(Rx, Ry)为矩形的右下角坐标。
通过以下步骤可以实现准确确定身份证号码所在区域:
预处理:对火车票图像进行预处理,包括去噪、图像增强等操作,以便更好地提取身份证号码区域。文字检测:利用文字检测算法,如基于深度学习的文本检测模型,对火车票图像进行文字检测,以找到可能包含身份证号码的文本区域。区域定位:根据检测到的文本区域,计算矩形的左上角坐标(Lx, Ly)和右下角坐标(Rx, Ry),将其表示为一个矩形,框出身份证号码所在的区域。局部自适应阈值分割:在身份证号码区域内,应用局部自适应阈值分割算法,如基于局部像素均值的自适应阈值分割,将身份证号码从背景中分离出来,提高识别的准确性。 基于BP神经网络的字符识别是一种通过训练神经网络来学习字符的特征和模式,实现字符准确识别的方法。通过准备数据集、提取特征、设计网络结构、训练网络并进行测试评估,可以不断优化网络参数和提高识别准确性。这种方法具有较好的可扩展性和泛化能力,可以应对不同字符类型和复杂度的识别任务,扩充字符识别的应用范围和提高识别准确率。
采用粒子群算法和神经网络算法的结合,对火车票识别问题具有重要的扩展作用。粒子群算法的全局搜索能力能够帮助神经网络在更大的参数空间中快速寻找最优解,进而改善神经网络算法收敛速度慢的问题。此外,粒子群算法的群体智能特性有助于避免神经网络陷入局部最优解,提高整体性能。
通过粒子群算法优化神经网络的参数,可以进一步优化网络结构和权重,提高火车票识别的准确性和鲁棒性。粒子群算法通过在搜索空间中迭代更新粒子的位置和速度,找到最佳解决方案,并将其应用于神经网络的参数优化过程中。这种组合方法不仅能够加快收敛速度,还能够更好地探索参数空间,进一步提高识别的性能和准确度。
三、模型训练 3.1 数据集 由于网络上缺乏合适的火车票信息识别数据集,我决定采取多种方式自制数据集。首先,我使用网络爬虫技术从各大火车票售卖网站收集了大量火车票图片和相关信息。然后,我利用手机进行现场拍摄,捕捉真实的车票场景和各种票据样本,包括不同字体、不同布局和不同质量的票据。这个自制的数据集将包含丰富多样的火车票图片和对应的标注信息,为火车票信息识别研究提供更准确、可靠的数据基础。我相信这个数据集的创造将为火车票信息识别领域的研究提供有力支持,并为相关技术的发展做出积极贡献。
在创建火车票信息识别自制数据集时,我还采用了数据增广技术来增加数据的多样性和鲁棒性。通过应用不同的数据增广方法,我能够生成更多的训练样本,提高模型的泛化能力。例如,我对采集到的火车票图片进行旋转、缩放、平移和镜像等操作,以模拟不同角度和尺度下的票据样本。此外,我还进行了光照变换、噪声添加和模糊处理等操作,以模拟现实中的图像变化和干扰。通过数据增广,我能够增加训练样本的数量和多样性,提高模型对各种情况下的火车票信息识别的准确性和稳健性。这种综合应用网络爬取和手机拍摄的数据,并结合数据增广技术,使得自制数据集更具代表性和实用性,为火车票信息识别的研究提供了更全面的支持。
3.2 实验环境搭建 电脑操作系统为Windows 7.0,搭载Intel Core i5处理器和8GB内存,同时使用Matlab 2015a作为软件平台。这样的配置提供了强大的计算能力和稳定的操作环境,适用于各种计算和数据处理任务。Windows 7.0作为操作系统提供了用户友好的界面和广泛的软件兼容性,使得系统易于使用和管理。Intel Core i5处理器的高性能和多核心架构,能够处理复杂的计算任务和并行计算。8GB的内存容量可以支持较大规模的数据处理和内存需求。
3.3 实验及结果分析 在每个训练步骤(epoch)中,模型的训练过程一般按以下步骤进行:
输入数据:将训练数据输入到模型中。对于图像数据,可以通过批量加载图像和相应的标签来组成一个训练批次。
前向传播:通过前向传播计算模型的输出。输入数据经过模型的各层进行计算和变换,最终得到模型的预测输出。
计算损失:将模型的输出与真实标签进行比较,计算损失值(loss)。损失函数衡量了模型预测结果与真实标签之间的差异程度。
反向传播:使用反向传播算法计算损失函数对模型参数的梯度。梯度表示了损失函数对模型参数的变化敏感程度,通过梯度可以知道应该如何更新参数来减小损失。
参数更新:根据梯度和优化算法,更新模型的参数。常见的优化算法如随机梯度下降(SGD)、Adam等。优化算法根据梯度的方向和大小来更新模型参数,使得损失函数逐渐减小。
重复迭代:重复执行步骤2到步骤5,直到达到预定的训练轮次或模型收敛的条件。每次迭代都会更新模型的参数,使得模型逐渐适应训练数据,提高性能。
相关代码示例:
def preprocess_image(image): # 灰度化 gray = cv2.
补充说明 apt-get命令 是Debian Linux发行版中的APT软件包管理工具。所有基于Debian的发行都使用这个
包管理系统。deb包可以把一个应用的文件包在一起,大体就如同Windows上的安装文件。
语法 apt-get [OPTION] PACKAGE 选项 apt-get install 安装新包 apt-get remove 卸载已安装的包(保留配置文件) apt-get purge 卸载已安装的包(删除配置文件) apt-get update 更新软件包列表 apt-get upgrade 更新所有已安装的包 apt-get autoremove 卸载已不需要的包依赖 apt-get dist-upgrade 自动处理依赖包升级 apt-get autoclean 将已经删除了的软件包的.deb安装文件从硬盘中删除掉 apt-get clean 删除软件包的安装包 -c:指定配置文件。 参数 管理指令:对APT软件包的管理操作;软件包:指定要操纵的软件包。 实例 使用apt-get命令的第一步就是引入必需的软件库,Debian的软件库也就是所有Debian软件包的集
合,它们存在互联网上的一些公共站点上。把它们的地址加入,apt-get就能搜索到我们想要的软
件。/etc/apt/sources.list是存放这些地址列表的配置文件,其格式如下:
deb web或[ftp地址] [发行版名字] main/contrib/non-[free] 我们常用的Ubuntu就是一个基于Debian的发行,我们使用apt-get命令获取这个列表,以下是我整理
的常用命令:
在修改 /etc/apt/sources.list 或者 /etc/apt/preferences 之后运行该命令。此外您需要定期运行这一命令以确保您的软件包列表是最新的:
apt-get update 安装一个新软件包:
apt-get install packagename 卸载一个已安装的软件包(保留配置文件):
apt-get remove packagename 卸载一个已安装的软件包(删除配置文件):
apt-get –purge remove packagename 会把已装或已卸的软件都备份在硬盘上,所以如果需要空间的话,可以让这个命令来删除你已经删掉的软件:
6.1.9 蓝桥杯数学之素数筛 引言 在编程竞赛和算法设计中,寻找素数是一个常见且重要的任务。素数筛,尤其是埃拉托斯特尼筛法(埃氏筛)和线性筛,是两种高效寻找素数的方法。本文将介绍这些方法及其在蓝桥杯等编程竞赛中的应用。
埃拉托斯特尼筛法(埃氏筛) 埃拉托斯特尼筛法是最古老和最简单的素数筛选方法之一。
实现原理 创建一个布尔数组,初始时假设所有数都是素数。从第一个素数2开始,将所有2的倍数标记为非素数。继续到下一个未被标记的数,重复步骤2。进行到不超过所需范围的平方根为止。 C++ 实现 #include <iostream> #include <vector> using namespace std; vector<int> sieveOfEratosthenes(int n) { vector<bool> isPrime(n+1, true); vector<int> primes; isPrime[0] = isPrime[1] = false; for (int p = 2; p * p <= n; p++) { if (isPrime[p]) { for (int i = p * p; i <= n; i += p) { isPrime[i] = false; } } } for (int p = 2; p <= n; p++) { if (isPrime[p]) { primes.
nginx:反向代理+静态资源代理中间件;redis:缓存中间件;zookeeper:分布式协调中间件;kafka:消息中间件;rabbitmq:消息中间件;mysql:数据库中间件;elasticsearch:搜索引擎中间件;
stompcmd是一个用于与STOMP协议的消息队列服务器进行交互的命令行工具。要安装stompcmd,你需要确保你的系统上已经安装了Java运行时环境(JRE)或Java开发工具包(JDK)。
以下是安装stompcmd的一般步骤:
下载stompcmd的安装包。你可以从ActiveMQ的官方网站或其他可靠的源获取stompcmd的安装包。确保下载适用于你操作系统和架构的正确版本。解压安装包。将下载的安装包解压到你选择的目录中。配置环境变量。将stompcmd的路径添加到你的系统环境变量中,以便在命令行中访问stompcmd命令。具体方法取决于你的操作系统。验证安装。打开终端或命令提示符,并输入stompcmd -version来验证stompcmd是否正确安装并可用。如果一切正常,你应该能够看到stompcmd的版本信息。 请注意,以上步骤是一般性的指导,具体安装过程可能会因你的操作系统和环境而有所不同。确保按照适用于你的系统和环境的详细说明进行操作,并参考相关的文档或资源以获取更详细的指导。
🌞欢迎来到一起看论文
🌈博客主页:卿云阁
💌欢迎关注🎉点赞👍收藏⭐️留言📝
✉️希望可以和大家一起完成进阶之路!
🙏作者水平很有限,如果发现错误,请留言轰炸哦!万分感谢!
核心思想 DAT的核心思想主要包括以下几个方面:
可变形注意力(Deformable Attention):传统的Transformer使用标准的自注意力机制,这种机制会处理图像中的所有像素,导致计算量很大。而DAT引入了可变形注意力机制,它只关注图像中的一小部分关键区域。这种方法可以显著减少计算量,同时保持良好的性能。
动态采样点:在可变形注意力机制中,DAT动态地选择采样点,而不是固定地处理整个图像。这种动态选择机制使得模型可以更加集中地关注于那些对当前任务最重要的区域。
即插即用:DAT的设计允许它适应不同的图像大小和内容,使其在多种视觉任务中都能有效工作,如图像分类、对象检测等。
attention机制中的query,key,value Query、Key的作用是用来在token之间搬运信息的,而Value本身就是从当前token当中提取出来的信息。本质上都是 对X的线性变换。
本文提出了一种简单有效的可变形的自注意力模块,并在此模块上构造了一个强大的Pyramid Backbone,即可变形的注意力Transformer(Deformable Attention Transformer, DAT),用于图像分类和各种密集的预测任务。不同于DCN,在整个特征图上针对不同像素学习不同的offset,作者建议学习几组query无关的offset,将key和value移到重要区域(如图1(d)所示),这是针对不同query的全局注意力通常会导致几乎相同的注意力模式的观察结果。这种设计既保留了线性空间的复杂性,又为Transformer的主干引入了可变形的注意力模式。
具体来说:
对于每个注意力模块,首先将参考点生成为统一的网格,这些网格在输入数据中是相同的;
然后,offset网络将query特征作为输入,并为所有参考点生成相应的offset。这样一来,候选的key /value被转移到重要的区域,从而增强了原有的自注意力模块的灵活性和效率,从而捕获更多的信息特征。
本文提出了Deformable Attention,在特征映射中重要区域的引导下,有效地建模Token之间的关系。这些集中的regions由offset网络从query中学习到的多组Deformable sampling点确定。采用双线性插值对特征映射中的特征进行采样,然后将采样后的特征输入key投影得到Deformable Key。
给定输入特征图,生成一个点的统一网格作为一个token,利用Linear layer把我们的query做出来,query留着后面直接做attention。
用这个query做一个offset,(告诉我attention的范围是什么),原始的图像经过down sample,比如上图剩下了4个Reference Points,然后加上offsets,对Reference Points发生了移动,移动到相应的位置,然后在这个位置我们取它临近的4个token,然后经过线性插值操作,这些token叫做Sample Features,然后把插值出来的token送到我们的这个value projection,key projection有了query,key,value,然后一起做attention。由于我们时间上取的token的位置不是一个整数,所以position of embedding也要相应的变化,对其进行Relative Position Bias Offsets 操作,然后一起做attention操作。Offset,首先输入是H*W*C,这个是我们query的尺寸,经过stride=r的,卷积核大小的k*k的,DWConv,然后是激活函数,然后再做一个1*1的convolution,就是对每一个channel做MLP。
文章目录 前言Column 的含义Column 的使用给 Column 加边框Column 使用 verticalArrangement 定位子项位置Column 使用 horizontalAlignment 定位子组件位置Column 设置了大小,可使用Modifier.align修饰符设置子组件对齐方式 Row 的含义Row 的使用 总结 前言 传统的View中使用的线性布局是 LinearLayout,Compose根据纵向和横向的方向不同分为 Column 和 Row 两种组件
Column 的含义 Column 是一个垂直线性布局组件,可将子组件按顺序从上到下垂直排列
@Composable inline fun Column( modifier: Modifier = Modifier, //修饰符 verticalArrangement: Arrangement.Vertical = Arrangement.Top, //垂直位置 horizontalAlignment: Alignment.Horizontal = Alignment.Start, //水平位置 content: @Composable ColumnScope.() -> Unit //垂直作用域 ) 注:Column 默认 垂直位置靠上,水平位置靠左
Column 的使用 Column{ Text(text = "Hello,World", style = MaterialTheme.typography.titleMedium) Text(text = "Jetpack Compose"
查看苹果手机,连wifi后的ip地址
电脑去ping 手机的ip地址,发现ping不通
解决方案:
应该是酒店wifi的问题,让朋友开个手机热点,电脑和我的手机都连这个热点,就可以抓包了
Nacos 先来一个注意:以下涉及到配置和项目的创建,我的jdk是jdk17,idea是2023.2.4,并且是社区版的idea
1.什么是Nacos Nacos是Dyamic Naming and Configuration Service的首字母简称,一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。Nacos致力于帮助我们发现、配置和管理微服务。Nacos提供了一组简单易用的特性集,帮助我们快速实现动态服务发现,服务配置,服务元数据及流量管理。Nacos帮助我们更敏捷和容易的构建、交付和管理微服务平台。Nacos是构建以“服务”为中心的现代应用架构。
2.上面的话我想你听了肯定还很摸棱两可,下面我用通俗易懂的话来解释一下!!! 想象一下,你是一个指挥家,负责指挥一个由许多乐器组成的交响乐团。每个乐器就像是一个微服务,它们各自演奏自己的部分,但需要协调一致才能演奏出美妙的音乐。在这个比喻中,Nacos 就像是你的助手,帮助你管理这些乐器(微服务)。
服务发现和管理:就好比乐器需要知道何时该演奏,何时该停止。Nacos 会告诉每个微服务(乐器)其他服务(乐器)的位置和状态,确保它们能够协调一致地工作。
配置管理:想象一下,如果乐团中某个部分的演奏风格或速度需要改变,你需要通知到相关的乐器。Nacos 允许你轻松地调整和传达这些改变(配置),确保每个微服务都按照最新的要求来执行。
服务健康监测:这就像确保每个乐器都能正常演奏,没有出现问题。Nacos 不断检查每个微服务的健康状态,如果发现问题,就会及时通知,确保整个系统的稳定运行。
所以,Nacos 基本上是在帮助你指挥这个庞大的微服务交响乐团,确保每个部分都能和谐地工作,最终演奏出美妙的“音乐”(即流畅、高效的应用程序)
3.Nacos功能 Nacos主要功能主要有以下两个
1.配置中心
2.注册中心
3.1配置中心 配置中心是一种集中化管理配置的服务,它的主要作用主要有以下几个:
1.集中管理配置信息:配置中心将不同服务的配置信息集中放在一起进行管理,实现了配置信息的集中存储
2.动态更新配置:配置中心的配置信息可以通过操作界面或者API进行动态更新,无需重启服务就可以应用到最新的配置信息
3.配置信息共享:将配置集中在配置中心中,不同的服务实例可以共享同一套配置信息
4.配置信息安全:配置中心可以对配置信息提供安全管理,权限控制等管理功能
5.信息追溯:指出配置版本管理,历史记录等管理功能
下面我来对上面五条用人话解释
集中管理配置信息:
比方说,你有一个在线购物应用,其中包含用户服务、订单服务和支付服务等微服务。每个服务都有自己的配置信息,例如数据库连接、缓存设置等。通过配置中心,你可以将这些服务的配置信息集中存放和管理,而不是分散在各个服务中。
动态更新配置:
假设你的购物应用需要更改支付服务的某个参数,比如交易超时时间。通过配置中心,你可以直接更新这个参数,而不需要重启支付服务。服务会自动获取最新的配置并应用更改。
配置信息共享:
如果你的购物应用的多个服务都需要访问相同的数据库,你可以在配置中心设置数据库连接信息。这样,所有服务都可以共享这一配置,而无需在每个服务中单独配置数据库信息。
配置信息安全:
在配置中心,你可以设置权限,以确保只有授权的人员能够访问和修改配置信息。比如,你可能只允许高级开发人员修改数据库的连接字符串,以防止未授权的更改。
信息追溯:
假设你更新了购物应用中某个服务的配置,但这导致了一些问题。通过配置中心的版本管理和历史记录功能,你可以轻松查看哪些更改被做了,并且回滚到之前的配置版本,恢复服务的正常运行。
3.2注册中心 注册中心是微服务架构一个重要的组件,用于实现服务的注册与发现,注册中心的主要作用包括以下几个:
1.服务注册: 服务实例启动的时候,将自身信息注册到注册中心,包括服务名称、地址、端口等。
2.服务发现: 消费者向注册中心查询服务,并获取服务实例来访问服务
3.服务健康检查: 注册中心定期检查服务实例健康情况,过滤不健康实例
4.服务路由: 提供服务的路由与负载均衡功能
5.服务监控: 统计服务调用次数,时长等,用于监控服务状态
6.服务更新: 当服务实例信息变更时,向注册中心发送更新信息通知
人话解释
服务注册:
假设你有一个在线书店应用,其中包含一个"书籍搜索服务"。当这个服务启动时,它会向Nacos注册中心注册自己的信息,如服务名称是"book-search-service",地址可能是"192.168.1.5",端口是8080。这样,注册中心就知道了这个服务的存在和如何访问它。
服务发现:
在同一个在线书店应用中,假设有一个"用户界面服务"需要调用"书籍搜索服务"来显示书籍数据。"用户界面服务"会询问Nacos注册中心"书籍搜索服务"的位置,注册中心返回"书籍搜索服务"的地址和端口,然后"用户界面服务"可以直接调用该服务。
服务健康检查:
Nacos定期检查"书籍搜索服务"是否正常运行,例如通过发送心跳信号或进行实际的服务调用。如果服务没有响应或响应时间过长,Nacos会认为这个实例不健康,并从可用服务列表中移除它。
服务路由和负载均衡:
假设"书籍搜索服务"有多个实例运行在不同的服务器上。当"用户界面服务"请求"书籍搜索服务"时,Nacos根据设定的路由策略(如轮询、最少连接等)决定应该将请求发送到哪个实例,实现负载均衡。
服务监控:
Nacos可以记录每次对"书籍搜索服务"的调用次数、响应时间等信息。这些数据可以用于监控服务的性能、发现潜在的问题或进行容量规划。
服务更新:
如果"书籍搜索服务"的某个实例因为升级或维护改变了其地址或端口,该实例会向Nacos发送更新信息。Nacos注册中心会更新其记录,确保其他服务能够获取到最新的访问信息。
4.Nacos优点 1.
文章目录 1. 简介2. 预备条件3. 安装 helm4. 安装 cert-manager4.1 yaml 安装4.2 helm 安装 5. 安装 rancher6. 验证7. 界面预览版本 1. 简介 Rancher 是一个 Kubernetes 管理工具,让你能在任何地方和任何提供商上部署和运行集群。
Rancher 可以创建来自 Kubernetes 托管服务提供商的集群,创建节点并安装 Kubernetes,或者导入在任何地方运行的现有 Kubernetes 集群。
Rancher 基于 Kubernetes 添加了新的功能,包括统一所有集群的身份验证和 RBAC,让系统管理员从一个位置控制全部集群的访问。
此外,Rancher 可以为集群和资源提供更精细的监控和告警,将日志发送到外部提供商,并通过应用商店(Application Catalog)直接集成 Helm。如果你拥有外部 CI/CD 系统,你可以将其与 Rancher 对接。没有的话,你也可以使用 Rancher 提供的 Fleet 自动部署和升级工作负载。
Rancher 是一个 全栈式 的 Kubernetes 容器管理平台,为你提供在任何地方都能成功运行 Kubernetes 的工具。
2. 预备条件 安装 kubernetes ,这里我选择 rke2 方式 3. 安装 helm wget https://get.helm.sh/helm-v3.13.3-linux-amd64.tar.gz tar -xzvf helm-v3.
🌞欢迎来到带你读论文 🌈博客主页:卿云阁
💌欢迎关注🎉点赞👍收藏⭐️留言📝
🌟本文由卿云阁原创!
📆首发时间:🌹2024年1月28日🌹
✉️希望可以和大家一起完成进阶之路!
🙏作者水平很有限,如果发现错误,请留言轰炸哦!万分感谢!
[1]github源码 Deformable-ConvNets
[2]论文 Deformable Convolutional Networks
Deformable convolution 文章提出了可变卷积,添加了位移变量,这个变量根据数据的情况学习,偏移后,相当于卷积核每个方块可伸缩的变化,从而改变了感受野的范围,感受野成了一个多边形。
(a)是普通的卷积,卷积核大小为3*3,采样点排列非常规则,是一个正方形。
(b)是可变形的卷积,给每个采样点加一个offset(这个offset通过额外的卷积层学习得到),排列变得不规则。
(c)和(d)是可变形卷积的两种特例。
(c)加上offset,达到尺度变换的效果
(d)加上offset,达到旋转变换的效果。
传统的卷积结构可以定义成公式1,其中是输出特征图的每个点,与卷积核中心点对应,假设我们有一个像素p0,pn是p0在卷积核范围内的每个偏移量。
可变形卷积则在上述公式1的基础上为每个点引入了一个偏移量,偏移量是由输入特征图与另一个卷积生成的,通常是小数。
由于加入偏移量后的位置非整数,并不对应feature map上实际存在的像素点,因此需要使用插值来得到偏移后的像素值,通常可采用双线性插值,用公式表示如下:将插值点位置的像素值设为其4领域像素点的加权和,领域4个点是离其最近的在特征图上实际存在的像素点,每个点的权重则根据它与插值点横、纵坐标的距离来设置,公式最后一行的max(0, 1-...)就是限制了插值点与领域点不会超过1个像素的距离。
额外的conv层来学习offset,共享input feature maps。然后input feature maps和offset共同作为deformable conv层的输入,deformable conv层操作采样点发生偏移,再进行卷积。
Deformable RoI pooling RoI pooling是把不同大小的RoI(w*h)对应的feature map 统一到固定的大小(k x k)。
pooling则是先对RoI对应的每个bin按照RoI的长宽比例的倍数进行整体偏移(同样偏移后的位置是小数,使用双线性差值来求),然后再pooling。
由于按照RoI长宽比例进行水平和竖直方向偏移,因此每一个bin的偏移量只需要一个参数来表示,具体可以用全连接来实现。
6.1.8 蓝桥杯数学之欧拉函数&欧拉降幂 引言 在编程竞赛中,欧拉函数和欧拉降幂是解决一系列数论问题的关键工具。欧拉函数用于衡量与某个正整数互质的数的数量,而欧拉降幂则利用欧拉函数来简化大幂次运算。本文将探讨这两个概念及其在蓝桥杯等编程竞赛中的应用。
欧拉函数 (Euler's Totient Function) 欧拉函数 ϕ(n) 表示小于或等于 n 的正整数中与 n 互质的数的数量。
计算公式 欧拉函数可以通过以下公式计算:
其中,p1,p2,…,pk 是 n 的所有不同的素因子。
实现 在 C++ 中,可以通过以下方式实现欧拉函数:
#include <iostream> using namespace std; int eulerTotient(int n) { int result = n; for (int p = 2; p * p <= n; ++p) { if (n % p == 0) { while (n % p == 0) n /= p; result -= result / p; } } if (n > 1) result -= result / n; return result; } int main() { int number; cout << "
基本概念 术语 文档(document):每条记录就是一个文档,会以 JSON 格式进行存储
映射(mapping):索引中文档字段的约束信息,类似 RDBMS 中的表结构约束(schema)词条(term):对文档内容分词得到的词语,是索引里面最小的存储和查询单元词典(term dictionary):由文本集合中出现过的所有词条所组成的集合词条索引(term Index):为了在词典中快速找到某个词条,需要为词条建立索引。通过压缩算法,词条索引的大小只有所有词条的几十分之一,因此词条索引可以存储在内存中,从而提供更快的查找速度倒排表(posting list):记录词条出现在哪些文档里,以及出现的位置和频率等信息。倒排表中的每条记录称为一个倒排项(posting)索引(index):相同类型(文档结构)的文档集合 索引前的文档集合:
索引后的文档集合:
8.
比较 RDBMS vs ES
使用场景:MySQL 擅长于事务类型操作,可以确保数据的安全性和一致性;ES 则擅长于海量数据的检索、分析与计算。 MySQL + ES 组合使用架构:
语法 DDL 类型 注意:index 默认为 true,即 ES 会默认给设置的字段设置倒排索引,如无需设置倒排索引需要手动设置为 false
语法示例 PUT /索引库名称 { "mappings": { // 定义 schema "properties": { // schema 的具体字段极其类型说明 "字段1": { "type": "text" "analyzer": "ik_smart" }, "字段2": { "type": "keyword", "index": false }, "字段3": { "type": "object", "properties": { // 嵌套字段 "
实现集群主从缩容【4/4】 接上一节,在当前机器为4主4从的架构上,减缩容量为3主3从架构。即实现删除6387和6388.
示意图如下:
第一步:查看集群情况(第一次)
redis-cli --cluster check 127.0.0.1:6387 root@localhost:/data# redis-cli --cluster check 127.0.0.1:6387 127.0.0.1:6387 (bf73145e...) -> 1 keys | 4096 slots | 1 slaves. 122.114.161.116:6381 (6e961a47...) -> 1 keys | 4096 slots | 1 slaves. 122.114.161.116:6383 (78ac7be1...) -> 1 keys | 4096 slots | 1 slaves. 122.114.161.116:6382 (f097fec9...) -> 1 keys | 4096 slots | 1 slaves. [OK] 4 keys in 4 masters. 0.00 keys per slot on average. >>> Performing Cluster Check (using node 127.
CSS过渡(Transitions)是CSS3中的一个特性,允许你在CSS属性值之间添加过渡效果,使得元素样式的变化看起来更平滑、更自然。通过CSS过渡,你可以在一定的时间内逐渐改变CSS属性的值,而不是瞬间变化,从而创建出动画效果。
基本语法 CSS过渡主要通过以下四个属性来定义:
transition-property:指定应用过渡效果的CSS属性名称。如果要对所有可过渡的属性应用相同的过渡效果,可以使用all关键字。
transition-duration:定义过渡效果持续的时间,以秒(s)或毫秒(ms)为单位。
transition-timing-function:定义过渡效果的时间曲线,即速度如何随时间变化。常见的值有linear、ease、ease-in、ease-out和ease-in-out,也可以使用cubic-bezier函数自定义。
transition-delay:定义过渡效果何时开始,即从元素样式发生变化到过渡效果开始的这段时间。
示例 /* 对背景颜色应用过渡效果 */ div { width: 100px; height: 100px; background-color: blue; transition-property: background-color; transition-duration: 2s; transition-timing-function: ease-in-out; transition-delay: 1s; } /* 当鼠标悬停时改变背景颜色 */ div:hover { background-color: red; } 在这个示例中,div元素的背景颜色在鼠标悬停时会在3秒内从蓝色平滑过渡到红色,过渡开始前有1秒的延迟。
简写形式 所有的过渡属性都可以在transition属性中进行简写:
div { transition: background-color 2s ease-in-out 1s; } 如果需要对多个属性应用过渡效果,可以在transition属性中列出多组值,每组值之间用逗号分隔:
div { transition: background-color 2s ease-in-out, width 2s ease-in-out; } 注意事项 并不是所有的CSS属性都可以应用过渡效果。一般来说,只有数值和颜色的CSS属性可以过渡,例如width、height、opacity和background-color等。过渡效果依赖于元素样式的改变触发,常见的触发方式有伪类(如:hover)、JavaScript修改样式等。过度使用过渡效果可能会导致性能问题,尤其是在移动设备或性能较差的设备上。 通过合理使用CSS过渡,你可以为Web页面添加吸引人的视觉效果,提升用户体验。然而,要注意过渡效果的使用场景和性能影响,确保它们为用户带来正面的影响。
如果你想通过Shell脚本将ActiveMQ中的Topic消息从一个服务器转发到另一个服务器,你可以使用stomp命令行工具来实现。
以下是一个示例脚本,演示如何使用Shell脚本将ActiveMQ中的Topic消息从一个服务器转发到另一个服务器:
#!/bin/bash # 源ActiveMQ服务器的连接参数 SOURCE_ACTIVEMQ_HOST="source_activemq_host" SOURCE_ACTIVEMQ_PORT=1099 SOURCE_TOPIC_NAME="source_topic" # 目标ActiveMQ服务器的连接参数 TARGET_ACTIVEMQ_HOST="target_activemq_host" TARGET_ACTIVEMQ_PORT=1099 TARGET_TOPIC_NAME="target_topic" # 连接到源ActiveMQ服务器并获取消息 stompcmd -H $SOURCE_ACTIVEMQ_HOST:$SOURCE_ACTIVEMQ_PORT -e subscribe -id SUB -to $SOURCE_TOPIC_NAME | while read line; do # 将消息发送到目标ActiveMQ服务器 echo "$line" | stompcmd -H $TARGET_ACTIVEMQ_HOST:$TARGET_ACTIVEMQ_PORT -e send -to $TARGET_TOPIC_NAME done 在上面的示例中,我们使用stompcmd命令行工具连接到源ActiveMQ服务器,并通过订阅源Topic来获取消息。然后,我们通过管道将获取到的消息传递给另一个stompcmd命令行工具,将其发送到目标ActiveMQ服务器的目标Topic。
你需要将SOURCE_ACTIVEMQ_HOST、SOURCE_ACTIVEMQ_PORT、SOURCE_TOPIC_NAME、TARGET_ACTIVEMQ_HOST、TARGET_ACTIVEMQ_PORT和TARGET_TOPIC_NAME替换为你实际的ActiveMQ服务器连接参数。
请注意,这只是一个简单的示例,实际的实现可能更加复杂,取决于你使用的具体消息队列系统和协议。你需要根据你使用的消息队列系统的文档和要求进行相应的调整和修改。
年底了公司的事情特别多,基本上没有更新博客信息。今天稍微空了点,陆续为为大家介绍Java web项目,今天要介绍的是一个基于SpringBoot+Vue开发的小程序考试系统、整个系统属于中等难度级别的项目,合适于课程设计或者毕业设计。小程序考试系统分学生、家长、系统管理员三种用户类型。学生、家长主要通过小程序来完成相关的操作;管理员通过web来进行日常的管理的操作。学生的主要功能有:在线练习、在线考试、错题本;家长的功能:学生绑定、学生成绩查看;系统管理员的功能:管理员登陆、新闻公告管理、考试管理、题库管理、用户管理、管理员管理、权限管理、答题排行。整个系统界面漂亮,特别是答题面板设计上用了大量的时间,整个系统有完整源码,可以直接用于课程设计或者毕业设计。希望大家可以喜欢。喜欢的帮忙点赞和关注。一起编程、一起进步。
软件架构 Spring Boot和Vue.js是两个不同的技术栈,分别用于构建后端和前端应用程序。
Spring Boot是一个用于构建Java应用程序的开发框架,它通过约定大于配置的原则简化了Spring应用程序的创建和开发过程。Spring Boot集成了大量常用的第三方库和工具,使得开发者可以快速地构建健壮、安全和易于维护的应用程序。
Vue.js是一个用于构建用户界面的渐进式JavaScript框架,它提供了一套开发规则,使得开发者可以提高开发效率。Vue.js通过组件化的方式将应用程序分解为可复用的组件,使得应用程序的维护和扩展变得更加容易。
后端(Spring Boot):
用户请求通过Nginx或Node.js等前端服务器进行代理和转发。Spring Boot应用程序负责处理业务逻辑、数据持久化和安全控制等后端功能。通过RESTful API与前端进行数据交互,返回JSON格式的数据。可以使用MySQL或其他关系型数据库作为数据存储。 前端(Vue.js):
通过Ajax或Fetch等技术向后端发送请求,获取数据并进行展示。使用Vue Router进行页面路由管理。使用Vuex进行状态管理。通过组件化的方式构建用户界面,每个组件可以独立开发和测试。可以使用Element UI、Vuetify等UI框架提高开发效率。 这种架构可以实现前后端分离,前后端可以独立开发和部署,降低了系统的耦合度,提高了开发效率和可维护性。同时,前端和后端可以使用不同的技术和框架,只要遵循相同的API规范即可实现数据的交互和通信。实现原理如下图:
系统主要功能 小程序考试系统分学生、家长、系统管理员三种用户类型。学生、家长主要通过小程序来完成相关的操作;管理员通过web来进行日常的管理的操作。学生的主要功能有:在线练习、在线考试、错题本;家长的功能:学生绑定、学生成绩查看;系统管理员的功能:管理员登陆、新闻公告管理、考试管理、题库管理、用户管理、管理员管理、权限管理、答题排行。整个系统的功能架构图如下图所示:
实现效果 (一) 管理员效果 1 管理员登陆 2 管理员主界面 3 用户管理 4 考试管理 5 题库管理 6 权限管理 7 答题排行 (二) 小程序效果 8 小程序端开始界面 9 小程序主界面 10 在线考试 11 查看答题面板 12 查看答题情况 13 答题结果面板 14 家长登陆 15 查看孩子学习情况 16 查看学习情况
关键代码 @RequestMapping("/decodeOpenid") @ResponseBody public JSONObject decodeOpenid(HttpServletResponse response, @RequestParam String code){ response.setContentType("text/html;charset=UTF-8"); response.
Guava库提供了丰富的集合类API,这些API扩展了Java标准库中的集合功能,提供了更多的灵活性和便利性。
在日常开发中,集合类是我们日常编程不可或缺的一部分。Java标准库为我们提供了一套基本的集合类,但在实际项目中,我们往往需要更加灵活和强大的集合功能。这时,Google的Guava库便成为了我们的得力助手。Guava库扩展了Java的集合类,提供了一系列高效、实用且易于使用的集合API。在本文中,我们将深入探索Guava库中常用的集合类API,并了解它们如何提升我们的开发效率。
不可变集合:守护数据的永恒之石 首先,我们要介绍的是Guava提供的不可变集合。在编程中,有时我们需要创建一些一旦初始化就不会再更改的集合。这些集合被称为不可变集合。Guava为我们提供了ImmutableList、ImmutableSet和ImmutableMap等不可变集合的实现。这些集合在创建时确定了内容,并且保证了之后无法修改。这种不可变性带来了诸多好处,比如线程安全、减少错误和提高代码可读性。当你需要一个不会变动的集合时,Guava的不可变集合将是你的最佳选择。
其他API敬请期待后续文章
1. ImmutableList 一个不可变的列表实现,提供了与Java List接口类似的方法,但保证了列表内容不可更改。
2. ImmutableSet 一个不可变的集合实现,与Java Set接口类似,但不允许添加或删除元素。
3. ImmutableMap 一个不可变的映射实现,类似于Java的Map接口,但键值对是固定的,无法修改。
这些不可变集合在创建时确定内容,之后不可更改,有助于编写线程安全的代码。
在pom.xml中添加如下依赖:
<dependency> <groupId>com.google.guava</groupId> <artifactId>guava</artifactId> <version>31.0.1-jre</version> <!-- 请检查是否有更新的版本 --> </dependency> 然后,在你的Java代码中使用这些不可变集合:
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableMap; public class GuavaImmutableCollectionsExample { public static void main(String[] args) { // 创建一个ImmutableList ImmutableList<String> immutableList = ImmutableList.of("Apple", "Banana", "Cherry"); System.out.println("ImmutableList: " + immutableList); // 尝试修改ImmutableList(这将导致编译时错误) // immutableList.add("Date"); // 这行代码将无法编译 // 创建一个ImmutableSet ImmutableSet<Integer> immutableSet = ImmutableSet.of(1, 2, 3, 4, 5); System.
空洞骑士是一款基于横板平台跳跃的传统风格2D动作冒险游戏。庞大的游戏世界交错相通,玩家控制小虫子去探索幽深黑暗的洞穴,成为了一代人茶余饭后的惦念,深受广大玩家们的喜爱。
这类平台跳跃游戏一般是游戏开发初学者以及独立游戏开发者们比较青睐的类型,也是诸多开发者们开发游戏Demo的第一站。
为了让更多的游戏开发者们能够做出自己心中想要的平台跳跃游戏Demo,今天我们讲解如何使用Unity3D引擎制作此类游戏。
我们需要掌握以下三项基本的游戏开发技术。
1、角色操控以及手感优化的技术要点
2、角色的四方向射线检测的技术要点
3、各种平台的技术要点
一、角色操控以及手感优化的技术要点
这里我们涉及到引擎如何控制一个游戏物体完成移动的知识。
对于Unity3D引擎来说,移动一个物体的核心原理是每一帧更新物体在3D坐标系中的位置。
对于横板游戏来说,我们关注的是水平方向和垂直方向的移动,而对于Z轴纵深方向的移动,除了某些特殊情况外,角色部分基本不需要考虑。
而对于移动而言,我们可以使用基本的平移方法Translate来完成移动,也可以通过更新Transform、Postion来完成移动。同样可以通过对角色对象添加刚体组件Rigidbody,然后通过设置刚体组件的velocity属性来完成移动。
当然你也可以通过使用Unity引擎提供的角色控制器CharacterController 完成对角色移动的控制。还有一些提供移动方法的插件这里就不做过多的赘述。
面对众多的移动选择,该选择哪一种成了初学者们最容易头疼的地方。由于刚体和角色控制器都自带了碰撞检测,所以很多同学会选择这两者之一作为2D平台跳跃移动的方式。
许多游戏开发者在游戏开发到中后期时往往会遇到很多棘手的问题。开发者们为了维护和修改这些问题往往付出了非常巨大的代价和精力,却始终没有办法从根本解决问题。这就导致了很多游戏最终无法开发完成,开发者为此也付出了高昂的学习成本。
所以这里我们推荐大家使用最基本的Translate方法来完成移动。因为它足够简单,没有过多的牵连,可以为开发者们提供最大程度的可操作空间。
同时,因为刚体组件和角色控制器会涉及到一定的引擎物理,而平台跳跃游戏中产生的物理情况,大部分并非模拟现实的物理情况,所以我们需要自己来为它开发相关的物理部分。
这时使用引擎自带的物理反而会产生很多的不可控问题,导致意外情况的增加。因为Translate方法本身没有自带碰撞检测,所以我们还需要提供一些可维护性以及可控制性强的物理检测方法。
来看看下图中的方法:
这里我们使用射线检测的方式来完成,这个方法包括但不限于撞墙检测、脚下地面检测、头顶碰撞检测、穿越平台检测、爬坡检测等。
这里使用角色控制器的同学可能遇到过类似跳跃失败、爬坡控制性不强的问题,出现这个问题的具体原因上面已经做过阐述。
二、角色的四方向射线检测的技术要点
这里主要的技术要点在于为了达到精确检测和掌控力更强的控制碰撞。平台跳跃类游戏一般不会使用Unity3D自带的刚体及碰撞器来完成各项碰撞检测,取而代之的是使用基础射线。
为了能够检测角色脚下、头顶、前后方是否碰撞各类平台以及怪物、道具等,我们需要搭建一个健壮的射线检测基础架构。这里需要注意的技术要点有:射线检测的数量、检测的时机、检测的层、检测的起点、方向以及长度等。可以帮助我们完成游戏中需要的各项检测,同时能够达到非常精确的控制以及按需检测等多项好处,是同学对于平台类游戏碰撞检测的必学核心技术点之一。
三、各种平台的技术要点
最后我们说说游戏中各项平台的功能。横板跳跃游戏中,平台分为基础平台、可向下穿越平台、可移动平台等类型;又可以组合出可移动基础平台、可移动向下穿越平台、不可移动基础平台和不可移动向下穿越平台等多种类型的平台。
在要点二中我们可以知道,对于角色检测平台,一定离不开射线的辅助。而平台的制作,主要是基于平台的位置和位移,来精确的修正角色的位置和位移。比如在落到平台时,角色需要精确的修正Y轴坐标为平台接触点坐标,而跳起来顶到头上的平台时,需要修正坐标为接触点坐标减去角色碰撞器高度等。
对于移动平台,初学者容易进入一个误区,就是让角色成为平台的子物体以帮助角色在平台移动。而这样操作的结果是丧失了精确性,容易产生更多bug,并且不符合我们的框架设计原理。
正确的做法是通过每帧修复角色的位移,让角色位置能够叠加平台的移动方向的速度产生的位移以及角色自身控制产生的位移,这样才能够在统一的框架下完成精确的处理。
关于2D平台跳跃游戏的技术点我们就分析到这里,为了让喜欢游戏开发的小伙伴能尽早开发出自己的《空洞骑士》类游戏Demo,我们开设了《3D版空洞骑士》4天训练营,让大家从0做出一款游戏Demo。扫描下方二维码回复[空洞骑士]即可免费参与
独立游戏开发,能赚到钱吗? 近年来,移动互联网的发展使独立游戏得以高速增长。一批富有创造力的开发者通过移动平台推出了大量独具个性的游戏。但他们同时面临资源有限的困境,如何实现商业化运营成为需要解决的难题。为此,本文将深入剖析独立游戏的商业化路径,并给出提升商业化水平的建议。
01 独立游戏概述 A .什么是独立游戏
独立游戏是由个人或小团队自主研发和发行的游戏。相比大公司开发的游戏,独立游戏的开发团队很小,通常只有个人或几个人,没有几百人的大团队。独立游戏开发者可以完全根据自己的想法来决定游戏的风格和内容,不受其他公司影响。另外,独立游戏的开发资金也比较有限,主要靠开发者自己解决。但是独立游戏开发者更有创造力,他们的游戏追求独特的游戏体验,有很强的自主性。独立游戏更注重内容和玩法。所以独立游戏是游戏行业很重要的一部分。
B .独立游戏的特点
与大公司开发的游戏相比,独立游戏开发者可以自己决定想做什么游戏,不用听别人的。另外,独立游戏也没有大公司那么多钱投入开发,开发者主要靠自己的能力。但是,独立游戏开发者有很强的创造力,他们的游戏往往比较新颖,玩法有创新。总的来说,独立游戏开发者可以自由地开发有创意的游戏,这是它最大的特点。
了解了什么是独立游戏及其特点后,接下来看看独立游戏的盈利方式。
02 独立游戏盈利方式 独立游戏要实现盈利,主要可以通过以下几种方式:
A .移动应用商店销售
移动平台拥有广阔的用户群体基础,这为独立游戏提供了足够的潜在用户。相比传统游戏发行,移动应用商店降低了发布门槛,让独立开发者很容易就能把游戏推向市场。与此同时,移动游戏的类型多样,契合移动平台的快节奏特点,这使得独立开发者可以选择合适的题材来开发游戏。在商业模式上,移动平台用户更容易接受付费下载的商业模式,这为独立游戏带来了直接的收入。可以说,正是移动平台的用户基础效应、发布的便捷性、游戏类型的契合度、以及直接的盈利模式,共同促成了移动应用商店销售成为独立游戏实现盈利的重要渠道。
B .Steam平台销售
在Steam上,开发者可以方便地自主发布和推广自己的游戏,不需要经过中间商。另外,拥有高知名度的Steam可以更容易让玩家接受和信任独立游戏。在游戏价格上,Steam也支持灵活的定价策略,独立开发者可以根据情况合理定价。平台上还会不时举办打折促销活动,吸引更多新玩家。总之,Steam提供的强大玩家群体、自主发行机制、品牌效应等都使其成为独立游戏实现盈利的重要平台。
C .游戏内广告
在游戏中投放广告是一种流行的盈利方式,特别是在移动平台上。广告商会根据广告曝光量(即有多少玩家看到了他们的广告)而非点击或销售量来支付费用。广告类型包括激励式广告、插屏广告、横幅广告和原生广告。
尽管独立游戏有多种盈利方式,但在商业化过程中仍面临诸多困境。
03 独立游戏商业化困境 01
有限的资源:
相对于大型游戏工作室,独立开发者可能拥有更少的预算和资源。这可能会影响游戏的质量和开发时间。为了克服这个挑战,独立开发者需要寻找创造性的方法来最大限度地利用他们的资源,例如使用免费的开源工具来创建高质量的图形和声音。
02
营销难题:
与大型工作室相比,独立开发者可能没有足够的营销资源或专业的营销人员。因此,他们需要使用巧妙的营销技巧来吸引玩家并扩大游戏的受众群体。这包括确定目标市场、利用论坛、社交媒体和其他在线渠道来与玩家互动等。
03
资金问题:
相对于大型游戏开发公司,独立开发者可能缺乏支持游戏创作和推广所需资金。为了筹集资金,他们可能需要利用个人资源、众筹或贷款等方式。
04
竞争激烈:
独立游戏市场竞争激烈,因此需要开发者具备出色的技能、耐心和毅力。他们需要在有限的时间内完成多项任务,并找到在竞争激烈的市场中脱颖而出的方法。
05
商业模式选择:
选择适合自己游戏的盈利模式需要考虑多个因素,例如游戏类型、受众群体、市场需求等。常见的盈利模式包括销售游戏、游戏内广告、赞助和众筹等。
面对这些困境,如何提高独立游戏的商业化水平也成为一个重要的课题。
04 提高独立游戏商业化的建议 A ,注重提升游戏品质
对独立游戏来说,提高游戏本身的品质和内容是最重要的。如果游戏可玩性不高,画面不精致流畅,剧情没有吸引力,就很难留住玩家,自然也就无从谈起商业化。所以独立游戏开发者要在有限的资源下,尽力打造运行流畅、画面精美、剧情精彩的游戏内容,这是商业化的基础。当玩家因为高品质的游戏内容而喜欢上这个游戏时,才更有可能付费支持、传播推荐,从而实现独立游戏的商业成果。与此同时,国家也高度重视游戏产业的发展,也希望游戏内容能承载正向价值观,成为优质文化产品。如果独立游戏能在寓教于乐的同时提供高质量体验,就能获得用户和国家的双重认可。
B 创意结合大众口味
独立游戏要实现商业化,就需要在保持核心创意的基础上,适当融入大众喜闻乐见的元素。这可以吸引更多玩家体验游戏,产生口碑传播,扩大销量。创新点满足核心玩家,大众化要素减轻普通玩家的进入门槛。这样既突出独立游戏的个性,又兼顾可及性。正确融合创新和大众口味,能促进独立游戏商业化。
C 聚焦细分领域
独立游戏资源有限,直接竞争主流游戏比较困难。因此可以聚焦细分领域,针对特定用户提供定制内容。细分领域用户需求明确稳定,容易积累口碑。竞争少,更易突出独特风格。用户粘性高,利于变现。适度聚焦细分市场,能提升独立游戏商业化。
D 借力平台资源
平台拥有大量用户,让游戏易触达潜在玩家群。平台提供销售渠道,并利用算法推荐提升曝光。利用平台举办的活动刺激销量。平台的评价体系可以推动优质游戏脱颖而出。
E 多样化变现
独立游戏商业化不能过于依赖单一变现方式。应提供多种变现选择,满足不同消费群体,实现全面变现。兼顾免费和付费体验,设计可选付费项目,针对不同游戏阶段设计虚拟物品,开发新变现功能。多样化变现组合超越单一方式局限性,能吸引更多用户付费,使商业化更稳健高效。
总的来说,独立游戏开发确实面临许多挑战,但聪明的开发者可以通过提升游戏品质、聚焦细分市场、利用平台资源、多元化变现等途径提高商业化。独立游戏的魅力在于创新和自主性。
相信随着移动互联网的发展,独立游戏市场前景广阔。只要开发者发挥创造力与毅力,寻找合适的商业模式,独立游戏同样可以通过聪明的手段获得丰厚的回报,实现开发者的梦想
海量制作游戏的教程资源限时免费领取,扫描下方二维码,添加助教老师
在Flutter中,你可以通过在Scaffold的body上添加一个GestureDetector来实现点击空白处隐藏键盘的操作。下面是一个示例代码:
import 'package:flutter/material.dart'; class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( body: GestureDetector( onTap: () { FocusScopeNode currentFocus = FocusScope.of(context); if (!currentFocus.hasPrimaryFocus && currentFocus.focusedChild != null) { FocusManager.instance.primaryFocus?.unfocus(); } }, child: YourWidget(), // 替换为你的具体内容 ), ), ); } } 在这个示例中,我们在Scaffold的body上添加了一个GestureDetector,并设置了onTap回调函数。当用户点击空白处时,会触发onTap回调函数,然后我们通过FocusScopeNode来判断当前焦点是否在输入框上,如果是,则调用FocusManager.instance.primaryFocus.unfocus()来隐藏键盘。
注意:你需要将YourWidget替换为你实际使用的Widget。
文章目录 1.路由的封装抽离2.声明式导航 - 导航链接3.声明式导航-两个类名自定义匹配的类名 4.声明式导航 - 跳转传参查询参数传参动态路传参两种传参方式的区别动态路由参数可选符 5.Vue路由 - 重定向6.Vue路由 - 4047.Vue路由 - 模式设置8.编程式导航 - 两种路由跳转9.编程式导航 - 路由传参 1.路由的封装抽离 问题:所有的路由配置都堆在main.js中合适吗?
目标:将路由模块抽离出来。好处:拆分模块,利于维护
之前所添加的路由配置都是写在main.js中的
方法:src下面新建一个文件router,里面建一个index.js,在里面导入router
index.js //一直换路径很麻烦,可以用@/view.Find(@就是src,就直接从src下面找,是绝对路径) import Find from '../views/Find' import My from '../views/My' import Friend from '../views/Friend' import Vue from 'vue' import VueRouter from 'vue-router' Vue.use(VueRouter) //VueRouter插件初始化 //创建了一个路由对象 const router = new VueRouter({ //routes 路由规则们 routes:[ {path:'/find',component:Find}, {path:'/my',component:My}, {path:'/friend',component:Friend} ] }) export default router main.js import Vue from 'vue' import App from '.
ARP(地址解析协议,Address Resolution Protocol)是一种用于在网络中解析或确定目标主机的物理地址(如以太网MAC地址)的网络协议。ARP主要用于IPv4网络,它使得设备能夠在知道目标设备的IP地址的情况下找到其相应的物理地址。ARP是局域网(LAN)环境中不可或缺的协议之一,对于实现IP数据包的正确传递至目标设备至关重要。
工作原理 ARP请求:当一个设备需要知道另一个设备的物理地址时,它会在本地网络上广播一个ARP请求。这个请求包含目标设备的IP地址。ARP回应:网络上的所有设备都会收到这个ARP请求,但只有IP地址匹配的设备会回应。匹配的设备发送一个ARP回应,告诉请求者它的物理地址。更新ARP缓存:一旦请求者接收到ARP回应,它会将这个新获得的IP地址到物理地址的映射存储在本地的ARP缓存中,以便将来使用。 ARP缓存 设备通常维护一个ARP缓存(ARP表),里面存储了最近的IP地址到物理地址的映射。这样可以减少网络上的ARP请求,加快数据包的传输。 ARP欺骗 ARP欺骗(ARP Spoofing)是一种网络攻击,攻击者发送伪造的ARP消息,以改变其他设备的ARP缓存。这种攻击可以导致流量重定向,甚至是中间人攻击。 ARP与IPv6 在IPv6网络中,ARP协议被邻居发现协议(Neighbor Discovery Protocol, NDP)所替代。NDP执行ARP在IPv4网络中的功能,同时还提供了一些额外的功能,如地址自动配置和路由器发现。 ARP是网络通信的基本组成部分,尤其是在IPv4网络中。尽管它的设计简单,但它在网络中的角色至关重要,确保了数据包能够准确地到达目标设备。
目录
一、创建QT文件
二、目录结构讲解
1、.pro文件
2、源文件与头文件
3、编译运行
4、界面文件
三、梦开始的地方(Hello World!)
1、代码方式
2、拖拽方式
四、Qt中的“容器”
五、Qt的对象树机制
1、对象树的引入 2、对象树的概念讲解
一、创建QT文件 首先我们打开Qt Creator,如下所示;
由于可能大家版本不同,可能有的会是如下界面,不过用法都相同;
我们在欢迎界面中点击创建,会弹出如下如下页面;此时第一列我们选择第一个,表示我们要创建一个应用程序,其中第二个是基于Python的;
然后我们在第二列中我们选择第一个表示我们要创建一个桌面应用程序,第二个表示我们要创建一个控制台的Qt程序;这里我们选择第一个 Qt Widgets Application;
接着会弹出下面这个窗口,我们设置项目名和项目路径,小编这里起的项目名为24_01_28_HelloWorld_1
接着我们要选择编译我们项目的编译器;这里我们选择qmake即可,大部分情况都会选择qmake;
这里我们要为我们接下来创建的窗口程序创建一个类,这里我们选择QWidget作为基类,最基本的窗口程序类;
对于基类的选择,目前有如下三种;如下所示;
QMainWindow:主窗口类,一般用于较为复杂的程序应用,除了中央客户区界面,还包括菜单栏,工具栏,状态栏等多个可停靠的工具对话框等;
QWidget:最简单,最基础的窗体程序,里面可放置多个控件;
QDialog:对话框程序,一般用户弹窗;
这么一介绍,可能还是很懵,不过也很正常,这个在后面学习中可以慢慢体会;
接下来是语言和翻译文件的选择,这里用于国际化软件,一般当我们的软件需要多种语言时,我们才会设置这一栏,这里我们直接点击下一步即可;
这一步时选择编译工具,小编当时安装了很多编译软件,所以这里有多个,这里我们选择一个即可;
选择版本控制系统,这里若你有版本控制可以选择Git,若没有选择None即可;
这样,我们一个完整的项目就创建好了;
我们发现左边项目文件管理区域中会存在三个默认目录,一个是头文件,一个是源文件,还有一个是界面文件;下面我会依次讲解这三个目录下的文件;
二、目录结构讲解 1、.pro文件 首先,我们不难发现的是目录结构中,第一个.pro文件,这个文件就是qmake编译的文件,可以理解成我们之前写过的makefile文件;如下所示;
2、源文件与头文件 我们首先从main.cc这个源文件开始看起;
首先我们需要使用一个QApplication的类,无论是哪个QT程序都需要这个类,我们将命令行参数传递给这个类,接着我们创建一个Widget的类,这个类也就是我们一开始创建的那个类,继承自QWidget,我们通过继承方法show来显示这个控件,同时我们也可以通过hide来隐藏这个控件,最后返回时,我们调用exec方法,这个方法会将程序控制权交给我们的QT,等待用户交互,直至用户想要退出程序后,该函数才会返回;
widget.h文件理解;
widget.cc文件理解;
特别注意的是setupUi主要是绑定界面目录下的Ui文件,是当前类与界面目录下某一Ui文件绑定关系的函数;
3、编译运行 我们可以点击项目页面左下角的三角形编译运行项目;
不一会,我们会发现弹出一个窗口,这个窗口就是我们代码的运行结果;
4、界面文件 我们点击界面文件目录下的widget.ui文件,Qt Creator会帮我们弹出一个设计师页面,我们在这个设计师页面下可以通过手动拖拽的方式开发Qt程序;如下所示;
我们可以通过拖拽的方式将左边控件拖拽到设计师页面中来完成Qt程序的设计,这个过程中会自动生成代码;我们点击左边菜单栏中的编辑回到项目文件中;
此时我们看到的代码才是我们刚才设计师页面中的真实样貌;每当我们进行拖拽时,会自动生成相应的代码;
三、梦开始的地方(Hello World!) 接下来我将用两种方式来编写一个Hello World程序;
1、代码方式 在这之前,首先我向大家介绍一个小控件——QLable;
QLable就是标签控件,与html中的标签类似;我们使用这个控件前,需要引入头文件QLable,在Qt中,一般来说,我们使用的类的头文件与类名同名;
我们在widget.cc文件中,QWidget的构造函数内编写如上代码,我们便完成了一个Hello World程序,其中关于对象树的知识暂时不介绍,还有这个对象必须是new出来的;我们观察一下程序运行结果,如下所示;
2、拖拽方式 我们将刚才写的代码注释掉;然后点击界面文件中的 widget.ui 文件;我们在控件中找到Label;
我们直接可以将控件拖拽到设计师页面中,右下角,我们可以设置控件属性;
到这一步,我们的程序已经完成了,我们直接点运行,如下所示;
以下是一个示例代码,演示如何在Jython中使用OpenWire库连接ActiveMQ,将一个主题(topic)上的订阅消息转发到另一个ActiveMQ服务器上:
from org.apache.activemq import * from org.apache.activemq.transport import * # 创建连接工厂 factory = ConnectionFactory() factory.setBrokerURL("tcp://localhost:61616") # 创建连接 connection = factory.createConnection() connection.start() # 创建生产者 producer = connection.createProducer(ActiveMQDestination("MY_QUEUE")) # 创建消息转换器,将BytesMessage转换为String transformer = Transformers.transformers().addTransformer(BytesMessageToStringTransformer()) # 创建目标连接工厂和连接 targetFactory = ConnectionFactory() targetFactory.setBrokerURL("tcp://target_server:61616") targetConnection = targetFactory.createConnection() targetConnection.start() targetDestination = ActiveMQDestination("TARGET_TOPIC") targetProducer = targetConnection.createProducer(targetDestination) # 订阅主题并转发消息 consumer = connection.createConsumer(ActiveMQDestination("MY_TOPIC")) consumer.setMessageListener(new MessageListener() { public void onMessage(Message message) { try { # 将接收到的BytesMessage转换为String transformer.transform(message); String messageText = message.toString(); System.
一、介绍: 1、背景: 在 Redis 的 2.6 以上版本中,除了可以使用命令外,还可以使用 Lua 语言操作 Redis。 Redis 命令的计算能力并不算很强大,而使用 Lua 语言则在很大程度上弥补了 Redis 的这个不足。
2、特点: (1)原子性:redis会将整个脚本作为一个整体执行,中间不会被其他命令插入(Redis执行命令是单线程)。
(2)减少网络开销:在Lua脚本中可以把多个命令放在同一个脚本中运行;
(3)复用性:客户端发送的脚本会永远存储在redis中,这意味着其他客户端可以复用这一脚本来完成同样的逻辑。
3、使用方法: Redis 支持两种方法运行脚本,一种是直接输入一些 Lua 语言的程序代码;另外一种是将 Lua 语言编写成文件。
当公司迁移远程git仓库时,我们需要修改git仓库的远程仓库的地址,可以一个一个的修改,但是如果项目比较多并且改的东西都一样的话,使用脚本修改就比较方便了。
预备知识: 查看远程仓库地址: git remote -v 如
node@ykt03:~/rainclassroom/egg-web$ git remote -v
origin http://10.9.8.99/nodejs/egg-web.git (fetch)
origin http://10.9.8.99/nodejs/egg-web.git (push)
获取远程仓库地址: git remote get-url origin node@ykt03:~/rainclassroom/egg-web$ git remote get-url origin
http://10.9.8.99/nodejs/egg-web.git
这里需要考虑特殊情况:
即:有些git版本没有 git remote get-url origin 函数,获取不了原来的仓库地址的格式,就通过变通的方式获取。
git remote -v | head -n 1 | cut -d " " -f 1 | cut -c 8- 解读:
通过 git remote -v 获取两行的远程信息通过 head -n 1 只取第一行通过 cut -d " " -f 1 得到 origin http://10.
NAT(网络地址转换,Network Address Translation)是一种网络技术,用于在一个网络与另一个网络之间重新映射IP地址。NAT最常见的应用是在家庭和小型办公室的路由器中,用于将私有(内部)IP地址转换为公共(外部)IP地址,从而使多个设备可以共享单个公共IP地址来访问互联网。NAT的主要目的是减少公共IP地址的需求,同时提高网络安全性。
NAT的工作原理和主要特点如下:
地址映射:NAT设备(通常是路由器)将网络内部的私有IP地址映射为公共IP地址。在发送数据包到互联网时,源IP地址(私有地址)被替换为路由器的公共IP地址。当数据包从互联网返回时,NAT设备再将公共IP地址转换回原始的私有IP地址。
端口转换(NAPT):网络地址端口转换(NAPT)是NAT的一种常见形式,允许多个设备共享单个IP地址。NAPT通过在映射时使用不同的端口号来区分不同的内部设备。这样,单个公共IP地址就可以用于多个设备的网络连接。
类型:
静态NAT:预先定义IP地址的一对一映射,通常用于永久性的IP地址转换。动态NAT:根据可用的公共IP地址池动态分配IP地址映射。PAT(端口地址转换):也称为NAPT,它允许多个设备共享同一个IP地址,但使用不同的端口号。 优点:
节省IP地址:减少对公共IP地址的需求。增强安全性:隐藏了内部网络的结构和IP地址,对外部网络不可见。 缺点:
限制端到端连接:NAT可能干扰某些应用程序(如VoIP和P2P应用)的端到端连接。地址转换开销:可能导致延迟和性能问题。 配置:NAT配置通常在路由器或防火墙上进行,需要指定内部和外部接口,以及地址映射规则。
NAT在当今的网络环境中起着重要作用,尤其是在IPv4地址枯竭的情况下。然而,随着IPv6的推广和普及,NAT的需求可能会逐渐减少,因为IPv6提供了更多的IP地址空间。
一.关键名词解释 VAO: Vertex Array Object, 顶点数组对象,你要绘制的图形。
VBO:Vertex Buffer Object, 顶点缓冲对象,所有顶点的集合。
EBO:Element Buffer Object, 元素缓冲对象,顶点的索引值。
IBO: Index Buffer Object, 索引缓冲对象。
管线:又称图像渲染管线,将原始的3D坐标转换为屏幕上有颜色的像素。分为两部分:
第一部分就是将3D坐标转成平面的2D坐标,第二部分将2D坐标转成屏幕有颜色的像素。
着色器:管线接受3D坐标,然后转化成有颜色的像素。期间的工作很复杂,GPU上有成千上万个小处理器核心,它们能够并行处理小程序,这些小程序可以是默认的,也可以是开发者自定义的,这些用来最终处理成2D有颜色的像素的程序,统称为着色器。
顶点着色器:可编程的着色器,前面所说的并行小程序的其中一种,它的作用是将用户输入的3D坐标空间位置(向量vec3)转成空间位置(向量vec4)。向量4中最后个参数w原文作者后续会说,这里先记着。
图元装配:告诉opengl你要绘制的图片是什么类型的,绘制指令需要指定你要绘制成什么样的形状,这里,常用的有:GL_POINTS(点), GL_TRIANGLES(三角形), GL_LINE_STRIPS(线)。
几何着色器:根据图元装配指定的类型,会生成新的顶点和新的三角形。(具体还未清楚具体作用)。
光栅化阶段:将图元映射到屏幕上真正的像素点,生成供片段着色器使用的片段。在使用片段着色器之前,裁切掉视图以外的像素点,提高效率。
片段着色器:可编程的着色器,主要是计算一个像素真正的颜色。通常片段着色器包含3D厂场景的数据(包含光照,阴影,光的颜色), 这些都被计算在内。
测试与混合:所有颜色确定之后,那就是透明度的问题对吧,当然,还会确认这个像素呈现的深度和模板值。深度原文作者理解的就是z轴的值,代表离你的距离,是代表在物体的前面还是后面,能理解吗?模板值,原文作者后续会讲,后面再整理。
总之,着色器渲染的过程:顶点输入(接受用户输入的3D坐标数组)==》顶点着色器==》图元装配==》几何着色器==》光栅化阶段==》片段着色器==》测试与混合
二.开始创建六边形编码 1.创建两个着色器顶点和片段
// 顶点着色器的代码 const char *vertexShaderSource = "#version 330 core\n" "layout (location = 0) in vec3 aPos;\n" "void main()\n" "{\n" " gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);\n" "}\0"; // 片段着色器的代码 const char *fragmentShaderSource = "#version 330 core\n"
目录
100215. 按键变更的次数
原题链接
题目描述
接口描述
思路分析
AC代码
100195. Alice 和 Bob 玩鲜花游戏
原题链接
题目描述
接口描述
思路分析
AC代码
100206. 子集中元素的最大数量
原题链接
题目描述
接口描述
思路分析
AC代码
100179. 给定操作次数内使剩余元素的或值最小
原题链接
题目描述
接口描述
思路分析
AC代码
100215. 按键变更的次数
原题链接 100215. 按键变更的次数
题目描述 给你一个下标从 0 开始的字符串 s ,该字符串由用户输入。按键变更的定义是:使用与上次使用的按键不同的键。例如 s = "ab" 表示按键变更一次,而 s = "bBBb" 不存在按键变更。
返回用户输入过程中按键变更的次数。
注意:shift 或 caps lock 等修饰键不计入按键变更,也就是说,如果用户先输入字母 'a' 然后输入字母 'A' ,不算作按键变更。
接口描述 class Solution { public: int countKeyChanges(string s) { } }; 思路分析 一次遍历,直接模拟即可
引入activemq模块:from activemq import ActiveMQClient from activemq import ActiveMQClient 是一个Python的导入语句,它从activemq模块中导入了ActiveMQClient类。
解释一下各个部分:
from activemq: 这表示我们正在从一个名为activemq的模块中导入内容。import ActiveMQClient: 这表示我们只导入activemq模块中的ActiveMQClient类。 一旦导入了ActiveMQClient,你就可以在你的代码中使用它,例如创建ActiveMQ客户端的实例,进行各种与ActiveMQ服务器的交互等。
注意:要使用这个导入语句,你需要确保已经安装了activemq库。如果还没有安装,你可以使用pip来安装:
pip install activemq 此外,你还需要确保你的环境中有一个正在运行的ActiveMQ服务器,因为你的Python代码将尝试连接到这个服务器。
python通过 61616端口连接activemq Apache ActiveMQ是一个开源的消息代理软件,它实现了JMS 1.1和J2EE 1.4规范,支持多种协议。ActiveMQ提供了消息队列(Queue)和主题(Topic)两种消息传递模式。
ActiveMQ默认使用61616端口,可以通过在连接URL中指定tcp协议和端口号来连接到ActiveMQ服务器。例如,以下是一个使用Python连接ActiveMQ服务器的示例代码:
from activemq import ActiveMQClient client = ActiveMQClient("tcp://localhost:61616") # 创建一个Session对象 session = client.create_session() # 创建一个Destination对象,指定要发送消息的目标 destination = client.create_destination("my_queue") # 创建一个MessageProducer对象,用于发送消息 producer = session.create_producer(destination) # 创建一个Message对象,设置消息内容 message = session.create_message("Hello, ActiveMQ!") # 发送消息 producer.send(message) # 关闭连接 client.close() 在上面的代码中,我们首先创建了一个ActiveMQClient对象,指定要连接的ActiveMQ服务器地址和端口号。然后,我们创建了一个Session对象,用于创建Destination和MessageProducer对象。接着,我们创建了一个Destination对象,指定要发送消息的目标(Queue或Topic)。然后,我们创建了一个MessageProducer对象,用于发送消息。最后,我们创建了一个Message对象,设置消息内容,并使用MessageProducer对象的send方法发送消息。最后,我们关闭了连接。
python通过activemq库订阅主题 要通过Python使用ActiveMQ库订阅主题,您可以使用ActiveMQClient类。下面是一个示例代码,演示如何使用ActiveMQClient类连接到ActiveMQ并订阅主题:
from activemq import ActiveMQClient def on_message(message): print('Received message: %s' % message.
文章目录 前言Dialog 普通弹框Dialog 普通弹框的使用AlertDialog 警告弹框AlertDialog 警告弹框的使用 总结 前言 在我们传统的UI界面中,经常用到弹框,Compose也有弹框,但是Compose的弹框显示和隐藏和传统的弹框显示(show)和隐藏 (dismiss)不一样,Compose中显示与否要看是否重组被执行,所以它显示与否要依赖状态控制
Dialog 普通弹框 Dialog是最底层的弹框,可以在该组件之上封装
@Composable fun Dialog( onDismissRequest: () -> Unit, //关闭回调函数 properties: DialogProperties = DialogProperties(), //对话框的属性,用于自定义对话框 content: @Composable () -> Unit //对话框内容 ) Dialog 普通弹框的使用 @Composable fun DialogMethod(){ val openDialog = remember { mutableStateOf(false) } BaseDialog(dialogState = openDialog) Button(modifier = Modifier.wrapContentSize(), onClick = { openDialog.value = !openDialog.value}) { Text(text = "显示普通dialog") } } @Composable fun BaseDialog(dialogState:MutableState<Boolean>){ if(dialogState.value){ Dialog(onDismissRequest = { dialogState.
三层交换机与防火墙对接上网配置示例 组网图形
图1 三层交换机与防火墙对接上网组网图
三层交换机简介配置注意事项组网需求配置思路操作步骤配置文件 三层交换机简介 三层交换机是具有路由功能的交换机,由于路由属于OSI模型中第三层网络层的功能,所以称为三层交换机。
三层交换机既可以工作在二层也可以工作在三层,可以部署在接入层,也可以部署在汇聚层,作为用户的网关。
配置注意事项 本举例中的防火墙配置以USG6650 V500R001C60为例,其他防火墙的配置方法请参见对应的文档指南。
本举例中的交换机作为DHCP服务器适用的产品和版本如下: V200R009C00及后续版本的S2720-EIV200R005C00SPC300及后续版本的S2750-EI、S5700-LI、S5700S-LIS3700-SI、S3700-EI、S3700-HIS5700-SI、S5700-EI、S5700-HI、S5710-X-LI、S5710-EI、S5710-HI、S5720-LI、S5720S-LI、S5720-SI、S5720S-SI、S5720I-SI、S5720-EI、S5720-HI、S5730-HI、S5730-SI、S5730S-EI、S5731-H、S5731-S、S5731S-S、S5731S-H、S5731-H-K、S5732-H、S5732-H-K、S2730S-S、S5735-L-I、S5735-L1、S300、S5735-L、S5735S-L1、S5735S-L、S5735S-L-M、S5735-S、S500、S5735S-S、S5735-S-I、S5735S-H、S5736-SS6700-EI、S6720-LI、S6720S-LI、S6720-SI、S6720S-SI、S6735-S、S6720-EI、S6720S-EI、S6720-HI、S6730-H、S6730-S、S6730S-S、S6730S-H、S6730-H-KS7703、S7706、S7712、S7710、S7703 PoE、S7706 PoE、S7905、S7908、S9703、S9706、S9712 本举例中产品的默认适用版本请参见“案例适用的产品和版本说明”中的表1。
组网需求 如图1所示,某公司拥有多个部门且位于不同网段,各部门均有访问Internet的需求。现要求用户通过三层交换机和防火墙访问外部网络,且要求三层交换机作为用户的网关。
配置思路 采用如下思路进行配置:
配置交换机作为用户的网关,通过VLANIF接口,实现跨网段用户互访。
配置交换机作为DHCP服务器,为用户分配IP地址。
开启防火墙域间安全策略,使不同域的报文可以相互转发。
配置防火墙PAT转换功能,使用户可以访问外部网络。
操作步骤 配置交换机 # 配置连接用户的接口和对应的VLANIF接口。
<HUAWEI> system-view [HUAWEI] sysname Switch [Switch] vlan batch 2 3 [Switch] interface gigabitethernet 0/0/2 [Switch-GigabitEthernet0/0/2] port link-type access //配置接口接入类型为access [Switch-GigabitEthernet0/0/2] port default vlan 2 //配置接口加入VLAN 2 [Switch-GigabitEthernet0/0/2] quit [Switch] interface gigabitethernet 0/0/3 [Switch-GigabitEthernet0/0/3] port link-type access [Switch-GigabitEthernet0/0/3] port default vlan 3 [Switch-GigabitEthernet0/0/3] quit [Switch] interface vlanif 2 [Switch-Vlanif2] ip address 192.
文章目录 📚优化内容📚html和css优化🐇搜索框部分🐇刷新按钮部分 📚js🐇搜索框部分🐇刷新部分 前期回顾:【d3】力导图优化,本文主要是基于上篇代码,以代码段添加的方式实现优化。
📚优化内容 添加搜索框功能,实现搜索高亮。
双击空白处,图表还原的同时搜索框清零。添加刷新按钮,页面刷新。
📚html和css优化 🐇搜索框部分 搜索框部分的样式直接套的模板,修改了对应的颜色和div在页面的位置(忘记存参考博客了,后续找回来了再放(>人<;)html部分<div class="search-box"> <input type="text" id="searchBox" class="search-txt" placeholder="name?" /> <a class="search-btn"> <i class="fa fa-search" aria-hidden="true"></i> </a> </div> css部分.search-box{ position: absolute; left: 20%; top: 10%; transform: translate(-50%,-50%); background-color: #a04c3b; height: 30px; margin-top: 20px; padding: 10px; border-radius: 40px; } .search-txt{ border:none; background: none; outline: none; float: left; padding: 0; color: #fff; font: 16px sans-serif; line-height: 30px; width: 0; /* 动画过渡 */ transition: 0.4s; } .
🌈个人主页: 会编程的果子君
💫个人格言:“成为自己未来的主人~” 目录
浮点数在内存中的存储
浮点数的存储
浮点数存的过程
浮点数取的过程
题目解析
浮点数在内存中的存储 常见的浮点数:3.14159.1E10等,浮点数家族包括:float double long double等,浮点数表示的范围:float.h中定义
浮点数的存储 首先,我们先来看一段代码:
#include<stdio.h> int main() { int n = 9; float* pFloat = (float*)&n; printf("n的值为:%d\n", n); printf("*pFloat的值为:%f\n", *pFloat); *pFloat = 9.0; printf("num的值为:%d\n", n); printf("*pFloat的值为:%f\n", *pFloat); return 0; } 大家想一下,在这段代码中,输出的结果是什么?
上面的代码中,num和*pFloat在内存中明明是同一个数,为什么浮点数和整数打印出的结果会相差这么大。
要理解这个结果,一定要搞懂浮点数在计算机内部的表示方法
根据国际标准IEEE(电气和电子工程协会)754,任意一个二进制浮点数V可以表示成下面的形式:
V = (−1) ^S* M * 2^E
• (−1)S 表⽰符号位,当S=0,V为正数;当S=1,V为负数
• M 表⽰有效数字,M是⼤于等于1,⼩于2的
• 2 E 表⽰指数位
举例来说:
十进制的5.0,写成二进制是101.0,相当于1.01*2^2
那么,按照上面的格式,可以得出s=0,m=1.01,e=2
十进制的-5.0,写成二进制是-101.0,相当于-1*1.01*2^2,那么,s=1,m=1.01,e=2
IEEE 754规定:
文章目录 一、初识RocketMQ二、NameServer三、消息发送*3.1 Topic路由机制*3.2 消息发送高可用设计*3.3 DefaultMQProducer3.4 消息发送基本流程 四、消息存储4.1 存储文件的组织方式4.2 内存映射4.3 刷盘策略4.4 过期文件删除机制 五、消息消费六、相关问题6.1 为什么要使用消息队列6.2 为什么要选择RocketMQ6.3 RocketMQ有什么优缺点6.4 消息队列有哪些消息模型6.5 RocketMQ用什么消息模型6.6 消息的消费模式6.7 RoctetMQ架构6.8 如何保证消息的可靠性(不丢失)6.9 如何处理消息重复的问题6.10 怎么处理消息积压6.11 顺序消息如何实现6.12 如何实现消息过滤6.13 延时消息6.14 怎么实现分布式消息事务的6.15 死信队列6.16 如何保证RocketMQ的高可用6.17 RocketMQ的整体工作流程6.18 为什么RocketMQ不使用Zookeeper作为注册中心6.19 Broker是怎么保存数据的6.20 RocketMQ怎么对文件进行读写的6.21 消息刷盘怎么实现的6.22 RocketMQ消息长轮询6.23 什么时候清理过期消息6.24 RocketMQ的负载均衡是如何实现的6.25 消息队列设计成推消息还是拉消息6.26 如何设计一个消息队列6.27 RocketMQ消息体过大的解决方案6.28 如何保证幂等性 一、初识RocketMQ RocketMQ设计基于主题的发布与订阅模式,其核心功能包括消息发送、消息存储和消息消费,整体设计追求简单和性能高效,主要体现在如下3个方面:
1、NameServer的设计极其简单
Topic路由信息无须在集群之间保持强一致,而是追求最终一致性,并且能容忍分钟级的不一致。正是基于这种特性,RocketMQ的NameServer集群之间互不通信,这样极大地降低了NameServer实现的复杂度,对网络的要求也降低了不少,性能相比较ZooKeeper还有了极大的提升。2、高效的I/O存储机制
RocketMQ追求消息发送的高吞吐量,RocketMQ的消息存储文件被设计成文件组的概念,组内单个文件大小固定,方便引入内存映射机制,所有主题的消息存储按顺序编写,极大地提升了消息的写性能。同时为了兼顾消息消费与消息查找,引入了消息消费队列文件与索引文件。3、容忍存在设计缺陷
消息中间件的实现者经常会遇到一个难题:如何保证消息一定能被消息消费者消费,并且只消费一次?RocketMQ的设计者给出的解决办法是不解决这个难题,而是退而求其次,只保证消息被消费者消费,在设计上允许消息被重复消费。这样极大地简化了消息中间件的内核,使得实现消息发送高可用变得非常简单和高效,消息重复问题由消费者在消息消费时实现幂等。 作为一款消息中间件,RocketMQ需要解决的问题:
1、架构模式
RocketMQ与大部分消息中间件一样,采用发布订阅模式,主要参与组件包括:消息发送者、消息服务器(消息存储)、消息消费和路由发现。2、顺序消息
所谓顺序消息,就是消息消费者按照消息达到消息存储服务器的顺序消费。RocketMQ可以严格保证消息有序。3、消息过滤
消息过滤是指在消息消费时,消息消费者可以对同一主题下的消息按照规则只消费自己感兴趣的消息。RocketMQ消息过滤是由服务端和消费端共同完成的。4、消息存储
消息中间件的一个核心实现是消息的存储,对于消息存储一般有如下两个维度的考量:消息堆积能力和消息存储性能。RocketMQ追求消息存储的高性能,引入内存映射机制,所有主题的消息按顺序存储在同一个文件中。同时为了避免消息在消息存储服务器中无限地累积,引入了消息文件过期机制与文件存储空间报警机制。5、消息高可用性
通常影响消息可靠性的有以下几种情况: 1)Broker异常崩溃。
2)操作系统崩溃。
3)机器断电,但是能立即恢复供电。
4)机器无法开机(可能是CPU、主板、内存等关键设备损坏)。
5)磁盘设备损坏。
对于前3种情况,RocketMQ在同步刷盘模式下可以确保不丢失消息,在异步刷盘模式下,会丢失少量消息。后2种情况属于单点故障,一旦发生,该节点上的消息会全部丢失。如果开启了异步复制机制,RoketMQ能保证只丢失少量消息。
6、消息到达(消费)低延迟
RocketMQ在消息不发生堆积时,以长轮询模式实现准实时的消息推送模式。7、确保消息必须被消费一次
RocketMQ通过消息消费确认机制(ACK)确保消息至少被消费一次,因为ACK消息有可能出现丢失等情况,RocketMQ无法做到消息只被消费一次,所以有重复消费的可能。8、回溯消息
回溯消息是指消息消费端已经消费成功,根据业务要求,需要重新消费消息。RocketMQ支持按时间向前或向后回溯消息,时间维度可精确到毫秒。9、消息堆积
消息中间件的主要功能是异步解耦,必须能应对前端的数据洪峰,提高后端系统的可用性,这必然要求消息中间件具备一定的消息堆积能力。RocketMQ使用磁盘文件存储消息(内存映射机制),并且在物理布局上为多个大小相等的文件组成逻辑文件组,可以无限循环使用。RocketMQ消息存储文件并不是永久存储在消息服务器端的,而是提供了过期机制,默认保留3天。10、定时消息
定时消息是指消息发送到Broker后,不能被消息消费端立即消费,而是要到特定的时间点或者等待特定的时间后才能被消费。因为如果要支持任意精度的定时消息消费,就必须在消息服务端对消息进行排序,这势必带来很大的性能损耗,所以RocketMQ不支持任意进度的定时消息,只支持特定延迟级别。11、消息重试机制
RocketMQ支持消息重试机制。消息重试是指在消息消费时如果发生异常,消息中间件支持消息重新投递。 二、NameServer 消息中间件的设计思路一般是基于主题的订阅发布机制,消息生产者(Producer)发送某一主题的消息到消息服务器,消息服务器负责该消息的持久化存储,消息消费者(Consumer)订阅感兴趣的主题,消息服务器根据订阅信息(路由信息)将消息推送给消费者(推模式)或者消息消费者主动向消息服务器拉取消息(拉模式),从而实现消息生产者与消息消费者的解耦。
RocketMQ架构:
代理模式就是给对象提供一个代理,并由代理对象来控制原对象的引用,使得客户不能与真正的目标对象通信,代理对象是目标对象的代表, 其他需要与这个目标对象打交道的操作都是和这个代理对象在交涉
静态代理 抽象角色:一般使用接口和抽象类来实现
public interface Rent { //抽象对象 public void rent(); } 真实角色:被代理的角色
public class Host implements Rent{ @Override public void rent() { System.out.println("房屋出租"); } } 代理角色:代理真实角色
public class Proxy implements Rent{ private Host host; public Proxy(Host host){ this.host=host; } @Override public void rent() { host.rent(); } } 客户:使用代理角色进行操作
public class Client { public static void main(String[] args) { //房东要租房 Host host = new Host(); //中介帮房东 Proxy proxy = new Proxy(host); //客户找中介 proxy.
鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之CheckboxGroup组件
一、操作环境 操作系统: Windows 10 专业版、IDE:DevEco Studio 3.1、SDK:HarmonyOS 3.1+
二、CheckboxGroup组件 提供多选框组件,通常用于某选项的打开或关闭。
子组件 无。
接口 CheckboxGroup(options?: { group?: string })
创建多选框群组,可以控制群组内的Checkbox全选或者不全选,group值相同的Checkbox和CheckboxGroup为同一群组。
参数 参数名
参数类型
必填
参数描述
group
string
否
群组名称。
说明:
多个相同群组名称的CheckboxGroup,仅第一个CheckboxGroup生效。
属性 除支持通用属性外,还支持以下属性:
名称
参数类型
描述
selectAll
boolean
设置是否全选。
默认值:false,若同组的Checkbox显式设置select,则Checkbox的优先级高。
从API version 9开始,该接口支持在ArkTS卡片中使用。
selectedColor
ResourceColor
设置被选中或部分选中状态的颜色。
从API version 9开始,该接口支持在ArkTS卡片中使用。
事件 支持通用事件外,还支持以下事件:
名称
功能描述
onChange (callback: (event: CheckboxGroupResult) => void )
CheckboxGroup的选中状态或群组内的Checkbox的选中状态发生变化时,触发回调。
从API version 9开始,该接口支持在ArkTS卡片中使用。
CheckboxGroupResult对象说明
从API version 9开始,该接口支持在ArkTS卡片中使用。
名称
一.概述
QFile 类支持对文件进行读取、写入、删除、重命名、拷贝等操作,它既可以操作文件文件,也可以操作二进制文件。
二.QFile方法
1.使用 QFile 读写文件之前必须先打开文件,调用 open() 成员方法即可,常用的语法格式为:
bool QFile::open(OpenMode mode)
mode 参数用来指定文件的打开方式,下表罗列了此参数的可选值以及各自的含义:
表 1 QFile文件打开方式
打开方式
含 义
QIODevice::ReadOnly
只能对文件进行读操作
QIODevice::WriteOnly
只能对文件进行写操作,如果目标文件不存在,会自行创建一个新文件。
QIODevice::ReadWrite
等价于 ReadOnly | WriteOnly,能对文件进行读和写操作。
QIODevice::Append
以追加模式打开文件,写入的数据会追加到文件的末尾(文件原有的内容保留)。
QIODevice::Truncate
以重写模式打开,写入的数据会将原有数据全部清除。注意,此打开方式不能单独使用,通常会和 ReadOnly 或 WriteOnly 搭配。
QIODevice::Text
读取文件时,会将行尾结束符(Unix 系统中是 "\n",Windows 系统中是 "\r\n")转换成‘\n’;将数据写入文件时,会将行尾结束符转换成本地格式,例如 Win32 平台上是‘\r\n’。
根据需要,可以为 mode 参数一次性指定多个值,值和值之间用|分割。比如:
QIODevice::ReadOnly | QIODevice::Text:表示只允许对文件进行读操作,读取文件时,会将行尾结束符转换为 '\n';
QIODevice::WriteOnly | QIODevice::Text:表示只允许对文件进行写操作,将数据写入文件时,会将行尾结束符转换为本地格式;
QIODevice::ReadWrite | QIODevice::Append | QIODevice::Text:表示对文件进行写操作,写入的数据会存放到文件的尾部,同时数据中的行尾结束符转换为本地格式。
注意,传递给 mode 参数的多个值之间不能相互冲突,比如 Append 和 Truncate 不能同时使用。
如果文件成功打开,open() 函数返回 true,否则返回 false。
目录
一、AidLearning的优点
二、使用场景
三、最佳实践
四、总结与展望
随着移动设备的普及和技术的不断进步,越来越多的开发者开始寻求在手机端进行编程的方法。对于Python编程者来说,AidLearning是一款非常实用的手机编程神器。本文将深入剖析AidLearning的优点、使用场景和最佳实践,帮助你全面了解这款手机端的Python编程工具。
一、AidLearning的优点 AidLearning是一款基于Python的手机编程应用,它提供了丰富的编程功能,让用户在手机上就能轻松编写和运行Python代码。以下是AidLearning的主要优点:
便携性:手机作为现代人随身携带的设备,使用AidLearning可以在任何时间、任何地点进行编程。这为那些需要在移动中编程或在碎片化时间里进行编程的人提供了极大的便利。无论是在公交车上、排队等候还是休息时间,只要拿出手机,即可随时编写和运行Python代码。实时反馈:AidLearning支持实时运行代码,用户可以立即看到代码的输出结果,这对于学习和调试非常有帮助。通过实时反馈,用户可以快速验证代码的正确性,及时发现和修正错误,提高了编程的效率和准确性。丰富的库支持:AidLearning集成了大量的Python库,包括科学计算、数据分析、机器学习等,使得在手机上进行复杂编程成为可能。这意味着用户可以利用AidLearning进行各种高级编程任务,如数据挖掘、机器学习模型的训练等。代码编辑器优化:AidLearning的代码编辑器针对手机触屏进行了优化,提供了智能代码补全、语法高亮等功能,大大提高了编程效率。此外,编辑器还支持自动缩进、代码格式化等常用编辑功能,使得编写Python代码更加便捷。社区支持:AidLearning拥有庞大的用户社区,遇到问题时可以快速找到解决方案或寻求社区的帮助。社区内聚集了大量的Python编程爱好者和技术专家,他们乐于分享经验、解答问题,为用户提供了良好的学习氛围和技术支持。 二、使用场景 移动学习与编程入门:对于想要学习Python编程的初学者,AidLearning提供了一个直观且易于上手的平台。通过手机端的编程环境,用户可以随时随地学习Python的基础知识,通过编写小段代码加深理解。这种移动学习方式打破了传统的学习模式,让学习不再局限于固定的时间和地点,更加灵活高效。灵感捕捉与快速实验:开发者或科研人员可以利用AidLearning进行头脑风暴或快速实验,捕捉灵感,进行初步的尝试和验证。在移动设备上进行编程,可以随时记录下突发的灵感或创意,并通过实时运行来验证其可行性。这种即时的编程方式有助于激发创造力,促进创新思维的产生。移动数据处理与计算:利用AidLearning集成的科学计算库,用户可以在手机上进行简单的数据处理和计算。例如,数据清洗、统计分析等任务都可以在手机端完成。这对于需要在移动环境下处理数据的用户来说非常实用,无需依赖固定的计算机设备。远程控制与自动化:通过AidLearning,用户可以编写Python脚本远程控制其他设备或进行自动化操作。例如,通过手机控制智能家居设备、定时执行任务等。借助手机与外部设备的连接,用户可以实现远程控制和自动化管理,为日常生活和工作带来便利。教育应用与互动编程:在教育领域,AidLearning可以作为教学工具用于编程课程中。教师可以通过AidLearning与学生进行互动编程,实时查看学生的代码并给予指导。此外,学生还可以利用AidLearning进行自主学习和项目实践,提高实际操作能力和解决问题的能力。随时随地的个人项目开发:对于个人项目开发而言,AidLearning提供了一个方便的编程环境。无论是在家中、咖啡馆还是在外出旅行时,只要有手机在手,就可以随时开展项目工作。利用手机的便携性,用户可以随时调整和完善项目代码,保持工作的连续性和高效性。创意应用开发:开发者可以利用AidLearning进行创意应用的开发。通过在手机上直接编写和测试代码,可以快速实现各种创意应用的设计和开发。例如,开发小游戏、制作简单的AI应用等。这种开发方式能够加速应用的诞生和迭代过程,让创意更快地转化为实际应用。实时监控与数据分析:在某些行业应用中,如物联网、智能监控等场景下,AidLearning可以帮助开发者实现实时监控和数据分析功能。通过在手机上直接处理和展示数据,用户可以快速获取关键信息并进行决策。这种实时的数据处理方式对于许多实际应用场景具有重要的意义。社交分享与协作编程:利用AidLearning的社交功能,用户可以将自己的代码分享给朋友或同事进行交流和协作。在共享的代码 编辑器中,多个人可以同时进行编程,共同完成项目。这种社交分享与协作编程的方式打破了传统的编程模式,促进了知识的共享和团队的合作。
三、最佳实践 利用实时反馈进行调试:由于手机屏幕相对较小,编写复杂的代码可能会遇到困难。利用AidLearning的实时反馈功能,用户可以及时看到代码的输出结果,快速发现和修正代码中的错误。这种即时的调试方式提高了编程的效率和准确性,减少了错误的发生。合理管理项目与代码:在手机端进行编程时,建议使用版本控制工具(如Git)管理代码,这样可以更好地跟踪代码的修改历史和协同工作。同时,合理组织项目结构和代码文件,便于管理和维护。通过合理的管理方式,用户可以保持代码的整洁和可维护性,提高项目开发的效率和代码质量。注重代码可读性与可维护性:在手机端编程时,由于屏幕大小的限制,编写简洁、可读性强的代码尤为重要。遵循良好的编码规范,使用有意义的变量名和函数名,编写注释等,都有助于提高代码的可读性和可维护性。这样在与其他人协作或日后自己查看代码时,都能够快速理解代码的功能和逻辑。测试与验证:在手机端进行编程时,由于设备性能和网络环境的限制,测试和验证代码的正确性尤为重要。编写单元测试、集成测试等必要的测试用例,确保代码的稳定性和可靠性。同时,在多种设备和不同网络环境下进行测试,以验证代码在不同环境下的表现和兼容性。注意隐私与安全:在手机端进行编程时,需要注意保护个人隐私和数据安全。避免在AidLearning中处理敏感信息,如账号密码、银行卡信息等。同时,确保下载和使用第三方库时遵循相关法律法规和隐私政策。在使用手机端编程应用时,用户应关注应用的权限请求,只授予必要的权限,以保护个人隐私数据的安全。 四、总结与展望 随着移动设备的普及和技术的不断进步,手机端编程已经成为一种趋势。AidLearning作为一款优秀的手机端Python编程工具,为用户提供了便捷、高效的学习和开发环境。通过深入了解其优点、使用场景和最佳实践,我们可以更好地利用这一工具提高编程效率、拓展应用场景。
未来,随着移动设备性能的提升和更多创新功能的加入,我们期待在手机端看到更多富有创意和实用价值的Python编程应用。同时,随着5G、物联网等技术的快速发展,手机端编程将在实时数据处理、远程控制等领域发挥更大的作用。此外,随着人工智能技术的进步,手机端编程将更加智能化、自动化,降低编程门槛,让更多人能够轻松地表达自己的创意和想法。
总的来说,AidLearning作为一款手机端的Python编程神器,为移动编程带来了巨大的便利。通过不断探索和实践,我们可以更好地利用这一工具来提升编程体验和工作效率。同时,我们也需要关注隐私与安全问题,确保在享受便捷的同时保护个人数据的安全。
目录
登录到百度智能云,找到文字识别
完成操作指引
开通
查看车牌识别的api文档
编辑编辑
查看自己应用的api key
查看回应的数据格式 编程步骤
ui界面编辑
添加模块,头文件和定义变量
新建两个类,一个图像Image类,一个http类,http类继承QObject类,并添加头文件并定义成员和函数
实现图像Image类,Http类的函数
在ui界面的cpp中添加全局变量,根据自己的应用来写,开头有获取方法
编写打开图片按钮的点击事件
编写识别按钮的点击事件
登录到百度智能云,找到文字识别 完成操作指引 免费尝鲜---服务类型选择交通---接口选择全部----0元领取创建应用---填写应用名称---个人----应用描述 开通 查看车牌识别的api文档 查看自己应用的api key 查看回应的数据格式 编程步骤 ui界面编辑 添加模块,头文件和定义变量 在pro中添加模块 QT += core gui network 在ui界面类的.h里添加 #include <QDebug> #include <QJsonArray> #include <QJsonDocument> #include <QJsonObject> #include <QThread> #include <QFileDialog> #include "image.h" #include "http.h" 新建两个类,一个图像Image类,一个http类,http类继承QObject类,并添加头文件并定义成员和函数 Image类
#include <QString> #include <QImage> #include <QBuffer> #include <QTextCodec> public: static QByteArray imageToBase64(QString fileName); Http类
#include <QString> #include <QNetworkAccessManager> #include <QNetworkReply> #include <QNetworkRequest> #include <QEventLoop> public: static bool post_syns(QString url,QMap<QString,QString>header,QByteArray& requestData,QByteArray&replyData); 实现图像Image类,Http类的函数 Image类
一、题目 1、题目描述 有两个水壶,容量分别为 jug1Capacity 和 jug2Capacity 升。水的供应是无限的。确定是否有可能使用这两个壶准确得到 targetCapacity 升。
如果可以得到 targetCapacity 升水,最后请用以上水壶中的一或两个来盛放取得的 targetCapacity 升水。
你可以:
装满任意一个水壶清空任意一个水壶从一个水壶向另外一个水壶倒水,直到装满或者倒空 2、接口描述 class Solution { public: bool canMeasureWater(int jug1Capacity, int jug2Capacity, int targetCapacity) { } }; 3、原题链接 365. 水壶问题 - 力扣(LeetCode)
二、解题报告 1、思路分析 由于每次倒出都是整壶的倒,倒入一定倒满则可以等效为直接倒了一壶
所以最终水量一定为sx+ty
根据初等数论的内容可以知道x,y最大公因数d可以表示为sx+ty=d并且d是能被这样表示的最小正整数,那么sx+ty=z成立当仅当z整除x和y最大公因数
2、复杂度 时间复杂度: O(1) 空间复杂度:O(1)
3、代码详解 class Solution { public: bool canMeasureWater(int x, int y, int z) { if (x + y < z) return false; if (x == 0 || y == 0) return z == 0 || x + y == z; return z % gcd(x, y) == 0; } };