数字操作篇 1、判断是否为数字
// 利用位运算符实现判断 const isNumber = (value) => ((value | 0) === value); isNumber('123x') // false isNumber('0') // false isNumber(123) // true isNumber(0) // true isNumber(null) // false isNumber(undefined) // false 2、生成随机数
const randomNum = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min; randomNum(1, 10) // 6 randomNum(10, 20) // 11 3、进制转换
// 假设数字10要转换成2进制 const toDecimal = (num, n = 10) => num.toString(n) toDecimal(10, 2) // '1010' // 10的2进制为1010 const toDecimalism = (num, n = 10) => parseInt(num, n) toDecimalism(1010, 2) 4、四舍五入
数组篇 1、数组打乱(洗牌函数)
const shuffleArray = arr => arr.sort(() => Math.random() - 0.5) shuffleArray([1,2,3,4,5,6,7,8,9,10,11,12]) 2、生成数组
// 方案一 // n为需要生成的范围 const createArray = (n) => new Array(n).fill(0).map((v, i) => i) // 方案二 const createArray = (n) => Array.from(new Array(n), (v, i) => i) createArray(100) // 0 - 99数组 3、数组去重
// 方案一 const removeDuplicates = (arr) => Array.from(new Set(arr.flat(Infinity))) // 方案二 const removeDuplicates = (arr) => [...new Set(arr)] removeDuplicates([1, 4, 3, 4, 5]) 4、最大值索引
文章目录 前言一、如何封装getConnection方法?1.创建工具DruidUtil类2.编写我们的工具类 二、如何使用这个工具类呢?三.如何引入事务呢?1.明白什么是事务2.事务用代码实现 总结 前言 JDBC是一种用于Java语言连接数据库的API,它提供了一组用于访问和处理各种关系型数据库的接口和类。在使用JDBC连接数据库时,我们可以将连接数据库的方法进行封装,以便于在其他地方进行重用和调用。
方法封装可以将连接数据库的一系列步骤进行抽象和简化,使得我们在使用时只需要调用一个简单的方法即可完成连接。例如,我们可以将连接数据库的方法封装成一个getConnection()方法,该方法接受数据库连接参数作为输入,然后返回一个Connection对象,这个对象可以用来执行SQL语句和操作数据库。
通过将JDBC连接数据库的方法进行封装,我们可以提高代码的可维护性和可读性,减少重复代码的出现,同时还可以降低代码的耦合度。这样,在开发过程中,我们可以更加专注于业务逻辑的实现,而不需要关注底层的数据库连接细节。
一、如何封装getConnection方法? 1.创建工具DruidUtil类 首先,我们在scr目录下创建一个名为util的模块来存放我们的工具类。
之后在该模块下创建一个名为DruidUtil类的java文件。(这里我使用的名称是JdbcUtil)
2.编写我们的工具类 import com.alibaba.druid.pool.DruidDataSourceFactory; import javax.sql.DataSource; import java.io.IOException; import java.io.InputStream; import java.sql.Connection; import java.sql.SQLException; import java.util.Properties; //用于加载连接,对外提供获取连接和回收连接的方法 //利用线程本地变量,存储连接信息,确保一个线程的多个方法可以获取同一个Connection //优势:事务操作的时候 service 和 dao 属于同一个线程,不用传递参数 //它们可以调用getConnection主动获取相同的连接池 public class JdbcUtil { private static DataSource dataSource = null; private static ThreadLocal<Connection> thread = new ThreadLocal<>(); static { //初始化连接池对象 Properties properties = new Properties(); InputStream resourceAsStream = JdbcUtil.class.getClassLoader().getResourceAsStream("druid.properties"); try { properties.load(resourceAsStream); } catch (IOException e) { throw new RuntimeException(e); } try { dataSource = DruidDataSourceFactory.
一、父子组件 方式1 Vue3 父 ——> 子 props传递参数; 子 ——> 父 emit方法传递数据 父组件:
<template> <div> <child :propsName="propsData" @vote="voteId"></child> </div> </template> <script setup lang="ts"> import { ref } from 'vue' import child from '@/components/child'; let propsData = ref({ id: 25, name: 'Jack', age: 18}) const voteId = (id) => { console.log('子组件传递的参数id为:'+id); } </script> 子组件
<template> <div> <div @click="vote(propsData.id)">{{ propsData.name }}</div> </div> </template> <script setup lang="ts"> import { defineProps, defineEmits } from 'vue' defineProps({ count: { propsData: Obiect, default: () => {} } }) const emits = defineEmits(['vote']) const vote = (id) => { emits('vote', id) } </script> Vue2 父 ——> 子 props传递参数; 子 ——> 父 emit方法传递数据 父组件:
一、支持向量机,support vector machine,SVM 找到一个超平面将不同的数据分隔开,并且该使得该超平面到支持向量间的间隔最大化。
函数间隔:在超平面wx+b=0确定的情况下,|y||wx+b|能够表示点x到距离超平面的远近,y*(w*x+b)的正负性表示分类的正确性。几何间隔:即点到超平面的距离, ∣ y ∣ ∣ w ∗ x + b ∣ ∣ ∣ w ∣ ∣ \frac{|y||w*x+b|}{||w||} ∣∣w∣∣∣y∣∣w∗x+b∣,如果成比例的改变超平面的w和b时几何间隔不变。最终目标函数为:
(1)其中取y的值为1和-1,是为了计算方便和几何意义明确。实际取任何值都可以,只要不同的类的点函数值有不同的符号即可。(2)支持向量刚好在虚线间隔边界上,即y*(wx+b)=1。对于所有不是支持向量的点,则显然有y(w*x+b)>1。目标函数最大化问题转为最小化问题:
(1)目标函数是二次的,约束条件是线性的,所以它是一个凸二次规划问题。(2)可以用现有的Quadratic programming(二次规划)包求解。(3)或者手动求解。通过拉格朗日乘子法,目标函数变成了:
再得到与原问题等价的对偶问题:
(1)为了容易求解,将minmax原始问题转化为maxmin对偶问题,即先求L 对w、b的极小,再求L 对的极大。(2)原问题是满足 KKT 条件的,所以原问题能有最优化解法,所以可以转化成了对偶问题。 α \alpha α固定,分别对w,b求偏导数,再令 ∂L/∂w 和 ∂L/∂b 等于零。求得的结果代入 L ( w , b , α ) L(w,b,\alpha) L(w,b,α),此时拉格朗日函数只包含了 α \alpha α变量,目标函数为:可以利用SMO算法求解对 α \alpha α的极大,得出最终的w和b。
所以分类超平面为:
(1)对于新点 x的预测,只需要计算它与训练数据点的内积即可(2)同时发现:非Supporting Vector 所对应的系数都是等于零的,因此对于新点的内积计算实际上只要针对少量的“支持向量”而不是所有的训练数据(3)直观上来理解的话,“支持向量”后方的点对超平面是没有影响的,超平面只与“支持向量”有关。通过引入核函数,将输入空间映射到高维特征空间,最终在高维特征空间中构造出最优分离超平面,从而把平面上本身不好分的非线性数据分开。从而解决了非线性分类问题,此时的分类超平面为:
(1)核函数为ϕ,该非线性映射函数能将数据数据变换到另一个特征空间。(2)核函数方法:在特征空间中直接计算内积〈φ(xi · φ(x)〉,避开了直接在高维空间中进行计算。(3)手工构造出对应的核函数比较困难,通常直接用一些常用的核函数,如多项式核、高斯核、线性核。 二、核函数 三、从线性回归到逻辑回归,Logistic Regression,LR 线性回归可以建模为(回归问题):
y = β0 + β1x1 + β2x2 + … + βn*xn + ε
vite.config.js
import { fileURLToPath, URL } from 'node:url' import dns from 'dns' import { defineConfig } from 'vite' //重点部分 import vue from '@vitejs/plugin-vue' dns.setDefaultResultOrder('verbatim') //重点部分 // https://vitejs.dev/config/ export default defineConfig({ plugins: [vue()], resolve: { alias: { '@': fileURLToPath(new URL('./src', import.meta.url)) } }, server:{ //重点部分 proxy:{ "/api":{ target:"http://xxxx", changeOrigin:true, rewrite: (path) => path.replace(/^\/api/, ''), } } } }) 此处定义了"/api"的路径为http://xxxx,
main.js配置
import { createApp } from 'vue' import App from './App.vue' import cors from 'cors' //重点部分 const app =createApp(App) app.
环境准备 1、安装nodeJs
2、点击全局工具配置
3、选择安装nodeJS
用jenkins创建一个构建任务 General页签不用配置
源码管理我这里选择git
构建触发器也不用配置
构建环境选择Provide Node & npm bin/ folder to PATH
构建页签
我这里是本地windows系统安装的jenkins,所以添加Execute Windows batch command
Linux 系统选择 Execute shell
构建后操作
然后保存
目录
1 测量学基础
1.1 地球的形状和大小
1.1.1 大地水准面
1.1.2 大地体
1.1.3 地球椭球
2 坐标系统
2.1 地理坐标系
2.2 投影坐标系
2.3 局部坐标系(假定坐标系)
2.4 高程坐标系
3 地图投影
3.1 投影概念
3.2 投影分类
3.3 投影类型
3.4 投影面与地球表面关系
4 常见投影地图
4.1 世界地图
4.1.1 中国版世界地图
4.1.2 欧洲版世界地图
4.1.3 俄罗斯版世界地图
4.1.4 澳大利亚版世界地图
4.1.5 美国版世界地图
4.1.6 巴西版世界地图
4.1.7 南极版世界地图
4.2 各种投影地图
4.2.1 柏哥斯星状投影
4.2.2 彭纳 (Bonne) 投影
4.2.3 等距方位 (Azimuthal equidistant) 投影
4.2.4 立方体投影
4.2.5 富勒 (Fuller) 投影
4.2.6 温克尔三重 (Winkel Tripel) 投影
目录
1.自编码器产生背景
2.自编码器原理
(1)一般的神经网络结构
(2)自编码器
3.自编码器的实现
(1)网络结构
(2)代码实现
1.自编码器产生背景 像我们目前所进行的图像分类,目标识别,图像分割等都是基于有监督学习来的,所以对于海量的数据需要进行人工的标注。但是随着时代的发展和人工智能不断的火起来,对于数据量的需求已经不是想象中的样子了,数据量的需求已经远远超出人们的认知。面对海量的数据集,有没有一种办法就是能够从中学习到数据的分布P(x)的算法呢?
提示:而解决上面的算法计算无监督学习。
自编码器 自编码器(autoencoder, AE)是一类在半监督学习和非监督学习中使用的人工神经网络(Artificial Neural Networks, ANNs),其功能是通过将输入信息作为学习目标,对输入信息进行表征学习(representation learning)自编码器原理 包含编码器(encoder)和解码器(decoder)两部分 。按学习范式,自编码器可以被分为收缩自编码器(contractive autoencoder)、正则自编码器(regularized autoencoder)和变分自编码器(Variational AutoEncoder, VAE),其中前两者是判别模型、后者是生成模型 。按构筑类型,自编码器可以是前馈结构或递归结构的神经网络。自编码器应用场景 自编码器具有一般意义上表征学习算法的功能,被应用于降维(dimensionality reduction)和异常值检测(anomaly detection) 。包含卷积层构筑的自编码器可被应用于计算机视觉问题,包括图像降噪(image denoising) 、神经风格迁移(neural style transfer)等 。 2.自编码器原理 (1)一般的神经网络结构 能否利用神经网络的强大非线性表达能力去学习到低维的数据表示呢?但是这样也会引入一个问题就是,训练神经网络都是在有标签的清况下,对于一个无监督的学习,是没有标签的,只有输入的数据本身x.
(2)自编码器 我们希望从编码器到解码器的最后输出近似等于原来的输入,所以自编码器的优化目标如下:
3.自编码器的实现 (1)网络结构 (2)代码实现 本文的代码下载:GitHub - KeepTryingTo/Pytorch-GAN: 使用Pytorch实现GAN 的过程
参考书籍和链接
《TensorFlow深度学习》
自编码器相关知识点介绍
网址:首页-Quicky Sharing
使用文档:使用文档-Quicky Sharing
后续会添加微信扫码登录等必要功能
原因很简单
浏览器里的迅雷下载插件,关掉就行
一.单列布局 1.水平居中 **(1)父元素 text-align:center;子元素:inline-block;** 优点:兼容性好; 不足:需要同时设置子元素和父元素 <divclass="parent"> <divclass="child"></div> </div> .parent{ width: 500px; height: 200px; background: red; text-align: center; } .child{ display: inline-block; width: 300px; height: 100px; background: blue; } (2).子元素 margin:0 auto;
优点:兼容性好
缺点:需要指定宽度
<divclass="parent"> <divclass="child"></div> </div> .parent{width: 500px; height: 400px; background: red; } .child{margin: 0 auto; width: 300px; height: 100px ;background: blue; } (3).父元素:relative;子元素:absolute;left:50%;margin-left:-宽度的一半
优点:兼容性好
缺点:需要知道子元素的宽度
<div class="parent"> <div class="child"></div> </div> .parent { position: relative; top: 0; left: 0; width: 500px; height: 400px; background: red; } .
1、绝对路径用什么符号表示?当前目录、上层目录用什么表示?主目录用什么表示? 切换目录用什么命令? 答:
绝对路径: 如/etc/init.d
当前目录和上层目录:./ …/
主目录: ~/
切换目录:cd
2、怎么查看当前进程?怎么执行退出?怎么查看当前路径? 答:
查看当前进程:ps
执行退出:exit
查看当前路径:pwd
3、怎么清屏?怎么退出当前命令?怎么执行睡眠?怎么查看当前用户 id?查看指定帮助用什么命令?? 答:
清屏:clear
退出当前命令:ctrl+c彻底退出
执行睡眠 :ctrl+z挂起当前进程fg恢复后台查看当前用户id:”id“:查看显示目前登陆账户的uid和gid及所属分组及用户名
查看指定帮助:如man adduser这个很全 而且有例子;adduser–help这个告诉你一些常用参数;info adduesr;
4、Ls命令执行什么功能? 可以带哪些参数,有什么区别? 答:
ls执行的功能: 列出指定目录中的目录,以及文件哪些参数以及区别:a所有文件l详细信息,包括大小字节数,可读可写可执行的权限等
5、查看文件有哪些命令? 答:
vi文件名#编辑方式查看,可修改
cat文件名#显示全部文件内容
more文件名#分页显示文件内容
less文件名#与more相似,更好的是可以往前翻页
tail文件名#仅查看尾部,还可以指定行数
head文件名#仅查看头部,还可以指定行数
6、列举几个常用的Linux命令。 答:
列出文件列表:ls【参数 -a -l】
创建目录和移除目录:mkdir rmdir
用于显示文件后几行内容:tail,例如: tail -n 1000:显示最后1000行
打包:tar -xvf
打包并压缩:tar -zcvf
查找字符串:grep
显示当前所在目录:pwd创建空文件:touch
编辑器:vim vi
7、你平时是怎么查看日志的? 答:
Linux查看日志的命令有多种:tail、cat、tac、head、echo等,本文只介绍几种常用的方法。
1、tail
最常用的一种查看方式
命令格式: tail[必要参数][选择参数][文件]
-f 循环读取
-q 不显示处理信息
执行pnpm i时异常,pnpm: EPERM: operation not permitted, copyfile ... pnpm官网:https://pnpm.io/
安装
npm install -g pnpm
查看版本
pnpm -v
执行pnpm i 异常
ENOENT ENOENT: no such file or directory, copyfile ‘F:.pnpm-store\v3\files\64\6c1be74c0d7ea00bc295426cab18bed2fb53865e0eb1682f4480917b0c008d9582612e62668ea0cdb0bcb6aa8c507889c7cec0eb730340f25cfa5d40b208ee-exec’ -> ‘F:\workspace\vue-element-plus-admin-master\node_modules.pnpm\es5-ext@0.10.62\node_modules_tmp_14284_aec13d5741d0b788d0eb0477ec773213_postinstall.js’
EPERM EPERM: operation not permitted, copyfile ‘F:.pnpm-store\v3\files\64\6c1be74c0d7ea00bc295426cab18bed2fb53865e0eb1682f4480917b0c008d9582612e62668ea0cdb0bcb6aa8c507889c7cec0eb730340f25cfa5d40b208ee-exec’ -> ‘F:\workspace\vue-element-plus-admin-master\node_modules.pnpm\es5-ext@0.10.62\node_modules_tmp_34344_0f8ca4cf1206f120dce9852c8b41b215_postinstall.js’
处理方式:
.pnpm-store开放完全控制 选中
文件夹.pnpm-store,右键——属性——安全——选中当前电脑用户——编辑——勾选完整控制——确定 重新执行 pnpm i
文章目录 1、Lombok简介2、使用Lombok的问题2.1 驼峰问题2.2 相同的字符串不同的大小写 3、关于使用Lombok的总结4、写在最后 1、Lombok简介 Lombok项目是一个Java库,它会自动插入您的编辑器和构建工具中,从而为你优化Java代码。通过注解的方式代替我们手动生成getter、setter、toString等方法。
虽然现在的IDE可以帮我们自动生成,但是整个类显的很臃肿。尤其类的属性太多时,查看属性非常不方便。使用Lombok可以使我们的代码更加简洁,可以说是程序员的福音。
官网地址:https://projectlombok.org/
2、使用Lombok的问题 使用Lombok一时爽,但是需要一些问题之后,如果不了解细节,查找原因难上加难,这可能也是一些公司不建议使用Lombok的原因。下面总结了一下遇到的几个问题。
2.1 驼峰问题 先来看一下一个案例:
public class Book { private String uName; } 先来看看IDE和JDK帮我们生成的getter、setter方法:
public class Book { private String uName; public String getuName() { return uName; } public void setuName(String uName) { this.uName = uName; } } 生成getter,setter方法的语法是是这样的:getXxxx,setXxx
但是当遇到案例的属性,就会特殊处理成getxxx、setxxx
与之类似属性还有如下:
public class Book { private String uName; private String AName; private boolean isEmpty; private boolean iseasy; private boolean aBoolean; private boolean BBoolean; public String getuName() { return uName; } public void setuName(String uName) { this.
文章目录 一、默认版本-64bit代码原理范围:优点缺点 二、修改版本一:32bit三、修改版本二:生成15位的id优点:代码 一、默认版本-64bit 雪花算法原理图:
使用1位作为符号位,确定为0, 表示正
使用41位作为毫秒数
使用10位作为机器的ID : 高5位是数据中心ID, 低5位是机器ID
使用12位作为毫秒内的序列号,意味着每个节点每秒可以产生4096(212)个ID;该算法通过二进制的操作进行实现,单机每秒内理论上最多可以生成1000*(2^12),即409.6万个ID。
/** * Twitter_Snowflake<br> * SnowFlake的结构如下(每部分用-分开):<br> * 0 - 0000000000 0000000000 0000000000 0000000000 0 - 00000 - 00000 - 000000000000 <br> * 1位标识,由于long基本类型在Java中是带符号的,最高位是符号位,正数是0,负数是1,所以id一般是正数,最高位是0<br> * 41位时间截(毫秒级),注意,41位时间截不是存储当前时间的时间截,而是存储时间截的差值(当前时间截 - 开始时间截) * 得到的值),这里的的开始时间截,一般是我们的id生成器开始使用的时间,由我们程序来指定的(如下下面程序IdWorker类的startTime属性)。41位的时间截,可以使用69年,年T = (1L << 41) / (1000L * 60 * 60 * 24 * 365) = 69<br> * 10位的数据机器位,可以部署在1024个节点,包括5位datacenterId和5位workerId<br> * 12位序列,毫秒内的计数,12位的计数顺序号支持每个节点每毫秒(同一机器,同一时间截)产生4096个ID序号<br> * 加起来刚好64位,为一个Long型。<br> * SnowFlake的优点是,整体上按照时间自增排序,并且整个分布式系统内不会产生ID碰撞(由数据中心ID和机器ID作区分),并且效率较高,经测试,SnowFlake每秒能够产生26万ID左右。 */ public class SnowflakeIdWorker { // ==============================Fields=========================================== /** 开始时间截 (2015-01-01) */ private final long twepoch = 1420041600000L; /** 机器id所占的位数 */ private final long workerIdBits = 5L; /** 数据标识id所占的位数 */ private final long datacenterIdBits = 5L; /** 支持的最大机器id,结果是31 (这个移位算法可以很快的计算出几位二进制数所能表示的最大十进制数) */ private final long maxWorkerId = -1L ^ (-1L << workerIdBits); /** 支持的最大数据标识id,结果是31 */ private final long maxDatacenterId = -1L ^ (-1L << datacenterIdBits); /** 序列在id中占的位数 */ private final long sequenceBits = 12L; /** 机器ID向左移12位 */ private final long workerIdShift = sequenceBits; /** 数据标识id向左移17位(12+5) */ private final long datacenterIdShift = sequenceBits + workerIdBits; /** 时间截向左移22位(5+5+12) */ private final long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits; /** 生成序列的掩码,这里为4095 (0b111111111111=0xfff=4095) */ private final long sequenceMask = -1L ^ (-1L << sequenceBits); /** 工作机器ID(0~31) */ private long workerId; /** 数据中心ID(0~31) */ private long datacenterId; /** 毫秒内序列(0~4095) */ private long sequence = 0L; /** 上次生成ID的时间截 */ private long lastTimestamp = -1L; //==============================Constructors===================================== /** * 构造函数 * @param workerId 工作ID (0~31) * @param datacenterId 数据中心ID (0~31) */ public SnowflakeIdWorker(long workerId, long datacenterId) { if (workerId > maxWorkerId || workerId < 0) { throw new IllegalArgumentException(String.
ENSP学习心得
eNSP软件安装 安装eNSP之前必须先安装以下三个插件:
VirtualBoxWinPcapWireshack eNSP作为模拟器主体,需要对应版本的VirtualBox和WinPcap提供虚拟环境,Wireshack用于实验当中测试抓取数据包使用。
安装好这三个插件,只需要点下一步选择好对应的安装位置即可,然后就可以安装eNSP软件了。
这里就是eNSP的页面啦
二.eNSP使用
1.左边一栏是我们的设备选择,上方是各种设备,下
是同类设备的不同型号
2.选择新建拓扑(这两个那个都行)
3.将我们需要的设备拽出来就可以了
选好设备之后进行连线 接口上的字是可以随意拖动的,为方便查看接口号,可
自行拖动放在方便查看的地方
①开启设备(点击图中按钮) ②选中图中所有设备鼠标右键点启动
成功启动设备(证明eNSP安装真的没有问题了) 进行设备配置 机器
端口
IP地址
默认网关
AR1
g0/0/0
192.168.1.1/24
不适用
AR2
g0/0/1
192.168.2.1/24
不适用
PC1
e0/0/1
192.168.1.100/24
192.168.1.1
PC2
e0/0/1
192.168.1.101/24
192.168.1.1
PC3
e0/0/1
192.168.2.100/24
192.168.2.1
PC4
e0/0/1
192.168.2.101/24
192.168.2.1
PC1:
PC2:
PC3:
PC4:
因PC1和PC2在同一局域网,所以他俩可以相互ping 通,同理PC3和PC4也是可以ping通的。
PC1 ping PC2:
PC2 ping PC1:
PC3 ping PC4:
PC4 ping PC3:
8.配置路由器
9.检验是否配置成功
PC1 ping 路由器:
目录
前言:
1.学习Java基础知识:
2.掌握面向对象编程(OOP)概念:
3.熟悉Java集合框架:
4.学习Java异常处理:
5.学习Java IO:
6.掌握Java多线程编程:
7.学习Java网络编程:
8.学习Java数据库编程:
9.学习Java框架:
前言: 为什么学习java,有人说“java是最好的编程语言”,对于一名程序员,学习java是必不可少的,作为新手Java开发工程师,你有必要看我这篇Java学习之路,让你对Java的学习路线与更深的理解,这篇路线包括学习过程中的一些基础模块代码,可以让你更加直观的了解需要学习的到底什么,话不多说直接上干货;
1.学习Java基础知识: 在学习Java基础知识时,你需要了解Java的语法、变量和数据类型、控制结构、数组、字符串和输入/输出操作等基础知识。
Java的语法比较简单易懂,适合初学者入门。同时,Java也是一种强类型语言,因此在使用时需要注意数据类型的转换。
Java基本语法示例代码:
public class HelloWorld { public static void main(String[] args) { System.out.println("Hello, World!"); } } Java变量和数据类型示例代码:
int age = 20; double score = 90.5; String name = "Tom"; boolean isMale = true; Java控制结构示例代码:
if (age > 18) { System.out.println("Adult"); } else if (age > 12) { System.out.println("Teenager"); } else { System.out.println("Child"); } Java数组示例代码:
Spring Boot是最流行的用于开发微服务的Java框架。在本文中,我将与你分享自2016年以来我在专业开发中使用Spring Boot所采用的最佳实践。这些内容是基于我的个人经验和一些熟知的Spring Boot专家的文章。
在本文中,我将重点介绍Spring Boot特有的实践(大多数时候,也适用于Spring项目)。以下依次列出了最佳实践,排名不分先后。
1、使用自定义BOM来维护第三方依赖 这条实践是我根据实际项目中的经历总结出的。
Spring Boot项目本身使用和集成了大量的开源项目,它帮助我们维护了这些第三方依赖。但是也有一部分在实际项目使用中并没有包括进来,这就需要我们在项目中自己维护版本。如果在一个大型的项目中,包括了很多未开发模块,那么维护起来就非常的繁琐。
怎么办呢?事实上,Spring IO Platform就是做的这个事情,它本身就是Spring Boot的子项目,同时维护了其他第三方开源库。我们可以借鉴Spring IO Platform来编写自己的基础项目platform-bom,所有的业务模块项目应该以BOM的方式引入。这样在升级第三方依赖时,就只需要升级这一个依赖的版本而已。
<dependencyManagement> <dependencies> <dependency> <groupId>io.spring.platform</groupId> <artifactId>platform-bom</artifactId> <version>Cairo-SR3</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> 2、使用自动配置 Spring Boot的一个主要特性是使用自动配置。这是Spring Boot的一部分,它可以简化你的代码并使之工作。当在类路径上检测到特定的jar文件时,自动配置就会被激活。
使用它的最简单方法是依赖Spring Boot Starters。因此,如果你想与Redis进行集成,你可以首先包括:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> 如果你想与MongoDB进行集成,需要这样:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-mongodb</artifactId> </dependency> 借助于这些starters,这些繁琐的配置就可以很好地集成起来并协同工作,而且它们都是经过测试和验证的。这非常有助于避免可怕的Jar地狱。
https://dzone.com/articles/what-is-jar-hell
通过使用以下注解属性,可以从自动配置中排除某些配置类:
@EnableAutoConfiguration(exclude ={ClassNotToAutoconfigure.class}) 但只有在绝对必要时才应该这样做。
有关自动配置的官方文档可在此处找到:
https://docs.spring.io/spring-boot/docs/current/reference/html/using-boot-auto-configuration.html。
3、使用Spring Initializr来开始一个新的Spring Boot项目 这一条最佳实践来自Josh Long (Spring Advocate,@starbuxman)。
Spring Initializr 提供了一个超级简单的方法来创建一个新的Spring Boot项目,并根据你的需要来加载可能使用到的依赖。
https://start.spring.io/
使用Initializr创建应用程序可确保你获得经过测试和验证的依赖项,这些依赖项适用于Spring自动配置。你甚至可能会发现一些新的集成,但你可能并没有意识到这些。
4、考虑为常见的组织问题创建自己的自动配置 这一条也来自Josh Long(Spring Advocate,@starbuxman)——这个实践是针对高级用户的。
如果你在一个严重依赖Spring Boot的公司或团队中工作,并且有共同的问题需要解决,那么你可以创建自己的自动配置。
1.环境准备 Windows 10Anaconda(基于Python3.9),已配置好环境变量yolov5相关的代码、权重文件等,已经打包整理好,可以通过百度网盘绿色下载。链接: https://pan.baidu.com/s/1okVkfpqjI5wD6PigK-AH0w?pwd=yscw 提取码: yscw 2.在Anaconda中创建虚拟环境 Anconda除了提供丰富的科学包外,还可以通过创建虚拟化境的方式用于进行环境隔离。虚拟环境的隔离有效避免了不同的Python项目需要依赖模块的版本不同导致的各种冲突。这里提供一种图形化操作方式。
(1)打开Anaconda Navigator
(2)依次点击一下两个按钮,然后在弹出的表单里面填写环境的名字和Python的版本,(例如,环境的名字:DL,Python版本为3.9)
注:需要仔细看好虚拟环境在哪个目录下,这个路径后面在PyCharm中会用到
(3)打开Anaconda Prompt,使用以下命令可以查看当前有哪些虚拟环境
conda env list 可以看到,base环境是下载Anaconda自带的,DL是刚才我们新建的。
可以使用下面的命令进入DL环境
conda activate DL 在这个全新的环境下可以下载Python项目依赖的模块。
4.安装PyTorch和部署yolov5代码 (1)如果电脑没有配备GPU显卡,可以先使用CPU版本的PyTorch,对于初学者不会有太大影响,安装起来也比较简单。
访问:PyTorch官网
点击上述配置就生成了在conda prompt下的安装命令。
conda install pytorch torchvision torchaudio cpuonly -c pytorch 回到刚才新建的DL环境,直接输入该命令,运行即可。然后安装完毕,可以使用下面的命令查看当前环境下已经安装好的模块和版本信息
pip list (2)yolov5代码部署和测试
在前面提供的网盘地址中,可以下载“yolov5-4.0.zip”,与之相匹配,权重文件也要下载对应4.0版本的(共计四个.pt文件,比较大)。把yolov5-4.0解压缩后,放在一个不含有中文字符的路径下:(建议放在一个空间比较大的位置) 下载权重文件后,移动到yolov5-4.0\weights目录下: 在DL环境下通过requirements.txt来安装yolov5依赖的模块: pip install -r requirements.txt 可能会出现下面的报错:解决办法是解压缩网盘中的“pycocotools2.0.2.rar”的两个文件夹移到新建的DL环境下(需要先找到Anaconda安装包的位置!)
以我的路径为例,是:
D:\Software_Download\Anaconda_Install\Anaconda3\envs\DL\Lib\site-packages 移动后如下图所示:
重新执行刚才的命令,就不会报错了。
运行测试程序:在DL环境的命令行中输入以下命令: python detect.py --source data\Images\bus.jpg --weights weights\yolov5s.pt --img 640 可能会出现以下报错:
这是PyTorch代码的小问题,修改方法:找到DL环境的目录,进入Lib\site-packages\torch\nn\modules例如:
D:\Software_Download\Anaconda_Install\Anaconda3\envs\DL\Lib\site-packages\torch\nn\modules 打开upsampling.py,大概在151行的位置,进行如下修改:
return F.interpolate(input, self.size, self.scale_factor, self.
当涉及到Nginx的详细教程,由于篇幅限制,我无法在单个回答中提供完整的教程。然而,我可以为您提供一个简单而清晰的指南,以帮助您开始使用Nginx。
1. 安装Nginx
- 在Linux上,您可以使用包管理器安装Nginx。例如,在Ubuntu上,您可以运行以下命令进行安装:
```
sudo apt update
sudo apt install nginx
```
- 在macOS上,您可以使用Homebrew进行安装。运行以下命令:
```
brew install nginx
```
- 在Windows上,您可以从Nginx官方网站下载适用于Windows的安装程序,并按照安装向导进行安装。
2. 启动和停止Nginx
- 在Linux上,Nginx安装完成后会自动启动。您可以使用以下命令来启动、停止或重新加载Nginx:
```
sudo systemctl start nginx # 启动Nginx
sudo systemctl stop nginx # 停止Nginx
sudo systemctl reload nginx # 重新加载Nginx配置
```
- 在macOS上,您可以使用以下命令来启动、停止或重新加载Nginx:
```
sudo nginx # 启动Nginx
sudo nginx -s stop # 停止Nginx
sudo nginx -s reload # 重新加载Nginx配置
```
- 在Windows上,您可以在Nginx的安装目录中找到`nginx.exe`文件,并使用命令提示符运行相应的命令。
通常Xilinx FPGA时钟二选一用如下原语实现,其中S为时钟选择输入,I0和I1为两路时钟输入,O为一路时钟输出。
BUFGMUX #(
)
BUFGMUX_inst (
.O(O), // 1-bit output: Clock output
.I0(I0), // 1-bit input: Clock input (S=0)
.I1(I1), // 1-bit input: Clock input (S=1)
.S(S) // 1-bit input: Clock select
);
BUFGMUX类似assign clkout = sel ? clkin1 : clkin0;这样一个功能,但是为什么不直接用assign语句呢?
因为用assign作二选一的话,会用到逻辑资源里的选择器,时钟信号会偏离全局时钟树进入选择器,这样可能会造成一些问题。
对于低速时钟可以考虑使用assign作切换,但是不建议这么做。高速时钟切换需要使用原语。在Vivado开发环境下,如果使用到时钟二选一的场景,如何对时钟进行约束有如下说明。
通常来讲,时钟二选一之后会驱动部分时序元件,也就是两个时钟具有重复时钟路径。如下图的例子。
clk125 和 clk250 是 clkcore_buf 的两个输入时钟,这两个时钟经过BUFGCTRL(在Xilinx 7系列FPGA中,直接使用BUFGMUX会消耗一个BUFGCTRL资源)后有重复时钟路径,针对这两个时钟做如下约束:
create_generated_clock -name clk125_bufgctrl \
-divide_by 1 [get_pins bufgctrl_i/O] \
-source [get_ports bufgctrl_i/I0]
create_generated_clock -name clk250_bufgctrl \
-divide_by 1 [get_pins bufgctrl_i/O] \
正常情况下使用malloc申请内存,要么是申请成功返回有效地址,要么是内存申请失败(内存不足)返回NULL
如果出现返回了地址却无法访问的情况,很有可能是前面代码访问内存时出现了越界(在有效内存外进行了写入)的情况,影响到了malloc时申请内存所需要的相关信息
但还有一种情况是已排除前面越界的可能,但仍然无法访问内存
目前该情况目前只在.c文件的x64位的visual studio 2017中遇见过(其他版本不确定)
malloc申请内存成功时,本身是返回void *类型的指针的,但在visual studio编译源码时,它并不包含stdlib.h,并采用了一些自己的定义,返回int类型,这就导致x64中的8字节指针在发生强转时,缺失了4字节
解决方案: 在每个使用malloc的文件中加上include <stdlib.h>,或是定义一些宏,这将保证生成的源文件能包含stdlib.h
一.创建和使用
1.数组定义
①声明数组:使用数组前都需要声明
②形式:
elementType [ ]arrayName;
elementType arrayName[ ];
❶elementType为数组元素类型,可以是基本数据类型(booleam型或char型),引用类型(String型或Employee等);
❷arrayName为数组名,是一个引用产量;
❸[ ]指明变量为数组变量,既可以放在变量前面,也可以在后面
例如,这几个数组:
double [ ]marks;
String [ ]words;
②创建数组:为数组的每个元素分配储存空间
一般格式为:
arrayName = new elementType[arraySize];
该语句功能是分配arraySize个elementType 类型的存储空间,并通过 arrayName来引用。
例如:
marks= new double[5];
数组包含5个double型元素
words = new String[3];
数组包含3个String型元素
数组的声明与创建可以写在一个语句中。例如
double [ ]lmarks = new double[5];
String [ ]words = new String[3];
当用new运算符创建一个数组时,系统就为数组元素分配了存储空间,这时系统根据指定的长度创建若千存储空间并为数组每个元素指定默认值。对数值型数组元素默认值是0;字符型元素的默认值是\u0000;布尔型元素的默认值是false;如果数组元素是引用类型,其默认值是null。
前面两个语句分别分配了5个double 型和3个String类型的空间,并且每个元素使用默认值初始化。两个语甸执行后效果如图5-1所示。数组 marks的每个元素都被初始化为0.0,而数组words的每个元素被初始化为null。
2.访问数组元素:声明并用new分配空间后可以使用每一个元素。方法为:
arrayName [index]
其中,index为数组元素下标或索引,下标从0开始,到数组的长度减1。例如,上面定义的words数组定义了三个元素,所以只能使用words[0]、words[1]和words[2]这三个元素。数组一经创建大小不能改变。
数组作为对象提供了一个length成员变量,它表示数组元素的个数,访问该成员变量的方法为arrayName.length。
下面程序演示了数组的使用和length成员的使用。
ArrayDemo.java
package com. demo;
public class ArrayDemo{
同行列对角线的格 题目描述 输入三个自然数 N N N, i i i, j j j( 1 ≤ i ≤ n 1 \le i \le n 1≤i≤n, 1 ≤ j ≤ n 1 \le j \le n 1≤j≤n),输出在一个 N × N N \times N N×N 格的棋盘中(行列均从 1 1 1 开始编号),与格子 ( i (i (i, j ) j) j) 同行、同列、同一对角线的所有格子的位置。
如: n = 4 n=4 n=4, i = 2 i=2 i=2, j = 3 j=3 j=3 表示了棋盘中的第二行第三列的格子,
当我们遇到请求后台接口遇到 Access-Control-Allow-Origin 时,那说明跨域了。
跨域是因为浏览器的同源策略所导致,同源策略(Same origin policy)是一种约定,它是浏览器最核心也最基本的安全功能,同源是指:域名、协议、端口相同
解决跨域常用方法:
一、VUE中常用proxy来解决跨域问题
1、在vue.config.js中设置如下代码片段
module.exports = { dev: { // Paths assetsSubDirectory: 'static', assetsPublicPath: '/', proxyTable: { // 配置跨域 '/api':{ target:`http://www.baidu.com`, //请求后台接口 changeOrigin:true, // 允许跨域 pathRewrite:{ '^/api' : '' // 重写请求 } } }, } 复制
2、创捷axioss实例时,将baseUrl设置为 ‘/api’
const http = axios.create({ timeout: 1000 * 1000000, withCredentials: true, BASE_URL: '/api' headers: { 'Content-Type': 'application/json; charset=utf-8' } }) 复制
二、JSONP解决跨域
Jsonp(JSON with Padding) 是 json 的一种”使用模式”,可以让网页从别的域名(网站)那获取资料,即跨域读取数据。
如何选择合适的消息队列 Kafka、RabbitMQ、RocketMQ 如何选择合适的消息队列 Kafka、RabbitMQ、RocketMQ一、概述二、简介:Kafka RabbitMQ RocketMQ1. Kafka概述优点缺点适用场景 2. RabbitMQ概述优点缺点适用场景 3. RocketMQ概述优点缺点适用场景 分析说明:Kafka RabbitMQ RocketMQ 三、多维度对比1. 吞吐量2. 可靠性3. 稳定性4. 扩展性5. 协议支持6. 社区支持7. 访问速度四、不同业务下的选择(1)低延迟高吞吐量需求(2)实时性要求不高的数据存储(3)处理千万级别以上的数据(4)偏重于批处理等离线业务的数据传输 2. 结论 五、 小结1. 消息队列系统的价值2. 小结对比 如何选择合适的消息队列 Kafka、RabbitMQ、RocketMQ 一、概述 消息队列(Message Queue)可以在不同的系统或应用程序之间传递数据和消息。利用消息队列,应用程序可以异步地进行数据交换,解耦应用程序和提高系统可扩展性。以下是消息队列的常见应用场景:
异步处理:当应用程序需要执行一些非实时的操作时,可以将它们放在消息队列中进行异步处理。解耦系统:消息队列可以将应用程序解耦,降低系统的耦合性。缓存/削峰:将消息存储在消息队列中,可以在高峰期将流量平滑分配给后端服务,有效控制系统的负载。分布式架构:消息队列可以支持分布式架构,使得分布式系统更加高效、稳定。 二、简介:Kafka RabbitMQ RocketMQ 1. Kafka概述 Kafka 是一个可扩展、高性能、分布式的消息队列系统。Kafka 采用分布式的发布-订阅模式,消息可以存储在磁盘上,可以保证高吞吐量的写入和读取操作
以下是 Kafka 的优点和缺点:
优点 可以保证高吞吐量的写和读非常可靠、容错能力强可以水平扩展 缺点 部署复杂,需要管理多个节点对于应用程序来说,需要自己管理偏移量 适用场景 大量数据的批量处理数据流处理 2. RabbitMQ概述 RabbitMQ 是一个开源的 AMQP(高级消息队列协议)消息队列系统,支持多个客户端的连接。RabbitMQ 简单易用,对实时性和可用性的保证非常强。以下是 RabbitMQ 的优点和缺点:
优点 对实时性和可用性的保证非常强可以支持多种协议拥有丰富的Web管理界面 缺点 性能较差,无法处理大数据量单节点运行时,数据的可用性不高 适用场景 实时消息传递任务队列 3. RocketMQ概述 RocketMQ 是一个分布式、可靠、高效的消息队列系统。RocketMQ 的应用场景非常广泛,可以用于大数据处理、电商、金融等众多领域。以下是 RocketMQ 的优点和缺点:
响应码(Response Code)是指在HTTP协议中,服务器向客户端返回的响应状态码,用来表示服务器处理请求的结果是否成功或出现了错误。响应码由三位数字组成,第一位数字定义了响应的类别,后两位数字没有分类的作用。
下面是一些常见的响应码及其含义:
1xx:信息响应类,表示接收到请求并且继续处理
100 Continue:客户端应继续发送请求。这个临时响应是告诉客户端,已经收到请求,但是没有响应。客户端应该继续发送请求,直到服务器返回一个正常的响应。101 Switching Protocols:服务器已经理解请求,并且可以切换到其他协议,比如 WebSocket。 2xx:成功响应类,表示动作被成功接收、理解和接受
200 OK:请求已成功,请求所希望的响应头或数据体将随此响应返回。201 Created:请求成功并且服务器创建了新的资源。 3xx:重定向响应类,表示需要客户端进行进一步的操作才能完成请求
301 Moved Permanently:请求的网页已永久移动到新位置。302 Found:请求的网页已临时移动到新位置。 304 Not Modified:缓存未更新,客户端的缓存资源是最新的,服务器告诉客户端可以使用本地缓存。
4xx:客户端错误响应类,表示客户端发送的请求有误
400 Bad Request:请求错误,服务器不理解请求的语法。401 Unauthorized:请求未授权。 403 Forbidden:拒绝访问,服务器拒绝该请求。
404 Not Found:未找到,请求的资源不存在。
5xx:服务器错误响应类,表示服务器无法完成合法请求的处理
500 Internal Server Error:服务器遇到了一个未曾预料的状况,导致了它无法完成对请求的处理。 502 Bad Gateway:错误的网关,作为代理或网关的服务器从上游服务器接收到的响应无效。
503 Service Unavailable:服务器当前无法处理请求,可能是由于过载或停机维护。 其中,例如404、500等是常见的错误响应码。而像200、201等则表示请求成功,请求的资源已经找到或者已经被创建。根据不同的响应码,客户端可以做出相应的处理,比如重新发送请求、重定向、提示用户等等。
标题 一.MapReduce框架原理(下)1.1 OutputFormat数据输出1.1.1 OutputFormat接口实现类1.1.2 自定义OutputFormat案例实操 1.2 MapReduce内核源码解析1.2.1 MapTask工作机制1.2.2 ReduceTask工作机制1.2.3 ReduceTask并行度决定机制1.2.4 MapTask & ReduceTask源码解析 一.MapReduce框架原理(下) 1.1 OutputFormat数据输出 1.1.1 OutputFormat接口实现类 OutputFormat是MapReduce输出的基类,所有实现MapReduce输出都实现了 OutputFormat接口。下面我们介绍几种常见的OutputFormat实现类:
1.OutputFormat实现类(默认输出格式为TextOutputFormat 按行读取)
2.自定义OutputFormat
应用场景:如,输出数据到MYSQL/HBase/Elasticsearch等存储框架中
步骤:自定义一个类继承FileOutputFormat --> 改写RecordWriter,具体改写输出数据的write()方法
1.1.2 自定义OutputFormat案例实操 1)需求
过滤输入的 log 日志,包含 atguigu 的网站输出到 D:\java_learning\output\outputformat1,不包含 atguigu 的网站输出到 D:\java_learning\output\outputformat2。
(1)输入data
(2)期望输出数据
两个txt文件:
2)需求分析
3)案例实操
(1)编写 LogMapper 类
package com.root.mapreduce.OutPutFormat; import org.apache.hadoop.io.IntWritable; import org.apache.hadoop.io.LongWritable; import org.apache.hadoop.io.NullWritable; import org.apache.hadoop.io.Text; import org.apache.hadoop.mapreduce.Mapper; import java.io.IOException; public class LogMapper extends Mapper<LongWritable, Text,Text, NullWritable> { @Override protected void map(LongWritable key, Text value, Mapper<LongWritable, Text, Text, NullWritable>.
🌺 作者主页: 🌱仙女不下凡🌱
🌺 欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正!
v-on event '@showSizeChange' must be hyphenated 报错意思是 v-on事件“@showSizeChange”必须使用连字符 针对驼峰的错误提示,修改为连字符即可
解决方法
@showSizeChange ------- > @show-size-change
记得以前opkg一直是好的,但是今天切到mt7621上面突然发现不能用
一开始提示opkg update的时候:
说明网站不对,也就是openwrt的源不对
修改opkg源,位置在板子上/etc/opkg/distfeeds.conf文件里
查了好多源,最终还是官方源可以使用
官方源如下:
src/gz openwrt_core Index of /releases/21.02.0/targets/x86/64/packages/
src/gz openwrt_base Index of /snapshots/packages/x86_64/base/
src/gz openwrt_luci Index of /snapshots/packages/x86_64/luci/
src/gz openwrt_packages Index of /snapshots/packages/x86_64/packages/
src/gz openwrt_routing Index of /lede/snapshots/packages/x86_64/routing/
src/gz openwrt_telephony Index of /lede/snapshots/packages/x86_64/telephony/
官方源你也得选对型号,
core中他的是x86,而我的是mt7621
base和后面的是x86_64,而我的是mipsel_24kc
修改好了还是不对,提示别的错误:
提示wget: SSL support not available, please install one of the libustream-ssl-* libraries as well as the ca-bundle and ca-certificates packages
说明缺依赖的库:
make menuconfig的时候选择libustream-openssl,ca-certificates,还有wget都选上(如果opkg install可以用就直接opkg install 这几个库),
之后就不会提示这个问题了,但是opkg update还是没解决,提示如下:
1.进入mysql官网 2.点击DOWNLOADS去下载页面,页面往下滚动,点击MySQL Community (GPL) Downloads »下载社区版 3.点击MySQL Installer for Windows–>选择window安装版 4.选择下面这一项,点击Download 5.点击No thanks, just start my download. 6.然后会弹出一个提示框,可以选择下载到任意一个目录 7.我习惯新建一个install目录,用于存放软件安装包 8.双击下载好的文件 - mysql-installer-community-8.0.33.0,接下来就进行安装过程,选择默认安装模式Developer Default后点击Next 9.点击Next 10.点击Execute进行安装 11.等待安装过程,安装速度取决于电脑性能,可能10分钟也可能半小时 12.安装完成点击Next 13.继续点击Next 14.以下信息默认,继续点击Next 15.选择第一个,点击Next 16.设置Mysql的密码,然后点击Next 17.点击Next 18.点击Next 19.点击Execute开始安装 20.出现successful字样,那么恭喜你,已经成功安装mysql8.0,然后点击Finish 21.点击Next 22.点击Finish 23.输入密码,点击Check测试是否连接成功,如果出现Connection succeeded代表连接成功 24.点击Execute安装 25.点击Finish完成安装 26.配置MySQL环境变量,找到MySQL安装目录,复制 27.右键此电脑,打开环境变量 28.新建一个系统变量 29.选中Path系统变量,然后点击编辑 30.点击新建 然后一直点击确定,就配置好了
31.打开命令行工具win+R,输入cmd进入命令行窗口 输入密码,然后连接上MySQL
可以通过命令对数据库做一些操作,比如创建数据库,新建表等等,也可以通过可视化界面工具连接MySQL数据库
此篇叙述到此结束
矩阵交换行 题目描述 给定一个 5 × 5 5 \times 5 5×5 的矩阵(数学上,一个 r × c r \times c r×c 的矩阵是一个由 r r r 行 c c c 列元素排列成的矩形阵列),将第 n n n 行和第 m m m 行交换,输出交换后的结果。
输入格式 输入共 6 6 6 行,前 5 5 5 行为矩阵的每一行元素,元素与元素之间以一个空格分开。
第 6 6 6 行包含两个整数 m m m、 n n n,以一个空格分开( 1 ≤ m , n ≤ 5 1 \le m,n \le 5 1≤m,n≤5)。
1. 场景:在改进yolov7过程中出现错误。
2. 解决:可以尝试将batch_size调小。
文章目录 一. 队列操作:可以使用哈希类型来实现队列操作,例如将任务放入队列中等待处理。二. 地理位置信息:哈希数据类型支持地理位置相关操作。例如,在一个应用程序中,可以使用哈希表来储存城市名称和对应的经纬度坐标。三. 配置文件:哈希数据类型适合用于储存配置文件。例如,在一个Web应用程序中,可以使用哈希表来保存各种配置参数(如数据库连接参数、日志级别等)。四. 对象属性存储:适合用于存储对象的各个属性,如用户信息、商品信息等。五. 缓存:可以将经常访问的数据存储在哈希类型中,以便快速读取和响应客户端请求。六. 计数器:可以使用哈希类型来实现计数器功能,每个键对应一个计数器,值为计数器的当前值。七. 数据过滤:可以使用 Redis 哈希数据类型来存储需要过滤的关键字,然后在应用程序中进行匹配和过滤。八. 统计网站访问量:可以使用redis哈希数据类型来记录网站每个页面的访问量,以便进行统计分析。九. 分布式锁:可以使用 Redis 哈希数据类型来实现分布式锁,保证多个进程或线程对同一资源的互斥访问。十一. 统计用户行为:如果你需要统计用户的行为,如点击次数、购买次数等,那么可以使用哈希数据类型来进行统计。通过使用哈希数据类型,在每个键中记录用户对应行为的数量,并且可以很方便地进行更新和查询。十二. 缓存页面内容:如果你需要缓存一些页面内容,以提高网站的访问速度,那么可以使用哈希数据类型来进行缓存。通过使用哈希数据类型,可以将每个页面的内容都存储在一个键下面,并且可以很方便地进行更新和查询。 一. 队列操作:可以使用哈希类型来实现队列操作,例如将任务放入队列中等待处理。 队列是一种常见的数据结构,它遵循先进先出(FIFO)的原则,即先进入队列的元素先被处理。在实际应用中,我们常常需要将任务放入队列中等待处理,这时可以使用哈希类型来实现队列操作。
具体来说,可以使用Redis的哈希类型来实现队列操作。假设我们有一个任务队列,其中每个元素包含任务的ID和任务的内容,可以将每个元素存储为一个哈希类型,其中哈希的key为任务的ID,哈希的value为任务的内容。将任务放入队列中等待处理时,可以使用Redis的LPUSH命令将任务ID放入一个列表中,然后使用Redis的HMSET命令将任务的内容存储为一个哈希类型。当需要处理任务时,可以使用Redis的RPOP命令从列表中取出任务ID,然后使用Redis的HGETALL命令获取任务的内容。处理完成后,可以使用Redis的HDEL命令将任务从哈希中删除。
使用哈希类型来实现队列操作的优点是可以方便地存储和获取任务的内容,同时避免了重复存储相同的内容。缺点是需要额外的存储空间来存储任务的内容,同时需要注意同步列表和哈希的操作,以避免数据不一致的情况发生。
将任务ID放入队列中等待处理:
redis_conn.lpush("task_queue", task_id) 将任务的内容存储为一个哈希类型: redis_conn.hmset(task_id, {"content": task_content}) 从队列中取出任务ID: task_id = redis_conn.rpop("task_queue") 获取任务的内容: task_content = redis_conn.hgetall(task_id) 将任务从哈希中删除: redis_conn.hdel(task_id, "content") 二. 地理位置信息:哈希数据类型支持地理位置相关操作。例如,在一个应用程序中,可以使用哈希表来储存城市名称和对应的经纬度坐标。 三. 配置文件:哈希数据类型适合用于储存配置文件。例如,在一个Web应用程序中,可以使用哈希表来保存各种配置参数(如数据库连接参数、日志级别等)。 配置文件通常包含大量的键值对,且这些键值对经常需要被读取和更新。哈希数据类型提供了一种快速的查找和更新方式,因此非常适合用于储存配置文件。
在一个Web应用程序中,通常需要保存许多配置参数,例如数据库连接参数、日志级别、缓存配置等等。这些配置参数经常需要被读取和更新,而哈希表提供了O(1)时间复杂度的查找和更新操作,使得读取和更新配置参数非常高效。
此外,哈希表还具有灵活性,可以根据需要动态地添加或删除配置项,而不需要修改整个配置文件。这使得应用程序的配置管理更加方便和可扩展。
以下是一个使用Redis哈希数据类型储存Web应用程序配置文件的代码例子:
import redis # 连接Redis数据库 r = redis.Redis(host='localhost', port=6379, db=0) # 定义配置文件 config = { 'db_host': 'localhost', 'db_port': 3306, 'db_user': 'root', 'db_password': 'password', 'log_level': 'info' } # 将配置文件储存为Redis哈希 r.
一、需要的东西 Opencv4.5.2的zip包(OpenCV官网下载)
二、操作步骤 1. 上传opencv4.5.2的zip包到home目录(不一定home目录,根据运维情况决定)
2. 运行解压缩命令
unzip opencv-452.zip 3. 进入opencv-452文件夹,创建文件夹
cd opencv-452 mkdir build 4. 进入文件夹中
cd build 5. 如果没有安装cmake,使用下列命令安装,并且查看版本信息。
sudo yum install cmake cmake -version 需要高一点的版本,我安装的是cmake version 3.7.2版本,如果版本过低会提示升级版本。
解决方法: (1)移除老版本cmake版本并安装依赖包
yum remove cmake -y ; yum install -y gcc gcc-c++ make automake openssl openssl-devel (2)下载cmake-3.7.2.tar.gz安装包并解压 cmake官网地址,或者直接命令安装
wget https://cmake.org/files/v3.7/cmake-3.7.2.tar.gz ; tar -zxf cmake*.tar.gz (3)编译/安装
cd cmake* ; ./bootstrap ; gmake -j `grep 'processor' /proc/cpuinfo | wc -l` ; gmake install (4)查看编译后的cmake版本并创建连接
Python中的深拷贝和浅拷贝 Python中的拷贝分为深拷贝和浅拷贝两种方式。 浅拷贝 浅拷贝(shallow copy)指的是将一个对象的引用赋值给另一个变量,这样两个变量指向的是同一个对象,当其中一个变量修改该对象时,另一个变量也会受到影响。 深拷贝 深拷贝(deep copy)则是创建一个新的对象,新对象与原对象完全独立,两个对象互不影响。 用法 在Python中,可以使用copy模块中的copy()函数来进行浅拷贝,也可以使用copy模块中的deepcopy()函数来进行深拷贝。 例子 下面是一个简单的例子,演示了浅拷贝和深拷贝的区别:
import copy # 浅拷贝 a = [[1, 2], [3, 4]] b = copy.copy(a) b[0][0] = 0 print(a) # 输出 [[0, 2], [3, 4]] print(b) # 输出 [[0, 2], [3, 4]] # 深拷贝 c = [[1, 2], [3, 4]] d = copy.deepcopy(c) d[0][0] = 0 print(c) # 输出 [[1, 2], [3, 4]] print(d) # 输出 [[0, 2], [3, 4]] 可以看到,当对浅拷贝的结果进行修改时,原始对象也会受到影响;而对深拷贝的结果进行修改时,原始对象不受影响。 总结 在实际开发中,我们通常需要根据需要选择浅拷贝还是深拷贝。通常来说,浅拷贝适用于小规模的数据处理,而深拷贝则适用于需要保留原始数据结构的情况。
文章目录 GNN图神经网络的元素消息传递方式 GCN消息传递方式 GAT消息传递机制 GNN 图神经网络的元素 节点,邻接矩阵
为什么要计算多层
邻居的邻居,融合多阶邻居特征 消息传递方式 图神经网络是一个相对宽泛的概念,本质是每个节点embedding都要融合邻居的特征,根据具体融合方式的不同又衍生出了下面各种具体模型。
最简单的GNN消息传递可以看做fc,所有邻居节点以权重w向当前节点加权,最终取一个mean/max/min等激活函数。
GCN 消息传递方式 Z = A X W Z=AXW Z=AXW,A为调整后的邻接矩阵,X是节点 embedding,W是可训练参数
调整后的邻接矩阵即对原始邻接矩阵做归一化,乘以度矩阵D,分左右各乘 D 1 / 2 D^{1/2} D1/2,做行、列归一化
GCN可以做半监督任务,部分节点没有标签,计算loss时只是用有标签的。一般层数3-5层即可,过大效果不好 GAT 消息传递机制 增加了attention结构,计算一阶邻居节点之间的相似度,进行加权
e i j = L e a k y R e L U ( W a ( W f x i ⊕ W f x j ) ) e_{ij}=LeakyReLU(W_a(W_fx_i\oplus W_fx_j)) eij=LeakyReLU(Wa(Wfxi⊕Wfxj))
α i j = e x p ( e i j ) ∑ o ∈ N ( i ) e x p ( e i o ) \alpha_{ij}=\frac{exp(e_{ij})}{\sum_{o\in N(i)}exp(e_{io})} αij=∑o∈N(i)exp(eio)exp(eij)
内部淬灭(FRET)底物Abz-DDIVPCSMSY(NO₂)T-NH₂允许直接,特异性检测NS3-4A蛋白酶活性(Km = 51 +/- 3 μM, kcat = 0.39 min⁻¹)。
编号: 200003
中文名称: Abz-Asp-Asp-Ile-Val-Pro-Cys-Ser-Met-Ser-Tyr(3NO2)-
CAS号: 852572-93-1
单字母: Abz-DDIVPCSMS-Y(3NO2)-T-NH2
三字母: Abz-Asp-Asp-Ile-Val-Pro-Cys-Ser-Met-Ser-Tyr(3NO2)-Thr-NH2
氨基酸个数: 11
分子式: C58H84N14O22S2
平均分子量: 1393.5
精确分子量: 1392.53
等电点(PI): 3.9
pH=7.0时的净电荷数: -1.03
平均亲水性: 0.066666666666667
疏水性值: 0.22
来源: 人工化学合成,仅限科学研究使用,不得用于人体。
储存条件: 负80℃至负20℃
通过网上了解的解决方法,我尝试了三种,来解决rg.exe、git.exe内存占用过大的问题,以及插件的原因。效果最明显的方法是我卸载了C/C++插件。
第一种方法:
VS Code→文件→首选项→设置→搜索
search.followSymlinks:false
第二种方法:
VS Code→文件→首选项→设置→搜索Code Actions On Save。
"git.enabled": false 通过前两种方法,我的电脑cpu占用率从90%多降到了60%。
第三种方法是解决插件问题,这也是引起我电脑上的vscode高cpu占用率的原因:
直接以管理员身份运行vscode,建议卸载微软提供的c/c++扩展。最后记得重启,我电脑的cpu占用率最终下降到了6%。
参考链接:
解决vs-code高cpu占用率问题
如何解决vscode频繁唤起git for Windows 导致电脑内存占用多大,cpu占用率飙升、风扇狂转问题_vscode占用cpu过高_一只花小妖的博客-CSDN博客
https://www.cnblogs.com/angel648/p/12872523.html
1.下载 地址:RXTX for Java
2.部署到Windows
下载完成后将rxtxSerial.dll文件放到java的对应目录下(如图)
然后把RXTXcomm.jar包引入到项目中或者使用maven引入都可以
本地jar包直接引入
在项目根目录下新建lib文件夹并导入RXTXcomm.jar,然后在pom中引入本地jar包即可
<dependency> <groupId>com.test</groupId> <artifactId>rxtxcomm</artifactId> <version>2.2</version> <scope>system</scope> <systemPath>${basedir}/lib/RXTXcomm.jar</systemPath> </dependency> maven引入:在pom中写入如下内容即可
<dependency> <groupId>org.bidib.jbidib.org.qbang.rxtx</groupId> <artifactId>rxtxcomm</artifactId> <version>2.2</version> </dependency> 3.编码
import gnu.io.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Enumeration; import java.util.TooManyListenersException; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; public class SerialPortDataHandle extends Thread implements SerialPortEventListener { private static final Logger logger = LoggerFactory.getLogger(SerialPortDataHandle.class); // 通讯端口管理,控制对通信端口的访问的中心类 static CommPortIdentifier portManager; // 有效连接上的端口的枚举 static Enumeration<?
wvp修改以下配置:
docker 部署zlmediakit
docker pull zlmediakit/zlmediakit 运行zlm容器
docker run -id -p 1935:1935 -p 8080:80 -p 8443:443 -p 8554:554 -p 10000:10000 -p 10000:10000/udp -p 8000:8000/udp -p 9000:9000/udp -p 30000-30500:30000-30500/tcp -p 30000-30500:30000-30500/udp zlmediakit/zlmediakit:master
内外网开启端口时要注意红圈部分需要同时开通TCP+UDP
wvp+zlm都启动成功的情况下访问wvp部署的服务器ip+wvp端口(默认18080)出现以下页面, 默认账号密码都是admin
国标设备是下级自动注册的,何为下级?比如:wvp显示海康IPC,则海康IPC为下级,wvp为上级,在比如:如果其他平台想显示wvp的部分设备视频,则wvp为下级,其他平台为上级。
如果点播视频是zlm报错ssrc超时,这时候可以点击编辑按钮,去掉ssrc勾选
如果设备注册不上来检查下海康网络是否正常, 自动获取即可, 静态地址要确认ip地址未被占用
设备注册上来之后修改收流ip(公网地址)和密码(海康28181页面密码), 选择部署的zlm节点
然后点击通道, 点击播放,正常会弹出摄像头窗口, 如果一直转圈且wvp返回收流超时或点播超时
首先检查wvp与zlm版本是否一致, 单个版本过高或过低都会影响,成功播放会出现弹出下面窗口
如果弹窗视频未播放, 黑屏一直等待播放中检查下面地址是否是公网地址, 内外网开发的端口尽量保持一致, 比如内网8080逗号外网也是8080,这样能避免后面ip是公网的, 但端口是内网的。很多时间超时问题基本上都是配置或者网络问题, 把这两项都检查一遍能解决大部分超时问题。
Java NIO(New IO)是Java 1.4版本中引入的一套全新的IO处理机制,与之前的传统IO相比,NIO具有更高的可扩展性和灵活性,特别是在网络编程和高并发场景下,表现得更为出色。
NIO提供了四个核心组件:Channel、Buffer、Selector和SelectionKey,通过它们的协同配合,实现数据的读写和同步、非同步IO操作。本文将从基础概念、核心组件、使用方法等方面全面详细地介绍Java NIO,总字数约8000字。
一、基础概念
1.1 IO和NIO的区别
Java IO和NIO的主要区别在于两者的处理方式不同。Java IO是面向流(Stream)的,它将输入输出数据直接传输到目标设备或文件中,以流的形式进行读写;而NIO则是面向缓冲区(Buffer)的,它将会使用缓存去管理数据,使得读写操作更加快速和灵活。
特别是在网络编程和高并发场景下,Java NIO表现得更为出色。Java IO在进行网络通信时,每个客户端连接都需要创建一个线程来进行处理,这样会导致系统资源的浪费。Java NIO则只需要一个线程就可以完成对多个客户端连接的处理,大大减少系统资源的占用。
1.2 缓冲区
缓冲区是Java NIO中一个非常重要的概念,它是用来存储IO操作的数据的一段连续区域。缓冲区可以在内存中创建,并可以通过通道(Channel)进行读写操作,也可以作为参数传递给其他方法。除此之外,缓冲区还有特定的类型,例如ByteBuffer、CharBuffer、IntBuffer等。
不同类型的缓冲区都包含以下几个基本属性:
Capacity:容量,缓冲区中最多可以存储的元素数量;Position:当前位置,下一个要被读取或写入的位置;Limit:限制,缓冲区中的限制,表示可以读写的元素数量;Mark:标记,可以让缓冲区记住一个position或limit的值,通过调用reset()方法来恢复到这些值。 缓冲区的读写操作都会修改position和limit属性,例如在从缓冲区中读取数据时,position属性会自动向后移动,而limit属性则不会更改,因此读取操作只能读取到limit位置之前的数据。
1.3 通道
通道(Channel)是Java NIO中网络或文件IO操作的抽象,它类似于传统IO中的Stream,但是它更加灵活和高效。通道可以和缓冲区一起使用,让数据直接在缓冲区之间进行传输,可以使用Selector选择器实现非阻塞IO操作。
通道主要分为以下四种类型:
FileChannel:用于文件读写操作;DatagramChannel:用于UDP协议的网络通信;SocketChannel:用于TCP协议的网络通信;ServerSocketChannel:用于监听TCP连接请求。 在使用NIO进行网络编程时,我们常常使用SocketChannel和ServerSocketChannel来实现客户端与服务器之间的通信。使用FileChannel可以完成对本地文件的读写操作,使用DatagramChannel可以发送和接收UDP协议的数据包。
1.4 选择器和选择键
选择器(Selector)和选择键(SelectionKey)是Java NIO提供的另外两个核心组件。选择器用于检测一个或多个通道的状态,并且可以根据通道状态进行非阻塞选择操作。而选择键则是一种将通道和选择器进行关联的机制。
使用选择器可以实现单线程管理多个通道的方式,以此实现高并发IO操作。在选择器的模型中,每个通道都会注册到一个选择器上,并且每个通道都有一个其唯一的选择键对象来代表这个通道。选择键对象包含几个标志位,表示通道的当前状态等信息。
选择器可以监听多个通道的事件,例如连接就绪、读取数据就绪、写入数据就绪等等。当有一个或多个通道的事件就绪时,选择器就会自动返回这些通道的选择键,我们可以通过选择键获取到对应的通道,然后进行相应的操作。
二、核心组件
Java NIO包含了四个核心组件:Channel、Buffer、Selector和SelectionKey。下面我们将分别介绍这四个组件的作用和使用方法。
2.1 Channel
Channel是Java NIO中网络通信和文件IO操作的抽象,类似于传统IO中的Stream。它可以支持双向读写操作,并且可以通过缓冲区来直接进行数据读取或写入。通常情况下,我们会创建一个Channel对象,然后将其绑定到一个Socket、File、Pipe等资源上进行读写操作。
NIO中主要提供了以下几种类型的Channel:
FileChannel:用于文件读写操作;DatagramChannel:用于UDP协议的网络通信;SocketChannel:用于TCP协议的网络通信;ServerSocketChannel:用于监听TCP连接请求。 我们可以通过调用相应的工厂方法来创建不同类型的Channel。
2.1.1 FileChannel
FileChannel是Java NIO中对本地文件读写操作的封装。正如其名字所示,FileChannel对象是针对文件的Channel,通过FileInputStream或FileOutputStream来获取。通过FileChannel,我们可以实现对文件的读取和写入操作,也可以使用它的position()方法来控制读写位置,并配合Buffer进行数据操作。
下面是一个使用FileChannel读取文件的例子:
public static void main(String[] args) throws IOException { RandomAccessFile file = new RandomAccessFile("test.txt", "rw"); FileChannel channel = file.getChannel(); ByteBuffer buffer = ByteBuffer.
目录 一、MySQL学习路线二、MySQL常见操作1、查看所有数据库show databases。2、MySQL 创建数据库3、删除数据库4、选择数据库use databasename5、查看该数据库下所有表show tables6、创建数据库表7、删除数据库 三、增删改查1、插入数据2、查询数据3、where子句4、更新语句5、删除语句6、like语句7、UNION 操作符8、order by 排序9、GROUP BY分组 四、LEFT JOIN左连接、RIGHT JOIN右连接、INNER JOIN内连接五、NULL 值处理六、正则表达式七、MySQL基础知识总结 大家好,我是哪吒。
一、MySQL学习路线 二、MySQL常见操作 1、查看所有数据库show databases。 2、MySQL 创建数据库 CREATE DATABASE test;
3、删除数据库 drop database test;
4、选择数据库use databasename 5、查看该数据库下所有表show tables 6、创建数据库表 CREATE TABLE IF NOT EXISTS `student`( `id` INT UNSIGNED AUTO_INCREMENT, `name` VARCHAR(100) NOT NULL, `sex` VARCHAR(40) NOT NULL, `op_date` DATE, PRIMARY KEY ( `id` ) )ENGINE=InnoDB DEFAULT CHARSET=utf8; INT是整形;AUTO_INCREMENT表示自增;VARCHAR(100)表示字符串类型;NOT NULL表示非空;DATE时间数据类型;PRIMARY KEY主键;InnoDB设置存储引擎;CHARSET设置编码; 7、删除数据库 DROP TABLE student;
概述
智能卡接口(7816)是外部智能卡通过2 线交换8 位数据的串行同步通讯手段。芯片提供了2 个7816主机接口模块。
⚫ 2路独立7816接口
⚫ 具备卡时钟输出端口,输出频率在1MHz~5MHz之间可设
⚫ 位传输方向可配置,支持MSB First或LSB First
⚫ 错误信号宽度可配置为1/1.5/2个ETU
⚫ 发送数据支持传输错误重发机制,重发次数可配置为0~3次
⚫ 支持EGT可设0~256,并支持多种超时中断
⚫ 具有数据接收完成/接收错误中断,并提示错误类型
⚫ 发送中断产生条件可配置为缓冲区空或移位寄存器空
⚫ 支持DMA接口
接口时序
参照7816 协议标准,7816 基本接口时序如下:
⚫ 一个起始位后跟8个数据位及1个校验位,以1ETU或2ETU的GUARDTIME结束。
⚫ 单字节数据长度最小为11ETU或12ETU。
⚫ 第10.5个ETU接收电路校验接收数据,若校验正确,则插入2个ETU的GUARDTIME,确保数据长度为12ETU,并在第11个ETU时令RX_BUSY无效并产生可能的OE_ERR标志,完成数据发送;若接收校验出错,则在第10.5ETU拉低IO,产生ERROR SIGNAL。ERROR SIGNAL最短1个ETU,最长2个ETU。并在第11个ETU根据需要产生RPAR_ERR标志。
⚫ 第11个ETU时发送电路未采样到ERROR SIGNAL,则说明发送数据正确,数据发送完成,令TX_BUSY无效。
⚫ 若第11个ETU发送电路采样到ERROR SIGNAL,则说明发送数据错误,根据设定产生需要的TPAR_ERR或等待2个ETU后重发数据。
⚫ 所有中断标志尽可能都在同一时刻产生,使得MCU可以正确及时处理中断。
在服务中引入了swagger文档,但在生产环境需要屏蔽;
否定请求/v2/api-docs 、/swagger-ui.html可以看到所有api;
1、关闭swagger v3 springfox: documentation: # 总开关(同时设置auto-startup=false,否则/v3/api-docs等接口仍能继续访问) enabled: false auto-startup: false swagger-ui: enabled: false 2、关闭swagger v2 增加开关参数:swagger.enable
@Configuration @EnableSwagger2 @ConditionalOnProperty(name = "swagger.enable", havingValue = "true") public class SwaggerConfig { @Bean public Docket createRestApi() { return new Docket(DocumentationType.SWAGGER_2) .apiInfo(apiInfo()) .select() .apis(RequestHandlerSelectors.basePackage("com.xxx.controller")) .paths(PathSelectors.any()) .build(); } //构建 api文档的详细信息函数,注意这里的注解引用的是哪个 private ApiInfo apiInfo() { return new ApiInfoBuilder() .title("Swagger2 构建RESTful API") .description("User API 描述") .contact(new Contact("xx", "", "xx@xxx.com")) .version("1.0") .build(); } } 放置到应用配置中:
项目背景 前几个月开始做的项目,需要一个使用海洋场景。但是因为项目很急,所以海水需要使用别人已经写好的开源代码。当时就想起了Unity曾经有一个URP宣传片中的海水似乎还不错,于是便基于此项目的海水进行修改(Unity在GitHub上有两个项目,一个是Boat Attack,也就是宣传片中的项目,但海水是使用的旧版Boat Attack Water。另一个项目便是Boat Attack Water,后续有进行修改,这里采用的是新版。)
下载下来表现很奇怪,稍微修改一下海水的参数,效果其实还是达不到要求(刚导入还会有一些无关紧要的报错,记得好像是没有找到Resources文件夹下的设置文件还是什么,可以自己简单看一下报错位置,改改就没事了。当然能容忍打开项目就弹几个报错的话也可以不管,应该是不影响使用的):
表面只能看到白沫的海水(一开始我确实没搞懂这是什么,如果Bloom默认强度画面一片白) 图a. 把白沫参数调一调(基本是关了),贴着海面看还行? 图b. 稍微远一点完全不能看,如果再远一些就都是明显的贴图质感 项目时间跨度比较“长”(明明就才两三个月),很多东西我也记不太清了,再加上有些东西可能也不适合讲,所以就随便做个展示。
海水 因为海水可能主要是用于近景渲染同时也为了节省性能所以效果并不理想,于是在Shader里面一通乱改,在基本相同的海水和相机参数下,图片效果对比(光照、天空盒不一样但整体应该差的也不是特别大,海水颜色在尽量相同了):
原海水稍远景渲染效果,修改关键参数看不到任何的修改反馈,动起来感觉完全是贴图 基本上细腻很多,远处也更加自然一些,同时加了一些基于高度产生的白沫 基于贴图颜色来修改海水顶点位置、法线方向、以及白沫强度生成的动态尾迹:
网上随便找的贴图用粒子系统临时做的尾迹,效果一般但大概是那么个意思 补充:关于海水的实现 (可能会因为记忆错乱写错一些细节,主要是介绍该海水的大体实现思路,对细节感兴趣可以看源码)
Boat Attack Water的海水实际上分为近海面和远海面两部分。近海面使用的是始终跟随相机XZ坐标的一个固定网格模型(除此之外我了解到还有一种解决方案,大概是基于屏幕空间映射动态生成覆盖整个画面内海水的网格,好处是拉近可以渲染细节,而远离也可以渲染大场景)。但这个网格模型大小毕竟是有限的,覆盖不到地平线那么远,因此远处使用了一个法线向内的圆柱面,并将海水远景渲染在了上面。从上图b可以看到明显的分界,近处的海水会有顶点的偏移且渲染细节较多,远处看起来更加平坦,有明显的贴图感。
关于远海的部分没细看过就不瞎扯了,主要讲一下近海部分。
海浪:Gerstner叠加生成的,然后在vs里修改了顶点的位置和法线,问题在于如果面数不够密集的话会有很严重的失真(所以法线被我改到了ps里,但为了让远景看着不至于十分尖锐而且富有规律、以及避免摩尔纹等,包括海浪等各方面都做了点距离衰减)。
微表面:因为基本的海浪缺少了细腻海平面波动,因此实际上海水的法线还叠加了一层微表面贴图的扰动,图a中细腻的“皱纹”就是因此而来。
近岸白沫:基本上应该是使用的深度图之类的,对比一下场景和海面的深度,非常接近时会混合白沫(代码里好像简单看到过,因为不需要修改就没仔细看)。
海面白沫:没注意原本是怎么做的,因为刚打开项目发现很奇怪就直接被我关了。后来因为项目需要在海浪比较大的时候简单加一些白沫,我就采样了它自带的白沫贴图的其中一个通道然后混合了海面高度。
着色:主要包括折射、反射、太阳高光、SSS(其实还有混合白沫、雾那些)。折射大概是渲一张不透明物体图然后采样做一些扰动,反射提供几种选择,基本就用的平面反射,也是多渲一张图采样,高光用的URP里的DirectBDRF(),SSS应该是个近似解。最后的结果就是折射、反射用菲涅尔系数(用的URP里的F_Schlick()实现做了简单修改)做一个混合后叠加高光、SSS。
光谱渲染 实际上场景里的所有颜色都是通过光谱计算得到的,也就是从光源、材质到成像都是光谱数据。但完全实时的光谱渲染性能开销会非常大(简单理解就是原本rgb三通道相乘的部分变成了几十上百个通道相乘,仅此处开销就翻几十倍,而光谱渲染还会多一些额外步骤),于是考虑项目实际情况做了预计算,下边是一个基于光谱渲染的结果(即图片上方渲染的球或者立方体)与理论结果(背后的标准色板图片)的对比:
基于光谱渲染的球 模型换成了立方体,光照垂直入射,漫反射强度为1,仔细看会发现其实有细微误差 其实项目大部分时间在做一些业务逻辑、界面之类的方便调整各种参数、输出各种结果等等。这些主要是注意各种细节避免bug,比较无聊也学不到什么东西,就不再展示了。
Qt-AES加密库 AES在线加解密工具[1] Qt-AES加密库[2] Qt AES/DES加密算法库 软件/文件/任意长度字符串加密 试用期许可使用方法软件试用期算法对称加密和非对称加密非对称加密(Asymmetric Cryptography)实例总结加密算法 [3] Qt笔记-AES加密[4] AES 加密和解密 AES在线加解密工具 http://tool.chacuo.net/cryptaes/
[1] Qt-AES加密库 原文链接:https://blog.csdn.net/joyopirate/article/details/108746223
Qt_AES加密库源码下载
https://github.com/bricke/Qt-AES
从gitee上找到一个封装代码,https://gitee.com/BlueBuger/Qt-AES.git
将代码克隆到本地
git clone https://gitee.com/BlueBuger/Qt-AES.git 这个库支持:
密钥长度:
AES_128
AES_192
AES_256加密方式:
ECB
CBC
CFB
OFB填充方式:
ZERO
PKCS7
ISO 使用方法
http://www.lgwimonday.cn/archives/1976
/*加密步骤: * 1、设置字符串负载load、密码key、偏移量iv; * 2、字符串转字节数组; * 3、encryption.encode(input, key,iv)加密; * 4、base64编码输出; * 解密步骤: * 1、设置字符串密码key、偏移量iv、密文code; * 2、字符串转字节数组; * 3、密文base64解码; * 4、encryption.decode(code, key,iv)解密; * 5、QByteArray decode = QAESEncryption::RemovePadding(decodedText,QAESEncryption::PKCS7)移除填充; * 6、转字符串输出; */ 使用时只需要AES加密库的源代码中的这三部分,拷贝到自己的源代码文件夹,然后将 qaesencryption.h、qaesencryption.cpp加入到工程中就可以了。
项目场景 通过希冀平台做大数据spark中词频统计实验时,上传文件总是出bug。
问题描述 这次实验那个上传文件困扰了很久,周二上午写的时候就是不对,然后就问了老师,老师说是因为没有上传的原因,然后我就一步步的按照实验介绍里的备注一个个的弄,但发现总是不成功,出现一堆bug,做‘创建基础RDD和键值对RDDs’测试的时候因为没有成功上传test文件,所以test导入不成功。
于是又重新上传文件到Hadoop等等,但提示我Java 找不到,弄了一个小时还是不行,于是周三晚上又开始重新弄,甚至系统桌面还原,但这次我创建Hadoop文件路径它竟然提示我内存不足!!!很令人气愤!我又来回根据实验指导书配置并重新还原了两次,还是不行,这个时候,又出现了连接的问题。
我朋友说你重启试试,于是我重启电脑,这下算是可以了。
解决方案 以下是我的正确操作步骤
下载实验附件,首先点击附件,全选里面的内容,并复制粘贴到主机桌面上。再通过更多——>上传文件到远程桌面,将文件上传到/mnt/cgshare中。
根据实验介绍的备注里的Hadoop的创建和文件路径,进行文件的上传。
安装test_helper,首先切换到master节点下,通过pip3 install test_helper命令进行安装,其次切换到/usr/local/bin/python3.6/lib/python3.6/site-packages/test_helper目录,将文件夹中test_helper.py文件替换成实验数据中的test_helper.py文件(我这里的做法是自己用vim命令手动修改,即将文件里的内容通过delete键删除,再利用更多里的剪切板将附件里的test_helper.py的内容粘贴进去)
涉及到测试时,需要在/usr/local/bin/python3.6/lib/python3.6/site-packages/test_helper目录下使用pyspark命令,所以在此目录下输入pyspark --master spark://master:7077
由图中可以看出此时的test的模块已经成功导入。
目录
1、Python的输入函数input()
1、input函数介绍
1.1作用:
1.2返回值类型:
1.3值得存储:
2、input函数的基本使用
2、Python中的运算符
2.1算术运算符
2.1.1标准算术运算符
2.1.2取余运算符(%)
2.1.3幂运算符(**)
2.1.4特殊运算
2.2赋值运算符
2.2.1赋值运算符执行顺序为从右到左
2.2.2支持链式赋值
2.2.3支持参数赋值
2.2.4支持系列解包赋值 2.3比较运算符
2.3.1最常见的几种比较运算符
2.3.2 ==和is的比较
2.3.3 is not
2.4布尔运算符
2.4.1三种布尔运算符号
2.4.2 in以及not in
2.5位运算符
2.5.1位与&
2.5.2位或|
2.5.3左移位运算符<<
2.5.4右移位运算符>>
3、运算的比较级
1、Python的输入函数input() 1、input函数介绍 1.1作用: 接受来自用户的输入
1.2返回值类型: 输入的类型为str
1.3值得存储: 使用=对输入的值进行存储
2、input函数的基本使用 2、Python中的运算符 2.1算术运算符 2.1.1标准算术运算符 标准运算符就是加(+)、减(-)、乘(*)、除(/)、整除(//)
2.1.2取余运算符(%) 2.1.3幂运算符(**) 2.1.4特殊运算 2.1.4.1关于整除运算的特殊情况
1、负数整除正数 #一正一负向下取整 例如:-9//4的结果为-3(-9除4结果为-2.25 向下取整为-3)
2.1.4.2关于取余运算的特殊情况
1、一正一负要公式 (公式:余数=被除数-除数*商)
例如:9%-4的结果:
1、先算出商的值:
9//-4=-3
2、余数=被除数-除数*商
9-(-4)*-3=9-12=-3
3、结果为-3
同理可得:-9%4的结果为3
2.2赋值运算符 2.2.1赋值运算符执行顺序为从右到左 2.
我们知道,GPU擅长做并行计算,像element-wise操作。GEMM, Conv这种不仅结果张量中元素的计算相互不依赖,而且输入数据还会被反复利用的更能体现GPU的优势。但AI模型计算或者HPC中还有一类操作由于元素间有数据依赖,会给并行化带来挑战,那就是reduce操作。它代表一类操作,即将多个元素通过某种特定的运算进行归约。其应用很广泛,很多其它算法也以它为基础,如scan, histogram等操作。
最naive的计算方式是序列化地挨个累加。虽然序列化的实现很简单,但无法获得并行处理器带来的好处。为了得到并行计算的好处,需要将计算分布到多个核上。但就像前面说的,序列化的方式由于会导致每个元素计算时都依赖前面的累加结果,难以完全并行。对于reduce,一个基本思路是尽可能地将部分计算并行,以一种树形的结构来分阶段计算最终结果。
CUDA SDK Sample中的关于reduce的例子展示了如何用CUDA高效地进行计算。其中包含了CUDA中的一些特性的使用及技巧。相关代码在cuda-samples项目的Samples/2_Concepts_and_Techniques/reduction目录。Reduce相关的sample主要散落在下面几个子目录中:
reductionreductionMultiBlockCGthreadFenceReduction Reduction 对于reduction这个sample,文件reduction/reduction.cpp中的runTest为程序的主入口函数。如果运行时命令行指定--shmoo参数,则会对于1到32M的数据,执行7种不同的kernel。然后生成csv格式的报告。
./reduction --shmoo 这里采用的是two pass reduction的方法,即分两次pass做全部数据的计算。第一个pass是做CTA内的reduce,然后做CTA的local sum做reduce。这几个kernel主要用于第一个pass的。下面看看这几个reduce kernel的实现:
reduce0 这是最基础的版本。它对于n(2的幂)个元素的输入数组,使用n个线程,在log(n)步内完成计算。
首先将输入元素从global memory g_idata移到shared memory sdata,每个线程移一个元素。
// load shared mem unsigned int tid = threadIdx.x; unsigned int i = blockIdx.x * blockDim.x + threadIdx.x; sdata[tid] = (i < n) ? g_idata[i] : 0; cg::sync(cta); 然后用log-step reduction在CTA内部做reduction。
// do reduction in shared mem for (unsigned int s = 1; s < blockDim.x; s *= 2) { // modulo arithmetic is slow!
本文是基于 《基于能量-应变关系计算弹性常数—VASPKIT v1.00新功能》、《基于应力-应变关系计算弹性常数—VASPKIT v1.2.0新功能》,并在此基础上进行整理记录,在此对原分享者表示感谢。
1 准备优化彻底的POSCAR文件,注意通常采用标准的惯用原胞计算弹性常数,如果不确信POSCAR文件中是否是标准的惯用原胞,可以用vaspkit-603/604生成标准结构;
补充:在Materials Project中下载所需材料的CIF文件,利用VESTA导出为XX.VASP文件,重命名为POSCAR
2 结构优化(弛豫)
INCAR 获取 :vaspkit → 101 → LR
KPOINTS 获取 : vaspkit →102→ 2→ 0.03 (由于计算弹性常数对K-mesh要求很高,因此对于半导体(金属体)体系,生成K点的精度应不小于0.03(0.02) * 2π Å-1)
2.1 如果弛豫发现报错
最好重新走一遍结构优化,或者INCAR中加上【ISYM=0】 忽略对称性(但是增加计算量)
3 弹性模量计算文件准备
POSCAR : 使用结构优化后的新坐标, cp CONTCAR POSCAR
KPOINTS : vaspkit →102 →2 →0.03
INCAR : vaspkit →101 →DC , 可以除了PREC参数,也可以手动设置ENCUT=1.5*ENMAX
Global Parameters ISTART = 0 LREAL = F PREC = High (截断能设置默认值1.5-2倍) LWAVE = F LCHARG = F ADDGRID= .
本文目录 1. 文件操作2. 编辑操作3. 调试操作4. 视图操作5. 注释和取消注释6. 缩进和格式化7. 大小写转换8. 定位到行首与行尾9. 其它 1. 文件操作 Ctrl + O:打开文件Ctrl + S:保存文件Ctrl + Shift + S:全部保存Ctrl + N:新建文件Ctrl + Shift + N:新建项目Ctrl + W:关闭当前窗口Ctrl + Shift + W:关闭所有窗口Ctrl + Tab:切换打开的文件Ctrl + Shift + Tab:在打开的文件之间切换 2. 编辑操作 Ctrl + X:剪切Ctrl + C:复制Ctrl + V:粘贴Ctrl + A:全选Ctrl + Z:撤销Ctrl + Y:重做Ctrl + F:查找Ctrl + H:替换F12:转到定义Ctrl + F12:查找所有引用Shift + F12:查找当前引用 3. 调试操作 F5:开始调试Shift + F5:停止调试F9:设置或清除断点,断点行不执行F10:单步执行代码F11:单步进入函数Shift + F11:单步跳出函数Ctrl + Alt + Q:快速观察Ctrl + Alt + P:自动窗口Ctrl + Alt + V:变量窗口 4.
使用pip安装包时提示报错如下:
ERROR: Could not find a version that satisfies the requirement <package> (from versions: none)
ERROR: No matching distribution found for <package>
大多数是网络问题,替换使用国内的镜像来源加速即可。
打开cmd
输入 pip install <package> -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com 按回车执行命令后,安装成功。
例如:
1.为什么 因为出现 -842150451 所在的位置没有进行初始化,就是该地址里面是空的,没有放东西。
2.如何解决 该问题的解决要根据不同代码而异---------因此今天我要讲的是“道”,即方法。
出现 -842150451 的本质我们已经知道(所在的位置没有进行初始化,地址里面没放东西),我们就需要根据自己的代码去思考,去调试哪个地方没有初始化,为什么没有初始化成功
以本人例子作为案例: (1)出现的问题: 我在写 合并有序表(顺序方式存储)时,出现了下面的问题
(2)解决的方法---调试 根据代码出现的问题,我们知道,在合并版块出现了问题,即出现了-842150451
于是我们去找到该版块代码去调试
调试的过程中发现,
if (*pa >= *pb)
{
*pc++ = *pb++;
}
该代码多执行了一次。
为什么? 极有可能是判断条件出了问题。
ppb(即lb最后元素的位置) 的地址位置 应该 比实际的要大
那么我们的ppb 存放的地址就是错误的
检查发现,果真,我们写成了 Elemtype* ppb = lb->elem + la->length - 1; 而实际上 应该是 Elemtype* ppb = lb->elem + lb->length - 1; 改完后,代码就运行正常了。
一、linux中数组的定义 数组(Array)是有序的元素序列。 若将有限个类型相同的变量的集合命名,那么这个名称为数组名。组成数组的各个变量称为数组的分量,也称为数组的元素,有时也称为下标变量。用于区分数组的各个元素的数字编号称为下标。 1,数组的默认规则 数组中的每个元素分分隔符一定为空格隔开每个元素都拥有与其对应的下标,第一个对应的下标值为0 2,字符串和字符列表的定义 字符串的定义格式: 变量名= 字符数据 字符串列表的定义格式: 变量名="字符 分隔符 字符............." 3,数组的定义方法 1)方法一 数组名=(value0 value1 value2 ......) 2)方法二 数组名=( [0]=value1 [1]=value2 [2]=value3.........[N-1]=valueN )
3)方法三 1.定义一个字符串列表 :列表名="value1 value2 value3...........valueN"
2.用数组获取字符串列表中的内容: 数组名=($列表名) 4)方法四 数组名[0]=value1
数组名[1]=value2
数组名[2]=value3
数组名[3]=value4
............................
数组名[N-1]=valueN
二、数组的输出,删除和长度统计 1,数组元素输出 1)单元素输出 格式:echo ${数组名[下标]} 2)数组全部元素输出 方式一:echo ${数组名[*]}
方式二:echo ${数组名[@]}
3)条件判断输出方式 该输出方式,当数组存在元素,则输出数组的,如果不存在,则输出我们指定的内容 格式:echo ${数组名:-'选择输出的内容'}
4)数组切片(任意字符起输出任意个数数组元素) 方式一:echo ${数组名[*]:下标:个数}
方式一:echo ${数组名[@]:下标:个数}
2,数组的删除 1)删除单个数组元素 格式: unset 数组名[N] 其中N为存在元素的数组下标
2)删除整个数组 格式: unset 数组名[*] 或 unset 数组名[@] 3,数组的长度 格式:echo ${#数组名[*]}或 echo ${#数组名[@]}
1. 官方文档 文档:java_ee_api_中英文对照版.chm
2. Listener 监听器介绍 Listener 监听器它是 JavaWeb 的三大组件之一。JavaWeb 的三大组件分别是:Servlet 程序、Listener 监听器、Filter 过滤器Listener 是 JavaEE 的规范,就是接口监听器的作用是,监听某种变化(一般就是对象创建/销毁, 属性变化), 触发对应方法完成相应的任务
JavaWeb 中的监听器(共八个), 目前最常用的是 ServletContextListener, 后面案例演示.
3. JavaWeb 的监听器 3.1 ServletContextListener 监听器 作用:监听 ServletContext 创建或销毁(当我们 Web 应用启动时,就会创建 ServletContext),即生命周期监听
应用场景:
(1)加载初始化的配置文件;比如 spring 的配置文件
(2)任务调度(配合定时器 Timer/TimerTask)
相关方法
应 用 实 例
HspServletContextListener.java
/** * 解读 * 1. 当一个类实现了 ServletContextListener * 2. 该类就是一个监听器 * 3. 该类可以监听的事件 由该类实现的监听接口决定,比如 实现ServletContextListener * , 则该类就可以监听 ServletContext对象的创建和销毁, 以此类推 * 4.
目录
方法1:for循环输出图案
方法2:使用心形公式
使用pow()函数修改程序
方法3:使用心形公式
方法1:for循环输出图案 #include<stdio.h> #include<stdlib.h> int main() { int i,j; //开头空5行 for(i=1;i<=5;i++) printf("\n"); //前三行 for(i=1;i<=3;i++) { for(j=1;j<=17-2*i;j++) printf(" "); for(j=1;j<=4*i+1 ;j++) printf("*"); for(j=1;j<=13-4*i;j++) printf(" "); for(j=1;j<=4*i+1 ;j++) printf("*"); printf("\n"); } //中间3行输出29颗星 for(i=1;i<=3;i++) { for(j=1;j<=10;j++) printf(" "); for(j=1;j<=29;j++) printf("*"); printf("\n"); } //下7行 倒三角造型 for(i=1;i<=7;i++) { for(j=1;j<=2*i-1+10;j++) printf(" "); for(j=1;j<=31-4*i;j++) printf("*"); printf("\n"); } //图案最后一行一颗星 for(i=1;i<=14+10;i++) printf(" "); printf("*"); //下方空5行 for(i=1;i<=5;i++) printf("\n"); system("color 0c"); //修改系统色,前景色为c红色,背景色为0黑色。 return 0; } 方法1补充:符号的输出可以用printf()实现也可以用putchar()实现,构成图案的符号可以试着用字符型变量代替,看官可以自行修改。
YOLO数据集统计标签框尺寸分布 YOLO数据集统计标签框尺寸分布 在深度学习中,使用YOLO算法进行目标检测时,需要准备符合YOLO数据集格式的数据。其中,每个标签框由5个参数确定:标签、框中心的x坐标、框中心的y坐标、框的宽度、框的高度。本文将介绍如何使用Python统计YOLO数据集中标签框的尺寸分布。
准备工作 首先,需要准备符合YOLO数据集格式的数据。数据集中应包含图片和对应的标签文件。标签文件中应包含每张图片中所有标签的信息,每个标签占一行。以标签文件的第一行为例,格式如下:
0 0.345 0.678 0.123 0.456 其中,第一个数字为标签,后面四个数字分别是框中心的x坐标、框中心的y坐标、框的宽度、框的高度。这些数字都是相对于图片尺寸的比例,范围在0到1之间。
统计标签框尺寸分布 首先,我们需要定义一个函数traverse_folder,用于遍历一个文件夹中的所有图片和标签文件,并将它们的文件名以列表的形式返回:
import os def traverse_folder(folder_path): # 遍历这个文件夹中的文件返回名称 images = [] for file in os.listdir(folder_path): if file.endswith('.jpg') or file.endswith('.png') or file.endswith('.jpeg') or file.endswith('.txt'): images.append(file) images.sort() return images 接下来,我们需要定义一个函数traverse_file,用于读取一个标签文件,并将其中的每一行以列表的形式返回:
def traverse_file(file_path): # 读txt txt_files = [] with open(file_path, 'r') as f: for line in f: txt_files.append(line) return txt_files 定义一个函数update_lables,用于更新标签框的尺寸和位置。其中,tag参数为1、2、3、4中的一个,分别对应左上、左下、右上、右下四个位置。该函数将计算出新的标签框的尺寸和位置,并将它们以列表的形式返回:
def update_lables(lables_info, tag): # tag 1 2 3 4 分别对应左上,左下,右上,右下 resl = [] for lable_info in lables_info: lable_info = lable_info.
文章目录 前言一、使用步骤1. 添加iText依赖2.创建一个Controller 总结 前言 在Spring Boot应用程序中生成PDF需要使用第三方库,本例中我们将使用iText库,它是一个用于生成PDF文件的Java库。下面是一个示例代码,演示了如何使用iText在Spring Boot中生成PDF。
一、使用步骤 1. 添加iText依赖 在pom.xml文件中添加以下依赖:
代码如下(示例):
<dependency> <groupId>com.itextpdf</groupId> <artifactId>itextpdf</artifactId> <version>5.5.13</version> </dependency> 2.创建一个Controller 在Spring Boot应用程序中,我们需要创建一个Controller类,将其注解为@Controller,并添加一个用于生成PDF的请求处理程序。
import java.io.ByteArrayOutputStream; import java.io.IOException; import javax.servlet.http.HttpServletResponse; import com.itextpdf.text.Document; import com.itextpdf.text.DocumentException; import com.itextpdf.text.Font; import com.itextpdf.text.Paragraph; import com.itextpdf.text.pdf.PdfWriter; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.ResponseBody; @Controller public class PDFController { @GetMapping("/generate-pdf") public @ResponseBody void generatePDF(HttpServletResponse response) throws IOException { // 创建一个新的Document对象 Document document = new Document(); try { // 创建一个输出流 ByteArrayOutputStream baos = new ByteArrayOutputStream(); // 将输出流与PdfWriter绑定 PdfWriter.
因为shell脚本默认的文件格式是utf-8
因此如果我们的格式为gbk格式的话
需要指定export lang= zh_CN.GBK
在 centos7 上安装配置 MySQL8.0 教程 在 Centos 环境上的安装配置安装配置连接 在 Centos 环境上的安装配置 安装环境为:在 win11系统 -> virtualbox 虚拟机 -> centos7.9 系统 -> MySQL8.0
测试时间为:2023 年 05 月
安装 确定所要下载的版本: $ uname -m # 输出 x86_64 $ cat /etc/redhat-release # 输出 CentOS Linux release 7.9.2009 (Core) 下载对应版本的 rpm 文件资源 Download MySQL Yum Repository : 对应文件为:Red Hat Enterprise Linux 7 / Oracle Linux 7 (Architecture Independent)
点击:浏览器 ->下载 -> 右键复制文件下载链接,安装 yum 资源:
下载链接为:https://repo.mysql.com//mysql80-community-release-el7-7.noarch.rpm
其实很多人不知道,责任链模式是我们工作中经常遇到的模式,特别是web后端工程师,我们工作中每时每刻都在用:因为市面上大部分的web框架的过滤器基本都是基于这个设计模式为基本模式搭建的。
1.模式介绍 我们先来看一下责任链模式(Chain Of Responsibility Design Pattern )的英文介绍:
Avoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request. Chain the receiving objects and pass the request along the chain until an object handles it.
翻译成中文就是:将请求的发送和接收解耦,让多个接收对象都有机会处理这个请求。将这些接收对象串成一条链,并沿着这条链传递这个请求,直到链上的某个接收对象能够处理它为止。
这么说比较抽象,用更加容易理解的话来进一步解读一下。在责任链模式中,一个请求过来,会有多个处理器(也就是刚刚定义中说的“接收对象”)依次处理同一个请求。即请求先经过 A 处理器处理,然后再把请求传递给 B 处理器,B 处理器处理完后再传递给 C 处理器,以此类推,形成一个链条。链条上的每个处理器各自承担各自的处理职责,所以叫作责任链模式。
2.模式demo 2.1UML 责任链模式(Chain Of Responsibility Design Pattern )的整体结构如下:
2.2 标准demo 我们依据标准的UML图,写出一个具体的例子(对应UML图):
首先定义一个接口IHandler:
type IHandler interface { SetNext(handler IHandler) Handle(score int) } 然后分别构建三个不同的实现:
public class EnumConvertTools { private EnumConvertTools() { throw new IllegalStateException("Utility class"); } /** * @description:通用的枚举转换的工具类 * <p> * 通过传入的参数,获取枚举的信息 * clazz 为对象的class对象 * convertType 为枚举的信息 * value 为比对的Key值 * </p> * @Date: 2022/12/4 23:24 * @jdk: 1.8 */ public static <T> String getEnumNameOrCodeByConvert(Class<T> clazz, String convertType, String value) { if (StringUtils.isNotBlank(value)) { //Enum接口中没有values()方法,我们仍然可以通过Class对象取得所有的enum实例 T[] arr = clazz.getEnumConstants(); //通过类型进行判定 if (EnumConvertEnum.ConvertTypeEnum.CODE_TO_NAME.getCode().equals(convertType)) { //通过code获取name return getNameByCode(clazz, arr, value); }else if (EnumConvertEnum.ConvertTypeEnum.NAME_TO_CODE.getCode().equals(convertType)) { //通过name获取code return getCodeByName(clazz, arr, value); }else { throw new YnetPlatformException(ErrorConstantPlatformVariable.
一、前言 多周期路径约束允许用户根据设计时钟波形修改计时器确定的setup和hold关系。默认情况下,Vivado IDE时序分析执行单周期分析。这种分析可能过于限制,并且可能不适用于某些逻辑路径。最常见的例子是逻辑路径,它需要一个以上的时钟周期才能使数据在端点稳定。如果路径起点和终点的控制电路允许,Xilinx建议您使用多周期路径约束来放宽设置要求。根据您的意图,保留要求可能仍然保持原始关系。这有助于时序驱动算法将注意力集中在要求更严格且具有挑战性的其他路径上。它还可以帮助减少运行时间。
二、set_multicycle_path 语法 指示从路径的开始到结束传播数据所需的时钟周期数。
set_multicycle_path [-setup] [-hold] [-rise] [-fall] [-start] -[end] [-reset_path] [-from <args>] [-rise_from <args>] [-fall_from <args>] [-to <args>] [-rise_to <args>] [-fall_to <args>] [-through <args>] [-rise_through <args>] [-fall_through <args>] [-quiet] [-verbose] <path_multiplier> 选项含义-setup应用于setup路径的多周期检查,同时也会影响hold路径的检查,当未指定-setup或hold时,这也是set_multiplier_path命令的默认行为;-hold仅仅作用于hold路径的多周期检查,用于改变hold路径的时钟周期关系;-rise/fall指定该约束专门应用于路径端点上的上升沿/下降沿延迟;-start默认情况下,setup路径多周期约束是相对于目标时钟定义的。要修改相对于源时钟的setup要求,必须使用-start选项;-end默认情况下,hold路径多周期约束是相对于源时钟定义的。要修改相对于目的时钟的hold要求,必须使用-end选项;-reset_path在应用多周期路径乘数之前重置指定的路径;-from <args>多周期约束作用路径的起点列表-rise_from <args>多周期约束作用起点列表的上升沿路径;–fall_from <args>多周期约束作用起点列表的下降沿沿路径;-to <args>多周期约束作用路径的终点列表-rise_to <args>多周期约束作用终点列表的上升沿路径-fall_to <args>多周期约束作用终点列表的下降沿路径-through <args>pins、cell、nets列表,所有经过该列表的路径均受多周期约束作用;-rise_through <args>pins、cell、nets列表,所有经过该列表的上升沿路径均受多周期约束作用;-fall_through <args>pins、cell、nets列表,所有经过该列表的下降沿路径均受多周期约束作用;-quiet忽略命令错误<path_multiplier>建立时间和保持时间周期数 当-setup和-hold均未设置时,或者只设置了-setup,path_multiplier同时作用于setup和hold检查
当-rise和-fall均未设置时,默认path_multiplier同时作用于上升沿和下降沿
三、同时钟域下的multicycle约束 静态时序分析工具,对默认的建立时间和保持时间的相对关系如下所示:
此时,建立时间和保持时间的计算关系如下:
建立时间: T D a t a p a t h ( m a x ) < T C L K ( t = p e r i o d ) − T s e t u p T _{Datapath(max)} < TCLK_{(t=period)} - T_{setup} TDatapath(max)<TCLK(t=period)−Tsetup
异常如下:
Could not read JSON: Unexpected token (START_OBJECT), expected START_ARRAY: need JSON Array to contain As.WRAPPER_ARRAY type information for class java.lang.Object
直接上解决方案:
redisTemplate.setHashKeySerializer(new StringRedisSerializer()); redisTemplate.setHashValueSerializer(new Jackson2JsonRedisSerializer(Object.class));
使用WinSCP SFTP在Win和Linux之间传输文件,发现传输速度只有10MB/s左右,网络可是千兆互联,完全发挥不出千兆网络的性能。
(-_-)!
后来换了台电脑速度好了点,能达到30MB/s。再换一台电脑,速度能达到70MB/s,三台电脑安装的Windows系统都是一样,SFTP软件的版本也是一样,速度差距这么大只能怀疑是CPU性能影响了。
更换SFTP软件,使用mobaxterm测试,现象也是一样,传输速度不理想。
排除了网线、软件和操作系统的问题,那就只能是电脑硬件的问题了。
后来查了下资料,发现SFTP使用了加密传输,估计这个加解密对CPU性能要求比较高,直接影响了传输速度。只是没想到影响这么大,传输速度10MB/s的电脑配置CPU是AMD的X6 1075T 十几年前的CPU,传输文件时CPU占用率60%左右,感觉占用率也不算很高。
只能怪SFTP对CPU性能要求比较高了,CPU差点,传输速度就上不去。
于是转而使用FTP,FTP可以不使用加密。
LinuxMint系统安装FTP服务:
sudo apt-get install vsftpd vsftp默认配置不允许上传文件,需要修改**/etc/vsftpd.conf配置文件,使能write_enable=YES**
sudo service vsftpd restart WinSCP软件新建站点,协议使用FTP,并修改高级配置选项,“文件名UTF-8编码” 开启,避免访问Linux文件时如果带有中文字符而出现乱码。
这样Win和Linux之间就可以互传文件了,测试速度理想情况下可以达到100MB/s满速,比原来的SFTP快多了。
如果使用FileZilla这款软件访问FTP,需要把默认传输类型选择成“二进制”,否则传输的文件大小不对。
图案示例
其实和之前说过的正立金字塔一毛一样,只不过这个每一行的星星规律不同。
第一行9个
第二行7个
不难看出规律为:2*(5-i)-1
#include<stdio.h> int main(){ int i,j,k; for(i=0;i<5;i++){ for(k=1;k<=5;k++){ if(k<=i+1-1)printf(" "); } for(j=1;j<=2*(5-i)-1;j++){ printf("*"); } printf("\n"); } } 有了正金子塔和倒金字塔就可以拼成一个菱形,但菱形中的倒三角很显然要少第一层。
示例:
代码:
#include<stdio.h> int main(){ int i,j,k; for(i=1;i<=5;i++){ for(k=1;k<=5;k++){ if(k<=5-i)printf(" "); } for(j=1;j<=2*i-1;j++){ printf("*"); } printf("\n"); } //。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。 for(i=0;i<4;i++){//到金字 printf(" "); for(k=1;k<=5;k++){ if(k<=i+1-1)printf(" "); } for(j=1;j<=2*(4-i)-1;j++){ printf("*"); } printf("\n"); } }
此功能必须是服务号或者测试号,订阅号没有此权限。测试号可以在【开发】=》【开发者工具】=》【公众平台测试账号】申请,本文以测试号为例:
一:公众平台设置回调域名和测试账号
注:设置成你网站域名,不要加协议,举例:www.aaa.com,本地域名也可以
二:将下面Oauth.php放到此域名下(更改成你自己的appID和appsecret):
<?php class Oauth { private $appID = 'xxxxxxx'; private $appsecret = 'xxxxxxxxxxxxxxxxxxxxxxxx'; private $code; private $token; private $openid; //授权地址,未授权会跳转到这个路径进行授权(power方法的访问路径) private $power_url = 'http://www.wx.com/Oauth.php?method=power'; //授权成功回调地址,授权成功后会跳转到这个路径获取用户信息(getUser方法的访问路径) private $redirect_uri = 'http://www.wx.com/Oauth.php?method=getUser'; //授权日志目录 private $log_filedir = "./logs/oauth/"; //获取用户信息 function getUser() { //判断用户session是否存在,存在直接返回[省略] //没有用户session则去授权获取 $this->code = $_GET['code']; $token = $this->getToken(); if($token['code']){ header('location:' . $this->power_url);//跳转到授权页面 } $url = 'https://api.weixin.qq.com/sns/userinfo?access_token='.$this->token.'&openid='.$this->openid.'&lang=zh_CN'; $user = $this->send($url); $this->_log('获取用户信息:' . $this->ajax($user)); if(!isset($user['openid'])) { $this->_log('获取用户信息失败!'); return "获取信息失败,请重新进入"; } //入库存session,将openid作为唯一标识[省略] //返回用户信息 return $this->ajax($user); } //获取token public function getToken() { $url = 'https://api.
目录
利用keras框架搭建一个CGAN模型是比较方便的,这里我就不多说什么了,直接上代码吧
数据集的构建大致如下:
关于tag.txt:
关于tags.txt:
文本相似度的对比可以通过余弦相似度比较,例如以下代码:
目前网络上搭建这种模型的文章已经很多了,在这里我会说一些在阅读其他作者的相关文章的同时进行搭建遇到的一系列问题以及数据集兼容的一点见解。
利用keras框架搭建一个CGAN模型是比较方便的,这里我就不多说什么了,直接上代码吧 import matplotlib.pyplot as plt import numpy as np from keras.optimizers import Adam from keras.layers import Input, Dense, Reshape, Flatten, Dropout, multiply, LeakyReLU, Layer, BatchNormalization, \ Embedding from keras.models import Model, Sequential import tensorflow as tf from tensorflow.python.keras.models import save_model from keras.utils import plot_model import myDataToMnist class Mycgan(): def __init__(self): self.img_rows = 64 # 输入图像像素行 self.img_cols = 64 # 输入图像像素列 self.img_tag = 1 # 标签 self.
问题 从微信云开发控制台导入数据库文件有两种格式:JSON和CSV。
而且在导入数据时,CSV格式仅支持导入字符串(string)和数字格式(number),对于嵌套的数组数据则视为字符串导入,所以结构化数据就不太好用CSV格式了。但如果是为了导出Excel格式,方便修改数据,可以导出CSV格式,office、WPS的Excel可以直接打开,但是若含有结构化嵌套数据,导入时要转化为JSON才行。
Excel数据怎样转化为JSON呢?
解决办法 使用 Jupyter Notebook Python的pandas库非常简单的几步就可以实现。
直接使用Python开发软件也可以,代码基本一样,但Jupyter Notebook非常方便查看数据。
剔除不需要的列,.iloc是按位置的切片方法
最后导出为JSON文件。
这样的行分隔JSON文件,微信云数据库才能导入。用逗号分隔的JSON文件暂时不行。
点击下面链接,可以下载上述完整代码:
Excel To Json-Python源代码 及Jupyter Notebook文件.zip
文章目录 一. 任务队列:由于Redis List支持阻塞式弹出元素,并且支持多个客户端同时阻塞在同一个List上,因此可以用来实现任务队列。例如,将需要异步执行的任务存储在一个List中,多个工作线程则通过阻塞式地弹出元素来获取任务。二. 实现日志记录:Redis的list还可以用来存储日志记录。比如说,在Web应用中,我们可以将用户请求的URL和请求时间push到一个list中,并设置list的长度为一定值,当需要查看日志时就可以通过lrange命令获取之前请求过的URL和请求时间。三. 分页查询:由于Redis List支持按照索引访问元素,因此可以用来实现分页查询。四. 消息通知:由于Redis List支持阻塞式弹出元素,并且支持多个客户端同时阻塞在同一个List上,因此可以用来实现消息通知。例如,将需要推送给用户的消息存储在一个List中,多个客户端则通过阻塞式地弹出元素来获取消息通知。五. 消息队列:由于Redis List支持阻塞式弹出元素,因此可以用来实现消息队列。生产者将消息推入List中,消费者则通过阻塞式地弹出元素来获取消息。六. 列表:Redis的List是一个双向链表,可以在列表两端进行快速的插入和删除操作。因此,List可以用来实现队列、栈等数据结构。七. 实现轮询队列:Redis的list还可以用来实现轮询队列。比如说,在在线客服系统中,我们可以将客户发送过来的消息push到一个list中,并由多个客服进程并发地从list中获取消息进行回复。这种方式既能够保证每个消息都会被处理到,又能够提高客服回复效率。八. 实现缓存淘汰策略:Redis支持设置key过期时间,但是在某些情况下,我们也可以使用list来实现缓存淘汰策略。比如说,在缓存系统中,我们可以将需要缓存的数据push到一个list中,并设置list的长度为一定值,当需要插入新数据时就可以将最早插入的数据pop出去,从而实现缓存淘汰。九. 实现任务调度:Redis的list还可以用来实现任务调度。比如说,在电商网站中,我们可以将需要发送邮件或短信通知的订单信息push到一个list中,并设置每个订单需要执行通知任务的时间戳。然后使用Redis提供的sorted set结构体按照时间戳排序获取需要执行通知任务的订单信息。十. 排行榜:由于Redis List支持按照索引访问元素,并且支持对List进行排序,因此可以用来实现排行榜。例如,在一个List中存储用户的积分信息,并按照积分从高到低排序。十一. 地理位置:由于Redis List支持按照索引访问元素,并且支持对List进行排序,因此可以用来实现地理位置。例如,在一个List中存储所有用户的经纬度信息,并按照距离从近到远排序,则可以通过取某个范围内的元素来获取附近的用户。十二. 实现分布式锁:Redis的list还可以用来实现分布式锁。比如说,在分布式系统中,我们可以将获取锁的请求push到一个list中,并通过lindex命令获取第一个请求进行加锁操作。这种方式既能够保证同一时间只有一个进程持有锁,又能够避免死锁等问题。十三. 时间轴:Redis List还可以用来实现时间轴功能。比如微博应用中用户发表一条微博就会被添加到自己的时间轴上,而其他用户关注该用户后也会将其微博添加到自己的时间轴上。这个功能可以通过将每个用户的时间轴作为一个List来实现。十四. 数据缓存:Redis List还可以用来实现数据缓存功能。比如需要缓存一些数据以加速读取速度,就可以将这些数据作为List中的元素,并且使用Redis提供的LRU淘汰策略控制缓存大小和淘汰过期数据。十五.栈:Redis list还可以被当做栈来使用,即只能在列表的头部添加和弹出元素。这种使用场景常用于浏览器历史记录、撤销操作等需要后进先出(LIFO)的场景。十六.实时在线用户列表十七.秒杀活动抢购十八.延迟任务队列十九.异步任务:通过将任务信息存储在Redis的List中,并使用多个worker进程来处理这些任务,可以实现异步任务处理。生产者向List中添加任务信息,worker进程则从List中取出任务并执行。二十.流水线操作:由于Redis支持管道操作,因此我们可以使用Redis List进行流水线操作。将需要执行的多个命令按顺序存储在List中,并通过一次性发送给Redis服务器来减少网络延迟和通信开销。二十一.实时聊天室:Redis的List可以作为聊天室中消息的缓存区域。每当有用户发送一条新消息时,就将该消息添加到聊天室对应的List中,并通过订阅/发布机制将该消息广播给所有在线用户。 一. 任务队列:由于Redis List支持阻塞式弹出元素,并且支持多个客户端同时阻塞在同一个List上,因此可以用来实现任务队列。例如,将需要异步执行的任务存储在一个List中,多个工作线程则通过阻塞式地弹出元素来获取任务。 Redis list 可以很方便地实现任务队列。任务队列是一种常见的设计模式,它用于在系统中排队和处理一系列异步任务。Redis list 可以用来存储任务,同时提供 push 和 pop 操作,实现任务的添加和取出。
具体实现步骤如下:
创建一个 Redis list,作为任务队列。
向任务队列中 push 任务,使用 lpush 或 rpush 操作。
从任务队列中取出任务,使用 lpop 或 rpop 操作。
处理任务。
下面是一个简单的示例,演示如何使用 Redis list 实现任务队列。
import redis # 连接 Redis r = redis.Redis() # 定义任务队列 key task_queue_key = 'my_task_queue' # 添加任务到队列 r.
案例:笔记本电脑没有声音怎么办?
【我的笔记本电脑为什么会没有声音呢?看视频听音乐一点声音都没有,实在太烦人了!应该怎么解决呢?】
笔记本电脑逐渐成为人们工作生活必备的工具。如果笔记本电脑没有声音,可能会影响我们听音乐、看视频、打游戏等体验。
如何解决笔记本电脑没有声音的问题?5种必会的方法已经总结好啦!
笔记本电脑没有声音怎么办? 很多朋友可能习惯了用笔记本电脑来听音乐、看视频。但有时我们会发现,笔记本听不到声音。那我们该如何解决呢?今天给大家安利5个超好用的方法!
方法1:检查音量设置 有时候,电脑扬声器正常但是没有声音,可能是因为音量设置较低或音量被关闭,导致没有声音。此时我们应先检查音量设置,操作如下:
1.右键单击任务栏右下角的音量图标,然后选择【打开声音合成器】;
2.确保音量滑块已向上滑动,并且【静音】选项未选中;
3.在【应用程序】音量下,确保您要听到的应用程序的音量已调到合适的位置。
方法2:检查音频设备 有时候如果我们的音频设备没有正确设置,也可能导致笔记本电脑没有声音,此时我们应对音频设备进行检查并设置正确的音频设备。操作如下:
1.右键单击任务栏右下角的音量图标,然后选择【打开声音设置】;
2.在【选择输出设备中】选择【扬声器】;
3.调整主音量为合适的音量。
方法3:检查驱动程序 如果您的笔记本电脑没有声音,可能是因为音频驱动程序出现了问题。笔记本电脑没有声音怎么处理,可以这样操作:
1.按下【Windows键+X】并选择【设备管理器】;
2.展开【声音、视频和游戏控制器】选项;
3.右键单击音频设备,点击【更新驱动程序软件】;
4.点击【自动搜索更新的驱动程序软件】。
方法4:检查线缆和插孔 笔记本电脑听不到声音,也可能是因为线缆或插孔出现了问题。可以按照以下步骤来检查插孔和线缆:
1.检查扬声器或耳机是否正确插入笔记本电脑的插孔中;
2.检查线缆是否有任何损坏或磨损;
3.检查插孔是否有任何污垢或损坏。
方法5:重启音频服务 电脑显示有音量但是没声音,可能是因为音频服务停止运行。可以按照以下步骤来重启音频服务:
1.按下【Win+R】打开运行对话框;
2.在运行对话框中键入【services.msc】,然后按回车键;
3.在【服务】窗口中,找到【Windows Audio】服务;
4.右键单击该服务,并选择【重新启动】。
总结: 以上就是5个解决笔记本电脑没有声音的神仙方法。如果您遇到了笔记本电脑没有声音的问题,您可以尝试这些方法来解决它们!
往期推荐:
回收站文件恢复,分享4个巧妙解决方法!https://blog.csdn.net/datarecover/article/details/130522886
Word下划线怎么打?速速get这5个实用方法!https://blog.csdn.net/datarecover/article/details/130523933
电脑截图快捷键有哪些?5大截图方法总结!(2023版)https://blog.csdn.net/datarecover/article/details/130420889
上测试服务器发现的有趣问题,做了一个报表导出功能,在开发机win10系统下,星期显示为“星期一”,“星期二”...,在测试服务器Linux系统下,显示为了“Monday”,“Tuesday”...
SimpleDateFormat sdf= new SimpleDateFormat("MM月dd日 EEEE"); String dateStr=sdf.format(new Date()); System.out.println(dateStr); // 在Windows下 // 02月06日 星期一 // ------------------- // 在Linux下 // 02月06日 Monday 解决办法:SimpleDateFormat方法添加第二个参数java.util.Locale.SIMPLIFIED_CHINESE
// 解决办法:SimpleDateFormat方法添加第二个参数java.util.Locale locale SimpleDateFormat sdf= new SimpleDateFormat("MM月dd日 EEEE", Locale.SIMPLIFIED_CHINESE); String dateStr=sdf.format(new Date()); System.out.println(dateStr); // 在Windows下 // 02月06日 星期一 // ------------------- // 在Linux下 // 02月06日 星期一 SimpleDateFormat方法如果只传(String pattern),会自动调用获取默认locale参数的重载方法,其中包含了语言参数,如果没有本地化设置就走默认英文了。windows当然是本地化设置为中文了,linux默认还是英文,所以出现了这个问题。保险起见以后还是都加上locale吧。
一、 国际化(i18n)北京外国语大学27种语言 vue-i18n + i18n Ally + xlsx + vue-json-excel
1. 开始开发用zh-cn.json的文件写完页面逻辑
2. 通过公司免费的api接口将每个字段翻译成27种语言(生成一个大对象)
3. 使用vue-json-excel读取json数据,导出一个excel文件
4. 让内容组同事修正翻译,通过腾讯文档同步内容,改完导成本地
5. 通过 xlsx 插件xlsx文件内容读出来,FileSaver 生成js文件
但是有个问题,后续添加的翻译,不能使用i18n Ally翻译了,它是全量翻译,会覆盖同事手动翻译的内容,只能使用公司翻译的接口,把新增的字段翻译(拿到zh-cn文件字段,对比en.json文件没有的就是新增的,翻译完第一个将所有新增的字段放在一个数组里边)将翻译内容写入json文件。后端的返回信息也需要翻译,在自己封装的接口请求方法加个变量,每个接口都需要传语言字段
国际化翻译 Vue-i18n 的架构组织和 $t 的原理,当遇到插值对象的时候,需要进行 parse 和 compileVue-i18n 通过转义字符避免 XSS通过观察者模式对数据进行监听和更新,做到无刷新更新页面全局自定义指令和全局组件的实现 二、大文件分片上传,断点续传
1.通过el-upload组件拿到binary类型文件
2.校验文件不能超高20G,通过请求接口盘点磁盘大小,是否够存储文件
3. 直接将文件抛给webworker,file.slice()进行分片5M每片,用spark-md5给每一片加密(md5是一种信息摘要算法,它是一段数据,即128bit的由“0”和“1”组成的一段二进制数据。无论原始数据长短是多少,其MD5值都只是128bit)
4. 传送index、hash、file、size、total
5. 断点续传,刷新或者退出前端会停止上传,再次上传拿到MD5,后台先查有没有这个,有的话返回上次的index,前端从index继续上传。
6. 每一片5M传输最合理(nginx默认的上传文件大小是有限制的,一般为2MB,修改client_max_body_size 30M),oss存储有自动清理垃圾文件机制。调用的oss的api
7. nginx默认限制请求1M,修改client_max_body_size 20M;
大文件下载 阶段1:后台返回文件地址,创建隐藏的iframe下载,批量下载是创建多个iframe或者后端生成zip下载。(单线程下载速度慢) 阶段2: 多线程大文件下载,http1.1的range字段(分片下载blod文件,请求返回206,部分下载,下载完成合并blod文件,单个域名并发限制一次最多只能发送6个请求) 或者用jszip压缩文件 const zip = new JSZip(); zip.file(file.name, file); const blob = await zip.generateAsync({type:"blob"}) saveAs(blob, "example.zip"); 升级http2,没有并发限制,并不是并发越多越好。最后经过大量测试24个请求是最快的,请求完24个在请求24分片,请求完成合并文件
ChatGPT是一款引人注目的产品,它的突破性功能在各个领域都创造了巨大的需求。
仅在发布后的两个月内,就累计了超过1亿的用户。它最突出的功能是能够在几秒钟内完成各种文案创作,包括论文、歌曲、诗歌、睡前故事和散文等
与流行的观点相反,ChatGPT可以做的不仅仅是为你写一篇文章,更有用的是它如何帮助指导您的写作过程和写作方法。
接下来手把手教你利用ChatGPT辅助完成写作的五种方法。
1.使用ChatGPT生成论文的观点
在开始写作之前,我们需要让ChatGPT帮我们充实想法,找到论文切入点。当老师布置论文时,通常会给予学生一个提示,让他们可以自由地表达和分析。这时,我们需要找到论文的角度和思路,然后开始撰写。
如果您最近写过一篇文章,您就会知道这一步通常是最棘手的部分。
而这正是ChatGPT 可以提供帮助的地方。
您需要做的就是输入论文主题,包括您想要的尽可能多的细节,包括您想要涵盖的内容,然后让 ChatGPT完成剩下的工作。
例如,根据我在大学时的一篇论文提示:
你能帮我想出这个论文的主题吗,“你要写一篇关于中国传统文化与企业管理的研究论文或案例分析。”我希望它包括中国古代孔子和孟子的不同管理思想以及中西方管理文化的融合。
几秒钟之内,人工智能就产生了一个回复,为我提供了论文的主题、文章重点以及可以在论文中包含哪些信息的见解和案例。
2.使用ChatGPT创建论文大纲 一旦你有了一个坚实的主题,就该开始集思广益你真正想在文章中包含的内容了。为了方便写作过程,我总是创建一个大纲,包括我想在文章中提及的不同观点。然而,写大纲的过程通常是繁琐的。
使用ChatGPT,你要做的就是让它帮你编写提纲。
在第一步中使用ChatGPT帮助我生成了论文的主题,我让ChatGPT根据主题给我写了一个大纲:
你能为论文“通过儒家和道家两个管理派系来分析中西方企业管理的方法与领导力的风格”制定一个大纲吗?
几秒钟后,ChatGPT输出了一个论文的整体轮廓,每个部分还提出了不同的重点。
这个大纲很详尽,可以浓缩成一篇较短的文章,也可以详细阐述成一篇较长的论文。如果你不喜欢某些东西或想进一步调整它,可以手动或使用更多的提问来进行调整。
知否AI问答,您24小时免费论文助理。
3.使用ChatGPT获取论文文献资料
既然您确切地知道要写什么,是时候寻找到优质资源来获取资料了。如果您不知道从哪里开始,就像前面的所有步骤一样,你可以直接询问ChatGPT。
接下来你需要做的是让它帮你的论文主题找到相关的文献资料。
例如,我问它如下:
你能帮我找到一篇论文的中文文献资料吗?“通过儒家和道家的思想来分析中西方管理的风格。”
4.使用ChatGPT写一篇范文
值得注意的是,如果您直接从ChatGPT中获取文本并提交,你的作品可能会被视为一种抄袭形式,因为它不是您的原创作品。与从其他来源获取的任何信息一样,任何AI生成的文本都应在你的作品中明确标识和记入。
如果您希望ChatGPT生成一段文本示例,请输入主题和所需的长度,然后观察它生成的内容。例如,我输入以下文字:
你能写一篇关于“通过儒家和道家两派管理思想来分析中西方企业管理的方法与领导力的风格”这一主题的五段式文章吗?
几秒钟之内,ChatGPT就完全按照我的要求输出了:一篇关于该主题的连贯的五段文章,可以帮助您指导自己的写作。
ChatGPT生成的内容是在统计上有效的形式将词语组织在一起,但他们不知道他们所说的是真实的还是准确的。
它无法创作原创作品,它只是简单地汇总了它已经吸收的所有内容。
它是你工作和做学术的有用起点,但不要指望它会受到启发或准确无误。
5.利用ChatGPT完善你的论文
撰写自己的论文后,你可以使用 ChatGPT的高级写作功能帮助你编辑完善论文。
你可以简单地告诉ChatGPT特别希望它完善哪些信息。例如,我要求它编辑文章结构、语法、流程、语气等。
如果你需要要求ChatGPT编辑您的文章,它会提示您将文本粘贴到提问栏中,然后它会指出文章中的错误并提供完善后的版本。这个功能非常有用,因为它可以比人工或其他校对工具更彻底地发现论文中的问题,并给出完善后的内容。
你还可以与ChatGPT共同编辑和协作,要求它查看特定段落或句子,并要求它重写或修复指定的论文内容以使其更加清晰。
知否AI问答,您24小时免费论文助理。
6.使用ChatGPT完成论文中的多语言翻译
ChatGPT可以翻译您的文本到不同语言,例如:您写的中文文章,可以通过ChatGPT将其翻译成英语、西班牙语等其他语言,彻底跨越语言障碍。
总之,ChatGPT可以非常有效地提高您的写作效率和质量。
“知否AI问答”提供免费体验ChatGPT功能,辅助完善论文,微信关注我们。
————
帆软报表常用函数: https://blog.csdn.net/weixin_45682994/article/details/129318039
问题1: 点击查询按钮没反应
解决方法: 一定要选择查询按钮,而不是按钮
问题2: 数据库中多行数据放在了同一行显示
解决方法: 扩展方向选择选择"纵向"
问题3: 页面显示的列,少于本来的数据列
**解决方法:**预览模式选择“填报预览”、“数据分析”即可
问题4: 多个数据集合并,将相同的列进行过滤,如以下数据集过滤选择"业务员"和"省份"。但是过滤之后,“批销数量”并没有匹配上。
**解决方法:**选中要匹配的数据了,例如"批销数量",选中过滤条件。格式一定要选“单元格”。
问题5: 常用参数组合,不显示
解决方法: 必须登录决策系统才可以显示 常用参数组合
问题6: 导出pdf、Word、图片时,数据和标题换行显示
解决方法: 模板设计器,默认页面大小为A4纸大小。可以看设计器中的列虚线,如果超过列虚线,即不能正确导出。需调整页面大小和数据宽度一致就可正确导出。
问题7: 俩个值为NULL的数据,相加为0。怎么能设置两个值为NULL的数据相加为NULL
解决方法: 给单元格添加条件属性。但当前值为0时,新值为null
问题8: Web页面调用报表页面,报错信息
解决方法:
1、src地址地址要写模板的Url地址,即设计器打开这个模板直接预览的地址。
如果是跨域,需要能访问通以及服务器允许跨域。到时候地址换成自己服务器的ip和端口
2、关闭“报表平台管理-安全管理-Security Headers”
问题9: 调整字体的大小,并没有改变下拉选项字体的大小
解决方法: 该字体大小只控制页面选择选项后文本框中的字体。
如想修改下拉框字体,需要自己修改CSS样式
文本:
this.btn.bind(‘click’,function() {
setTimeout(function(){
$(“.fr-combo-list-item”).css({“font-size”:“20px”})
},100);
});
问题10: 报表平台管理 – 密码员密码忘了怎么处理
解决方法: 修改db.scrips中:
INSERT INTO FINE_CONF_ENTITY VALUES(‘SystemConfig.serverInit’,‘success’)
success改成任意字段,保存重启服务。
问题11: 当数据条数超出页面长度,数据显示不全,且不出现滚动条。
解决方法: 将该报表的冻结行、列去掉
问题12: 请问一张表单里有两个seq()的时候怎么让他们分别统计。我现在预览的时候他们会共同计数,比如上面的seq统计到1,2,3,下面的seq就从4开始了
解决方法: 修改序号写法,由seq()改为&B10
if(len(B10) = 0, ‘’, &B10)
HTML+CSS 1 块元素垂直居中 1 弹性布局
display:flex;
justify-content: center;
align-items: center;
2 定位
position: absolute;
left:50%;
top:50%;
transform:translate(-50%,-50%)
3. 定位
position:absolute;
left:0;right:0;
top:0;bottom:0;
margin:auto;
2 盒模型和怪异盒模型 普通盒模型 content + paddign*2 + border*2 + margin*2 = 普通盒模型
怪异盒模型 contnet + margin*2 = 怪异盒模型 1.两者区别
标准盒模型总宽度 = width + 左右padding + 左右border + 左右margin
标准盒模型总高度 = height + 上下padding + 上下border + 上下margin
怪异盒模型总宽度 = width + 左右margin (width包含了padding和border)
怪异盒模型总高度 = height + 上下margin (height包含了padding和border)
jump server添加 Windows主机资产 添加Linux主机资产步骤我们可以参照 链接:jump server添加Linux主机资产 进行操作。
一、资产管理-资产列表-创建资产 IP根据自己实际情况填写。系统平台就选择windows即可。协议端口要选择rdp。
二、资产管理-系统用户-创建系统用户 用户名及密码根据实际情况手动添加更新即可。
三、权限管理-资产授权-创建资产授权规则 根据之前添加的步骤选择即可
四、会话管理-Web终端-选择windows-server终端测试连接
答:char 类型可以存储一个中文汉字,因为 Java 中使用的编码是 Unicode(不选择任何特定的编码,直接使用字符在字符集中的编号,这是统一的唯一方法), 一个 char 类型占 2 个字节(16bit),所以放一个中文是没问题的。
不完全对,有很多汉字在Unicode编码中是大于2个字节的。
引用:中文字符集 Unicode 编码范围
字符集字数Unicode 编码基本汉字20902字4E00-9FA5基本汉字补充90字9FA6-9FFF扩展A6592字3400-4DBF扩展B42720字20000-2A6DF扩展C4154字2A700-2B739扩展D222字2B740-2B81D扩展E5762字2B820-2CEA1扩展F7473字2CEB0-2EBE0扩展G4939字30000-3134A扩展H4192字31350-323AF康熙部首214字2F00-2FD5部首扩展115字①2E80-2EF3兼容汉字472字②F900-FAD9兼容扩展542字2F800-2FA1D汉字笔画36字31C0-31E3汉字结构12字2FF0-2FFB汉语注音43字3105-312F注音扩展32字31A0-31BF〇1字3007 Unicode 版本:15.0
字数备注:
① 部首扩展:2E9A 是空码位。
② 兼容汉字:FA6E、FA6F 是空码位。
此页面的字数按实际字数标示(排除空码位),编码范围则排除了首尾空码位。另一个页面《世界文字大全》的编码范围标注则与 Unicode 一致(包括空码位)。
关于UTF-8编码的优点:
UTF-8 UTF-8的特点是对不同范围的字符使用不同长度的编码。
事情是这样的,最近Claude AI挺火的,听说能够比肩ChatGPT,还不用翻墙,还能连互联网,能问到实时信息,所以我就尝试去注册一个slack,等到要添加Claude应用的时候,发现添加不了!说我当前地区不支持!App Unavailable !
然后我又去翻了墙,还是不支持,我去!我就去度娘搜了下,你猜怎么着?清一色的解决方案都是让人加入他们自己的slack组,完事在他们群聊里用Claude机器人,一个是不方便,而且还麻烦,有种寄人篱下的感觉。至于他们打着什么小算盘,我大致也能猜到。
我就不信邪,我一厦大计院的还搞不定这?
成了!最后真被我弄出来了! 我也不绕弯了,我直接说了,让你加入他们slack组的都是最后想让你付费帮你弄!我加了其中几个的v问了下,基本上都是三四十,虽然也不贵,毕竟是辛苦钱,
我豁出去了!我 ¥9.9!就是要把价格打下来!哈哈! 你要是觉得可以,¥9.9 我帮你搞定,让你拥有自己的Claude机器人,省的你再到处找解决办法了,毕竟时间就是金钱!
你要是觉得不值这个价,或者就是愿意寄人篱下去在别人slack底下用,那你不用加我!我只服务懂我价值的人!
来,废话不多说,上链接 (VX:kuzu9898)或者加入我的slack联系我:(点下面链接加我)
Slack
实现 tap 点击跳转
点击删除跳转条件
删除的不是自身:不用跳转删除的是最后一个:跳转到最后一个删除的是自身且不是最后一个:跳转到后一个(相当于当前元素下标) <template> <div class="tag"> <el-tag size="small" v-for="(item, index) in tags" :key="index" :effect="$route.name == item.name ? 'dark' : 'plain'" :closable="item.name !== 'home'" style="cursor: pointer" @click="changeMenu(item)" @close="handleClose(item, index)" >{{ item.label }}</el-tag > </div> </template> <script> import { mapMutations, mapState } from "vuex"; export default { computed: { // 从vuex获取的数据 ...mapState({ tags: (state) => state.top.tabsList }), }, methods: { // 触发vuex的mutations删除方法 ...mapMutations(["closeTag"]), // 点击 changeMenu(item) { this.$router.push(item.path); }, // tag删除 handleClose(item, index) { // item:tag元素,index:tag 索引 this.
本文已获授权,部分有删改。来源:Xtreme1
自 2012 年以来,深度学习技术变革引起的人工智能热潮,这股势头已经持续十年。在去年底 ChatGPT 的出现,大模型的超能力完全展现在大众的视线中,将人工智能行业又推向了一个全新的发展阶段,许多研究者更是惊呼“ChatGPT 爆火后,NLP 技术不存在了” [1]。因为过去的自然语言专家,有着擅长于自己的领域,有人专门做文本分类、有人专门做信息抽取、有人做问答、有人做阅读理解,而在大模型范式下,一个大语言模型就能实现多种NLP任务的完美统一。
计算机视觉(CV)领域,大家也都密切关注着“大一统”模型,所谓的“ImageGPT”以及“多模态 GPT”的发展。
4 月 5 日 Meta 发布了Segment Anything Model(SAM)——第一个图像分割基础模型,可以称得上是当前最先进的一种图像分割模型,其将NLP领域的prompt范式引进CV,让模型通过prompt一键抠图,在照片或视频中对任意对象实现一键分割,并且能够零样本迁移到其他任务[2],这意味着图片大模型时代已经来临。
同时,让人不禁发问,学术界和商用落地场景使用的、耗时耗力的人工标注的标准答案(Ground truth)是否还有存在的必要?
(文末有图像分割开源数据集推荐)
一、 什么是图像分割? 图像分割(Image Segmentation)是图像处理中的一种技术,也是计算机视觉领域核心任务之一。它是预测图像中每一个像素所属的类别或者物体,输出不同类别的像素级掩码。简单来说,就是将图像中的每个像素标注为属于哪一个对象,比如人、车、树等等,并精细地标注出每个物体的具体位置和形状。
大体上,图像分割可以分为三个子任务: 实例分割 (instance segmentation) 、语义分割 (semantic segmentation) 、全景分割 (panoptic segmentation),这三个子任务都有着大量的算法与模型。他们在计算机视觉、医学影像处理、数字艺术等领域都有广泛的应用。
目标检测与语义分割标注
二、“Segment Anything”项目发布了什么? Meta 发布了“Segment Anything Model(SAM)”和相应的数据集 SA-1B(segment anything),这是一项新的图像分割任务、模型和数据集。
核心亮点:
1. 该模型被设计和训练为可提示性(promptable),支持文本、关键点、边界框等多模态提示。你可以用一个点、一个框、一句话等方式轻松分割出指定物体;甚至接受其他系统的输入提示,比如根据AR/VR头显传来的视觉焦点信息,来选择对应的物体;
2. 可以非常灵活地泛化到新任务和新领域。积累了大量学习经验的SAM 已经能够理解对象的一般概念,不要额外训练,即可对不熟悉的物体和图像进行全自分割标注,可以为任意图像或视频中的任何对象生成掩码;
3. 对于稠密的图片,仍然有非常好的分割效率和效果;
4. 使用高效的SAM模型构建了迄今为止最大的分割数据集SA-1B(segment anything),包括超过 1 亿个 Mask 图和 1100 万张符合许可证的图片。为模型提供了充足的训练数据,有望成为未来计算机视觉分割模型训练和评测的经典数据集。
要知道,以往创建准确的分割模型“需要技术专家通过 AI 模型训练和大量人工精细标注数据进行高度专业化的工作”。而Meta 创建 SAM,旨在减少对专业培训和专业知识的需求,让这个过程更加“平等化”,以求推动计算机视觉研究的进一步发展。
三、 Segment Anything Model 的效果如何? Meta 表示,SAM 已经掌握了对物体的一般概念,能为任何图像或视频中的任何物体生成 Mask,即使在训练过程中没有遇到过这些物体和图像类型。SAM 足够通用,覆盖了广泛的用例,并可在新的图像“领域”(例如水下照片或细胞显微镜图像)上直接使用,无需额外训练(这种能力通常称为零样本迁移)。
数据库设计与优化是一个相对复杂的话题,需要涉及到多个方面,包括数据库的基本概念、关系型数据库的设计、数据库优化技巧等。下面将按照逻辑顺序一步一步详细介绍,排版清晰易懂,希望对你有所帮助。
# 数据库基础概念
## 什么是数据库?
数据库是一个有组织、有结构的数据集合。通常情况下,数据库是用来存储和管理各种数据的。
## 数据库管理系统(DBMS)是什么?
数据库管理系统是一种软件,用于管理和操作数据库。它提供了各种功能,包括创建和维护数据库、授权用户对数据库进行访问、执行查询、备份和还原数据等。
## 关系型数据库与非关系型数据库
关系型数据库是指数据以表格的形式组织,表格中的每行代表一个记录,每列代表一种属性。关系型数据库使用结构化查询语言(SQL)进行查询和管理。
非关系型数据库则没有固定的表格结构,它们使用不同的数据模型,例如文档模型、键值模型、图形模型等。非关系型数据库通常使用类似于JSON的格式进行查询。
## 数据库范式
数据库范式是一组规则,用于设计关系型数据库的表结构。通过遵循数据库范式,可以保证表结构的规范化和优化,从而提高数据的一致性和可靠性。
常见的数据库范式有:
- 第一范式(1NF):所有属性都是原子性的,不可再分。
- 第二范式(2NF):每个非主键属性都完全依赖于主键,而不是依赖于主键的一部分。
- 第三范式(3NF):非主键属性不依赖于其他非主键属性。
## 数据库索引
数据库索引是一种数据结构,用于快速查找数据库中的数据。通过创建索引,可以加快查询速度,提高数据库的性能。
## 数据库事务
数据库事务是一组操作,要么全部执行,要么全部回滚。通过使用事务,可以确保数据库的一致性和完整性。
# 关系型数据库设计
关系型数据库是最常用的一种数据库,本节将介绍如何进行关系型数据库的设计。
## 数据库设计的步骤
数据库设计通常分为以下步骤:
1. 确定数据需求:确定需要存储的数据类型和数据结构。
2. 设计概念模型:使用实体关系模型(ER模型)或UML类图等工具设计概念模型。
3. 转换为逻辑模型:将概念模型转换
接下来,我们需要考虑如何存储用户的个人信息,比如用户名、密码、邮箱等。一般来说,我们需要为每个用户分配一个唯一的ID,以便于在数据库中进行查找和修改。因此,我们可以设计一个名为"Users"的表来存储用户信息,该表包含以下字段:
- ID:用户唯一标识符
- Username:用户名
- Password:密码
- Email:邮箱
- CreateTime:用户创建时间
- UpdateTime:用户信息更新时间
接下来,我们考虑如何存储用户上传的图片或文件。我们可以设计一个名为"Files"的表来存储文件信息,该表包含以下字段:
- ID:文件唯一标识符
- UserID:上传文件的用户ID
- FileName:文件名
- FileType:文件类型(例如图片、文档等)
- FilePath:文件存储路径
- FileSize:文件大小
- CreateTime:文件上传时间
目录
一、类型转换
1、为什么需要数据类型转换
2、数据类型转化的函数
3、str()函数类型转换使用
4、int()函数类型转换使用
4.1int()不能将str类型数据转换成int
4.2int()将bool类型转换成int
4.3int()将float转换成int
5、Float()函数类型转换使用
5.1Float()函数不能将str类型转换成浮点数
5.2 Float()函数将int类型转换成浮点数
5.3 Float()函数将bool类型转换成浮点数
二、python注释
1、为什么会使用到注释
2、单行注释
3、多行注释
4、中文编码声明注释
一、类型转换 1、为什么需要数据类型转换 将不同的数据类型数据拼接到一起
2、数据类型转化的函数 函数名作用注意事项举例str()将其他类型转化成字符串也可用引号转换str(123)‘123’int()将其他数据类型转换成整数1、文字类和小数类字符串,无法转换成整数
2、浮点数转换成整数,抹零取整int(‘123’)123
int(9.8)float()将其他数据类型转换成浮点数 1、文字类无法转换成浮点数(浮点数字符串除外)
2、整数转换浮点数,末尾为.0
float(‘9.9’)
float(9) 3、str()函数类型转换使用 将int转换成str类型,将bool类型转换成str类型,将float类型转换成str类型
4、int()函数类型转换使用 4.1int()不能将str类型数据转换成int 但是有一种特殊情况可以进行转换,那就是将‘数字串’转换为int类型
其次不能将float的数字串转换为int类型
4.2int()将bool类型转换成int 在python中 True代表1 False代表0 4.3int()将float转换成int 5、Float()函数类型转换使用 有五组测试数据, 用来进行测试是否都能转换成float类型
s1='hello'
b1=False
i=98
s2='19'
s3='19.88'
5.1Float()函数不能将str类型转换成浮点数 特殊情况同int()将str类型转换成int类型情况类似,s2='19',s3='19.88'这两组是可以转换为float类型的
5.2 Float()函数将int类型转换成浮点数 将int数据类型转换成float数据类型,会在数据之后加上.0
5.3 Float()函数将bool类型转换成浮点数 同理,由于false转换成数值是为0,所以将false转为float类型时,会在末尾加上.0,就变成了0.0
二、python注释 1、为什么会使用到注释 在代码中对代码的功能进行解释说明的标志性文字,可以提高代码的可读性
注意:注释的内容会被python解释器忽视
python注释分为三种,一种是单行注释,一种是多行注释,另一种是中文编码声明注释
2、单行注释 以‘#’开头,直到换行结束
3、多行注释 没有单独的多行注释标记,将一对三引号之间的代码成为多行注释
4、中文编码声明注释 在文件开头加上中文声明注释,用以指定源码文件的编码格式
一、数据备份的重要性 备份的主要目的是灾难恢复。
在生产环境中,数据的安全性至关重要。
任何数据的丢失都可能产生严重的后果。
造成数据丢失的原因:
程序错误人为操作错误运算错误磁盘故障灾难(如火灾、地震)和盗窃 二、数据库备份的分类和备份策略 2.1 数据库备份的分类 1)物理备份 物理备份:对数据库操作系统的物理文件(如数据文件、日志文件等)的备份。
物理备份方法:
冷备份(脱机备份) :是在关闭数据库的时候进行的热备份(联机备份) :数据库处于运行状态,依赖于数据库的日志文件温备份:数据库锁定表格(不可写入但可读)的状态下进行备份操作 2)逻辑备份 逻辑备份:对数据库逻辑组件(如:表等数据库对象)的备份。
即以sql语句的形式,把库、表结构、表数据保存下来 2.2 数据库的备份策略 完全备份(全量备份):每次对数据库进行完整的备份。差异备份:备份自从上次完全备份之后被修改过的文件。增量备份:只有在上次完全备份或者增量备份后被修改的文件才会被备份。 三、常见的备份方法 物理冷备: (完全备份)
备份时数据库处于关闭状态,直接打包数据库文件备份速度快,恢复时也是最简单的 专用备份工具mydump或mysqlhotcopy (完全备份,逻辑备份)
mysqldump常用的逻辑备份工具 (导出为sql脚本)mysqlhotcopy仅拥有备份MyISAM和ARCHIVE表 启用二进制日志进行增量备份 (增量备份)
进行增量备份,需要刷新二进制日志 第三方工具备份
免费的MySQL热备份软件Percona XtraBackup (阿里云的工具:dts,支持热迁移)
四、MySQL完全备份介绍 4.1 什么是完全备份 完全备份是对整个数据库、数据库结构和文件结构的备份保存的是备份完成时刻的数据库是差异备份与增量备份的基础 4.2 完全备份的优缺点 优点:
备份与恢复操作简单方便 缺点:
数据存在大量的重复占用大量的备份空间备份与恢复时间长 4.3 完全备份的方法 1)物理冷备份与恢复 关闭MySQL数据库使用tar命令直接打包数据库文件夹直接替换现有MySQL目录即可 2)mysqldump备份与恢复 MySQL自带的备份工具,可方便实现对MySQL的备份可以将指定的库、表导出为SQL脚本使用命令mysq|导入备份的数据 五、完全备份与恢复 操作演示 5.1 物理冷备份 5.1.1 完全备份 先关闭数据库,之后打包备份
systemctl stop mysqld #先关闭服务 mkdir /backup/ #创建备份目录 rpm -q xz #使用xz工具进行压缩,检查xz工具是否已安装 yum install xz -y #如果没安装,可以先yum安装 tar Jcf /backup/mysql_all_$(date +%F).
文章目录 HTML结构HTML常见标签注释标题标签h1 - h6段落标签p换行标签br格式化标签图片标签img超链接标签a表格标签table列表标签ul ol dl表单标签`select`标签`textarea`标签无语义标签`div和span` HTML结构 形如:
<body></body> 这样的标签就是一个HTML标签,HTML文件有自己的基本结构:
<html> <head> <title>Document</title> </head> <body> hello world </body> </html> 上面就是一个HTML文件的基本结构,html 标签是整个html文件的根标签(最顶层标签),head 标签中写页面的属性,body 标签中写的是页面上显示的内容,title标签中写的是页面的标题。
层次关系:父子关系和兄弟关系,我们把html标签是head body标签的父标签,而head与body是兄弟的关系。
HTML常见标签 注释 <!-- 注释 --> 注释并不会显示在网页上,只有开发人员才能看见。
标题标签h1 - h6 从h1 - h6 标题的标签,数字越大,显示的字体越小。
段落标签p <p></p>
这样一段文字显示在网页上并不美观,我们可以使用p标签来分段:
注意:
1、p标签之间会存在一个空隙用来
2、段落会根据浏览器的宽度自动排版
3、HTML内容首尾处的换行,空格均无效
4、在HTML中文字之间输入空格只相当于一个空格,输入换行不会真的换行,而是相当于一个空格。
换行标签br <br/>
注意:
1、br标签是一个单标签
2、br标签没有空隙
3、<br/>是规范写法. 不建议写成 <br>
格式化标签 加粗: strong 标签 和 b 标签
倾斜: em 标签 和 i 标签
删除线: del 标签 和s标签
function numberFormat (number, decimals, decPoint, thousandsSep, roundtag) { /* * 参数说明: * number:要格式化的数字 * decimals:保留几位小数 * dec_point:小数点符号 * thousands_sep:千分位符号 * roundtag:舍入参数,默认 'ceil' 向上取,'floor'向下取,'round' 四舍五入 * */ number = (number + '').replace(/[^0-9+-Ee.]/g, '') roundtag = roundtag || 'ceil' // 'ceil','floor','round' var n = !isFinite(+number) ? 0 : +number var prec = !isFinite(+decimals) ? 0 : Math.abs(decimals) var sep = (typeof thousandsSep === 'undefined') ? ',' : thousandsSep var dec = (typeof decPoint === 'undefined') ?
spingboot默认日志系统LogBack、Log4j和slf4j使用详解 spingboot默认日志系统LogBack 依赖引入 Spring Boot默认使用LogBack日志系统,如果不需要更改为其他日志系统如Log4j2等,则无需多余的配置,LogBack默认将日志打印到控制台上。
如果要使用LogBack,原则上是需要添加dependency依赖的
<groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-logging</artifactId> 但是因为新建的Spring Boot项目一般都会引用spring-boot-starter或者spring-boot-starter-web,而这两个起步依赖中都已经包含了对于spring-boot-starter-logging的依赖,所以,无需额外添加依赖。
如何在项目中打印日志 新建一个配置类LogConfig,注入一个Bean,并在方法中打印日志
package com.jackie.springbootdemo.config; import com.jackie.springbootdemo.model.Person; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class LogConfig { private static final Logger LOG = LoggerFactory.getLogger(LogConfig.class); @Bean public Person logMethod() { LOG.info("==========print log=========="); return new Person(); } } Spring Boot默认的日志级别为INFO,这里打印的是INFO级别的日志所以可以显示。
很多开发者在日常写private static final Logger LOG = LoggerFactory.getLogger(LogConfig.class);总觉得后面的LogConfig.class可有可无,因为随便写个其他类也不会报错,但是准确编写class信息能够提供快速定位日志的效率。
我们看到打印的日志内容左侧就是对应的类名称,这个是通过private static final Logger LOG = LoggerFactory.getLogger(LogConfig.class);实现的。
如果将LogConfig.class换成xxx.class,输出日志就会显示对应的xxx类名。这样声明的好处就是方便定位日志。
如何将日志信息存储到文件 在本机环境,我们习惯在控制台看日志,但是线上我们还是要通过将日志信息保存到日志文件中,查询日志文件即可。
那么应该如何配置才能将日志信息保存到文件呢?
在我们创建的springboot项目中,resources目录下有个application.yml文件添加如下配置
idea非正常关闭后项目启动报错
当我们未关闭项目时直接关闭idea,再次打开idea会出现报错行为,这时我们可以尝试看看是不是项目未关闭依旧在跑导致的
打开idea底部的Terminal,如下图
输入jps回车,会出现正在跑的进程,看看自己的项目是不是包含在其中,可以看到下图我的项目是在运行中的,进程id为17156和12536
输入taskkill /pid 进程id /F 就可以把未关闭的项目给关闭,这个时候再跑项目就可以正常运行了
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBufUtil; import io.netty.buffer.Unpooled; import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.ByteToMessageDecoder; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import java.util.List; /** * @describe TCP/IP数据解码器 */ @Slf4j @Component public class MessageDecoderHandler extends ByteToMessageDecoder { private final ByteBuf header; private final ByteBuf ender; public MessageDecoderHandler() { this.header = Unpooled.buffer(); header.writeByte(0x7E); this.ender = Unpooled.buffer(); ender.writeByte(0x7E); } @Override protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception { // 显示十六进制的接收码 log.info("收到数据:{}", ByteBufUtil.hexDump(in)); if (ByteBufUtil.hexDump(in).startsWith("7e") && ByteBufUtil.hexDump(in).endsWith("7e")) { // 调用decode方法,识别帧头和帧尾 ByteBuf childBuf = decode(in); // 如果获得有效数据 if (childBuf !
很多不是程序员的朋友总是理解不了网站到底是什么,它到底是怎么存在和运行的,也总是以为建一个网站很复杂。其实建网站并不难,也不需要花费太大资金,只需要以下6个步骤即可做出一个网站。
第一步:注册域名并实名认证
第二步:购买云虚拟主机
第三步:域名备案
第四步:域名解析绑定
第五步:安装网站程序
第六步:网站二次开发与网站仿站
了解完以上6个步骤后,下面我们来详细学习下操作方法。
第一步:注册域名(也称网站网址、URL。如:xxxx.com)
什么是域名?
我们通常在上网时候访问的网址(如:www.baidu.com)这个就是一个域名,客观的讲它就是网站在互联网上的地址,是网站的入口。域名也是由若干部分组成,包括数字和字母。域名还可以起到引导、宣传、代表等作用。域名后缀可分为很多种,例如:我们经常看到的后缀有(.com、.cn、.net、.gov、.top、.xyz、.cc、.vip)等等。
域名注册费用怎么收取?
域名一般是按年注册,当然费用也是按年收取的,如果第二年不想要了,会被自动收回;现在如果在九灵云注册一个,一般现在费用大概为这些:.com要69元/年;.cn要30元/首年;.net要76元/年;.com.cn要30元/年;.net.cn要30元/年;目前注册域名公司有好多,如:腾讯云的爱名网、阿里云的万网等。域名如果已被他人抢先注册,就注册不了啦,因为原则上是先注册先得,不可重复的,那我们可以说它是独一无二的。
第二步:购买云虚拟主机(也称云服务器、网站空间)
什么是云虚拟主机?
云虚拟主机(Web Hosting)是一种网站托管服务。产品预装了常见网站开发语言的运行环境、数据库及管理工具,您可以通过云虚拟主机简单、低成本地发布托管网站。
怎么购买云虚拟主机?
这里以九灵云的云虚拟主机产品为例,具备高在线率、高安全性、高稳定性等多项优势,有共享IP和独立IP两种类型,共享IP价格比较低,只要7元/一个月,特别适合初级入门建站用户。新手建站建议购买共享IP云虚拟主机就够用了,共享IP的云虚拟主机有2GB的网页空间,支持语言:.NET,PHP,ASP,数据库:100M。购买成功后在控制面板有FTP账号和FTP地址,可以用于上传PHP网站程序或者ASP、.NET网站程序,当然云虚拟主机控制面板也支持一键安装网站程序,有dedeCMS内容管理系统、Discuz论坛系统、ECShop商城系统、metinfo企业官网系统等等。
三丰云的免费服务器 或者免费提供的免费1G空间搭建 适合新手练手
1g内存,1核cpu,10g ssd硬盘的云服务器够用了
免费1G空间
网站空间:1GIP MySql数据库:50M
语言环境:Asp/Php月流量:5GMsSql
做网站是足够了
第三步:域名备案(中国境内开设网站需要取得ICP备案,例如:浙ICP备XXXXX号)
为什么要备案?
根据中华人民共和国国务院令第291号《中华人民共和国电信条例》、第292号《互联网信息服务管理办法》(简称ICP管理办法),国家对提供互联网信息服务的ICP实行许可证制度。ICP证是网站经营的许可证,根据国家《互联网信息服务管理办法》规定,经营性网站必须办理ICP证,否则就属于非法经营。
备案审核时间
备案信息审核需要经过三个步骤:
1、服务器ISP接入商审核
2、待提交至通管局审核表示您提交的备案信息已通过ISP接入商审核, 备案系统正在向通管局系统提交您的备案信息, 备案系统会显示“待提交至通管局审核”, 提交时间取决于通管局的接口可靠性, 正常时间在一天以内;
3、待通管局审核表示备案信息已成功提交至工信部接口, 通管局正在接收数据或审核,审核时间一般不超过20个工作日
如何开始备案?
现在的域名注册商大多都会提供免费备案的服务,并且现在基本上都是电子化备案,无须再邮寄各种资料了,这里同样以九灵云为例子,备案前先准备好以下资料:
身份证件
智能手机一部(需要用手机人脸核验)
域名证书(域名注册成功后可获得)
然后登录电子化备案系统,选择新增网站接入按照提示填写相应的资料并且提交,提交后九灵云备案合作商会初次审核你的备案资料,如备案资料无误将会提交管局审核,经过漫长的等待,管局审核通过后会以短信的形式将ICP备案号发送到你的手机上,至此备案结束。
第四步:域名与云虚拟主机的解析绑定,让网站域名与云虚拟主机建立关联
什么是域名系统(DNS)?
DNS,Domain Name System或者Domain Name Service(域名系统或者域名服务)。域名系统为互联网上的主机分配域名地址和IP地址。由于网络中的计算机都必须有个IP地址,来识别, 互相之间才能通信,但让我们记住一大串的IP地址来访问网站显然是不可能的,人们更容易记住域名地址,而DNS系统的功能就是自动把域名地址翻译为IP地址。域名服务是运行域名系统的Internet工具。执行域名服务的服务器称之为DNS服务器,通过DNS服务器来应答域名服务的查询,DNS就是域名服务器,他的任务就是确定域名的解析,把域名解析成IP地址,比如A记录MX记录等等。
如何将域名解析到云虚拟主机的IP上?
在操作域名解析之前,首先要在云虚拟主机控制台添加绑定域名,这里以九灵云的云虚拟主机的控制台为例,进入九灵云用户中心->云虚拟主机->找的已经购买的主机->点击管理->找的域名绑定选项->然后点击添加域名。
根据域名绑定页面底部的提示,需要用别名解析(CNAME)到:xxxxxxxxxx.xxxxxx.cn(为了数据安全,已做掩饰),此时你需要将这一长串网址复制下来,以备域名解析使用。
在云虚拟机绑定域名后,再进入用户中心->域名->找的已经注册的域名->点击管理->添加解析,并根据云虚拟主机绑定域名的提示,添加一个CNAME的解析记录,并将主机(host)填写成:www,记录值就粘贴刚刚复制下来的一长串网址。
经过以上操作,域名已经成功解析到了云虚拟主机上,并且可以通过域名访问到云虚拟主机了。
第五步:安装网站程序(也叫建站程序、网站源码)
什么是网站程序?
网站程序通常是通过php、.NET、ASP等编程语言编写并设计的一套网页系统,有点类似我们电脑使用的软件系统。唯一不同的是网页系统是运行在云服务器、云虚拟主机上,可以通过任何有互联网的终端访问并查看。一般建站比较主流的就是CMS系统(内容管理系统),以下对一些比较有名的建站系统做一个简单介绍:
WordPress:这个比较有名气,全球使用量最大的博客程序,可以修改设计模板调用做企业站和外贸网站。更新比较快安全性也非常好,毕竟全球最大量使用。
DedeCMS:一款集简单、健壮、灵活、开源几大特点的开源内容管理系统,国内比较早的一套CMS系统。
discuz:做论坛的话这个首选,也是国内起步比较早的程序,目前被腾讯收购,对接公众号 和微信非常好。已经非常成熟,很多大型网站比如合肥论坛 化龙巷 等都用这种程序。
目录
一、什么是Socket套接字
二、UDP数据包套接字编程
1.DatagramSocket API
(1)关于Socket对象
(2)DatagramSocket方法
2. DatagramPacket API
DatagramPacket方法
3.基于UDP Socket的客户端服务器程序(回显服务器echo server)
4.单词翻译服务器
三、TCP数据包套接字编程
1.SeverSocket API
2.Socket API
3.基于TCP套接字的回显程序
一、什么是Socket套接字 数据报,Datagram,通过网络传输的数据的基本单元,包含一个报头(header)和数据本身,其中报头描述了数据的目的地以及和其它数据之间的关系。
概念:socket套接字,是由系统提供用于网络通信的技术,是基于TCP/IP协议的网络通信的基本操作单元。基于Socket套接字的网络程序开发就是网络编程。
TCP/IP五层网络模型:应用层,传输层,网络层,数据链路层,物理层。其中应用层主要是应用程序,传输层和网络层是是由系统内核封装的,数据链路层和物理层主要是由硬件和驱动实现的。在网络分层下,数据的传输离不开封装和分用。
程序员写网络程序 ,主要编写的是应用层代码,其他下面四层是程序员无法改变的。当应用程序需要将数据上传,此时就需要上层协议,调用下层协议,应用层调用传输层,传输层给应用层提供一组api,这组api就是套接字socket。
系统主要给我们提供两组Socket api:
1.基于UDP的api ;
2.基于TCP的api。
UDP协议和TCP协议的特点
UDP:无连接,不可靠传输,面向数据报,全双工
TCP:有连接,可靠传输,面向字节流,全双工
有/无连接:使用UDP/TCP通信的双方,各自是否需要刻意保存对端的相关信息;
可靠传输:信息发出去,尽可能的传输过去。
不可靠传输:信息发出去,不关注结果,不关注是否传输过去。
面向数据报:以一个UDP数据报为传输的基本单位。
面向字节流:以字节流为传输的基本单位,读写方式十分灵活。
全双工/半双工:一条路径双/单向通信。
二、UDP数据包套接字编程 主要提供了两个类:DatagramSocket(Socket对象),DatagramPacket(udp数据报)
关于“报”,是网络传输数据的基本单位,这些基本单位主要包括:报(datagram)(udp中使用),包(packet)(ip中使用),段(segment)(tcp中使用),帧(frame)(数据链路层中使用)。日常生活中,不会特意区分这些单位,但是写研究论文需要区分。
1.DatagramSocket API (1)关于Socket对象 Socket对象:相当于对应到系统中的一个特殊文件(socket文件),这个文件并非对应到硬盘上的某个数据存储区域,而是对应到网卡这个硬件设备。进行网络通信,离不开socket文件这样的对象,借助socket文件对象,才能间接的操作网卡(相当于遥控器)。
向socket对象中写数据,相当于通过网卡发送消息;向socket对象中读数据,就相当于通过网卡接收消息。
下图片的以太网适配器就是一个有线网卡:
无线网卡:
没有网卡就不能上网,一般是集成在主板上的。
文件:广义上,代指很多计算机中的软件/硬件资源;狭义上,代指硬盘上的一块数据存储区域。
DatagramSocket是UDP Socket用于发送和接收UDP数据报。
(2)DatagramSocket方法 DatagramSocket构造方法:绑定一个端口号(服务器),也可以不显示指定客户端
方法签名
方法说明
DatagramSocket
创建一个UDP数据报套接字的Socket,绑定到本机任意一个随机端口 (一般用于客户端)
DatagramSocket(int port)
创建一个UDP数据报套接字的Socket,绑定到本机指定的端口(一般用于服务端)
DatagramSocket(int port):此处Socket对象可能被客户端/服务器使用,服务器的socket往往需要关联一个具体的端口号(不变);客户端这里不需要手动指定,系统自动分配即可(可以改变)。
DatagramSocket方法:
方法签名
问题:使用drogon upload上传文件时,一直上传失败无响应
原因:drogon的config.json配置文件中限制了上传文件的大小为1M
//client_max_body_size: Set the maximum body size of HTTP requests received by drogon. The default value is "1M". //One can set it to "1024", "1k", "10M", "1G", etc. Setting it to "" means no limit. "client_max_body_size": "1M", //max_memory_body_size: Set the maximum body size in memory of HTTP requests received by drogon. The default value is "64K" bytes. //If the body size of a HTTP request exceeds this limit, the body is stored to a temporary file for processing.
阅读GC日志是处理Java虚拟机内存问题的基础技能,它只是一些人为确定的规则,没有太多技术含量。在本书的第1版中没有专门讲解如何阅读分析GC日志,为此作者收到许多读者来信,反映对此感到困惑,因此专门增加本节内容来讲解如何理解GC日志。
每一种收集器的日志形式都是由它们自身的实现所决定的,换而言之,每个收集器的日志格式都可以不一样。但虚拟机设计者为了方便用户阅读,将各个收集器的日志都维持一定的共性,例如以下两段典型的 GC日志: 33.125:[GC[DefNew:3324K->152K(3712K),0.0025925 secs] 3324K->152K(11904K),o. 0031680secs]
100.667:[Ful1 GC [Tenured:0K->210K(10240K),0.0149142 secs]
4603K->210K(19456K),[Perm : 2999K->2999K(21248K)],0.0150007 secs] (Times:user=0.01 sys-0.00,real=0.02 secs]
最前面的数字“33.125:”和“100.667:”代表了GC发生的时间,这个数字的含义是从Java虚拟机启动以来经过的秒数。
GC日志开头的“[GC”和“[Full GC”说明了这次垃圾收集的停顿类型,而不是用来区
分新生代GC还是老年代GC的。如宋nru,Vn“IEollCC”(这一般是因为出现了分配例如下面这段新生代收集奋ParrNvew H心u田日we日Goctem oc)方法所触发的收集,那么担保失败之类的问题,所以才导致STW)。如果是调用System.gc()方法所触发的收集,那么
在这里将显示“[Full GC (System)”。
(Full GC 283.736: [ParNew: 261599K->261599K(261952K),0.0000288 secs]接下来的“[DefNew”、“[ Tenured”、“[Perm”表示GC发生的区域,
这里显示的区域名
称与使用的GC收集器是密切相关的,例如上团中例从比n DenianwIm!an就几小日物“Default New Generation",所以显示的是“[DefNew”。如果是ParNew收集器,新生代名称
就会变为“[ParNew”,意为“Parallel New Generation”。如果采用Paralle
Scavenge收集器,那它配套的新生代称为“PSYoungGen",老年代和永久代同理,名称也是由收集器决定的。
后面方括号内部的“3324K->152K(3712K)”含义是“GC前该内存区域已使用容量->GC后该内存区域已使用容量(该内存区域总容量)”。而在方括号之外的“3324K->152K(11904K)”表示“GC前Java堆已使用容量->GC后Java堆已使用容量(Java堆总容量)”。
再往后,“0.0025925 secs”表示该内存区域GC所占用的时间,单位是秒。有的收集器会给出更具体的时间数据,如“LTimes : user=0.01 sys=0.00,real=0.02 secs]",这里面的user、sys和real与Linux 的time命令所输出的时间含义一致,分别代表用户态消耗的CPU时间、内核态消耗的CPU事件和操作从开始到结束所经过的墙钟时间(Wall Clock Time)。
CPU时间与墙钟时间的区别是,墙钟时间包括各种非运算的等待耗时,
例如等待磁盘IO、
等待线程阻塞,而CPU时间不包括这些耗时,但当系统有多CPU或者多核的话,多线程操作会叠加这些CPU时间,所以读者看到user或sys时间超过real时间是完全正常的。
navigator.clipboard.writeText在http协议下不可用的坑,浏览器禁用了非安全域的 navigator.clipboard 对象,安全域包括本地访问与开启TLS安全认证的地址,如 https 协议的地址、127.0.0.1 或 localhost 。(其实主要是http属于非安全域)下面的方法属于兼容了http的 function copyToClipboard(textToCopy) { // navigator clipboard 需要https等安全上下文 if (navigator.clipboard && window.isSecureContext) { // navigator clipboard 向剪贴板写文本 return navigator.clipboard.writeText(textToCopy); } else { // 创建text area let textArea = document.createElement("textarea"); textArea.value = textToCopy; // 使text area不在viewport,同时设置不可见 textArea.style.position = "absolute"; textArea.style.opacity = 0; textArea.style.left = "-999999px"; textArea.style.top = "-999999px"; document.body.appendChild(textArea); textArea.focus(); textArea.select(); return new Promise((res, rej) => { // 执行复制命令并移除文本框 document.execCommand('copy') ? res() : rej(); textArea.
随着软件开发行业的发展,越来越多的公司和开发人员在工作中会涉及到gRPC和WebSocket等接口类型,但是目前市面上能支持这种接口的调试工具却几乎没有,国外的工具大都晦涩难懂,不符合我们的开发习惯,很难上手使用。
经过多位用户的反馈建议, Apipost终于在最新更新的7版本中率先开始支持gRPC和WebSocket类型的接口调试。
在7版本客户端和Web端都可以看到,新建API调试时除了之前的Http类型的接口调试之外,已经支持新建gRPC调试和WebSocket类型接口调试。话不多说,先来看看如何使用吧!
1、gRPC调试 由于gRPC良好的生态、强大的性能、支持多种语言、基于http2.0的流式处理等多种优势,导致gRPC的使用频率越来越高,随之而来进行gRPC调试的需求也日益增加。选择在Apipost 7中进行gRPC调试,只需要简单的几步即可实现:
第一步:导入proto文件
支持从本地导入和在线导入proto文件,导入后可以看到目录区有导入的server和method。
第二步:选择调试方法
选择某个server下具体的方法,填写入参和服务地址,就可以直接调用!还可以选择证书。
2、WebSocket调试 由于WebSocket是一种在单个TCP连接上进行全双工通信的协议,浏览器和服务器只需要完成一次握手就直接可以创建持久性的连接,并进行双向数据传输,所以WebSocket的应用场景也越来越广泛。Apipost 7支持WebSocket、http://Socket.IO和Socket.JS类型调试,能满足多种场景的调试。调试步骤也so easy:
第一步:新建WebSocket
打开工作台后,可以看到明显的新建WebSocket入口,或者点击团队旁边的“新建”按钮也可以新建。
第二步:选择调试类型,输入socket地址
Apipost 7支持Raw、Socket.IO和Socket.JS三种类型,可以更多的满足不同类型的调试需求。
(注:http://Socket.IO调试在输入地址后,可以在“设置”里选择应该用于连接服务器的客户端版本)
第三步:点击连接
连接后,会出现连接成功的结果,此时也可以选择断开连接。
第四步:发送内容
Apipost 7支持发送Text、JSON、XML、Binary四种格式的内容,选好格式后输入内容,就可以发生了。
下面的返回结果也很清晰明了,点开可以看到发送的内容和信息详情,而且还可以做消息筛选,非常方便。
当然,Apipost发展到如今的第7版本,绝对不仅仅是能支持Http、gRPC、WebSocket等类型的API调试,还能实现API设计(代码未写、文档先行)、智能Mock、自动化测试(无需敲代码、全程可视化操作)等强大功能,让团队成员同时在线协作,内容实时同步,更高效完成工作。
学习安排上 作为一位过来人也是希望大家少走一些弯路,在这里我给大家分享一些软件自动化测试的学习资源,希望能给你前进的路上带来帮助。【无套路免费白嫖】
视频文档获取方式: 这份文档和视频资料,对于想从事【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴我走过了最艰难的路程,希望也能帮助到你!以上均可以分享,点下方小卡片即可自行领取。
1、通过argparse模块可实现通过命令行传递参数,并设置默认值
import argparse #初始化参数构造器 parser = argparse.ArgumentParser() #在参数构造器中添加命令行参数 parser.add_argument('--path',type = str,default = 'C:/Users/63058/Desktop/print') #获取命令行参数 args = parser.parse_args() #使用获取的命令行参数 path = args.path 2、执行代码时需对参数进行赋值
若不赋值则使用默认值运行
设计完整的程序实现以下功能:从键盘上输入3个整数,通过指针运算,找出3个数中的最大值与最小值和它们的地址,并实现最大值与最小值的交换(要求用指针作为函数参数处理)。
#include <stdio.h> void swap(int* a, int* b) { int tmp = *a; *a = *b; *b = tmp; } int main() { int a = 0; int b = 0; int c = 0; scanf("%d%d%d",&a ,&b, &c); printf("输入的三个数是%d,%d,%d\n",a,b,c); if (a > b) { if (b > c) { printf("最大数是%d,最小数是%d\n",a,c); swap(&a, &c); } else if (a > c) { printf("最大数是%d,最小数是%d\n",a,b); swap(&a, &b); } else { printf("最大数是%d,最小数是%d\n",c,b); swap(&c, &b); } } else // b >= a { if (a > c) { printf("