使用 nfs 文件系统 实现kubernetes存储动态挂载
1. 安装服务端和客户端
root@hello:~# apt install nfs-kernel-server nfs-common 其中 nfs-kernel-server 为服务端, nfs-common 为客户端。
2. 配置 nfs 共享目录
root@hello:~# mkdir /nfs root@hello:~# sudo vim /etc/exports /nfs *(rw,sync,no_root_squash,no_subtree_check) 各字段解析如下: /nfs: 要共享的目录 :指定可以访问共享目录的用户 ip, * 代表所有用户。192.168.3. 指定网段。192.168.3.29 指定 ip。 rw:可读可写。如果想要只读的话,可以指定 ro。 sync:文件同步写入到内存与硬盘中。 async:文件会先暂存于内存中,而非直接写入硬盘。 no_root_squash:登入 nfs 主机使用分享目录的使用者,如果是 root 的话,那么对于这个分享的目录来说,他就具有 root 的权限!这个项目『极不安全』,不建议使用!但如果你需要在客户端对 nfs 目录进行写入操作。你就得配置 no_root_squash。方便与安全不可兼得。 root_squash:在登入 nfs 主机使用分享之目录的使用者如果是 root 时,那么这个使用者的权限将被压缩成为匿名使用者,通常他的 UID 与 GID 都会变成 nobody 那个系统账号的身份。 subtree_check:强制 nfs 检查父目录的权限(默认) no_subtree_check:不检查父目录权限 配置完成后,执行以下命令导出共享目录,并重启 nfs 服务:
JDK 1.8 = 52
JDK 1.7 = 51
JDK 1.6 =50
JDK 1.5 = 49
JDK 1.4 = 48
JDK 1.3 = 47
JDK 1.2 = 46
JDK 1.1 = 45
1、安装操作系统 安装CentOS 7.9,最小化安装(Minimal)即可。
①系统要求 8核16G内存,100G存储空间
②安装依赖 yum -y install wget vim rpm apr apr-util bzip2 krb5-devel libyaml net-tools rsync zip libevent ③关闭selinux和防火墙 systemctl stop firewalld.service systemctl disable firewalld.service vi /etc/selinux/config #更改SELINUX=disabled reboot #重启后可以查看一下selinux状态 sestatus #正确的情况下会显示: SELinux status: disabled ④修改主机名 hostname gp-server vim /etc/hosts #在文件的末尾添加ip地址和主机名的映射关系 #例如:192.168.xxx.xxx gp-server 2、修改信号量配置文件 首先查看一下当前的配置:
ipcs -ls ------ Semaphore Limits --------
max number of arrays = 128
max semaphores per array = 250
max semaphores system wide = 32000
import sqlite3 from sqlite3 import Error def sql_connection(): try: con = sqlite3.connect(':memory:') return con except Error: print(Error) def sql_table(con): cursorObj = con.cursor() cursorObj.execute( '''create table a_table ( id int primary key not null, c2 int not null, c3 int not null );''') con.commit() cursorObj.execute('''create table b_table ( pid int not null references a_table, c2 int not null );''') con.commit() cursorObj.execute('insert into a_table values (1, 2, 3);') con.commit() cursorObj.execute('insert into b_table values (1, 4);') con.
(.[\u4E00-\u9FA5]+)|([\u4E00-\u9FA5]+.)
需要选择正则表达式模式哦
es的配置需要注意的地方分为系统配置和es本身相关的一些配置
ES系统配置优化 1.增大进程可以打开的文件数, vim /etc/security/limits.conf
* soft nofile 100000 * hard nofile 131072 生效方式:shell重新连接就生效,应该是新的会话就生效
2.增大进程可以创建的线程数 2.1 vim /etc/security/limits.conf * soft nproc 10240 * hard nproc 20480 生效方式:shell重新连接就生效,应该是新的会话就生效
2.2 vim /etc/security/limits.d/90-nproc.conf * soft nproc 20480 生效方式:shell重新连接就生效,应该是新的会话就生效
3.修改可以分配的vma数量(mmap计数) vim /etc/sysctl.conf
vm.max_map_count = 655360 生效方式: sysctl -p
4.关闭swap vim /etc/fstab
注释掉有swap的那一行,这种好像是需要重启才有效果 sudo swapoff -a 会在当前系统生效
5.设置尽可能低的使用swap vim /etc/sysctl.conf
vm.swappiness=0 生效方式: sysctl -p
6.允许进程锁定内存 vim /etc/security/limits.conf
* soft memlock unlimited * hard memlock unlimited 生效方式:shell重新连接就生效,应该是新的会话就生效
import os import logging import requests from bs4 import BeautifulSoup logging.basicConfig(level=logging.INFO) def store_girl_img(girl_url, store_girl_dir): # 把girl_url的单个小姐姐放入store_girl_dir文件夹 girl_html = requests.get(girl_url) #访问girl_url网址 girl_html.encoding = "gbk" #修改编码,不然会是乱码 girl_text = girl_html.text #获取girl_html的网页内容。girl_html.content返回的是bytes数据 girl_src = BeautifulSoup(girl_text, 'lxml').find("div",class_='content-pic').find('img')['src'] #BeautifulSoup用lxml库解析girl_html的网页内容,并找到所有class_='content-pic'的div标签 #再找到img标签下的src属性,得到单张照片的链接 print(girl_src) # 此处加headers是为防反爬虫,如果不加会响应403,没有权限 headers = { 'Referer': girl_url, 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36' } file_name = girl_src.split('/')[-1] #将http://img1.mm131.me/pic/2016/1.jpg切片成["http://img1.mm131.me/pic/2016","1.jpg"],[-1]就是去第二个1.jpg file_name = os.path.join(store_girl_dir, file_name) #在store_girl_dir目录下创建图片名字file_name,如1.jpg with open(file_name, 'wb') as f: #二进制模式打开file_name girl_content = requests.
编译原理第一章课后答案
https://www.cnblogs.com/zjh-study/p/10937847.html
一、什么是序列化?
简单来说,序列化就是将对象的状态储存到特定储存介质中的过程
在此过程中会将对象的公有成员、私有成员包括类名,转换成字节流(二进制),然后再把字节流写入数据流,储存到存储介质中,这里说的存储介质通常是文件
举个简单的例子,序列化就像我们做米饭的过程,米饭就是对象,电饭煲蒸饭的过程就是转换成字节流的过程,电饭煲就是数据流,饭碗就是存储介质(有些博客写着写着就饿了、、、、、)
二、序列化的意义
将Java对象序列化后,可以将其转化成字节序列,这样就可以保存在磁盘上,也可以同时借助网络进行传输,注意,这时候的对象是二进制的状态,如果再设置一个反序列化系统,可以实现平台无关性,这样就会非常的安全。反序列化之后可以得到相同对象,就不用担心数据因为平台问题显示异常了
三、序列化和反序列化代码的实现
举个把对象属性写入新文档的例子
上半部分是对象属性的封装和构造方法
* @Date:2021 * @Description; */ public class Student implements Serializable { private int id; private String name; private int age; private double height; public Student(int id, String name, int age, double height) { setId(id); setHeight(height); setName(name); setAge(age); } @Override public String toString() { return "Student{" + "id=" + id + ", name='" + name + '\'' + ", age=" + age + "
1、src里面存的是源文件(.java),就是人能看得懂的文件
2、bin里面存的是打包文件(.class),就是编译后的字节码文件,让机器看的
两个文件夹里面的文件名是对应的
分治算法思想解决找假硬币的问题
参考文章:
(1)分治算法思想解决找假硬币的问题
(2)https://www.cnblogs.com/zhezh/p/3773377.html
备忘一下。
SQL知识整理三:变量、全局变量、视图、事务、异常
参考文章:
(1)SQL知识整理三:变量、全局变量、视图、事务、异常
(2)https://www.cnblogs.com/chengxingliang/p/3333277.html
备忘一下。
koa-service ├─ babel.config.json - Babel配置项 ├─ package-lock.json ├─ package.json ├─ README.md └─ src - 源文件 ├─ app - koa实例 │ ├─ conf.js - koa相关配置项 │ └─ index.js - koa入口文件 ├─ auth - 权限验证 │ └─ index.js - 权限验证入口文件 ├─ controllers - 控制器 │ ├─ common - 公共控制器 │ ├─ index.js - 控制器入口文件 │ ├─ modules - 模块控制器 │ │ ├─ role.js - 角色控制器 │ │ └─ user.js - 用户控制器 │ └─ util.
sfspike 用于生成rsf道头、脉冲信号、层状速度模型
sfsmooth rect1=10 rect2=10 repeat=10 < input.rsf > output.rsf 速度场平滑
sfcat 数据拼接
sfwindow 数据剪裁
sfpad2 速度场边值镶边
sfdipfilter 斜干扰去除 未完待遇欢迎补充~~~
<template> <el-pagination @size-change="changeSize" @current-change="getData" :current-page="1" :current-page.sync="currentPage" :page-sizes="[10, 20, 40, 80]" :page-size="10" layout="total, sizes, prev, pager, next, jumper" :total="total"> </el-pagination> </template> data() { currentPage: 1 } methods:{ this.currentPage = 1; }
字节流和字符流的用法几乎完成全一样,区别在于字节流和字符流所操作的数据单元不同,字节流操作的单元是数据单元是8位的字节,字符流操作的是数据单元为16位的字符。
区别
字节流一般用来处理图像、视频、音频、PPT、Word等类型的文件。字符流一般用于处理纯文本类型的文件
字节流本身没有缓冲区,缓冲字节流相对于字节流,效率提升非常高,字符流本身就带有缓冲区
可以用转换流来进行转换;
举个例子
把a.txt文件中的字节先转换char型数组,再转换成字符流,因为char型可能会溢出的问题。但是会以空格的形式打印出来,所以用trim()方法来去除左右空格
/** * @Author: Adminstrator * @Date:2021 * @Description;转换流 * InputStreamReader用于将字节输入流转换为字符输入流, * OutputStreamWriter用于将字节输出流转换为字符输出流 * 使用转换流可以在一定程度上避免乱码,还可以指定输入输出所使用的字符集 */ public class TestTransfer { public static void main(String[] args) throws IOException { FileInputStream fis=new FileInputStream("a.txt"); InputStreamReader isr=new InputStreamReader(fis); char[] c=new char[fis.available()]; isr.read(c); FileOutputStream fos=new FileOutputStream("b.txt",true); OutputStreamWriter osw=new OutputStreamWriter(fos); osw.write(new String(c).trim()); osw.close(); isr.close(); fis.close(); } }
celery的简介 celery是一个基于分布式消息传输的异步任务队列,它专注于实时处理,同时也支持任务调度。它的执行单元为任务(task),利用多线程,如Eventlet,gevent等,它们能被并发地执行在单个或多个职程服务器(worker servers)上。任务能异步执行(后台运行)或同步执行(等待任务完成)。
在生产系统中,celery能够一天处理上百万的任务。它的完整架构图如下:
celery架构图
组件介绍:
Producer:调用了Celery提供的API、函数或者装饰器而产生任务并交给任务队列处理的都是任务生产者。Celery Beat:任务调度器,Beat进程会读取配置文件的内容,周期性地将配置中到期需要执行的任务发送给任务队列。Broker:消息代理,又称消息中间件,接受任务生产者发送过来的任务消息,存进队列再按序分发给任务消费方(通常是消息队列或者数据库)。Celery目前支持RabbitMQ、Redis、MongoDB、Beanstalk、SQLAlchemy、Zookeeper等作为消息代理,但适用于生产环境的只有RabbitMQ和Redis, 官方推荐 RabbitMQ。Celery Worker:执行任务的消费者,通常会在多台服务器运行多个消费者来提高执行效率。Result Backend:任务处理完后保存状态信息和结果,以供查询。Celery默认已支持Redis、RabbitMQ、MongoDB、Django ORM、SQLAlchemy等方式。 在客户端和消费者之间传输数据需要序列化和反序列化。 Celery 支出的序列化方案如下所示:
celery序列化
准备工作 在本文中,我们使用的celery的消息代理和后端存储数据库都使用redis,序列化和反序列化选择msgpack。
首先,我们需要安装redis数据库,具体的安装方法可参考:Redis 安装 | 菜鸟教程 。
我是装在ubuntu上的
启动redis,我们会看到如下界面:
目录
策略梯度基本知识
策略梯度公式
如何使损失函数更好?
添加基线
为每个动作分配不同的权重
策略梯度基本知识 强化学习主要分为两类:
基于价值的(如 Sarsa、Q-Learning 和 DQN 算法),先计算每个状态对应的动作的 Q 值,再选择 Q 值最大的动作执行。基于策略的:直接计算每个状态对应的动作或者动作的概率。 Policy Gradient 算法就是对策略函数进行建模,然后用梯度下降更新网络的参数。但是在强化学习中并没有实际的损失函数,而 PG 算法的目的是最大化累计奖励的期望值,因此将累计奖励的期望值作为损失函数,使用梯度上升算法来进行计算。
策略梯度公式 每一个动作 获得相应的奖励,则累积奖励为,我们希望累积奖励最大化,累积奖励是个变量,其期望是定值,因此我们希望累计奖励的期望最大化。
如何使损失函数更好? 添加基线 为每个动作分配不同的权重 技巧1中只要在同一个回合里面,同一场游戏里面,所有的状态跟动作的对都会使用同样的奖励项进行加权,这件事情显然是不公平的,因为在同一场游戏里面也许有些动作是好的,有些动作是不好的。给每一个不同的动作前面都乘上不同的权重。每一个动作的不同权重,它反映了每一个动作的好坏。
将权重从整场游戏的奖励的总和,改成从动作开始执行的时间 t 的奖励的总和
再增加一个衰减因子γ,意味着随着时间推移,组合越来越多,那么越后面的组合的影响就越来越小。
运算放大器和比较器无论外观或图纸符号都差不多,那么它们究竟有什么区别,在实际应用中如何区分?今天我们来图文全面分析一下,夯实大家的基础,让工程师更上一层楼。
先看下图,这是运算放大器和比较器的内部区别图:
从内部图可以看出运算放大器和比较器的差别在于输出电路。运算放大器采用双晶体管推挽输出,而比较器只用一只晶体管,集电极连到输出端,发射极接地。
比较器需要外接一个从正电源端到输出端的上拉电阻,该上拉电阻相当于晶体管的集电极电阻。
运算放大器可用于线性放大电路(负反馈),也可用于非线性信号电压比较(开环或正反馈)。电压比较器只能用于信号电压比较,不能用于线性放大电路(比较器没有频率补偿)。
两者都可以用于做信号电压比较,但比较器被设计为高速开关,它有比运算放大器更快的转换速率和更短的延时。
No.1
运算放大器 运算放大器在主板电路图中很常见,一般用于稳压电路;在负反馈电路中,它与晶体管配合相当于一个三端稳压器,但使用起来更灵活。
在许多情况下,需要知道两个信号中哪个比较大,或一个信号何时超出预设的电压(用作电压比较)。用运算放大器便可很容易搭建一个简单电路实现该功能。当V+电压大于V-电压时,输出高电平。当V+电压小于V-电压时,输出低电平。
分析一下电路,2.5V经电阻分压得到1V输入到V-端,当总线电压正常产生1.2V时,输入到V+,此时V+电压比V-电压高,输出一个高电平到CPU电源管理芯片的EN开启脚。
如果总线电压没输出或不正常少于1V,此时V+电压比V-电压低,输出低电平。
No.2
电压比较器 当比较器的同相端电压(V+)低于反相端电压(V-)时,输出晶体管导通,输出接地低电平;当同相端电压高于反相端时,输出晶体管截止,通过上拉电阻的电源输出高电平。
分析一下该电路,上面的比较器U8A当有VCC输出时经过分压电阻分压后,输入到同相端(V+),其电压大于5VSB经分压后输入到反相端(V-)的电压,内部晶体管截止,输出经上拉电阻的电源12V(同时下面的比较器U8B同相端电压也大于反相端,内部晶体管也是截止),N沟道场管Q37导通,输出VCC5V。
同时P沟道场管Q293截止。反之,当反相端电压大于同相端电压时,内部晶体管导通,上拉电源12V被拉低为低电平,N沟道场管Q37截止,同时P沟道场管Q293导通,输出5VSB。这个就是5VDUAL产生电路。
在实际应用中比较器都需要上拉电源,而运算放大器一般不需要。
1.浅谈传感器市场的发展趋势~
2.目前全球MCU的现状~
3.芯片缺货实情难判断,有MCU厂已进入对峙期~
4.【喂到嘴边了的模块】超级嵌入式系统“性能/时间”工具箱~
5.国产32位MCU未来要怎样发展?
6.做嵌入式软件开发提高代码编译速度的几种方法~
免责声明:本文系网络转载,版权归原作者所有。如涉及作品版权问题,请与我们联系,我们将根据您提供的版权证明材料确认版权并支付稿酬或者删除内容。
基本介绍
linux是一个多用户多任务的操作系统,任何一个使用系统资源的用户,都必须首先向系统管理员申请一个账号,然后以这个账号的身份进入系统
添加用户
基本语法
useradd 用户名应用案例
案例1:添加一个用户jack,默认该用户的家目录在 /home/jack [root@ShenLangBo ~]# useradd jack 细节说明
当用户创建成功后,会自动创建与用户同名的家目录
也可以使用 useradd -d 指定目录 新的用户名,给新创建的用户指定家目录 修改密码
基本语法
passwd 用户名应用案例
给jack指定密码 [root@ShenLangBo home]# passwd jack Changing password for user jack. New password: BAD PASSWORD: The password is shorter than 8 characters Retype new password: passwd: all authentication tokens updated successfully. 删除用户
基本语法
userdel 用户名应用案例
删除用户,但要保留家目录
userdel 用户名 (保留家目录)
删除用户以及家目录
userdel -r 用户名 (删除用户及家目录)
备注:
删除用户是非必须,勿删除用户的家目录 查询用户信息
1、引入依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> 2、配置
3、配置
修改了 Java 源代码以后。
1. 安装zookeeper (windows版) 下载zookeeper 网址 Index of /dist/zookeeper/zookeeper-3.4.13 解压后进入conf,将zoo_sample.cfg复制一份改名为zoo.cfg 注意配置中的参数: dataDir=D:\\Setup\\zookeeper\\data dataDirLog=D:\\Setup\\zookeeper\\log clientPort=2181 (zookeeper的端口号) 返回bin目录,启动zookeeper:运行zkServer.cmd,运行完毕运行zkCli.cmd 测试 2.安装dubbo-admin管理控制台(windows版) dubbo本身并不是一个服务软件。它其实就是一个jar包能够帮你的java程序连接到zookeeper,并利用zookeeper消费、提供服务。所以你不用在Linux上启动什么dubbo服务。 但是为了让用户更好的管理监控众多的dubbo服务,官方提供了一个可视化的监控程序,不过这个监控即使不装也不影响使用。 下载dubbo-admin https://github.com/apache/dubbo-admin/tree/master-0.2.0 整个工程下下来 修改 src\main\resources\application.properties 指定zookeeper地址 cmd打包dubbo-admin mvn clean package -Dmaven.test.skip=true (第一次打包时间可能有点长) target中找到dubbo-admin-0.0.1-SNAPSHOT,cmd进去命令行 输入java -jar dubbo-admin-0.0.1-SNAPSHOT.jar 访问: http://localhost:7001/ 看到如下界面 默认帐号密码都是root 3. 创建项目: 模拟需求:订单服务web模块在A服务器,用户服务模块在B服务器,A可以远程调用B的功能。 模块 功能 订单服务web模块 创建订单等 用户服务service模块 查询用户地址等 一、创建父工程Maven项目,springboot-dubbo 1.pom.xml <?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 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.test</groupId> <artifactId>spring-boot-dubbo</artifactId> <packaging>pom</packaging> <version>1.0-SNAPSHOT</version> <modules> <module>mall-api</module> </modules> </project> 二、右键新建module创建maven项目:mall-api 工程结构如下: 1.
先拔掉树莓派和pc之间的网线,在适配器选项中WiFi处取消网络共享给以太网,再重新共享网络给以太网(具体操作可参考下面WLAN修改共享给以太网)再连上网线,等待几分钟,看看在PC机上通过dos界面输入arp -a在192.168.137.1下面是否为静态ip(这个方法成功了,下面一堆操作只能让pc通过ssh连上树莓派,不能让树莓派上网即树莓派和PC不能共享网络)
在第一次通过网线将树莓派与PC相连,能够实现网络共享,但第二次使用则pc无法通过ssh连接树莓派,后面发现第一次能够成功时使用了静态ip,在第二次使用时,树莓派已经变成了动态ip,是造成这次失败的主要原因。下面将通过初次树莓派与PC相连和再次共享网络raspi无法ssh连接解决方案两方面描述。
树莓派与PC初次通过网线共享网络 ①树莓派版本:
Linux raspberrypi 5.10.63-v7l+ armv7l GNU/Linux (32位raspi buster版本)
②一根网线
③PC机
原理:我们个人的笔记本现在基本有两种方式联网,一种是插网线,第二种是通过wifi连接,我们可以通过wifi自己的笔记本连接网络,再通过网线和树莓派进行共享笔记本的wifi获得的网络。我们通过网线共享的网络,默认
使用192.168.137.0/255做为内网地址,192.168.137.1做为网关。
步骤:
首先我们要清楚,我们接下来的操作需要修改网络设置是WLAN和以太网。
①先将网线两端插入树莓派和PC
②WLAN修改
按win键->点击电源上面的设置->网络和Internet->WLAN->更改适配器选项->右击WLAN->属性->共享->勾选 允许其他网络用户通过此计算机的Internet连接来连接(N)->选择家庭网络连接为需要共享网络的以太网接口(插入网线就可以知道你是哪个以太网接口了)->下面那个 允许其他网络用户控制或禁用共享的Internet连接 也勾选->确定
③以太网修改
WLAN我们已经设置好,下面设置以太网
按win键->点击电源上面的设置->网络和Internet->以太网->更改适配器选项->右击以太网(插上网线有反应那个)->网络->双击 Internet协议版本4(TCP/IPv4)->使用下面的IP地址(IP地址:192.168.237.1;子网掩码:255.255.255.0)->其他如dns默认不用改就按确定。
通过win+R cmd命令进入DOS界面,输入
arp -a 在接口: 192.168.137.1 — 0x8 下面能看到树莓派的ip地址,最特殊的那个,当然现在是静态的(后面树莓派与PC连接,树莓派连不上网,发现这里变成了动态,网段也不再静态时的网段,就是这里出了问题)接下来就可以通过xshell或者SecureCRT或者vncvierer远程连接软件通过ssh连接树莓派。
通过ifconfig命令查看ip可以验证上面的步骤。
再次共享网络raspi无法ssh连接解决方案 win + R打开cmd
输入命令
arp -a 查看接口: 192.168.137.1 — 0x8 下面能看到树莓派的ip地址,发现IP地址变成动态了,导致无法通过ssh连接树莓派(已通过raspi-config打开interface option中的ssh和vnc)。下面我们通过修改树莓派IP地址来解决这个问题。
断电,拔出树莓派上的sd卡插入电脑
在boot盘符里找到cmdline.txt文件,修改cmdline.txt文件,打开文件在开头加入ip=192.168.137.37
这里要注意我们前面在以太网上设置了手动ip:192.168.137.1,所以这里也一定要192.168.137.开头,保持在同一个网段,且不要与其他ip冲突。
取出sd卡后插入树莓派,一定要保持网线相连再开启树莓派,否则无法开启。开启就能通过ssh连接树莓派了。
Nacos注册、配置中心整合Dubbo远程调用(文末含demo代码地址) 背景开发环境搭建父项目创建项目声明依赖 建立子模块创建order子模块 抽取公共的代码结构编写order模块中的Dubbo相关代码编写common模块中OrderService的实现类编写配置文件 启动Nacos进入Nacos管理界面创建配置文件将order模块注册到Naocs编写服务消费者模块调用order服务的接口编写配置文件 启动main模块,将其注册到Nacos中测试源码地址 背景 Nacos作为阿里巴巴技术栈中的一员,目前在应用得也是比较广泛。作为一个后起之秀,它相较于老一辈得Eureka注册中心也有很多优势。Dubbo同样也是阿里巴巴技术栈的成员,那么它和Nacos相结合无疑是非常不错的选择。最近看了很多帖子,要么是很老的,要么就是参考价值不大,索性,我自己写一个,Nacos和Dubbo整合使用的坑还是比较多。
开发环境 类别名称及版本开发工具IntelliJ IDEA 2021.2.3MAVENApache Maven 3.8.1JAVAJDK1.8.291SpringBoot2.4.2SpringCloudAlibaba2021.1MyBatis2.1.4Dubbo2.7.8Nacos2.0.3 请注意,以上版本(SpringBoot、SpringCloudAlibaba 、Dubbo)对应关系完全按照官方推荐来搭配的。版本差异或许会导致其他问题,但如果您有其他需求,请您查看官方文档以获取相关信息
版本参考地址
搭建父项目 通常来讲,我们会使用聚合的方式来统一项目中的依赖,直接在父项目中声明好依赖,并管理好版本,在子项目中我们就不再需要写版本号了,方便统一。
创建项目 我们的父项目事实上只有一个功能,那就是帮我们管理依赖版本,所以我们可以删除其不要的结构,让他看起来干净些。项目结构如下(项目名我只是随便写的一个):
声明依赖 创建好父项目之后,我们接下来把需要用到的各种依赖申明在父项目的POM的中dependencyManagement标签中,以方便我们管理其版本,使其版本统一。这里您需要注意以下packaging标签我们要声明为pom,因为我们这个只是作为父项目出现。如果您非常熟悉SpringBoot项目,那么您肯定知道spring-boot-maven-plugin插件,一般的SpringBoot项目导入spring-boot-maven-plugin插件的方式一般是这样的:
<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> 但是现在我们不能这么声明了,不然会报错,其他相关信息您可以参考官方文档。您应该以如下方式申明(版本我声明在properties中作为一个变量出现的,和SpringBoot的版本号一致):
<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <version>${spring-boot-dependencies.version}</version> <executions> <execution> <goals> <goal>repackage</goal> </goals> </execution> </executions> </plugin> </plugins> </build> 完整的POM文件代码如下:
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <packaging>pom</packaging> <groupId>com.fenzhichuanmei.sunflower</groupId> <artifactId>sunflower</artifactId> <version>1.0-SNAPSHOT</version> <properties> <maven.compiler.source>8</maven.compiler.source> <maven.compiler.target>8</maven.compiler.target> <mybatis.spring-boot.version>2.1.4</mybatis.spring-boot.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <spring-boot-dependencies.version>2.4.2</spring-boot-dependencies.version> <dubbo-spring-boot-starter.
目录
1、创建一个新的excel表格
2、 获取写入excel的数据data
3、将data类型转换为pandas接受的类型
4、写入到excel中
5、保存excel
最终结果
#!/usr/bin/env python # -*- coding: utf-8 -*- # @Time : 2021/11/9 23:18 # @Author : @linlianqin # @Site : # @File : writeDataIntoExcel.py # @Software: PyCharm # @description: import pandas as pd def writeDataIntoExcel(xlsPath: str, data: dict): writer = pd.ExcelWriter(xlsPath) sheetNames = data.keys() # 获取所有sheet的名称 # sheets是要写入的excel工作簿名称列表 data = pd.DataFrame(data) for sheetName in sheetNames: data.to_excel(writer, sheet_name=sheetName) # 保存writer中的数据至excel # 如果省略该语句,则数据不会写入到上边创建的excel文件中 writer.save() if __name__ == '__main__': data = {"
MapReduce工作原理及基础编程(代码见文章后半部分) JunLeon——go big or go home
目录 MapReduce工作原理及基础编程(代码见文章后半部分)
一、MapReduce概述
1、什么是MapReduce?
2、WordCount案例解析MapReduce计算过程
(1)运行hadoop自带的样例程序
(2)MapReduce工作过程
3、Shuffle过程详解
二、MapReduce编程基础
1、Hadoop数据类型
2、数据输入格式InputFormat
3、输入数据分块InputSplit和数据记录读入RecordReader
4、数据输出格式OutputFormat
5、数据记录输出类RecordWriter
6、Mapper类
7、Reduce类
三、MapReduce项目案例
1、经典案例——WordCount
2、计算考试平均成绩
3、网站日志分析
前言:
Google于2003年在SOSP上发表了《The Google File System》,于2004年在OSDI上发表了《MapReduce: Simplified Data Processing on Large Clusters》,于2006年在OSDI上发表了《Bigtable: A Distributed Storage System for Structured Data》。这三篇论文为大数据及云计算的发展奠定了基础。
一、MapReduce概述 1、什么是MapReduce? MapReduce是一个分布式、并行处理的计算框架。
MapReduce 把任务分为 Map 阶段和 Reduce 阶段。开发人员使用存储在HDFS 中数据(可实现快速存储),编写 Hadoop 的 MapReduce 任务。由于 MapReduce工作原理的特性, Hadoop 能以并行的方式访问数据,从而实现快速访问数据。
表1 map函数和rudece函数
函数输入输出说明map <k1,v1>
<0,helle world>
<12,hello hadoop>
1.设置span的line-height为div的高度 , 但是span中的文字会因为行高而在选中时的高亮高度变高
2.span外层的div(假设为divA)的外层再套一层div(divB), divA设置为margin-top: auto; margin-bottom: auto;
一般不建议去动span
行为级仿真:
是指仅对逻辑功能进行测试模拟,以了解其实现的功能是否满足原设计的要求,仿真过程没有加入时序信息,不涉及具体器件的硬件特性,如延时特性;也叫前仿真,综合前功能仿真
综合后仿真:
把综合生成的标准延时文件反标注到综合仿真模型中去,可估计门延时对电路带来的影响
布局布线后功能仿真:
针对特定的FPGA厂家技术的仿真,此级仿真是在综合后、实现前而进行的功能级仿真,功能级仿真一般验证综合后是否可以得到设计者所需要的正确功能;
布局布线后时序仿真:
将布局布线的延时信息反标注到设计网表中进行仿真。此时的仿真延时文件信息最全,包含门延时和布线延时,所以布线后仿真最准确,能较好地反映芯片的实际工作情况。
一般可以认为:
前仿真=功能仿真=行为级仿真=RTL级仿真,
后仿真=时序仿真=布局布线后仿真=门级仿真,
后仿真加入了传输延时和器件延时,接近实际芯片。
Java实现下载excel 依赖使用的是poi 实现目的请求HSSFWorkbook方法setResponseHeader方法fypclXls方法实现整个下载过程 依赖 使用的是poi 开发中经常会设计到excel的处理,如导出Excel,导入Excel到数据库中,操作Excel目前有两个框架,一个是apache 的poi, 另一个是 Java Excel
Apache POI 简介是用Java编写的免费开源的跨平台的 Java API,Apache POI提供API给Java程式对Microsoft Office(Excel、WORD、PowerPoint、Visio等)格式档案读和写的功能。POI为“Poor Obfuscation Implementation”的首字母缩写,意为“可怜的模糊实现”。
官方主页: http://poi.apache.org/index.html
API文档: http://poi.apache.org/apidocs/index.html
<!--Excel解析--> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>3.9</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>3.9</version> </dependency> </dependencies> 实现目的 最近公司的项目需要实现页面下载excel文件的功能
请求 在controller层创建一个请求方法
@RequestMapping(value = "/fypclXls",method = RequestMethod.GET) public void fypclXls(@RequestParam Map<String,Object> params,HttpServletRequest request,HttpServletResponse response){ //Query query = new Query(params); costDeviationService.fypclXls(params,request,response); } HSSFWorkbook方法 在业务层去创建一个方法
public HSSFWorkbook getHSSFWorkbook(String sheetName,String[] title,String[][] values,HSSFWorkbook workbook){ //sheetName 表名称 //title 表格第一行的表头名称 //values 存放的内容 //workbook 实现api的对象 if (workbook == null){ workbook = new HSSFWorkbook(); } HSSFSheet sheet = workbook.
思岚A1开箱测试 思岚A1开箱测试(实现雷达数据的查看+hector_slam建图)一、测试坏境二、测试功能三、具体实现过程注: 思岚A1开箱测试(实现雷达数据的查看+hector_slam建图) 一、测试坏境 ①、SLAMTEC A1激光雷达;
②、Ubuntu16.04 下 ROS Kinetic。
二、测试功能 ①、运行ROS包,查看雷达数据
②、使用hector_slam进行建图
三、具体实现过程 1、建立ROS工作空间
mkdir -p ~/dev/catkin_ws/src 进入src文件:
cd ~/dev/catkin_ws/src 初始化工作空间
catkin_init_workspace 在src文件中创建了一个 CMakeLists.txt 的文件,告诉系统ROS的工作空间。
2、下载ROS相关的功能包
在src目录下 下载SLAMTEC的激光雷达ROS包
git clone https://github.com/Slamtec/rplidar_ros.git 下载Hector_SLAM建图
git clone https://github.com/tu-darmstadt-ros-pkg/hector_slam.git 3、在工作空间中编译
cd ~/dev/catkin_ws/ catkin_make 添加环境变量source
source ~/dev/catkin_ws/devel/setup.bash (为了让source永久生效,应该写入.bashrc文件中)
echo"source~/dev/catkin_ws/devel/setup.bash" >> ~/.bashrc source ~/.bashrc 4、驱动安装
源码安装 rplidar-ros 雷达驱动
sudo apt-get install ros-kinetic-rplidar-ros 源码安装 hector_slam库
sudo apt-get install ros-kinetic-hector-slam 在rplidar_ros中新建slam.launch文件**(非常重要,不然会报错)**
在rplidar_ros/launch/目录下添加slam.launch文件:
slam.launch文件中复制如下内容
<launch> <node pkg="hector_mapping" type="
目录 一、Matlab快速绘制栅格地图1、几种常用的地图形式:1.1、尺度地图:1.2、拓扑地图:1.3、语义地图: 2、栅格地图用于路径规划的优势:3、matlab绘制栅格地图的核心函数及思想:3.1、colormap函数:3.2、sub2ind函数:3.3、ind2sub函数:3.4、为了在栅格地图呈现随机障碍物的效果,可以设置障碍物出现频率数值,根据该数据在所有栅格中生成随机数,从而确定障碍物栅格。3.5、image函数: 4、具体例子:4.1、利用Matlab快速绘制栅格地图matlab代码:4.2、运行结构:4.3、具体分析 一、Matlab快速绘制栅格地图 声明:本文是学习古月居~基于栅格地图的机器人路径规划算法指南 • 黎万洪 后写的笔记,好记性不如烂笔头!方便自己日后的巩固与复习,这个教程讲的很高,值得推荐!
1、几种常用的地图形式: 1.1、尺度地图: 具有真实的物理尺度,如:栅格地图、特征地图、点云地图,常用于地图构建、定位、SLAM、小规模路径规划。
1.2、拓扑地图: 不具备真实的物理尺度,只表示不同地点的连接关系和距离,如铁路网。
1.3、语义地图: 加标签的尺度地图,常用于人机交互。
2、栅格地图用于路径规划的优势: ①、可以将任意形状轮廓的地图,用足够精细的栅格进行绘制;
②、每一个栅格,可以通过不同颜色表示不同含义,如黑色代表障碍物、黄色代表起点、红色代表终点;
③、基于栅格地图进行路径规划有横、纵、斜三个规划方向。对应室内低速机器人可以完全按照路径行走;对于中高速机器人,可以考虑将路径进行平滑处理,以适用于非完全约束系统。
3、matlab绘制栅格地图的核心函数及思想: 3.1、colormap函数: 为栅格地图创建自定义颜色。如黄色栅格代表起点、红色为终点。
3.2、sub2ind函数: 将行列索引转为线性索引。对于右图栅格地图,10行1列,行从左上角自上而下排序,列从左上角自左向右排序。
3.3、ind2sub函数: 与sub2ind相反,是将线性索引转为行列索引。
3.4、为了在栅格地图呈现随机障碍物的效果,可以设置障碍物出现频率数值,根据该数据在所有栅格中生成随机数,从而确定障碍物栅格。 3.5、image函数: 利用colormap建立的颜色图,将数组信息显示为图像。
4、具体例子: 4.1、利用Matlab快速绘制栅格地图matlab代码: clc clear close all %% 构建颜色MAP图 cmap = [1 1 1; ... % 1-白色-空地 0 0 0; ... % 2-黑色-静态障碍 1 0 0; ... % 3-红色-动态障碍 1 1 0;... % 4-黄色-起始点 1 0 1;... % 5-品红-目标点 0 1 0; .
文章来源:企鹅号 - 程序猿GG
问题:
在开发springboot过程中一个很严重的资源问题就是内存占用过高,而实际上本机开发测试并没有很大的请求量,所以这是对电脑资源的一种严重的浪费,甚至导致IDE卡死、崩溃。
有时候非常简单的一个项目,只要启动就轻松占用1g内存,今天优化了下,成功把内存降到200m左右,其实主要开始默认配置有点大,这样优化不管是本地还是服务器又可以畅快运行了。
干货:
启动命令示例,这样启动150m左右差不多够了:
nohup java -jar -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=56m -Xms128m -Xmx128m -Xmn32m -Xss256k -XX:SurvivorRatio=8 -XX:+UseConcMarkSweepGC short-url.jar --spring.profiles.active=prod >/dev/null 2>&1&
参数意义:
-XX:MetaspaceSize=128m:元空间默认大小
-XX:MaxMetaspaceSize=128m:元空间最大大小
-Xms1024m:堆最大大小
-Xmx1024m:堆默认大小
-Xmn256m:新生代大小
-Xss256k:栈最大深度大小
-XX:SurvivorRatio=8:新生代分区比例 8:2
-XX:+UseConcMarkSweepGC:指定使用的垃圾收集器,这里使用CMS收集器
-XX:+PrintGCDetails:打印详细的GC日志
如果设置的内存大小太小,可以适当的根据实际情况更改配置。
发表于: 2019-12-28原文链接:https://kuaibao.qq.com/s/20191228A0LSHS00?refer=cp_1026腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。如有侵权,请联系 yunjia_community@tencent.com 删除。
echarts 节点拖拽 官方文档:Handbook - Apache ECharts
****************** 示例
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="/echarts/echarts.min.js"></script> <script src="/jquery/jquery-3.6.0.min.js"></script> <script type="text/javascript"> $(function (){ const myChart = echarts.init($("#container")[0]); const symbolSize = 20; const data = [ [40, -10], [-30, -5], [-76.5, 20], [-63.5, 40], [-22.1, 50] ]; myChart.setOption({ title: { text: '节点拖拽', left: 'center', textStyle: { color: '#826' } }, tooltip: { triggerOn: 'none', formatter: function (params) { return ( 'X: ' + params.
先来简单看一下要求
一,我们可以先编写Player类,先把属性定义好,然后进行封装
public class Player { private String name; //定义姓名 private int lvlNo=1; //定义级别编号为1 private long startTime=System.currentTimeMillis(); //定义开始时间 private long usedTime; //定义已用时间 private int totalScores=0; //定义初始积分为0 public void play(Game g){//传参进来,传入当前对象 g.run(this);//注释1:this是本类对象 } public Player(String name) { this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getLvlNo() { return lvlNo; } public void setLvlNo(int lvlNo) { this.lvlNo = lvlNo; } public long getStartTime() { return startTime; } public void setStartTime(long startTime) { this.
发现问题
看发那科机械臂操作手册,其中有一段关于机器人直角坐标值的叙述引起了我的注意,我看了这段话之后顿时联想到之前在ZS做项目时候遇见的奇异点问题,我坚信这两者之间必然有联系!
手册相关内容截图如下:
我之前在ZS做项目时候,在点动机器人时候,仅仅考虑了xyzwpr值,没有考虑到原来发那科机器人中的直角坐标还有其它元素(工具坐标系,用户坐标系,形态),经过两天的探索,终于搞明白了什么是机器人形态,及其类别!
机器人形态
在我的认知里,一个直角坐标值xyzwpr,可能会对应多个关节值,所以在指定xyzwpr后需要为机器人指定形态才可以唯一确定机器人的状态。在发那科机器人中,用关节配置和回转数来完全机器人状态。
关节配置
如下图所示:
(1)FLIP代表手腕上翻(j5>0);NOFLIP代表手腕下翻(j5<0)。而且当j5在0附近时候(大约上下3度),会提示在奇异点附近。六轴机器人最常见的奇异点就是就是这种类型,也叫腕部奇异点。对于不同的工作场景,制作不同的工具头,防止j5等于0,不失为一种避免腕部奇异点的方法。
(2)UP代表肘关节(j3所在位置)凸起;DOWN代表肘关节凹陷。
也可以说,当两个主臂夹角小于180,那么是UP;否是是DOWN。
(3)FRONT代表腕部在j1轴的一侧(有j2轴的一侧),BACK代表腕部在j1的另一侧(无j2轴的一侧)
不同情景:
F与N很好区分,下面着重展示一下不同U,D和T,B的组合:
————————————————
版权声明:本文为CSDN博主「悟道机器人」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/liu2015302026/article/details/113137416
核心思想 是:针对每个操作,都要注册一个与其对应的确认和补偿(撤销)操作。分为三个阶段:
Try 阶段:主要是对业务系统做检测(一致性)及资源预留(准隔离性)Confirm 阶段:主要是对业务系统做确认提交,Try阶段执行成功并开始执行 Confirm阶段时,默认Confirm阶段是不会出错的。即:只要Try成功,Confirm一定成功。(Confirm 操作满足幂等性。要求具备幂等设计,Confirm 失败后需要进行重试。
)Cancel 阶段主要是在业务执行错误,需要回滚的状态下执行的业务取消,预留资源释放。(Cancel 操作满足幂等性) 解决了协调者单点,由主业务方发起并完成这个业务活动。业务活动管理器也变成多点,引入集群。
同步阻塞: 引入超时,超时后进行补偿,并且不会锁定整个资源,将资源转换为业务逻辑形式,粒度变小。
数据一致性,有了补偿机制之后,由业务活动管理器控制一致性。
缺点:在Confirm,Cancel中都有可能失败。TCC属于应用层的一种补偿方式,所以需要程序员在实现的时候多写很多补偿的代码,在一些场景中,一些业务流程可能用TCC不太好定义及处理。
以下转自:拜托,面试请不要再问我TCC分布式事务的实现原理!【石杉的架构笔记】
一、写在前面 这篇文章,就用大白话+手工绘图,并结合一个电商系统的案例实践,来给大家讲清楚到底什么是TCC分布式事务。
首先说一下,这里可能会牵扯到一些Spring Cloud的原理,如果有不太清楚的同学,可以参考之前的文章:《拜托,面试请不要再问我Spring Cloud底层原理!》。
二、业务场景介绍 咱们先来看看业务场景,假设你现在有一个电商系统,里面有一个支付订单的场景。
那对一个订单支付之后,我们需要做下面的步骤:
更改订单的状态为“已支付”扣减商品库存给会员增加积分创建销售出库单通知仓库发货
三、进一步思考 实现一个TCC分布式事务的效果。
订单服务-修改订单状态,库存服务-扣减库存,积分服务-增加积分,仓储服务-创建销售出库单。 上述这几个步骤,要么一起成功,要么一起失败,必须是一个整体性的事务。
举个例子,现在订单的状态都修改为“已支付”了,结果库存服务扣减库存失败。那个商品的库存原来是100件,现在卖掉了2件,本来应该是98件了。
结果呢?由于库存服务操作数据库异常,导致库存数量还是100。这不是在坑人么,当然不能允许这种情况发生了!
但是如果你不用TCC分布式事务方案的话,就用个Spring Cloud开发这么一个微服务系统,很有可能会干出这种事儿来。
我们来看看下面的这个图,直观的表达了上述的过程。
所以说,我们 有必要使用TCC分布式事务机制来保证各个服务形成一个整体性的事务。
上面那几个步骤,要么全部成功,如果任何一个服务的操作失败了,就全部一起回滚,撤销已经完成的操作。
比如说库存服务要是扣减库存失败了,那么订单服务就得撤销那个修改订单状态的操作,然后得停止执行增加积分和通知出库两个操作。
四、落地实现TCC分布式事务 如何来实现一个TCC分布式事务,使得各个服务,要么一起成功?要么一起失败呢?
我们这就来一步一步的分析一下。以一个Spring Cloud开发系统作为背景来解释。
1、TCC实现阶段一:Try 首先,订单服务那儿,他的代码大致来说应该是这样子的:
其实就是订单服务完成本地数据库操作之后,通过Spring Cloud的Feign来调用其他的各个服务罢了。但是光是凭借这段代码,是不足以实现TCC分布式事务的啊?!
首先,上面那个订单服务先把自己的状态修改为:OrderStatus.UPDATING。
在pay()方法里,把订单状态(已支付)修改为UPDATING(修改中)。仅代表有人正在修改这个状态。
库存服务直接提供的那个reduceStock()接口里,也别直接扣减库存啊,你可以是冻结掉库存。
举个例子,本来你的库存数量是100,你别直接100 - 2 = 98,扣减这个库存!
你可以把可销售的库存:100 - 2 = 98,设置为98没问题,然后在一个单独的冻结库存的字段里,设置一个2。也就是说,有2个库存是给冻结了。
积分服务的addCredit()接口也是同理,别直接给用户增加会员积分。你可以先在积分表里的一个预增加积分字段加入积分。
比如:用户积分原本是1190,现在要增加10个积分,别直接1190 + 10 = 1200个积分啊!
你可以保持积分为1190不变,在一个预增加字段里,比如说prepare_add_credit字段,设置一个10,表示有10个积分准备增加。
仓储服务的saleDelivery()接口也是同理啊,你可以先创建一个销售出库单,但是这个销售出库单的状态是“UNKNOWN”。
也就是说,刚刚创建这个销售出库单,此时还不确定他的状态是什么呢!
一、Class类与Java反射 Class textFieldC=tetxField.getClass(); //tetxField为JTextField类对象
反射可访问的主要描述 1、访问构造方法
每个Constructor对象代表一个构造方法,利用Constructor对象可以操纵相应的构造方法。
getConstructors() //获取公有getConstructor(Class<?>... parameterTypes) //获取指定公有 getDeclaredConstructors() //获取所有 getDeclaredConstructor(Class<?>... parameterTypes) //获取指定方法 创建Demo1类,声明String类型成员变量和3个int类型成员变量,并提供3个构造方法。
package bao; public class Demo1{ String s; int i,i2,i3; private Demo1() { } protected Demo1(String s,int i) { this.s=s; this.i=i; } public Demo1(String... strings)throws NumberFormatException{ if(0<strings.length) { i=Integer.valueOf(strings[0]); } if(1<strings.length) { i2=Integer.valueOf(strings[0]); } if(2<strings.length) { i3=Integer.valueOf(strings[0]); } } public void print() { System.out.println("s="+s); System.out.println("i="+i); System.out.println("i2="+i2); System.out.println("i3="+i3); } } 编写Main类,在该类对Demo1进行反射访问的所有构造方法,并将该构造方法是否允许带有可变数量的参数、入口参数和可能抛出的异常类型信息输出。
package bao; import java.
目录 一、通过中断控制LED灯亮灭(1)创建项目(2)进入keil,重写回调函数 二、DMA发送用特定速率向上位机连续发送数据三、总结四、参考资料 一、通过中断控制LED灯亮灭 (1)创建项目 1.进入cubeMX,新建项目
2.选择芯片,并开始项目
3.点击sys,将debug选项改为Serial Wire
4.然后在Rcc里的HSE选择Crystal/Ceramic Resonator
5.将PB0选为外部中断触发器,PA1是控制led灯的,和将它选择为GPIO_output就行了
6.选择PLLCLK,然后将后面的晶振频率最大值改为72M赫兹
7.project里把toolchain那里改为MDK-ARM,版本选择最新的就行了,项目名和项目路径自己选择
8.选择生成初始化文件,然后选择生成代码就好了
这样项目就创建完成了!!
(2)进入keil,重写回调函数 1.函数代码
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin){ GPIO_PinState b0_pin = HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_0); // 读取b0的状态 b0_pin=1-b0_pin; switch (GPIO_Pin){//判断引脚 case GPIO_PIN_0: HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1,1-b0_pin); // 将a1写入与b0相同的电位 break; } } 2.进入main.c,将函数写入3.烧入
4.结果
二、DMA发送用特定速率向上位机连续发送数据 1.打开cubeMX,新建项目
2.选择芯片,并开始项目
3.把芯片的PA9、PA10分别点成USART1_TX和USART1_RX,选择左边USART1,点开后点击下方add,添加两个USART后选择对的RX和TX。
4.然后再project manger界面填写项目名,选着路径,最后把IDE换为MDK-ARM
5.code generator里的这一项也需要勾上,勾上后create code,再打开keil:6.打开keil,在main.c中加入下面代码
while (1) { uint8_t send_char[]="hello world\n";//发送的字符串 HAL_UART_Transmit_DMA(&huart1,(uint8_t *)send_char,0xc);//DMA发送 HAL_Delay(500);//延时 } 7.结果
三、总结 中断的核心是NVIC,其中重点是嵌套,有了嵌套就有了优先级,DMA传输将数据从一个地址空间复制到另一个地址空间,提供在外设和存储器之间或者存储器和存储器之间的高速数据传输。转移数据(尤其是转移大量数据)是可以不需要CPU参与。
四、参考资料 stm32hal库串口DMA收发
【STM32】HAL库 STM32CubeMX教程十一—DMA (串口DMA发送接收)
作者:sinxu,腾讯 CSIG 后台开发工程师
1. 什么是数据的一致性 “数据一致”一般指的是:缓存中有数据,缓存的数据值 = 数据库中的值。
但根据缓存中是有数据为依据,则”一致“可以包含两种情况:
缓存中有数据,缓存的数据值 = 数据库中的值(需均为最新值,本文将“旧值的一致”归类为“不一致状态”)
缓存中本没有数据,数据库中的值 = 最新值(有请求查询数据库时,会将数据写入缓存,则变为上面的“一致”状态)
”数据不一致“:缓存的数据值 ≠ 数据库中的值;缓存或者数据库中存在旧值,导致其他线程读到旧数据
2. 数据不一致情况及应对策略 根据是否接收写请求,可以把缓存分成读写缓存和只读缓存。
只读缓存:只在缓存进行数据查找,即使用 “更新数据库+删除缓存” 策略;
读写缓存:需要在缓存中对数据进行增删改查,即使用 “更新数据库+更新缓存”策略。
2.1 针对只读缓存(更新数据库+删除缓存) 只读缓存:新增数据时,直接写入数据库;更新(修改/删除)数据时,先删除缓存。后续,访问这些增删改的数据时,会发生缓存缺失,进而查询数据库,更新缓存。
新增数据时 ,写入数据库;访问数据时,缓存缺失,查数据库,更新缓存(始终是处于”数据一致“的状态,不会发生数据不一致性问题)
更新(修改/删除)数据时 ,会有个时序问题:更新数据库与删除缓存的顺序(这个过程会发生数据不一致性问题)
在更新数据的过程中,可能会有如下问题:
无并发请求下,其中一个操作失败的情况
并发请求下,其他线程可能会读到旧值
因此,要想达到数据一致性,需要保证两点:
无并发请求下,保证 A 和 B 步骤都能成功执行
并发请求下,在 A 和 B 步骤的间隔中,避免或消除其他线程的影响
接下来,我们针对有/无并发场景,进行分析并使用不同的策略。
A. 无并发情况 无并发请求下,在更新数据库和删除缓存值的过程中,因为操作被拆分成两步,那么就很有可能存在“步骤 1 成功,步骤 2 失败” 的情况发生(由于单线程中步骤 1 和步骤 2 是串行执行的,不太可能会发生 “步骤 2 成功,步骤 1 失败” 的情况)。
(1) 先删除缓存,再更新数据库
(2) 先更新数据库,再删除缓存
配置 import { defineConfig } from 'vite'; import vue from '@vitejs/plugin-vue'; export default defineConfig({ plugins: [vue()], // 配置需要使用的插件列表 // 本地运行配置,及反向代理配置 server: { host: 'localhost', // 指定服务器主机名 port: 8080, // 指定服务器端口 open: true, // 在服务器启动时自动在浏览器中打开应用程序 https: false, // 是否开启 https }, }); 大坑:当我们这么配置好后,启动项目,发现项目启动不了,报错:
这个错误很容易忽略,是因为没有下载插件的原因:npm install @vitejs/plugin-vue -D一定要下载这个插件和配置对应的插件信息plugin:[vue()]
项目搭建 npm init vite-app xxxx yarn create vite-app xxxx cd xxxx cd xxxx npm install yarn npm run dev yarn dev 安装路由 // npm/yarn npm install vue-router@next yarn add vue-router@next // 创建文件 src/route/index.js import {createRouter, createWebHistory} from 'vue-router' export const router = createRouter({ history: createWebHistory(), routes:[] }) // 挂载vue上 /main.js import {createApp} from 'vue' import {router} from './router/index.js' import app from './App.vue'; createApp(app).use(router).mount('#app') // 在项目中使用 import {useRoute,useRouter} from 'vue-router' setup(){ const router = useRouter() const route = useRoute() router.
文章目录 前言一、什么是 WSL二、WSL 的安装1.启用 WSL2.Windows 功能设置3.检查电脑版本号4.安装 Linux 发行版 三、WSL 的运行1.cmd 运行2.Windows PowerShell 运行3.WSL 运行 四、Ubuntu中的文件在Windows下的存放位置总结 前言 本文的主要内容是WSL的安装与运行。
一、什么是 WSL WSL是 Windows下的Linux子系统的简称,它是一个在Windows 10上能够运行原生Linux二进制可执行文件的兼容层。
WSL提供了一个微软开发的Linux兼容但不包含Linux代码的内核接口,二进制文件可以在其上运行。WSL不能运行图形用户界面和那些需要未实现的Linux内核服务的软件,但可以用外部软件来实现。
二、WSL 的安装 1.启用 WSL 无论接下来要安装哪个版本的 WSL,都要先启用它。以管理员身份运行 Windows PowerShell ,然后输入如下命令启用WSL。
dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
输入命令后回车,等待功能启用完成即可。
2.Windows 功能设置 在控制面板——>程序中依次按下图序号打开,勾选“适用于Linux的Windows子系统”。
3.检查电脑版本号 在设置——>系统——>关于中查看自己电脑的版本号。
4.安装 Linux 发行版 在Microsoft Store中(如果你的电脑中没有安装微软商城,点此下载微软商城下载)搜索Ubuntu,选择自己想要安装的版本安装即可。我这里安装的是Ubuntu 20.04 LTS(LTS是Long Term Support的简称,即长期支持)。
在安装界面下面有Windows的系统要求,在上一步中查看了自己的电脑版本号,如果低于这里的版本,就要先更新自己的电脑系统,然后再安装。
Ubuntu 20.04 LTS 安装完成后启动它,等待其安装一些配置,完成后便可以键入新的用户名和密码,如下图。
同时也将根目录密码一并设置了,方便以后操作。
三、WSL 的运行 1.cmd 运行 以管理员身份运行cmd,然后输入“bash”即可进入到Ubuntu系统下。
2.Windows PowerShell 运行 以管理员身份运行Windows PowerShell,然后输入“bash”即可进入到Ubuntu系统下。
引言 假设你已经了解了Vue3的setup函数,不了解的话可以先看看这篇文章。 拥抱Vue3 (二) setup函数_flow_camphor的博客-CSDN博客
在setup函数中我们知道它有两个参数,用于接收父组件传递参数的props、与负责表示上下文对象的context,在context中常用的是分发自定义事件的函数emit,用于组件抽象化后的通信。在了解了概念后我们可以在本文中动手抽象分离一个组件。
场景 现在假设需要抽象出一个移动端的顶部Header组件,首先想想一个顶部组件平时有哪些功能:名称、返回、返回主页、更多功能。如果某个页面不需要使用返回主页这个功能,使用时不进行参数传递即可。设置好props后在setup中打印props可以看到成功绑定的传参。
export default { props: { name: { type: String, default: '' }, back: { type: String, default: '' }, home: { type: Boolean, default: false }, more: { type: Boolean, default: false } } } 在处理完props传参后我们可以考虑context部分,比如说点击回退标签后触发某个事件,那么就会在身为调用者的父组件中绑定某个回调函数,在子组件emit后执行该函数。因此在和props同级的情况下声明将要emit的函数名称。这里贴出template部分与script部分的代码。
<template> <header class="simple-header van-hairline--bottom"> <i v-if="!home" class="nbicon nbfanhui" @click="goBack"></i> <i v-else class="nbicon nbhome"></i> <div class="simple-header-name">{{ name }}</div> <i v-if="more" class="nbicon nbmore"></i> </header> </template> <script> import { ref } from 'vue' import { useRouter } from 'vue-router' export default { props: { name: { type: String, default: '' }, back: { type: String, default: '' }, home: { type: Boolean, default: false }, more: { type: Boolean, default: false } }, emits: ['callback'], setup(props, context) { const home = ref(props.
一、题目内容 二、代码 public String minWindow(String s, String t) { HashMap<Character,Integer> hs=new HashMap<Character,Integer>(); HashMap<Character,Integer>ht =new HashMap<Character,Integer>(); for(int i=0;i<t.length();i++) { ht.put(t.charAt(i),ht.getOrDefault(t.charAt(i),0)+1); } String rnt=""; int cnt=0; int len=1000000; for(int i=0,j=0;i<s.length();i++){ hs.put(s.charAt(i),hs.getOrDefault(s.charAt(i),0)+1); if(ht.containsKey(s.charAt(i))&&hs.get(s.charAt(i))<=ht.get(s.charAt(i))) cnt++; while(j<i&&(!ht.containsKey(s.charAt(j))||hs.get(s.charAt(j))>ht.get(s.charAt(j)))){ int count=hs.get(s.charAt(j))-1; hs.put(s.charAt(j),count); j++; } if(cnt==t.length()&&i-j+1<len){ len=i-j+1; rnt=s.substring(j,i+1); } } return rnt; }
1.新建项目
2.项目结构
3.配置运行浏览器
4.运行到浏览器
5.运行效果
本文利用Java.net编写的网络客户端实现从服务器端下载文件的功能,本功能实现分三步:
1、创建本地待接收的远程文件。
2、创建本地至服务器端的远程连接。
3、将服务器端文件写入输入流,从输入流中将内容写入本地文件,完成文件下载。
代码如下: public static int downloadFile(String remoteURL,String fileDirectory,String fileName) { Path p=Paths.get(fileDirectory); File f_p=p.toFile(); try{ if(!f_p.exists()) { f_p.mkdir(); } File f=new File(p.toAbsolutePath().toString()+"\\"+fileName); if(!f.exists()) { f.createNewFile(); } FileOutputStream fos=new FileOutputStream(f); byte[] pb=new byte[1024]; URL url=new URL(remoteURL); URLConnection urlc=url.openConnection(); InputStream inputstream=urlc.getInputStream(); int length=-1; while(true) { length=inputstream.read(pb); if(length<0) { fos.flush(); break; } else { fos.write(pb,0,length); } } inputstream.close(); fos.close(); return 0; } catch(Exception e) { e.printStackTrace(); return -1; } 一、创建本地文件:
原文链接https://github.com/tporadowski/redis/issues/88
[16016] 26 Oct 14:30:01.264 # Redis successfully installed as a service.
[11692] 26 Oct 14:30:01.876 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
[11692] 26 Oct 14:30:01.876 # Redis version=5.0.9, bits=64, commit=9414ab9b, modified=0, pid=11692, just started
[11692] 26 Oct 14:30:01.876 # Configuration loaded
[11692] 26 Oct 14:30:01.889 # Could not create server TCP listening socket *:16379: listen: 提供了一个无效的参数。
解决方法:
修改redis.windows.conf,把bind 127.0.0.1的注释去掉
ES集群添加IK分词器 ES : 7.5.0
官方文档其实已经够优秀了,毕竟是中文的,这里只给出一些建议。
IKAnalyzer.cfg.xml 建议放到插件的目录下,要不然有可能会有一些问题
{plugins}/elasticsearch-analysis-ik-*/config/IKAnalyzer.cfg.xml 提供的http接口要支持head请求
<!--用户可以在这里配置远程扩展字典 --> <entry key="remote_ext_dict">location</entry> <!--用户可以在这里配置远程扩展停止词字典--> <entry key="remote_ext_stopwords">http://xxx.com/xxx.dic</entry> 这里的http://xxx.com/xxx.dic 请求方式是head请求,如果你像我们一样是通过一个http服务提供的接口,记得要支持head请求才行哦,最好是配置为支持各种post,get,head等
Windows10安装anaconda
1.官网下载安装包
官网下载Anaconda最新安装包:anaconda官网地址
2.下载完成后,找到下载文件双击该文件运行安装程序。依次点击next,I agree,选择All users,选择安装路径,下一步两个都勾选,点击安装。
3.一直点击下一步,最后一个取消勾选,完成。
4.安装结束后,打开电脑的CMD命令行(使用WIN徽标键+R, 然后输入CMD,点击OK),在其中输入 python,如果返回版本信息正确,则安装顺利完成。
如果出现上面警告,则需要激活conda版本中的python。
或者
conda activate base 再输入python查看。