文章目录 环境安装openOCD安装依赖克隆源码编译安装一键烧写脚本 安装minicom查找设备文件 环境 Ubuntu18.04
安装openOCD 参考:https://www.rt-thread.org/qa/thread-421278-1-1.html
安装依赖 sudo apt-get install build-essential pkg-config autoconf automake libtool libusb-dev libusb-1.0-0-dev libhidapi-dev sudo apt-get install libtool libsysfs-dev 克隆源码 git clone https://github.com/ntfreak/openocd.git 编译安装 sudo ./bootstrap sudo ./configure --enable-jlink --enable-cmsis-dap --enable-stlink sudo make sudo make install 一键烧写脚本 将以下代码保存为脚本,并将hex文件放在本脚本的目录下
sudo openocd -f /usr/local/share/openocd/scripts/interface/cmsis-dap.cfg -f /usr/local/share/openocd/scripts/target/stm32f4x.cfg -c "init" -c "reset init" -c "program ./NB_IOT.hex verify reset exit" 运行烧写脚本
chmod +x daplink.sh ./daplink.sh 安装minicom 参考:https://blog.csdn.net/u010164190/article/details/106788655
sudo apt-get install minicom sudo chmod 777 /dev/ttyUSB0 sudo minicom -s 找到:Serial port setup选项, 配置/dev/ttyUSB0设备.
Contest:
链接:https://ac.nowcoder.com/acm/problem/13947
来源:牛客网
n支队伍一共参加了三场比赛。
一支队伍x认为自己比另一支队伍y强当且仅当x在至少一场比赛中比y的排名高。
求有多少组(x,y),使得x自己觉得比y强,y自己也觉得比x强。
(x, y), (y, x)算一组。
输入描述:
第一行一个整数n,表示队伍数; 接下来n行,每行三个整数a[i], b[i], c[i],分别表示i在第一场、第二场和第三场比赛中的名次;n 最大不超过200000
输出描述:
输出一个整数表示满足条件的(x,y)数;64bit请用lld
题解:
题目应该是有个没有显式声明的条件:一场比赛种不存在两支队伍排名相同。
如果加上这个条件,也能做,处理一下这种情况即可。
第一点:考虑符合要求的队伍 和 三场比赛的排名。
显然只有两种情况: 出现两次, 出现一次;或者 出现两次, 出现一次;
那么我们从中任取两场比赛,对满足 和 各出现一次的做统计,结果数即为 。那么最终答案就是 。
因为同一对满足条件的 ,两种情况都是重复统计一次。
第二点:考虑两场比赛,如何统计 和 各出现一次。
记第一场比赛排名为 ,第二场比赛排名为 。
我们先按 排序。
那么即求 。即 数组的逆序对数。
常见求逆序对的方法有归并排序,或树状数组。
代码实现用树状数组。
树状数组维护区间。
区间中每个点 ,对应值为 的个数。
对于 ,区间 之和,即为 的值的个数。
顺序遍历 ,区间 之和计入答案,再更新树状数组,将 对应的值加一。
#include<bits/stdc++.h> typedef long long LL; using namespace std; const int maxn=2e5+10; const LL mod=1e9+7; const double pi=acos(-1.
说明: hosts文件位于C:\Windows\System32\drivers\etc
1、搜索power shell,以管理员权限运行
2、输入notepad命令打开空白txt文件
3、右击文件->选择打开->找到hosts文件所在路径->修改所有文件类型->打开hosts文件
4、添加IP及域名,点击保存即可修改成功。
根据网络资料整理,并进行了优化和测试,编写了python的thread线程装饰器,用于装饰函数
个人认为是完美版:装饰器使用方便,可以分别获取结果,也可以获取全部结果集合
如下:
from threading import Thread, currentThread import time class thread_wrap_class: ''' 函数的线程装饰器,返回thread线程实例,getResult获取结果, thread_wrap_class.getAllResult 获取结果集合 ''' Result_dict = {} thread_dict = {} class MyThread(Thread): def __init__(self, func, name='', *args, **kwargs): Thread.__init__(self) self.func = func self.name = name self.args = args self.kwargs = kwargs def run(self): print(f"{self} start with thread_wrap_class...") self.res = self.func(*self.args, **self.kwargs) thread_wrap_class.Result_dict[self.ident] = self.res def getResult(self): self.join() return self.res def __init__(self, func): self.func = func def __call__(self, *args, **kwargs): _mythr = self.
1、基于词典的方法(字符串匹配,机械分词方法)
定义:按照一定策略将待分析的汉字串与一个“大机器词典”中的词条进行匹配,若在词典中找到某个字符串,则匹配成功。
按照扫描方向的不同:正向匹配和逆向匹配
按照长度的不同:最大匹配和最小匹配
1.1正向最大匹配思想MM
1》从左向右取待切分汉语句的m个字符作为匹配字段,m为大机器词典中最长词条个数。
2》查找大机器词典并进行匹配。若匹配成功,则将这个匹配字段作为一个词切分出来。
若匹配不成功,则将这个匹配字段的最后一个字去掉,剩下的字符串作为新的匹配字段,进行再次匹配,重复以上过程,直到切分出所有词为止。
1.2逆向最大匹配算法RMM
该算法是正向最大匹配的逆向思维,匹配不成功,将匹配字段的最前一个字去掉,实验表明,逆向最大匹配算法要优于正向最大匹配算法。
1.3 双向最大匹配法(Bi-directction Matching method,BM)
双向最大匹配法是将正向最大匹配法得到的分词结果和逆向最大匹配法的到的结果进行比较,从而决定正确的分词方法。据SunM.S. 和 Benjamin K.T.(1995)的研究表明,中文中90.0%左右的句子,正向最大匹配法和逆向最大匹配法完全重合且正确,只有大概9.0%的句子两种切分方法得到的结果不一样,但其中必有一个是正确的(歧义检测成功),只有不到1.0%的句子,或者正向最大匹配法和逆向最大匹配法的切分虽重合却是错的,或者正向最大匹配法和逆向最大匹配法切分不同但两个都不对(歧义检测失败)。这正是双向最大匹配法在实用中文信息处理系统中得以广泛使用的原因所在。 1.4设立切分标志法
收集切分标志,在自动分词前处理切分标志,再用MM、RMM进行细加工。
1.5最佳匹配(OM,分正向和逆向)
对分词词典按词频大小顺序排列,并注明长度,降低时间复杂度。
优点:易于实现
缺点:匹配速度慢。对于未登录词的补充较难实现。缺乏自学习。
算法流程图如下:
文章目录 环境问题解决方法拷贝一个.bashrc文件使配置生效 环境 阿里云 Debian10
用户:root
问题 默认用户root在运行ls命令显示的目录和文件都是没有颜色的,这就无法很直接的分别是普通文件还是目录,这就感觉很难看,而且很难受,非得敲 # ls -all 命令才能看到是文件还是目录,这就很不爽。
解决方法 我在我的Debian系统中新建了一个git用户,可以在git的用户目录下面看到自动生成了一个.bashrc的文件
cd /home/git vim .bashrc 可以看到git用户目录下的.bashrc文件中有很多内容.
再回头看看root目录下的.bashrc文件
vim ~/.bashrc 空空如也~~~~
拷贝一个.bashrc文件 cd ~/ cp .bashrc .bashrc.backup #备份原生的.bashrc文件 cp /home/git/.bashrc . #拷贝有颜色的bashrc文件 使配置生效 source .bashrc ls /etc 可以看到显示的文件已经有颜色了!
fs=10000; %采样频率 N=10000; %采样点数 t = (0:N-1)/fs; %间隔 NFFT = 2^nextpow2(N);%转化为2的基数倍 f0= fs/2*linspace(0,1,NFFT/2); %求出FFT转化频率 g = 3*sin(6*t); f = g.*cos(60*t); g0 = f.*cos(60*t); %进行FFT变换 g1 = fft(g,NFFT)/N; f1 = fft(f,NFFT)/N; g01 = fft(g0,NFFT)/N; subplot(3,2,1); plot(g,'b');title('波形'); subplot(3,2,2); plot(f0,2*abs(g1(1:NFFT/2)),'b');title('频谱'); subplot(3,2,3); plot(f,'b');title('波形'); subplot(3,2,4); plot(f0,2*abs(f1(1:NFFT/2)),'b');title('频谱'); subplot(3,2,5); plot(g0,'b');title('波形'); subplot(3,2,6); plot(f0,2*abs(g01(1:NFFT/2)),'b');title('频谱');
文章目录 搭建5个MySQL节点使用Haproxy实现负载均衡Keepalived实现高可用方案 搭建5个MySQL节点 拉取镜像到本地 docker pull percona/percona‐xtradb‐cluster 镜像名称太长不方便使用,进行一下改名,改名后删除原来的镜像 docker tag percona/percona‐xtradb‐cluster pxc docker rmi percona/percona‐xtradb‐cluster 创建内网网段net1 创建网段:docker network create --subnet=172.18.0.0/24 net1 查询网段信息: docker inspect net1 删除网段:docker network rm net1 创建docker数据卷 创建:docker volume create --name v1 查看数据卷信息:docker inspect v1 删除:docker volume rm v1 重复操作创建v1-v5共5个数据卷 创建备份数据卷:docker volume create --name backup 创建容器 node1启动后一段时间再启动其他节点没如果node1没初始化完成就启动其他节点就会报错node如果启动几秒就挂掉了,删除对应的数据卷之后再重新创建数据卷再启动参数说明: -d 后台运行-p 3307:3306 将容器内的3306端口映射到宿主机3307端口-e 初始化MySQL的基本参数-v 映射宿主机数据卷和容器目录–name 指定容器名–net 指定容器的网关–ip 指定容器的IP,如果不指定会自动生成 #创建第1个MySQL节点 docker run -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD=abc123456 -e CLUSTER_NAME=PXC -e XTRABACKUP_PASSWORD=abc123456 -v v1:/var/lib/mysql -v backup:/data --privileged --name=node1 --net=net1 --ip 172.
Spring Boot 2.x: 爬取ip代理池入库 概述 因为爬虫的进阶阶段,最基本的就是要用到ip代理池,因为单个代理请求频繁,会被ban掉,所以要备一个代理池,用来请求使用
技术栈 HttpClientSpring Boot 2.3.1JDK 1.8 快速创建Spring Boot项目 访问 https://start.spring.io/ 生成一个初始项目
我们需要去请求接口,所以需要一个Web依赖
点击Generate,会下载一个zip的项目压缩包
导入Spring Boot项目 解压之后记得复制下demo文件夹放的路径
先用IDE编辑 pom.xml 文件,在下图红框上面加入下述代码
可以切换下载依赖的源为国内阿里源
<repositories> <!--阿里云主仓库,代理了maven central和jcenter仓库--> <repository> <id>aliyun</id> <name>aliyun</name> <url>https://maven.aliyun.com/repository/public</url> <releases> <enabled>true</enabled> </releases> <snapshots> <enabled>false</enabled> </snapshots> </repository> <!--阿里云代理Spring 官方仓库--> <repository> <id>spring-milestones</id> <name>Spring Milestones</name> <url>https://maven.aliyun.com/repository/spring</url> <releases> <enabled>true</enabled> </releases> <snapshots> <enabled>false</enabled> </snapshots> </repository> </repositories> <pluginRepositories> <!--阿里云代理Spring 插件仓库--> <pluginRepository> <id>spring-plugin</id> <name>spring-plugin</name> <url>https://maven.aliyun.com/repository/spring-plugin</url> <releases> <enabled>true</enabled> </releases> <snapshots> <enabled>false</enabled> </snapshots> </pluginRepository> </pluginRepositories> 下面是导入流程:
1. copy() copy()用来复制列表或字典里的值,而不是复制它们的引用。但是copy()只能复制单纯的、不包含子列表的列表。
a=[1,2,3] copyList=a.copy() print("After copying...","a=",a,"copyList=",copyList) a[0]=4 print("After changing...","a=",a,"copyList=",copyList) #输出 After copying... a= [1, 2, 3] copyList= [1, 2, 3] After changing... a= [4, 2, 3] copyList= [1, 2, 3] 可见,此时a与copyList就是两个不同的列表。因为copy()函数只让copyList复制了a中的值,所以a与copyList互不影响。
2. deepcopy() deepcopy()可以复制的列表里包含子列表,但copy()不可以。
import copy a=[1,2,3] deepCopyList=copy.deepcopy(a) #首先要导入copy,只能使用copy来调用deepcopy(list) print("After copying...","a=",a,"deepCopyList=",deepCopyList) a[0]=4 print("After changing...","a=",a,"deepCopyList=",deepCopyList) #输出 After copying... a= [1, 2, 3] deepCopyList= [1, 2, 3] After changing... a= [4, 2, 3] deepCopyList= [1, 2, 3] 在该形式的列表下,deepcopy()与copy()的方法相同。
下面介绍不同的地方:
import copy a=[1,2,[3,4]] copyList=a.
1.首先通过以下语句设置Activity为无标题和全屏模式:
1 // 设置为无标题栏 2 requestWindowFeature(Window.FEATURE_NO_TITLE); 3 4 // 设置为全屏模式 5 getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, 6 WindowManager.LayoutParams.FLAG_FULLSCREEN); 7 setContentView(R.layout.main); 2.下面给出xml文件配置,这里我们在res目录下建立layout-land和layout-port目录,相应的layout文件不变,比如main.xml。layout-land是横屏的layout,layout-port是竖屏的layout,其他的不用管模拟器自动寻找
main.xml文件如下:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:background="@drawable/white" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:id="@+id/myTextView1" android:layout_width="fill_parent" android:layout_height="wrap_content" android:textColor="@drawable/blue" android:text="the portrait" /> <Button android:id="@+id/myButton1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/str_button1" /> </LinearLayout> 这个xml文件需要在上述所说的2个文件夹下都需要放置.
3.获取资源id的view:
mButton01 = (Button) findViewById(R.id.myButton1); mTextView01 = (TextView) findViewById(R.id.myTextView1); 4.返回当前显示Activity的显示状态(横屏还是竖屏)
// Return the current requested orientation of the activity
if (getRequestedOrientation() == -1){ mTextView01.setText(getResources().getText(R.string.str_err_1001)); } 5.
文章目录 实验目的: 实验目的: 1、熟悉线性相位FIR滤波器的幅频特性和相频特性;
2、加深对窗函数法设计FIR数字滤波器的基本原理的理解;
3、了解Matlab有关窗函数法设计的子函数以及各种不同窗函数对滤波器性能的影响。
实验原理:
根据上式中的正、负号和长度N取为奇数
或偶数又将线性相位FIR滤波器分成四类。 要 根据所设计的滤波特性正确选择其中一类。
对于理想的数字低通滤波器频率响应,有下列子程序实现(程序名为ideallp.m):
function hd=ideallp(wc,N) tao=(N-1)/2; n=[0:(N-1)]; m=n-tao+eps; hd=sin(wc*m)./(pi*m); 实例:已知某FIR数字低通滤波器截止频率wc=0.2π,滤波器长度N=11,分别用矩形窗、汉 宁窗和布莱克曼窗来设计该滤波器,绘制幅频响应曲线和损耗函数曲线。
wc=0.2*pi; N=11; hd= ideallp(wc,N); % 用wc=0.2*pi的理想低通作为逼近滤波器 wd1=boxcar(N)' ; b1=hd.*wd1; % 用矩形窗设计: wd2=hanning(N)'; b2=hd.*wd2; % 用汉宁窗设计: wd3=blackman(N)' ;b3=hd.*wd3; % 用布莱克曼窗设计: [H1,w]=freqz(b1,1); % 用矩形窗设计的频率特性 [H2,w]=freqz(b2,1); % 用汉宁窗设计的频率特性 [H3,w]=freqz(b3,1); % 用布莱克曼窗设计的频率特性 subplot(1,2,1), plot(w,abs(H1),w,abs(H2),':',w,abs(H3),'-.');% 绘幅特性 legend('矩形窗','汉宁窗','布莱克曼窗') xlabel('\omega'),ylabel('|H(\omega)|') subplot(1,2,2), % 绘分贝幅特性 plot(w,20*log10(abs(H1)),w,20*log10(abs(H2)),':',w,20*log10(abs(H3)),'-.'); legend('矩形窗','汉宁窗','布莱克曼窗') xlabel('\omega'),ylabel('dB') ————————————————
freqz()函数
MATLAB提供了专门用于求离散系统频响特性的函数freqz(),调用freqz()的格式有以下几种:
(1)[H,w]=freqz(B,A,N); %N默认值为512
(2)[H,w]=freqz(B,A,N,‘whole’);
(3)[H,w]=freqz(B,A,[自定义区间]);
上式中B和A分别对应离散系统的系统函数H(z)的分子、分母多项式的系数向量:
B=[b1,b2,...]; A=[a1,a2,...]; 返回量H则包含了离散系统对应区间内N(N为正整数)个频率等分点的频率响应,w为N个频率等分点的值。
数据库表中存储的datetime类型的字段,查询出来变成了时间戳,在sql语句中进行转换
DATE_FORMAT(‘对应的datetime的字段名’,’%Y-%m-%d %H:%i:%s’)
安装 yarn create umi 或则使用npm
npm create umi 然后选择:ant-design-pro
其他的分别是:
app — 用简单的样板创建项目,支持typescript
block — 创建一个 umi 块
library — 用umi.创建一个库
plugin — 创建 umi 插件
选择版本:Pro V4
选择语言:js或则ts
选择完整版:complete
目录结构 本地开发 安装依赖
npm install 运行
npm start 效果如下:
问题描述:linux命令中带括号出现错误:“bash: 未预期的符号 `(' 附近有语法错误【syntax error near unexpected token `('】
产生原因:linux5.0之后,命令是不能带有括号的。
解决方法:在带括号的文件名称或命令上加双引号,如下所示:
第一种:加双引号 删除文件命令:rm -rf "test(1).jar" 导出数据库部分表结构及数据:exp apcoredb/apcoredb@ip:port/orcl file=test.dmp tables="(table1,table2...)" 第二种:加\转译 删除文件命令:rm -rf test\(1\).jar 备注:exp命令导出部分表结构及数据时加\转译无效,推荐使用加双引号
我们都很害怕生病,但感冒发烧这种从小到大的疾病我们已经麻木了,因为一星期他就会好,但是随着长大,各种发炎、三高、心脏病、冠心病响应而生。
心脏病作为一种发作起来让人看了就觉得恐怖的疾病,每年不知道夺走多少生命。而那些患病健在的人们也必须在自己后续的生命里割舍太多东西,以防止心脏病发作。
没有得病的时候,我们永远觉得它离自己很远。我对心脏病的认知就是这样,我不知道它患病的原因,也不知哪些原因会引起心脏病。而患病后如何保持正常生活等等,一概不知。
今天在kaggle上看到一个心脏病数据(数据集下载地址和源码见文末),那么借此深入分析一下。
数据集读取与简单描述 首先导入library和设置好超参数,方便后续分析。
import numpy as np import pandas as pd import matplotlib.pyplot as plt import seaborn as sns 通过对数据集读取和描述可以得到这两个表格:
可以看到有303行14列数据,每列的标题是age、sex、cp、……、target。他们就像每次去医院的化验单,非专业人士很多都不认识。所以利用官方的解释翻译后含义如下:
age: 该朋友的年龄sex: 该朋友的性别 (1 = 男性, 0 = 女性)cp: 经历过的胸痛类型(值1:典型心绞痛,值2:非典型性心绞痛,值3:非心绞痛,值4:无症状)trestbps: 该朋友的静息血压(入院时的毫米汞柱)chol: 该朋友的胆固醇测量值,单位 :mg/dlfbs: 人的空腹血糖(> 120 mg/dl,1=真;0=假)restecg: 静息心电图测量(0=正常,1=患有ST-T波异常,2=根据Estes的标准显示可能或确定的左心室肥大)thalach: 这朋友达到的最大心率exang: 运动引起的心绞痛(1=有过;0=没有)oldpeak: ST抑制,由运动引起的相对于休息引起的(“ ST”与ECG图上的位置有关。这块比较专业,可以点这个看一个解读)slope: 最高运动ST段的斜率(值1:上坡,值2:平坦,值3:下坡)ca: 萤光显色的主要血管数目(0-4)thal: 一种称为地中海贫血的血液疾病(3=正常;6=固定缺陷;7=可逆缺陷)target: 心脏病(0=否,1=是) 所以这些信息里都是患病或者健康者的一些身体指标,并没有和他是否抽烟、是否熬夜、是否遗传、是否作息规律那些东西,因此找不到指导现在我们生活的点,比如说明要戒烟戒酒那些东西。
顺手送上一篇知乎链接 此外上边只是我通过原版数据集给的解读翻译的,如有出错误,欢迎纠正
拿到一套数据首先是要看看这个数据大概面貌~
男女比例 先看看患病比率,男女比例这些常规的
countNoDisease = len(data[data.target == 0]) countHaveDisease = len(data[data.target == 1]) countfemale = len(data[data.sex == 0]) countmale = len(data[data.
IDEA的列选择模式 shift+alt+insert进入列选择模式,可选择一列或者多列
shift+alt+insert退出列选择模式
场景介绍: 工作中多人使用版本控制软件协作开发,常见的应用场景归纳如下:
假设小组中有两个人,组长小张,组员小袁
场景一:小张创建项目并提交到远程Git仓库
场景二:小袁从远程Git仓库上获取项目源码
场景三:小袁修改了部分源码,提交到远程仓库
场景四:小张从远程仓库获取小袁的提交
场景五:小袁接受了一个新功能的任务,创建了一个分支并在分支上开发
场景六:小袁把分支提交到远程Git仓库
场景七:小张获取小袁提交的分支
场景八:小张把分支合并到主干
场景一:小张创建项目并提交到远程Git仓库 创建好项目,选择VCS - > Import into Version Control -> Create Git Repository
接下来指定本地仓库的位置,按个人习惯指定即可,例如这里选择了项目源代码同目录点击OK后创建完成本地仓库,注意,这里仅仅是本地的。下面把项目源码添加到本地仓库。
下图是Git与提交有关的三个命令对应的操作,Add命令是把文件从IDE的工作目录添加到本地仓库的stage区,Commit命令把stage区的暂存文件提交到当前分支的仓库,并清空stage区。Push命令把本地仓库的提交同步到远程仓库。
IDEA中对操作做了一定的简化,Commit和Push可以在一步中完成。
具体操作,在项目上点击右键,选择Git菜单
因为是第一次提交,Push前需要指定远程仓库的地址。如下图,点击Define remote后,在弹出的窗口中输入远程仓库地址。
场景二:小袁从远程Git仓库上获取项目源码 即克隆项目,操作如下:输入小张Push时填写的远程仓库地址
接下来按向导操作,即可把项目从远程仓库克隆到本地仓库和IDE工作区。
场景三:小袁修改了部分源码,提交到远程仓库 这个操作和首次提交的流程基本一致,分别是 Add -> Commit -> Push。请参考场景一
场景四:小张从远程仓库获取小袁的提交 获取更新有两个命令:Fetch和Pull,Fetch是从远程仓库下载文件到本地的origin/master,然后可以手动对比修改决定是否合并到本地的master库。Pull则是直接下载并合并。如果各成员在工作中都执行修改前先更新的规范,则可以直接使用Pull方式以简化操作。
场景五:小袁接受了一个新功能的任务,创建了一个分支并在分支上开发 建分支也是一个常用的操作,例如临时修改bug、开发不确定是否加入的功能等,都可以创建一个分支,再等待合适的时机合并到主干。
创建流程如下:
选择New Branch并输入一个分支的名称
创建完成后注意IDEA的右下角,如下图,Git: wangpangzi_branch表示已经自动切换到wangpangzi_branch分支,当前工作在这个分支上。
点击后弹出一个小窗口,在Local Branches中有其他可用的本地分支选项,点击后选择Checkout即可切换当前工作的分支。
如下图,点击Checkout
场景六:小袁把分支提交到远程Git仓库 切换到新建的分支,使用Push功能
场景七:小张获取小袁提交的分支 使用Pull功能打开更新窗口,点击Remote栏后面的刷新按钮,会在Branches to merge栏中刷新出新的分支。这里并不想做合并,所以不要选中任何分支,直接点击Pull按钮完成操作。
更新后,再点击右下角,可以看到在Remote Branches区已经有了新的分支,点击后在弹出的子菜单中选择Checkout as new local branch,在本地仓库中创建该分支。完成后在Local Branches区也会出现该分支的选项,可以按上面的方法,点击后选择Checkout切换。
场景八:小张把分支合并到主干 新功能开发完成,体验很好,项目组决定把该功能合并到主干上。
MyBatis 3.x 版本提供了以下4个CRUD的高级注解。
@SelectProvider:用于构建动态查询SQL。
@InsertProvider:用于构建动态新增SQL。
@UpdateProvider:用于构建动态更新SQL。
@DeleteProvider:用于构建动态删除SQL。
动态SQL注解主要用于编写动态SQL。这里以@SelectProvider为例,它主要包含两个注解属性,其中,type表示工具类,method表示工具类的某个方法(用于返回具体的SQL语句)。
以下代码可以构建动态SQL,实现查询功能:
/** * 根据用户ID,获取用户信息 * @author pan_junbiao */ @SelectProvider(type = UserSqlBuilder.class, method = "buildGetUserByIdSql") public UserInfo getUserById(@Param("userId") int userId); UserSqlBuilder工具类的代码如下:
public class UserSqlBuilder { public String buildGetUserByIdSql(@Param("userId") int userId) { return new SQL() { { SELECT("*"); FROM("tb_user"); WHERE("user_id = #{userId}"); } }.toString(); } } 【实例】使用MyBatis的动态SQL注解,实现用户信息的查询、新增、修改、删除操作。
1、创建数据表 在MySQL数据库中创建用户信息表(tb_user),并添加数据。
-- 判断数据表是否存在,存在则删除 DROP TABLE IF EXISTS tb_user; -- 创建“用户信息”数据表 CREATE TABLE IF NOT EXISTS tb_user ( user_id INT AUTO_INCREMENT PRIMARY KEY COMMENT '用户编号', user_name VARCHAR(50) NOT NULL COMMENT '用户名称', blog_url VARCHAR(50) NOT NULL COMMENT '博客地址', blog_remark VARCHAR(50) COMMENT '博客备注' ) COMMENT = '用户信息表'; -- 添加数据 INSERT INTO tb_user(user_name,blog_url,blog_remark) VALUES('pan_junbiao的博客','https://blog.
Edge、Chrome、IE浏览器乱码解决
String useragent = request.getHeader("User-Agent"); response.reset(); response.setCharacterEncoding("utf-8"); response.setContentType("application/octet-stream"); if (useragent.contains("MSIE")||useragent.contains("Trident")||useragent.contains("Edge")) { attachmentName = URLEncoder.encode(attachmentName, "UTF-8"); } else { attachmentName = new String(attachmentName.getBytes("UTF-8"), "ISO8859-1"); } response.addHeader("Content-Disposition","attachment;filename="+ attachmentName+file_postfix); response.setCharacterEncoding("UTF-8");
1.STM32芯片,tcp服务器,网线连接时候,客户端不断重连可以正常稳定连接。
2.客户端不断重连时候,网线不断断开重连,最后客户端连不上,甚至程序直接死机。
通过仿真发现err_t tcp_server_accept(void *arg, struct tcp_pcb *pcb, err_t err),客户端申请连接pcb = NULL,也就是说没有空余的pcb给重连客户端使用,直接仿真tcp_active_pcbs信息发现,pcb->state = FIN_WAIT_1 || FIN_WAIT_2。网线不断断开,pcb关闭4次握手没有实现,只进行一部分,一直等待中。
更改lwip源码不知重哪里下手,也怕改错出现更多bug,只能取巧弄下。
在err_t tcp_server_accept(void *arg, struct tcp_pcb *pcb, err_t err)函数最前面加个判断,客户端连接分配的pcb为空闲(全被占用了),找到等待关闭pcb全释放了(可能会出现其他问题,不过我这只是单对单使用,能重连上就行)。
if(pcb == NULL){
/*网络不稳(不断插拔网线),强制释放pcb*/
tcp_find_waitPcb();
printf("MBtcp: accept pcb == NULL\r\n");
return ERR_ARG;
}
tcp_find_waitPcb()的函数定义:
void tcp_find_distant(void)
{
struct tcp_pcb *pcb = NULL;
for(pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next)
{
if(pcb->state == FIN_WAIT_1 || pcb->state == FIN_WAIT_2){
tcp_abort( pcb );
}
}
HTTP超文本传输协议(基于TCP/IP传递通信)
特点
简单快速:
客户给服务器发请求只发请求路径和方法,由于协议简单,所以HTTP服务器程序规模小,通信速度快
灵活:
允许传输任意类型数据,正在传输的类型由Content-Type来标记
无连接:
每次连接只处理一个请求,收到客户应答断开连接,节省时间
无状态:
对事物处理无记忆能力,缺少状态意味后续处理前面的信息要重传,导致每次传送数据量增大,若不需要前面信息则应答快
8种请求方法
请求报文
求报文由请求行、请求头部、空行和请求报文主体几个部分组成:
起始行:报文第一行,在请求报文里用来说明要做什么,在响应报文里说明出现了什么情况
首部字段:位于起始行后面,有零个或者多个,每个首部字段都包含一个名字和一个值,便于解析,两者之间用冒号(:)隔开,首部之间以一个空行结束。
主体:空行之后就是可选的报文主题。其中包含了所有类型的数据。请求主体中包括了要发送给Web服务器的数据,响应主体找那个装载了要返回给客户端的数据。主体中可以包含任何二进制数据,也可以包含文本。
响应报文
响应报文由起始行、响应头部、空行和响应报文主体这几个部分组成
工作过程
(1)终端客户在web浏览器地址栏输入访问地址http://www.ceshi.com:80/index.html
(2)web浏览器请求DNS服务器把域名www.ceshi.com解析成web服务器的IP地址
(3)web浏览器将端口号(默认是80)从访问地址(URL)中解析出来
(4)web浏览器通过解析后的ip地址及端口号与web服务器之间建立一条TCP连接
(5)建立TCP连接后,web浏览器向web服务器发送一条HTTP请求报文
(6)web服务器响应并读取浏览器的请求信息,然后返回一条HTTP响应报文。
(7)web服务器关闭HTTP连接,关闭TCP连接,web浏览器显示访问的网站内容到屏幕上。
状态代码、状态描述
状态代码由三位数字组成,第一个数字定义了响应的类别,且有五种可能取值。
1xx:指示信息 —— 表示请求已接收,继续处理。
2xx:成功 —— 表示请求已被成功接收、理解、接受。
3xx:重定向 —— 要完成请求必须进行更进一步的操作。
4xx:客户端错误 —— 请求有语法错误或请求无法实现。
5xx:服务器端错误 —— 服务器未能实现合法的请求
常见状态代码、状态描述的说明如下:
200 OK:客户端请求成功。
400 Bad Request:客户端请求有语法错误,不能被服务器所理解。
401 Unauthorized:请求未经授权,这个状态代码必须和 WWW-Authenticate 报头域一起使用。
403 Forbidden:服务器收到请求,但是拒绝提供服务。
404 Not Found:请求资源不存在,举个例子:输入了错误的URL
500 Internal Server Error:服务器发生不可预期的错误。
502:网关错误
503 Server Unavailable:服务器当前不能处理客户端的请求,一段时间后可能恢复正常。
不安全因素
使用明文 被监听
文章目录 一、实验目的二、实验内容2.1 实现多种页面置换算法并比较算法优劣 三、流程图3.1 算法流程 四、设计思想4.1 设计思路4.2 代码分析 五、代码实现六、运行结果6.1 初始化6.2 OPT6.3 FIFO6.4 LRU6.5 LFU 七、思考7.1 比较各种算法的命中率7.2 分析当用户内存容量增加时对命中率的影响 八、结尾 一、实验目的 存储管理的主要功能之一是合理地分配空间。请求页式管理是一种常用的虚拟存储管理技术。本实验的目的是通过请求页式管理中页面置换算法模拟设计,了解虚拟存储技术的特点,掌握请求页式存储管理的页面置换算法。因为源码中我对一些关键步骤的注释已经比较清晰了,所以在本文中不会再对每一个细节都进行分析,只分析整体的代码结构和所使用到的设计模式。
博客内所有文章均为 原创,所有示意图均为 原创,若转载请附原文链接。
二、实验内容 2.1 实现多种页面置换算法并比较算法优劣 (1)通过计算不同算法的命中率比较算法的优劣。同时也考虑了用户内存容量对命中率的影响(命中率 = 1 - 页面失效次数 ÷ 页地址流长度)。页面失效次数为每次访问相应指令时,该指令所对应的页不在内存中的次数。在本实验中,假定页面大小为1k,用户虚存容量为32k,用户内存容量为4页到32页。
(2)produce_addstream 通过随机数产生一个指令序列,共320条指令。
A、指令的地址按下述原则生成:
1)50%的指令是顺序执行的
2)25%的指令是均匀分布在前地址部分
3)25%的指令是均匀分布在后地址部分
B、具体的实施方法是:
1)在[0,319]的指令地址之间随机选取一起点m;
2)顺序执行一条指令,即执行地址为m+1的指令;
3)在前地址[0,m+1]中随机选取一条指令并执行,该指令的地址为m’;
4)顺序执行一条指令,地址为m’+1的指令
5)在后地址[m’+2,319]中随机选取一条指令并执行;
6)重复上述步骤1)~5),直到执行320次指令
C、将指令序列变换称为页地址流
在用户虚存中,按每k存放10条指令排列虚存地址,即320条指令在虚存中的存放方式为:
第0条~第9条指令为第0页(对应虚存地址为[0,9]);
第10条~第19条指令为第1页(对应虚存地址为[10,19]);
。。。。。。
第310条~第319条指令为第31页(对应虚存地址为[310,319]);
按以上方式,用户指令可组成32页。
(3)计算并输出下述算法在不同内存容量下的命中率。
1)最佳置换算法(OPT);
2)先进先出算法(FIFO);
3)最近最久未使用页面置换(LRU);
4)最少使用页面淘汰算法(LFU)
三、流程图 3.1 算法流程 四、设计思想 4.1 设计思路 该实验中需要实现四种页面置换算法,分别为 OPT、FIFO、LRU和LFU,通过分析发现这四种算法中都存在一种优先级的关系,只不过优先级的属性不同,比如在LRU算法中,优先级为最近一次访问距离现在的时间,即页面最近一次访问距离现在的时间越短其优先级越高,而对于LFU算法,优先级页面被访问的次数,即用户内存中页面被访问的次数越多,其优先级也就越高,越不容易被淘汰,而FIFO算法中的优先级就是进入用户空间的时间,时间越短优先级越高,OPT中的优先级就是页面下次被访问据当前的时间,时间越短优先级越高。
当我们找到了这几种算法中的优先级关系后,通过分析可以发现优先级队列可以很好的满足这个需求,而对于LRU算法的实现其实最简单的方法是如果被访问的页面存在于用户空间中,那么就将其提升至队尾(队尾入页面,队头出页面),但是为了保证多个算法的统一性,还是决定采用相同的抽象算法来实现。
而对于整体的代码结构设计,可以采用 模板方法设计模式 + 策略设计模式 的方法来进行实现,增强算法整体的灵活性、可扩展性和可维护性。
PySide2基础篇(十五)——QFileDialog运用 前言:
阅读这篇文章我能学到什么?
FileDialog被用于进行目录选择、单个文件选择、多个文件选择。下面讲解基本用法。
——如果你觉得这是一篇不错的博文,希望你能给一个小小的赞,感谢您的支持。
1 创建文件对话框 1.1 选择目录 getExistingDirectory()方法可调用目录选择对话框,选定目录后该函数返回所选路径。
代码示例:
from PySide2.QtWidgets import QApplication, QMainWindow, QFileDialog app = QApplication([]) MainWindow = QMainWindow() FileDialog = QFileDialog(MainWindow) FileDirectory = FileDialog.getExistingDirectory(MainWindow, "标题") #选择目录,返回选中的路径 print(FileDirectory) MainWindow.show() app.exec_() 运行结果:
C:/Users/think/Desktop/Python_Test/.svn 1.2 单选文件 单选文件对话框一次只能选择一个文件,且选中对象是文件不是目录。
代码示例:
from PySide2.QtWidgets import QApplication, QMainWindow, QFileDialog app = QApplication([]) MainWindow = QMainWindow() FileDialog = QFileDialog(MainWindow) FileDirectory = FileDialog.getOpenFileName(MainWindow, "标题") #选择目录,返回选中的路径 print(FileDirectory) MainWindow.show() app.exec_() 运行结果:
('C:/Users/think/Desktop/Python_Test/main.py', 'All Files (*)') 1.3 多选文件 多选文件对话框一次可以选择多个文件,且选中对象是文件不是目录。
昨天帮一位朋友ssm框架的一个问题,发现报了如下的问题:
Caused by: org.springframework.core.NestedIOException: Failed to parse config resource: class path resource [mybatis.xml]; nested exception is org.apache.ibatis.builder.BuilderException: Error parsing SQL Mapper Configuration. Cause: java.io.IOException: Could not find resource com/ssm/dao/daoMapper.xml 很明显该问题就是因为配置导致的。
1.maven项目pom.xml配置中没有将该配置文件作为资源文件引入,会导致找不到sql,解决办法就直接在maven的build下面加上如下代码。
<resource> <directory>${basedir}/src/main/java</directory> <includes> <include>**/*.xml</include> </includes> </resource> 这里只是添加了mybatis的xml其他配置其实也是一样的比如:
<resources> <resource> <directory>${basedir}/src/main/resources</directory> <includes> <include>**/*.yml</include> </includes> </resource> <resource> <directory>${basedir}/src/main/resources</directory> <includes> <include>**/*.properties</include> </includes> </resource> <resource> <directory>${basedir}/src/main/resources</directory> <includes> <include>**/*.xml</include> </includes> </resource> <resource> <directory>${basedir}/src/main/java</directory> <includes> <include>**/*.xml</include> </includes> </resource> </resources> 2.由于mybatis字段映射中的大小写拼错了,导致sql查询出来的导致不致。
由于该问题处理比较简单,各位有更好的处理方案请留言或私聊讨论,感谢~
在前面的博客中介绍了使用scikit-learn绘制分类器的学习曲线,今天介绍一下使用scikit-learn绘制分类器的ROC曲线,以及计算AUC的值。
ROC曲线主要用于衡量二分类器的性能,当正负样本不均衡时,准确率和召回率不能合理度量分类器的性能。关于ROC曲线和AUC的计算scikit-learn工具包中主要提供了以下几个函数:
1、roc_curve函数(只能用于二分类):根据模型预测结果(概率,置信度等)和样本真实标签,按照模型预测结果降序排序依次选择阈值,基于阈值计算fpr、tpr,基于fpr和tpr即可得到分类器的ROC曲线
2、auc函数:基于roc_curve函数返回fpr、tpr序列计算二分类器的AUC值
3、roc_auc_score函数:基于样本真实标签y_target和模型预测结果(概率,置信度等)计算AUC的值,可以用于计算多分类器的AUC数值
下面通过例子看一下函数的具体使用方法:
roc_curve示例:
根据模型预测结果(概率,置信度等)和样本真实标签,按照模型预测结果降序排序依次选择阈值,基于阈值计算fpr/tpr。
from sklearn.metrics import roc_auc_score from sklearn.metrics import roc_curve from sklearn.metrics import auc import numpy as np y = np.array([1, 1, 2, 2]) scores = np.array([0.1, 0.4, 0.35, 0.8]) fpr, tpr, thresholds = roc_curve(y, scores, pos_label=2) fpr, tpr, thresholds 输出的fpr、tpr和thresholds如下:
(array([0. , 0. , 0.5, 0.5, 1. ]),
array([0. , 0.5, 0.5, 1. , 1. ]),
array([1.8 , 0.8 , 0.4 , 0.
xml文件配置数据库链接, 在设置url时”&“符报错 1.错误信息 idea错误信息
运行报错 org.mybatis.generator.exception.XMLParserException: XML Parser Error on line 17: 对实体 "useUnicode" 的引用必须以 ';' 分隔符结尾。 at org.mybatis.generator.config.xml.ConfigurationParser.parseConfiguration(ConfigurationParser.java:111) at org.mybatis.generator.config.xml.ConfigurationParser.parseConfiguration(ConfigurationParser.java:82) at org.mybatis.generator.config.xml.ConfigurationParser.parseConfiguration(ConfigurationParser.java:74) at com.michael.supermall.tools.GeneratorDisplay.generator(GeneratorDisplay.java:24) at com.michael.supermall.tools.GeneratorDisplay.main(GeneratorDisplay.java:34) 2.问题原因 转义字符不合法的xml字符必须被替换为相应的实体。
xml中常用的预定义好的实体:
- < <(小于) - > >(大于) - & &(和) - ' '(单引号) - " "(双引号) 3.问题解决方案 使用实体& 替换对应&连接符
<jdbcConnection driverClass="com.mysql.cj.jdbc.Driver" connectionURL="jdbc:mysql://127.0.0.1:3306/mall?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8" userId="root" password="Haishao123"> </jdbcConnection>
上次cas5.3.14入门二,cas介绍及登陆流程讲到CAS Server 生成一个TGT对象,放入自己的缓存,本片介绍一下如何将TGT存储到redis,为什么要把它存储到redis 呢,为了高可用以及扩展集群部署,集群部署的时候显然存储在内存中是不合适的
先看官网:https://apereo.github.io/cas/5.3.x/ 官方提供了这么多存储TGT的方式,咱们只说redis 的方式,其他方式都可以参照配置。
参照官网
首先配置maven,其实还需要另外一个依赖
<dependency> <groupId>org.apereo.cas</groupId> <artifactId>cas-server-support-redis-ticket-registry</artifactId> <version>${cas.version}</version> </dependency> <dependency> <groupId>org.apereo.cas</groupId> <artifactId>cas-server-support-redis-service-registry</artifactId> <version>${cas.version}</version> </dependency> cas在 application.properties的所有配置都是通过CasConfigurationProperties这个类来读取的,我们看看这个类,打开我们按照上节说到的overlay项目,我使用的IDEA 工具配置了eclipse的快捷键,ctrl+shift+t 查找类,CasConfigurationProperties中看到这个
在代码中我们看到这一行,再点进去,这个类里面提供了各种ticket 的配置说明
public class TicketProperties implements Serializable { private static final long serialVersionUID = 5586947805593202037L; /** * Properties and settings related to session-transient tickets. */ @NestedConfigurationProperty private TransientSessionTicketProperties tst = new TransientSessionTicketProperties(); /** * Properties and settings related to proxy-granting tickets. */ @NestedConfigurationProperty private ProxyGrantingTicketProperties pgt = new ProxyGrantingTicketProperties(); /** * Properties and settings related to ticket encryption.
1.缩减索引字段 es中只保留必要字段,缩减字段能有效缩减文档大小,提高写入速度。
2.合理设置分片数和副本数 7.*默认1个分片1和副本。Elasticsearch官方建议一个分片的大小应该在20到40 GB左右,分片个数建议 >= 集群节点的个数,但是当索引较小时(写入性能需求 > 搜索性能需求时),可以使用1个分片,过多的分片也会影响写入性能。
分片大小对于搜索查询非常重要。
一方面, 如果分配给索引的分片太多,则Lucene分段会很小,从而导致开销增加。 当同时进行多个查询时,许多小分片也会降低查询吞吐量。另一方面,太大的分片会导致搜索性能下降和故障恢复时间更长。 在批量索引文档前可以将副本数设置为0,索引完成后恢复原来的值。
"number_of_replicas":1 "number_of_shards":1 3.索引刷新间隔refresh_interval 默认情况下refresh_interval为1s,数据写入1秒后就可以被搜索到,每次索引的refresh会产生一个新的Lucene段,Lucene段即为segment,segment在复合一定条件后,会自动合并,因此这会导致频繁的segment merge行为,如果不需要特别高的搜索实时性,应该降低索引refresh周期。-1:禁止刷新。在批量索引文档前可以将refresh_interval设置为-1,完成后修改为默认值。由于我的场景是每天都会全量同步,此处将refresh_interval设置为120s
"refresh_interval": "120s" 假如refresh_interval设置为-1,只是es中的定时任务不会执行。但是es会根据一个versionMap去强制做一次refresh操作,缓冲区满的时候也会触发refresh操作。每30秒有个定时器去检查shardIndexingBufferSize大小,最终调用updateShardBuffers方法去refresh
4.translog设置 随着translog文件越来越大时要考虑把内存中的数据刷新到磁盘中,这个过程称为flush。在默认设置下,translog的持久化策略为: request,每个请求 都“flush”,配置异步刷新,刷新时间120s。
"index.translog.durability": "async" "index.translog.sync_interval": "120s" 5.线程池队列 当写入队列满时,es会拒绝接受索引事件,适当增加写入队列大小,默认为200。线程池大小官方不建议进行修改。
thread_pool.write.queue_size: 500 6.使用es自动生成的id 无更新操作时,尽量使用es自动生成的id,当你index一个document使用特定的id,ES需要去检查是否在同一个shard存在相同的ID的文档,这是一个相当昂贵的操作,并且随着文档数量的增加,花费呈指数增长。如果使用自动生成id,ES会跳过这个检查,使得Index速度更快。但是当需要更新操作时不适用。
7.Indexing 缓冲大小 在执行大量的索引操作时,indices.memory.index_buffer_size的默认 设置可能不够,这和可用堆内存、单节点上的shard数量相关,可以考虑适当增大该值,增大该值,减少segment,就会减少merge。默认大小为10% 48mb
indices.memory.index_buffer_size: 20% indices.memory.min_index_buffer_size: 96mb 8.jvm.options Xmx和Xms的大小默认为1g,可以适当增加该值。
-Xms2g -Xmx2g 9.禁用swapping 在ES的官方文档上,要求Disabled Swapping。执行swapoff -a暂时禁用,机器重启后会恢复。要永久的关闭swapping,需要编辑/etc/fstab文件,将包含swap的行的注释掉。
参考文档:
https://www.cnblogs.com/eviltuzki/p/8439036.htmlhttps://blog.csdn.net/wmj2004/article/details/80804411https://blog.csdn.net/u012133048/article/details/93408374?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecasehttps://blog.csdn.net/HaixWang/article/details/80846749?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecasehttps://www.cnblogs.com/MyOceansWeb/p/12653965.htmlhttps://blog.csdn.net/laoyang360/article/details/85109769https://blog.csdn.net/laoyang360/article/details/976959317.*官方文档
我现在有一个SQL语句 SELECT FAQID,
FAQNAME,
TYPE,
CREATOR,
TOQUESTION,
SUPERCODE
FROM T_KBS_FAQ t
where TYPE = '1' <[AND FAQID = :faqId]>
<[AND FAQNAME like '%' ||:faqName || '%']>
<[AND CREATOR = :creator]>
<[AND SUPERCODE=:superCode]>
<[AND TOQUESTION=:toQuestion]>
<%:toKngType%>
现在数据过大 导致查询很慢,如何优化? 要建立几个字段建立索引怎么样建立, 建立好了如何使用 SQL语句又该怎写?
-------------------------------------------------------------------------------------------------------------------------------------------------
nameidrowid rowidid王一 1x001 x001 1王二 2x002 x002 2王三 3x003 x003 3表 索引select * from 表 where id = 3
索引是由where条件触发的 ,此查询语句中指定id=3,因为有索引直接从索引段中找到id=3对应的rowid,然后就可以快速用rowid快速找到表中的记录,如果没有索引,就是一行一行的查找id=3的记录 下面写几种常见索引的创建吧: (1) create index 索引名 on 表(字段名); //创建B树索引,一般用的OLTP中
sk-learn鸢尾花分类模型训练 在python的sklearn库中,有一些小型数据集,我们可以直接拿来进行模型训练学习。
Iris(鸢尾花)数据集是常用的分类实验数据集,由Fisher, 1936收集整理。Iris也称鸢尾花卉数据集,是一类多重变量分析的数据集。关于数据集共有150个样本,4个特征,3个目标值,我们可以这样引用:
from sklearn.datasets import load_iris # 1.获取鸢尾花数据集 iris = load_iris() print("鸢尾花数据集的返回值:\n", iris) # 返回值是一个继承自字典的Bench print("鸢尾花的特征值:\n", iris["data"]) print("鸢尾花的目标值:\n", iris.target) print("鸢尾花特征的名字:\n", iris.feature_names) print("鸢尾花目标值的名字:\n", iris.target_names) print("鸢尾花的描述:\n", iris.DESCR) 部分结果:
鸢尾花的特征值:
[[5.1 3.5 1.4 0.2]
[4.9 3. 1.4 0.2]
[4.7 3.2 1.3 0.2]
[4.6 3.1 1.5 0.2]
[5. 3.6 1.4 0.2]
[5.4 3.9 1.7 0.4]
[4.6 3.4 1.4 0.3]
[5. 3.4 1.5 0.2]
[4.4 2.9 1.4 0.2]
[4.9 3.1 1.5 0.1]
文章目录 1、简介2、下载并编译Qt4的库2.1 编译准备2.1.1 修改“qtftp-master\src\qftp”下的“qftp.pro”文件2.1.2 修改“qtftp-master\src\qftp”下的“qftp.h”文件 2.2 编译 3、应用编译好的库3.1 引用3.1.1 拷贝静态库到 lib 下3.1.2 拷贝动态库到 bin 下3.1.3 拷贝头文件到 QtNetwork 下 3.2 引用 1、简介 因为QFTP是Qt4的库,Qt5已经不用了,改用了QNetworkAccessManager来代替。但是Qt5提供的QNetworkAccessManager仅支持FTP的上传和下载,所以只能用QFTP了。
2、下载并编译Qt4的库 QFTP在Github的下载地址:https://github.com/qt/qtftp
先下载到本地,然后把它编译。注意编译前要改两个地方:
2.1 编译准备 2.1.1 修改“qtftp-master\src\qftp”下的“qftp.pro”文件 把“CONFIG += static CONFIG -= shared”改为“CONFIG += staticlib CONFIG += shared”,如下:
#CONFIG += static #CONFIG -= shared TEMPLATE = lib 2.1.2 修改“qtftp-master\src\qftp”下的“qftp.h”文件 //#include <QtFtp/qurlinfo.h> #include <qurlinfo.h> 2.2 编译 编译好后,会在编译好的文件夹的“lib”目录找到如下文件:
3、应用编译好的库 应用编译好的库有两种方式,一种是直接引用头文件,并在应用到ftp项目的目录加入lib和dll,在pro用添加引用库的参数。另一种则是放在Qt的目录下,以后所有项目都可以直接用这个库。本文讲的是后者。
3.1 引用 3.1.1 拷贝静态库到 lib 下 接下来将 Qt5Ftpd.lib、Qt5Ftp.lib、Qt5Ftpd.prl、Qt5Ftp.prl 拷贝至 Qt\Qt5.
个人博客
由于在外地,住的地方没有wifi,很难受,所以我就找能强力破解wifi的工具,最终发现了这款给力的软件,能破解你附近百分七十的wifi。
一,下载软件:幻影pin(自行百度搜索,也可关注工作号科技仔获取)
二.手动写入驱动文件(需要RE管理器和root权限,需自行百度和root,不会的可以关注公众号发送root)
三,打开手机幻影pin 选择破解率高的wifi破解,一般一天内可破解成功。
这里直接根据知识点进行步骤引导(由于我现在使用的是oracle,所以以oracle11g版本为例):
文章目录 一、 新建概念模型二、 新建物理模型三、 概念模型转换为物理模型四、 将物理模型导入数据库五、 从数据库中导出表物理模型 一、 新建概念模型 新建表
然后点击表组件,在中间空白的地方点击左键,放置两个表组件,如下图 然后双击编辑
编辑完后点击应用,确定!
然后同理再弄一个身份证表,但是在创建过程中,由于身份证表需要用到用户表的user_id,报错了
别慌,可以这么解决!
然后在重新创建身份证表,发现就可以了,创建后如下所示
2. 创建关系
点击关系组件,然后鼠标移到一个表,左键按住拖动到另一张表,就会自动创建one-many关系,其中,有这个图案的为many的一方。
然后双击关系链进行编辑
修改完点击应用、确定就创建成功了
二、 新建物理模型 然后后面的操作跟概念模型一样,新建user和card两张表,并且用关系组件将它们连接在一起,如下图
然后双击关系连接线,设置他们的关联字段即可
三、 概念模型转换为物理模型 概念模型转为物理模型
以我们上面创建的概念模型为例子,打开概念模型,然后开始转换
但是执行后却报错了:Entity Attribute name uniqueness
这里需要对powerdesign的一些配置进行修改下即可。
1)去掉"Tools -> Model Options"后 "Allow reuse"复选框,
2)去掉“ Tool->check model->Entity Attribute下Entity Attribute name uniqueness 和 Entity Attribute code uniqueness
修改完再一次执行,成功转为物理模型! 四、 将物理模型导入数据库 1.首先先确定自己需要导入的数据库类型
由于我是用的数据库是oracle的,所以
2. 导出为sql文件
然后点击确定即可!!!
然后,问题出现了,虽然表通过plsql工具成功的导入到了数据库中。但是点击查询表的时候提示表不存在,这又是咋回事???看了sql语句发现了端倪!!!
在powerdesign选择任意一个表,然后点击右键
可以看到,创建表的sql语句,表名和字段都加上了双引号,所以才会出错,这里只要配置将双引号去除即可!!
再试一次,成功导入!!
五、 从数据库中导出表物理模型 配置完,如果怕自己哪里配错的话,可以进行测试下数据库是否连接成功
如果没有问题了,就一路点击确定,直到跳回这个界面
文章目录 搭建Vue项目单文件组件格式001中文件修改为单文件组件形式TodoItem组件App.vue 效果插槽具名插槽(使用插槽替换属性传值)作用域插槽:子组件传递出状态给父组件使用 搭建Vue项目 cnpm install -g @vue/clivue create my-appcd my-appnpm run serve 单文件组件格式 <!-- 单文件组件模块1:模板 --> <template> <div id="app"> <img alt="Vue logo" src="./assets/logo.png"> <HelloWorld msg="Welcome to Your Vue.js App"/> </div> </template> <!-- 单文件组件模块2:逻辑 --> <script> // 引入文件 import HelloWorld from './components/HelloWorld.vue' export default { name: 'App', components: { // 注册为组件 HelloWorld } } </script> <!-- 单文件组件模块3:样式 --> <style> #app { font-family: Avenir, Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px; } </style> 001中文件修改为单文件组件形式 TodoItem组件 App.
1. 页面什么时候调入 在调页过程中有两个页面调入策略:一个是‘随用随调”策略,另- -个是“预调页”策略。
随用随调"策略:发生缺页中断时,缺哪页便调入哪页。预调页"策略:使用第1页,发生缺页中断,在调入第1页时连同第2、3… 一起调入。 预调页策略的优点:
一次读多个连续的页面, 可以减少磁头移动的时间,对系统效率提高有很大好处。当发现缺页已在内存时,当前进程不必让出控制权,仅仅将缺页转移到用户区,修改页表后就可继续运行。
进程的页面有可能处在什么位置?
2. 缺页从哪儿调入? 从磁盘交换区中调入缺页从磁盘文件区中调入缺页从磁盘缓冲区中调入缺页 3. 缺页调入需要多长时间? 从磁盘交换区中调入缺页 调入时间主要是读磁盘扇区的时间,由磁盘寻道时间、盘片旋转延迟时间和数据传送时间3部分组成(设备管理部分详细涉及)通常,调入时间约为数百μ s至数十ms通常,调入时间约为数百μ s至数十ms 从磁盘文件区中调入缺页 对文件区的访问需要检索文件目录,找到文件的外存地址后再读磁盘扇区(文件管理部分详细涉及)。其调入时间将数倍于从磁盘交换区中调入缺页的耗时,几十甚至几百毫秒。 从磁盘缓冲区中调入缺页 口系统允许采用“提前读"的访问策略时,用户程序运行中产生的缺页有可能已经驻留在内存的磁盘缓冲区内。口从该缓冲区内调入缺页的时间大体为数百ns 4.进程执行过程中要访问的页面有几种情况? 进程要访问的页面有两种情况
5.访问页面需要多长时间? 系统的有效时间T的估算
基本分页存储管理中的有效访存时间
在基本分页存储管理中,所有页面已在内存
设t为访问一次快存的时间,t为访问- -次内存的时间,P命中是访问快表命中率,则有效访存时间是
t=(1- P命中) x (t1+2t2) +p命中x(t1+t2)在请求分页存储管理中,页面分两种情况计算
请求分页管理中不缺页时的有效访存时间:
在请求分页存储管理中,不发生缺页时的这个访存时间t称为一个内存周期为ma。
ma=t
=(1-p命中)x(t1+2t1) +p命中x (t1+t2)
t1为访问一次快存的时间,t2为访问一 次内存的时间,P命中是访问快表命中率
请求分页综合有效访存时间T的估算:
今天我们对OAuth2.0的整合方式做一下笔记,首先我从网上找了一些关于OAuth2.0的一些基础知识点,帮助大家回顾一下知识点:
一、oauth中的角色
client:调用资源服务器API的应用
Oauth 2.0 Provider:包括Authorization Server和Resource Server
(1)Authorization Server:认证服务器,进行认证和授权
(2)Resource Server:资源服务器,保护受保护的资源
user:资源的拥有者
二、下面详细介绍一下Oauth 2.0 Provider(了解源码可+求求: 1791743380)
Authorization Server:
(1)AuthorizationEndpoint:进行授权的服务,Default URL: /oauth/authorize
(2)TokenEndpoint:获取token的服务,Default URL: /oauth/token
Resource Server:
OAuth2AuthenticationProcessingFilter:给带有访问令牌的请求加载认证
三、下面再来详细介绍一下Authorization Server:
一般情况下,创建两个配置类,一个继承AuthorizationServerConfigurerAdapter,一个继承WebSecurityConfigurerAdapter,再去复写里面的方法。
主要出现的两种注解:
1、@EnableAuthorizationServer:声明一个认证服务器,当用此注解后,应用启动后将自动生成几个Endpoint:(注:其实实现一个认证服务器就是这么简单,加一个注解就搞定,当然真正用到生产环境还是要进行一些配置和复写工作的。)
/oauth/authorize:验证
/oauth/token:获取token
/oauth/confirm_access:用户授权
/oauth/error:认证失败
/oauth/check_token:资源服务器用来校验token
/oauth/token_key:如果jwt模式则可以用此来从认证服务器获取公钥
以上这些endpoint都在源码里的endpoint包里面。
2、@Beans:需要实现AuthorizationServerConfigurer
AuthorizationServerConfigurer包含三种配置:
ClientDetailsServiceConfigurer:client客户端的信息配置,client信息包括:clientId、secret、scope、authorizedGrantTypes、authorities
(1)scope:表示权限范围,可选项,用户授权页面时进行选择
(2)authorizedGrantTypes:有四种授权方式
Authorization Code:用验证获取code,再用code去获取token(用的最多的方式,也是最安全的方式)
Implicit: 隐式授权模式
Client Credentials (用來取得 App Access Token)
Resource Owner Password Credentials
(3)authorities:授予client的权限
这里的具体实现有多种,in-memory、JdbcClientDetailsService、jwt等。
AuthorizationServerSecurityConfigurer:声明安全约束,哪些允许访问,哪些不允许访问
AuthorizationServerEndpointsConfigurer:声明授权和token的端点以及token的服务的一些配置信息,比如采用什么存储方式、token的有效期等
client的信息的读取:在ClientDetailsServiceConfigurer类里面进行配置,可以有in-memory、jdbc等多种读取方式。
jdbc需要调用JdbcClientDetailsService类,此类需要传入相应的DataSource.
下面再介绍一下如何管理token:
AuthorizationServerTokenServices接口:声明必要的关于token的操作
(1)当token创建后,保存起来,以便之后的接受访问令牌的资源可以引用它。
(2)访问令牌用来加载认证
sql 动态写入数据库字段
最有效的数据库优化之一是批处理写入。 批处理写入受大多数现代数据库和JDBC标准的一部分支持,并且受大多数JPA提供程序支持。 普通数据库访问包括在单独的数据库/网络访问中将每个DML(插入,更新,删除)语句发送到数据库。 每个数据库访问都有一定的开销,并且数据库必须独立处理每个语句。 批处理写入有两种形式,动态的和参数化的。 参数化是最常见的方法,通常可以带来最大的好处,因为动态可能存在解析问题。 要了解批处理编写,您必须首先了解参数化SQL。 SQL执行由两部分组成,即解析和执行。 解析包括将字符串SQL表示形式转换为数据库表示形式。 执行包括在数据库上执行已解析SQL。 数据库和JDBC支持绑定参数,因此SQL(数据)的参数不必嵌入SQL中。 这避免了将数据转换为文本的成本,并允许重复执行同一SQL语句,并执行多次。 这允许单个解析和多个执行,也称为“参数化SQL”。 大多数JDBC DataSource实现和JPA提供程序都支持参数化SQL和语句缓存,这可以有效避免在运行的应用程序中进行解析。 动态SQL示例 INSERT INTO EMPLOYEE (ID, NAME) VALUES (34567, "Bob Smith") 参数化SQL示例 INSERT INTO EMPLOYEE (ID, NAME) VALUES (?, ?) 参数化批处理编写涉及执行单个DML语句,但是具有用于多个同质语句的一组绑定参数,而不是用于单个语句的绑定参数。 这有效地允许数据库和网络将大批同质的插入,更新或删除作为单个操作而不是n个操作来处理。 数据库只需要执行最少的工作,因为只有一条语句,因此最多只有一个解析。 它也与语句缓存兼容,因此根本不需要进行语句解析。 限制是所有语句SQL必须相同。 因此,说插入1,000个Orders确实非常有用,因为每个Order的插入SQL是相同的,只有bind参数不同。 但这对插入1个订单或插入1个订单,1个OrderLine和1个客户没有帮助。 同样,所有语句必须是同一数据库事务的一部分。 动态批处理编写包括将一堆异构的动态SQL语句链接到一个块中,然后通过单个数据库/网络访问将整个块发送到数据库。 这样做的好处是只有一个网络访问权限,因此,如果数据库是远程的或通过慢速的网络访问,则可能会有很大的不同。 缺点是不允许参数绑定,并且数据库必须在接收到此庞大SQL块时对其进行解析。 在某些情况下,解析成本可能超过网络收益。 另外,动态SQL与语句缓存不兼容,因为每个SQL都不相同。 JDBC通过其Statement和PrepareStatement批处理API(从JDBC 2.0开始,很早以前就是JDK 1.2)标准化了批处理写入。 JDBC批处理API需要不同的JDBC代码,因此,如果您使用的是原始JDBC,则需要重写代码以在批处理和非批处理API之间切换。 现在,大多数JDBC驱动程序都支持这些API,但实际上并没有将DML批量发送给数据库,它们只是模拟API。 那么,如何知道您是否真的开始批量编写? 唯一真正的方法是对其进行测试,并衡量性能差异。 JPA规范没有标准化批写配置,但是大多数JPA提供程序都支持它。 通常,通过持久性单元属性在JPA中启用批处理写入,因此打开或关闭它是一个简单的配置问题,并且不需要更改编码。 一些JPA提供程序在使用开放式锁定时可能不支持批处理写入,并且可能不对SQL进行重新排序以使其能够进行批处理,因此即使启用了批处理写入,您仍可能无法进行批处理写入。 始终在打开和关闭批处理写入的情况下测试您的应用程序,并测量差异以确保其实际运行。 EclipseLink支持参数化和动态批处理编写(自EclipseLink 1.0起)。 在EclipseLink中,通过"eclipselink.jdbc.batch-writing"持久性单元属性启用了批处理写入。 EclipseLink提供了三个选项: "JDBC" , "Buffered"和"Oracle-JDBC" 。 应始终使用"JDBC"选项。 "
时间序列是按发生的时间先后顺序排列而成的数据,一般数据中会有一列是日期。时间序列分析的主要目的是根据已有的历史数据对未来进行预测。
在日常工作中,经常需要对时间序列数据做预测分析,预测分析就是根据现有的历史的数据来预估未知的未来的数据。例如,对下一年销量进行预测,以便做好业务规划。
Excel有个非常强大的功能——预测工作表,它就是基于历史时间数据来预测未来某时间段内的数据,并且会以图表的形式展示出来,从中能直观地看到预测的趋势。
下面通过一个案例看下如何使用Excel对时间序列数据进行预测分析。
下图是某服装实体店5月1日至5月24日每天的销量数据表,要求根据现有的销量数据预测接下来一个星期,也就是5月25到5月31日的销量。
1.单击销量数据中的任意单元格,点击【数据】-【预测工作表】
在弹出的“创建预测工作表”窗格中,可调整“预测结束”时间。因为在本案例中,只想预测到5月31日的销量数据,所以我对应地把“预测结束”时间调整为2020/5/31。
为了进一步了解 Excel 数据预测工作表的运行机制,我们把上图的“选项”展开,来看看其它参数的设置。除了上面提到的“预测结束”之外,Excel 的预测工作表还有以下几个主要参数:
预测开始:即从历史数据中的哪一天的数据开始进行预测;默认是从历史数据的最后一天开始预测,如案例中,默认从5月24日开始预测。当然,预测时间也可以手动调整,让其与历史数据有所重叠,有助于提高预测的准确性;
置信区间:也就是预测值的范围(预测的最大值-上限,预测的最小值-下限)默认是95%;该值越小,则上下限之间的范围越小;
季节性:周期性的规律,可以是自动检测或手动设置。设置一个周期数,比如12,表示每12个数据作为一个周期进行预测。需要注意的是,这里的“季节性”不是我们常规理解的“季节性”,而是历史数据所呈现的波动性和周期性。
例如:
3小时/为一个周期 3天/为一个周期 7天/为一个周期 11天/为一个周期 30天/为一个周期 …
在预测工作表中,“季节性”一般是可以自动检测出来的,但我们在点击“创建”前还是应该再次检查季节性的参数是否正确,否则需要手工调整。
如在本案例中,它已自动检测出“季节性”为7,也就是7天一个周期,所以,我并不需要手动设置为7,而直接用了“自动检测”。
日程表范围:就是历史数据里的时间数据;如本案例历史数据的日程表范围是“日期”列(A2:A25);
值范围:就是历史数据里用来计算预测的历史值;如本案例历史数据的值范围是列“销售量”列(B2:B25)。
使用以下方式填充缺失点:为了处理缺少点,Excel 使用插值,也就是说,只要缺少的点不到 30%,都将使用相邻点的权重平均值补足缺少的点。如果要改为将缺少的点视为零,可以单击列表中的“零”;
聚合重复项使用:如果数据中包含时间戳相同的多个值,比如是同 一日期的值有N个,那么Excel 将默认取这些值的平均值作为这时间戳的值。若要使用其他计算方法可从列表中选择所需的计算。
这么多参数不懂,怎么办?不要害怕,一般以上参数的设置,除了要调整“预测开始”“预测结束”或“季节性”的参数外,其他的默认即可。
2.在对上面的参数设置完成后,点击“创建”。
预测结果表会在原来数据表左侧生成的新工作表中呈现,预测结果图表如下所示,我们就预测到了5月25到5月31日的销量。
左侧的表格里,有趋势预测、置信下限(预测的最小值)、置信上限(预测的最大值),右边图表也对应着有趋势预测、置信下限、置信上限。
3.预测结果如何解读?
蓝色粗折线:是历史数据,对应着案例中5月1日到5月24日的销量数据;
最上面的黄色细线:叫做置信上限,即未来趋势的上限不超过此线,也就是说,数据最好的时候,就是置信上限这个数值;如5月25日的置信上限为245.34,即这天的销量最高能达到245件;
最下面的黄色细线:叫做置信下限,即未来趋势的下限不超过此线,也就是说,数据最差的时候,就是置信下限这个数值;如5月25日的置信下限为109.03,即这天的销量最低为109件;
上下两根黄色细线之间:叫做置信区间,即未来趋势在此区间中波动;如5月25日的销量就是在109.03-245.34之间波动;
中间黄色加粗线:叫做趋势线,即未来趋势最有可能沿此线的趋势发展;在案例中, 5月25日的销量最有可能是177件。
如果有对预测工作表有更多要求,可设置【置信区间】:设置预测值的上限和下限;置信区间值越小,上下限间的范围越小,反之,值越大上下限的范围越大。如下图是置信区间为95%和置信区间为80%的对比。
4.需要注意的地方
预测工作表要求有两列数据:历史时间列和历史值列。其中,时间列要求:必须均匀分布,也就是说,时间列必须为间隔相等的时序列。如下图。
5.总结
如何对时间序列数据进行预测分析?
Excel的“预测工作表”1秒就帮你搞定啦。
推荐:人工智能时代的必学技能
本文翻译自:Bootstrap 3 Glyphicons are not working
I downloaded bootstrap 3.0 and can't get the glyphicons to work. 我下载了bootstrap 3.0,无法让glyphicons工作。 I get some kind of "E003" error. 我收到某种“E003”错误。 Any ideas why this is happening? 任何想法为什么会这样? I tried both locally and online and I still get the same problem. 我在本地和网上尝试过,我仍然遇到同样的问题。 #1楼 参考:https://stackoom.com/question/1F4cm/Bootstrap-Glyphicons无效
#2楼 Note to readers: be sure to read @user2261073's comment and @Jeff's answer concerning a bug in the customizer. 读者注意:请务必阅读@ user2261073的评论和@ Jeff关于定制器中的错误的答案 。 It's likely the cause of your problem.
转载自图像处理中不适定问题(ill posed problem)或称为反问题(inverse Problem)
摘要 图像处理中不适定问题(ill posed problem)或称为反问题(inverse Problem)的研究从20世纪末成为国际上的热点问题,成为现代数学家、计算机视觉和图像处理学者广为关注的研究领域。数学和物理上的反问题的研究由来已久,法国数学家阿达马早在19世纪就提出了不适定问题的概念:称一个数学物理定解问题的解存在、唯一并且稳定的则称该问题是适定的(WellPosed)。如果不满足适定性概念中的上述判据中的一条或几条,称该问题是不适定的。
典型的图像处理不适定问题包括:图像去噪(ImageDe-nosing),图像恢复(Image Restorsion),图像放大(Image Zooming),图像修补(ImageInpainting),图像去马赛克(image Demosaicing),图像超分辨(Image super-resolution)等。
迄今为止,人们已经提出许多方法来解决图像处理中的不适定性。但是如何进一步刻画图像的边缘、纹理和角形等图像中重要视觉几何结构,提高该类方法在噪声抑制基础上有效保持结构和纹理能力是有待深入研究的问题。
1 不适定图像处理问题的国内外研究现状评述 由于图像处理中的反问题往往是不适定的。解决不适定性的有效途径是在图像处理中引入关于图像的先验信息。因此图像的先验模型对于图像反问题和其它计算机视觉还是图像处理问题至关重要。对于图像的先验模型的研究,研究者们从多个角度进行研究,其代表主要有“统计方法”和“正则化几何建模方法”,“稀疏表示方法”三种主流方法,而最近兴起的图像形态分量分析(MCA)方法吸引了大批国内外研究者的广泛关注。
1.1 正则化几何模型日新月异 关于自然图像建模的“正则化几何方法”是最近几年热点讨论的主题。其中一类方法是利用偏微分方程理论建立图像处理模型,目前的发展趋势是从有选择性非线性扩散的角度设计各类低阶、高阶或者低阶与高阶综合的偏微分方程,或者从实扩散向复扩散推广,从空域向空频域相结合以及不同奇异性结构的综合处理[1]。另一类方法是基于能量泛函最优的变分方法。
1992年,Rudin-Osher-Fatemi提出图像能被分解为一个属于有界变差空间的分量和一个属于 的分量 的全变差模型[2]。根据国际上及本人的研究表明:ROF模型模型较好地刻画了图像中视觉重要边缘结构,但不能描述纹理信息。2001年Meyer提出了振荡模式分解理论[2]:他认为振荡分量可以表示为某个向量函数的散度形式,而振荡分量可以属于3个可能的函数空间。首先引入有界变差(boundedvariational , BV)空间的一个近似对偶空间来表征图像的振荡分量;Meyer进一步指出John-Nirenberg的有界均值振荡空间和齐性Besov空间都是振荡分量比较合适的函数空间,由此导出了将图像分解的(BV,G)模型,(BV,F)模型和(BV,E)模型。Meyer从理论上基本解决了振荡分量的理论框架,成为纹理等振荡模式分解的奠基性工作,但是原始模型比较难计算。
后来的学者大都在Meyer工作的基础上展开工作。Vese-Osher提出将振荡分量建模为的向量场的散度来逼近(BV,G)模型[3],实质上是将G空间近似为负Soblev空间[4]。L.Lieu和L.Vese进一步推广到分数阶负Soblev空间[5]。Aujol,Chamboll等人定义了G-空间中的一个子空间,并根据Chamboll早期提出的ROF模型的投影算法的基础上,提出图像的振荡分量是在该子空间上的投影分量,由此提出了著名的BV空间半范+ G空间范数 + L2 范数约束优化的A2BC模型及子空间投影算法 [6-7]。J.B.Garnet,T.M.Le,Y.Meyer,L.A.Vese提出更一般的齐性Besov空间 来刻画振荡分量 [8]。
最近,.Aujol,A.Chamboll分别对TV范数、G范数、F范数、E范数,L 2范数对图像的卡通图像、纹理分量、高斯噪声进行数理统计和相关性分析,提出了分别运用TV范数、G范数和E范数分别来约束图像的卡通分量、纹理分量和噪声分量的三分量图像分解模型[9]。2007年,G.Gilboa和S.Osher受提出了非局部化G-空间的概念,并概括性的初步提出了非局部ROF模型、非局部Meyer模型、非局部ROF+L1模型[10],从理论上提供了图像先验模型研究的新思路。但综合目前研究来看,变分方法的主要不足是对于纹理和噪声的刻画还不够精细。
1.2 稀疏表示方兴未艾 图像的稀疏表示问题最早源于“有效编码假说”。Attneave最先提出:视觉感知的目标就是产生一个外部输入信号的有效表示。在神经生物学领域Barlow基于信息论提出了“有效编码假设”,认为初级视皮层神经细胞的主要功能就是去除输入刺激的统计相关性[11]。“有效编码假设”被提出以后,很多研究人员根据它的思想提出了不同的理论。主要思路分为两大类。直接方法是机理测试方法,即从生物机理上,在自然图像刺激条件下检测神经细胞的响应特性。著名的工作如:2001年在《Nature》上发表的研究结果表明,在冗余性测度和自然刺激条件下一组视网膜神经节对外界刺激独立编码[12];2000年在《Science》上发表了类似的成果[13]:通过记录短尾猿V1 区神经细胞在开放的自然场景和模拟自然场景条件下的神经细胞响应,验证了视皮层(V1区)神经细胞用稀疏编码有效表示自然场景,稀疏编码用最小冗余度传递信息。另外一个替代的方法是模型仿真方法,即利用自然图像的统计特性,建立模型模拟早期视觉处理系统的处理机制。例如Olshausen和 Field[14]提出了稀疏编码模型,稀疏编码理论表明,通过寻找自然图像的稀疏编码表示,该神经网络可以学习得到类似于简单细胞感受野的结构。Bell提出了基于信息最大化的无监督算法,通过度量“因子”的联合信息熵并且使之最大化,扩展了独立成分分析(ICA)方法,成功地构建有效编码模型并得到了与上面类似的结果[15]。Hyvarinen更进一步,应用一个两层的稀疏编码模型构造出类似于复杂细胞响应特性的基函数,而且基函数集合形成一个有规律的拓扑结构[16]。这部分表明有效编码假设也可适用于视觉系统高级区域神经细胞的处理过程。
目前关于图像稀疏表示系统的研究大体上沿着两条主线展开。其中一条是沿着多尺度几何分析理论。研究者认为图像的非平稳性和非高斯性,很难用线性算法进行处理,而应该建立合适的能够处理边缘到纹理各层面几何结构的图像模型;二维图像中的性状奇异性边缘和3-D图像中丝状物(filaments) 和管状物(tubes)几何特征不能被各向同性的“方块基”(如小波基)表示,而最优或者“最稀疏”的函数表示方法应该由各向异性的“锲形基”表征。因此以Ridgelet、Curvelet、Bandlet,Contourlet变换为代表的多尺度几何分析[16-22]理论成为图像稀疏表示的有效途径。图2.1.1(a)给出了二维可分离小波在不同分辨率下逼近曲线的过程,随着分辨率升高,尺度变细,最终表现为使用众多的“点”来逼近曲线。与小波相比,contourlet不仅具有小波的多分辨率特性和时频局部化特性,还具有很好的方向性和各向异性,即在尺度j时,小波基的支撑域边长近似为,而Contourlet的在该尺度下的基函数支撑域的纵横比可以任意选择。图2.1.1(b)为用Contourlet基函数的支撑域来逼近曲线的过程,由于它的基函数的支撑域表现为“长方形”,因而是一种更为有效稀疏的表示法。与二维可分离小波基函数的方向支撑域的各向同性不同,Contourlet基的“长方形”支撑域表现出来的是各向异性(anisotropy)的特点。上述稀疏表示方法都是采用“单一基”,另外一条图像稀疏表示的途径是:基函数被称之为原子库的过完备的冗余系统取代。Mallat和Zhang于1993年首先提出了信号在过完备库(over-completedictionary)上分解的思想[23]。通过信号在过完备库上的分解,用来表示信号的基可自适应地根据信号本身的特点灵活选取以得到信号非常稀疏的表示.后来人们提出了诸如基追踪算法、匹配追踪算法(MP)、正交匹配追踪算法(OMP)、混合匹配追踪算法(HMP)及许多变种。涉及的原子包括多尺度Gabor函数,各向异性的精细原子,小波和正弦函数的级联[24-15]等,并通过训练方法获得结构和纹理分量稀疏表示字典[26-28]。目前图像稀疏表示的研究也引起国内众多研究者的关注。中科院杨谦、汪云九等人,中科院计算所史忠植研究员,西安电子科技大学的焦李成教授、华南理工大学谢胜利教授,西南交通大学尹忠科教授等,南京理工大学韦志辉教授,肖亮博士等纷纷展开了稀疏表示的相关问题的研究。
目前图像稀疏表示的研究成为近3年国内众多研究者关注的热点问题,根据<<中国期刊全文数据库>>的检索来看,在2004年之前几乎没有相关报道,而从2004年1月至2008年2月,中国期刊发表的图像稀疏表示与多尺度几和分析应用方面的论文达到187篇,其中关于Ridgelet56篇,关于Contourlet 63篇,关于 Curvelet34篇,关于过完备稀疏表示34篇。西安电子科技大学的焦李成教授、华南理工大学谢胜利教授,西安交通大学尹忠科教授、国防科技大学王正明、教授及课题组成员等纷纷展开了基于稀疏表示的相关应用问题的研究[29-33]。本文作者在基于多尺度几何分析的图像增强、去噪、融合、边缘检测、感知压缩和数字水印等展开了相关应用研究,研究结果表明,基于稀疏表示的形态分量分解理论能够很好的捕获图像的几何特征,在图像建模和处理方面具有先天优势。但是综观国内的这些研究还与国外原创性成果具有很大差距。特别在稀疏表示字典的构造、高效稀疏分解算法、稀疏性重建等层面均有大量工作可做。
1.3 形态分量分析暂露头角 MCA方法是国际著名学者J.-L. Starck, M. Elad, D.L. Donoho在2004年提出的一种将图像分解为“几何结构”、“纹理”、“噪声”的形态分量分解方法[34]。该方法与混叠信号盲分离在本质上近乎相同,和独立分量分析(ICA)具有紧密联系。在MCA提出之前,图像分解的研究如火如荼。主要包括“基于稀疏表示的图像分解”和“基于变分方法的图像分解”。MCA方法较好的结合了变分方法和稀疏表示方法两类图像分解的优点,为不适定图像处理问题提供了良好的处理机制。首先从关于图像形态分量分解的变分方法来看,国际上研究的研究朝着对图像结构和纹理等形态成分刻画更精细、计算更简单的方向发展。图像分解的(BV,G)模型,(BV,F)模型和(BV,E)模型在本质上就是一种形态分量分析方法。
与基于变分方法的图像分解处理思路不同,J.L.Stack,M.Elad和D.L.Donoho的MCA框架中,一个重要的假设是图像的几何结构和纹理分量在某个特定的基库或过完备子字典下是类内稀疏的,而各形态分量稀疏表示的基库或过完备子字典之间具有不相干性。通过关于结构分量和纹理分量的分类稀疏表示稀疏的强稀疏性(l0范数或l1范数度量)达到图像形态分量的有效分离。由于目前所涉及的稀疏表示系统有三类:正交系统(如DCT,DWT);冗余系统(如Curvelet,Contoulet);过完备字典(如AR-Gauss混合字典)。随着稀疏表示理论的发展,通过不同的分类稀疏表示字典、稀疏性度量和正则化方法,可以导出不同的图像形态分量分析算法[35]。之后学者们对MCA中形态成分稀疏性和多样性[36]、自适应投影阈值选取[37]等问题作了研究,并推广到多通道情形[38]。
1.4 统计模型经久不衰 关于自然图像“统计建模方法”的研究由来已久。早期的研究工作,很大程度上受DavidField在20世纪80年代中期的一个重要发现所推动:自然图像的滤波器响应总是呈现出较大的峰度的统计性质[39]。经典小波分析之所以在信号和图像处理中取得重大成功,一个比较重要的因素是对小波变换域统计模型的研究取得重大进展,主要包括小波域的MRF模型,小波域隐马尔科夫模型和分层隐马尔科夫模型等。随着多尺度几何分析的兴起,人们对于Ridgelet、Curvelet、Bandlet,Contourlet变换域的统计模型相当关注。事实上,稀疏表示系数的直方图的峰度要远远大于3,呈现明显的非高斯性,这表明非高斯性蕴含图像的本质特性。例如,对Cameraman图像的Contourlet系数进行分析。观察上面的分布可以发现,Contourlet系数呈现明显的重尾分布。考察直方图的峰度(Kurtosis)经计算,峰度值远远大于典型的高斯分布Kurtosis值(大约为3)。许多单变量先验模型比如广义高斯模型、学生t-distribution模型已经被成功地用于自然图像的小波系数的这种非高斯统计特性。最近,学者们开始关注自然图像滤波器响应的联合统计行为。ZhuS.C较为全面的论述了自然图像视觉模式的四种主流的统计研究方法,并从信号的稀疏表示出发论述了包括多个Markov随机场模型及其变种[40]。焦李成等比较研究了多尺度变换域包括隐马尔科夫树(HMT)、背景隐马尔科夫模型(CHMM)等在内的10种统计模型[41]。基于形态分量分析的图像超分辨重建理论与算法 超分辨率重建(super-resolution reconstruction)是一种由一序列低分辨率退化图像重建一幅(或序列)高分辨率清晰图像的第二代复原技术[1]。超分辨率重建技术综合考虑成像过程中诸如运动变形、光学模糊、低采样率、随机噪声等等各种退化因素,在航空成像、遥感成像、医学成像、层析成像等众多领域具有广泛应用前景。从数学的角度看,图像超分辨率重建是Hardmard意义下的非适定数学反问题,因此成为图像处理、计算机视觉和计算调和分析等多学科领域国际上众多研究者关注的热点问题。
迄今为止,人们已经提出图像超分辨率重建的许多算法。但是如何进一步刻画图像的边缘结构、纹理等图像中重要视觉特征,提高图像超分辨算法对图像不同视觉特征的保持能力,解决超分辨问题的不适定性有待深入研究。图像超分辨是包含图像去噪、去模糊、去马赛克、图像放大等的组合问题,图像形态分量分析(MCA-Morphological Component Analysis)通过结合图像的稀疏表示(Sparcerepresentation)理论和变分方法进行图像分解,在图像超分辨应用中具有潜在优势:1)MCA通过分类稀疏表示字典将图像分解为“几何结构分量”、“振荡或纹理分量”、“噪声分量”,提供了良好的图像结构、纹理自适应处理和噪声分离机制;2)MCA继承了过完备稀疏表示与信号重建的优异性能,能够以最少的原子捕获图像中的高维奇异性特征。而这种捕获和跟踪机制是旋转、平移和伸缩不变的,因此对于超分辨重建的运动变形、光学模糊,低采样率的处理非常方便;3)MCA在稀疏表示的基础上,继承了图像几何正则化变分方法的优点,理论上为图像超分辨提供统一的变分框架。因此MCA理论为图像超分辨率复原提供了新的契机和研究思路。基于上述学术思想,本项目旨在通过不同基函数系统或过完备字典对图像形态分量的统计不相干性和稀疏性的研究,建立符合类内强稀疏而类间强不相干的几何结构和纹理分量稀疏表示子字典,提出更广义MCA框架下的稀疏性度量、非局部结构正则化和噪声先验度量模型,并在凸分析和稳健统计学思想下,提出MCA框架下联合处理图像放大、去噪、去模糊、去马赛克效应的超分辨重建模型,通过子空间投影和迭代收缩方法提出超分辨率重建的多步迭代算法。本项目对于推动超分辩重建、图像理解、稀疏表示理论等发展都有重要意义。
1.2 国内外研究现状及分析 MCA方法是国际著名学者J.-L. Starck, M. Elad, D.
文章目录 方法一:el-select方法二:安装插件 方法一:el-select <el-row :gutter="22"> <el-col :span="7"> <el-form-item label="省"> <el-select v-model="userForm.provinceId" placeholder="请选择" @change="queryProvinceDownCityList()"> <el-option v-for="(item,index) in provinceList" :label="item.cityname" :selected="item.id==userForm.provinceId" :value="item.id" :key="index"></el-option> </el-select> </el-form-item> <el-form-item label="市"> <el-select v-model="userForm.cityId" placeholder="请选择" @change="queryCityDownAreaList()"> <el-option v-for="(item,index) in cityList" :label="item.cityname" :selected="item.id==userForm.cityId" :value="item.id" :key="index"></el-option> </el-select> </el-form-item> <el-form-item label="区"> <el-select v-model="userForm.areaId" placeholder="请选择"> <el-option v-for="(item,index) in areaList" :label="item.cityname" :selected="item.id==userForm.areaId" :value="item.id" :key="index"></el-option> </el-select> </el-form-item> </el-col> </el-row> toRegister:function () { this.dialogFormVisible= true; var url = "/city/1"; this.$http.get(url).then((resp)=>{ if(resp.data.code == 20000){ console.
修改密码(将命令最后面的 “newpassword” 替换成你要改的新密码)
# cd /www/server/panel && python tools.py panel newpassword
最近一段时间,视频直播可谓大火。在视频直播领域,有不同的商家提供各种的商业解决方案,包括软硬件设备,摄像机,编码器,流媒体服务器等。本文要讲解的是如何使用一系列免费工具,打造一套视频直播方案。
视频直播流程 视频直播的流程可以分为如下几步:
采集 —>处理—>编码和封装—>推流到服务器—>服务器流分发—>播放器流播放
1.采集 采集是整个视频推流过程中的第一个环节,它从系统的采集设备中获取原始视频数据,将其输出到下一个环节。视频的采集涉及两方面数据的采集:音频采集和图像采集,它们分别对应两种完全不同的输入源和数据格式。视频采集的采集源主要有 摄像头采集、屏幕录制和从视频文件推流。
音频采集
音频数据既能与图像结合组合成视频数据,也能以纯音频的方式采集播放,后者在很多成熟的应用场景如在线电台和语音电台等起着非常重要的作用。音频的采集过程主要通过设备将环境中的模拟信号采集成 PCM 编码的原始数据,然后编码压缩成 MP3 等格式的数据分发出去。常见的音频压缩格式有:MP3,AAC,HE-AAC,Opus,FLAC,Vorbis (Ogg),Speex 和 AMR等。
音频采集和编码主要面临的挑战在于:延时敏感、卡顿敏感、噪声消除(Denoise)、回声消除(AEC)、静音检测(VAD)和各种混音算法等。
图像采集
将图像采集的图片结果组合成一组连续播放的动画,即构成视频中可肉眼观看的内容。图像的采集过程主要由摄像头等设备拍摄成 YUV 编码的原始数据,然后经过编码压缩成 H.264 等格式的数据分发出去。常见的视频封装格式有:MP4、3GP、AVI、MKV、WMV、MPG、VOB、FLV、SWF、MOV、RMVB 和 WebM 等。
图像由于其直观感受最强并且体积也比较大,构成了一个视频内容的主要部分。图像采集和编码面临的主要挑战在于:设备兼容性差、延时敏感、卡顿敏感以及各种对图像的处理操作如美颜和水印等。
2.处理 视频或者音频完成采集之后得到原始数据,为了增强一些现场效果或者加上一些额外的效果,我们一般会在将其编码压缩前进行处理,比如打上时间戳或者公司 Logo 的水印,祛斑美颜和声音混淆等处理。在主播和观众连麦场景中,主播需要和某个或者多个观众进行对话,并将对话结果实时分享给其他所有观众,连麦的处理也有部分工作在推流端完成。
如上图所示,处理环节中分为音频和视频处理,音频处理中具体包含混音、降噪和声音特效等处理,视频处理中包含美颜、水印、以及各种自定义滤镜等处理。
3.编码和封装 3.1编码 如果把整个流媒体比喻成一个物流系统,那么编解码就是其中配货和装货的过程,这个过程非常重要,它的速度和压缩比对物流系统的意义非常大,影响物流系统的整体速度和成本。同样,对流媒体传输来说,编码也非常重要,它的编码性能、编码速度和编码压缩比会直接影响整个流媒体传输的用户体验和传输成本。
视频编码的意义
原始视频数据存储空间大,一个 1080P 的 7 s 视频需要 817 MB
原始视频数据传输占用带宽大,10 Mbps 的带宽传输上述 7 s 视频需要 11 分钟
而经过 H.264 编码压缩之后,视频大小只有 708 k ,10 Mbps 的带宽仅仅需要 500 ms ,可以满足实时传输的需求,所以从视频采集传感器采集来的原始视频势必要经过视频编码。
基本原理
为什么巨大的原始视频可以编码成很小的视频呢?这其中的技术是什么呢?核心思想就是去除冗余信息:
1)空间冗余:图像相邻像素之间有较强的相关性
2)时间冗余:视频序列的相邻图像之间内容相似
3)编码冗余:不同像素值出现的概率不同
一,链路聚合的基本概念
产生背景:
1.随着网络规模的扩大,用户对骨干链路的带宽和可靠性提出了越来越高的要求。在传统技术中,常用更换高速率的接口板或者更换高速率接口板的设备的方式来增加带宽,但这种方案需要付出高额的费用,而且不够灵活。
2.采用链路聚合技术可以在不进行硬件升级的条件下,通过将多个物理接口捆绑为一个逻辑接口,来达到增加链路带宽的目的。在实现增大带宽的同时,链路聚合采用备份链路的机制,可以有效的提高设备之间链路的可靠性。
应用场景:
在企业网络中,所有设备的流量再转发到其他网络前都会汇聚到核心层,再由核心区设备转发到其他网络,或者转发到外网。所以,在核心层设备负责数据的高速交换时,容易发生拥塞。在核心层部署链路聚合,可以提升整个网络的数据吞吐量,解决拥塞问题。
如下:两台交换机SWA和SWB之间通过两条成员链路相互连接,通过部署链路聚合,可以确保SWA和SWB之间的链路不会产生拥塞。
链路聚合
解释:
1.链路聚合就是把两台设备之间的多条物理链路聚合在一起,当作一条逻辑链路来使用。这两台设备可以是一对路由器、一对交换机、或者是一台路由器和一台交换机。一条聚合链路可以包含多条成员链路,(注:在ARG3系列路由器和X7系列交换机上默认最多为8条)
2.链路聚合能够提高链路带宽。理论上,通过聚合几条链路,一个聚合口的带宽可以扩展为所有成员口带宽的总和,这样就有效地增加了逻辑链路的带宽。
3.链路聚合为网络提供了该可靠性。配置了链路聚合后,如果一个成员接口发生故障时,该成员接口的物理链路会把流量切换到另一条成员链路上。
4.链路聚合还可以在一个聚合口上实现负载均衡,一个聚合口可以把流量分散的多个不同的成员口上,通过成员链路把流量发送到一个目的地,将网络产生的拥塞的可能性降到最低。
二,链路聚合技术的的基本原理
链路聚合模式:
链路聚合模式包含两种模式:手工负载均衡模式和静态LACP(Link Aggreation Control Protocol)模式及
1.手工负载分担模式下,Eth-Trunk的建立、成员接口的加入由手工配置,没有链路聚合控制协议的参与。该模式下所有活动链路都参与数据的转发,平均分担流量,因此称为负载分担模式。如果某条活动链路故障,链路聚合组自动在剩余的活动链路中平均分担流量。当需要在两个直连设备之间提供一个较大的链路带宽而设备不支持LACP协议时,可以采用手工负载分担模式。ARG3系列路由器和X7系列交换机可以基于目的MAC地址,源MAC地址,或者基于源MAC地址和目的MAC地址,源IP地址,目的IP地址,或者基于源IP地址和目的IP地址进行负载均衡。
2.在静态LACP模式中,链路两端的设备相互发送LACP报文,协商聚合参数。协商完成后,两台设备确定活动接口和非活动接口。在静态LACP模式中,需要手动创建一个Eth-Trunk口,并添加成员口。LACP协商选举活动接口和非活动接口。静态模式也叫M:N模式。M代表活动成员链路,用于在负载均衡中转发数据。N代表非活动链路,用于冗余备份。如果一条活动链路发生故障,该链路传输的数据被切换到一条优先级高的备份链路上,这条备份链路转变为活动状态。
3.两种链路聚合模式的主要区别是:在静态LACP模式中,一些链路充当备份链路; 在手工负载均衡模式中,所以成员都处于转发状态。
数据流控制
1.在一个聚合口中,聚合链路两端的物理接口(即成员口)的所有参数必须一致,包括物理口的数量,传输速率,双工模式和流量控制模式。所有成员可以是二层接口或三层接口。
2.数据流在聚合链路上传输,数据顺序必须保持不变。一个数据六块可以看作是一组MAC地址和IP地址相同的帧。eg:两台设备的SSH或SFTP连接可以看作一个一个数据流。如果未配置链路聚合,只是用一条物理链路来传输数据,那么一个数据流中的帧总能按正确的顺序到达目的地。配置了链路聚合后,多条物理链路被绑成一条聚合链路,一个数据中的帧通过不同的物理链路传输。如果第一个帧通过一条物理链路传输,第二个帧通过另一条五路链路传输,这样一来,同一数据流的第二个数据帧就可能比第一个数据帧先到达对端设备,从而产生接收数据包乱序的情况。
3.为了避免这种情况发生,Etn-Trunk采用逐流负载分担的机制,这种该机制把数据帧的地址通过HASH算法生成HASH-KEY值,然后根据这个数值在Etn-Trunk转发表中寻找对的出接口,不同的MAC或IP地址,HASH得到的HASH-KEY值不同,从而出接口也就不同,这样既保证了同一数据流的帧在一条物理链路转发,又实现了流量在聚合组内各物理链路上的负载分担。逐流负载分担能保证报的顺序,但不能保证带宽利用率
注:负载分担的类型主要包括以下几种,用户可以根据具体应用选择不同的负载分担类型
1.根据报文的源MAC地址进行负载分担; 2.根据报文的目的MAC地址进行负载分担; 3.根据报文的源ip地址进行负载分担; 4.根据报文的目的IP地址进行负载分担; 5.根据报文的源MAC和目的MAC地址进行负载分担; 6.根据报文的源IP和目的IP地址进行负载分担; 7.根据报文的VLAN、源物理端口等对L2、IPV4、IPV6和MPLS报文进行增强型负载分担; 三,链路聚合的基本配置
二层配置:
[SWA]interface Eth-Trunk 1 [SWA-Eth-Trunk1interface GigabitEthernet0/0/1 [SWA-GigabitEthernet0/0/1]eth-trunk 1 [SWA-GigabitEthernet0/0/1]interface GigabitEthernet0/0/2 [SWA-GigabitEthernet0/0/2]eth-trunk 1 注意:
本例中,通过执行interface Eth-trunk 命令配置链路聚合。这条命令创建了-个Eth-Trunk口, 并且进入该Eth-Trunk口视图。trunk_ia用来唯- 标识一个Eth-Trunk, 该参数的取值可以是0到63之间的任何-一个整数。如果指定的Eth- Trunk口已经存在,执行interface eth-trunk命令 会直接进入该Eth-Trunk口视图。
配置Eth-Trunk口和成员口,需要注意以下规则:
1. 只能删除不包含任何成员口的Eth-Trunk口。 2. 把接口加入Eth-Trunk口时,二层Eth-Trunk口的成员 口必须是二层接口,三层Eth-Trunk口的成员口必须是三层接口。 3. 一个Eth-Trunk口最多可以加入8个成员口。 4.加入Eth-Trunk口的接口必须是hybrid接口 (默认的接口类型) 5.一个Eth-Trunk口不能充当其他Eth-Trunk口的成员口 6.
方法一:
run()函数中初始化和start timer。
void MyThread::run() { timer = new QTimer(); timer->setInterval(100); //这里要用setInterval来设置间隔 connect(timer,SIGNAL(timeout()),this,SLOT(timerOut())); timer->start(); this->exec(); } void MyThread::timerOut() { qDebug()<<"Current Thread ID:"<<QThread::currentThreadId(); } 方法二:
run()函数中初始化timer,其他函数start timer,定时器采用信号与槽采用Qt::DirectConnection连接,这样不会跳转到其他线程。
void MyThread::run() { timer = new QTimer(); connect(timer,SIGNAL(timeout()),this,SLOT(timerOut()),Qt::DirectConnection); startTimer(); exec(); } void MyThread::startTimer(){ qDebug()<<"Current Thread ID:"<<QThread::currentThreadId(); timer->start(1000); } void MyThread::timerOut() { qDebug()<<"Current Thread ID:"<<QThread::currentThreadId(); }
又隔段时间没写博客了,今天写下博客。之前在项目遇到要实现这样一个需求,如下图所示:
就是根据不同的状态呈现不同的颜色,一开始拿到这个需求的时候有点迷惑,后来自己查了下文档,发现可以这样做,废话不多说,直接上代码(相关逻辑代码可以忽略):
//template里面 <ul class="flex calendar_day font-ml flex"> <li v-for="(item, index) in calendarInfo.calendars" :key="item.id" :class="[ judgeFirstDay, item.approvalStatus === 0 ? 'finishing' : item.approvalStatus === 1 ? 'finish' : item.approvalStatus === 2 ? 'unfinished' : '' ]" >{{ item.day }}</li> </ul> // computed里面 judgeFirstDay() { let day = ""; if (this.calendarInfo.calendars[0]) { day = this.calendarInfo.calendars[0].week; } switch (day) { case 1: return "li_one"; break; case 2: return "li_two"; break; case 3: return "
前言 最近在工作中想完成一个java通过jdbc连接SQL Server数据库导出数据字典的功能时发现本地用jdk8和对应的SQL Server驱动(可通过SQLServer官网或者maven库下载-mssql-jdbc-8.2.2.jre8.jar)可以正常连接SQL Server2019,然后当我们导出jar包到项目中打算使用时,发现项目的环境是jdk1.6,这时程序与SQL Server2019无法正常建立连接,因为驱动是要在jre8的环境下才能运行的。这时我们就想换成jdk1.6支持的SQL Server驱动——sqljdbc4.jar,本以为换个驱动即可正常运行,结果发现接下来引发的异常竟让我折腾了一整天。
问题原因 jdk1.6因为安全套接字加密协议的不同,当连接SQL Server2014及以上版本时需要额外的jar包(bcpkix-jdk15on-1.60.jar和bcprov-ext-jdk15on-1.60.jar)和修改java.security(jdk目录下的/jre/lib/security/java.security)使其能成功使用我们引入的包
解决过程 开始时,直接换了jar包后连接本地的SQL Server2019直接报异常:
com.microsoft.sqlserver.jdbc.SQLServerException: 驱动程序无法通过使用安全套接字层(SSL)加密与 SQL Server 建立安全连接。错误:“java.lang.RuntimeException: Could not generate DH keypair”。 at com.microsoft.sqlserver.jdbc.SQLServerConnection.terminate(SQLServerConnection.java:1352) at com.microsoft.sqlserver.jdbc.TDSChannel.enableSSL(IOBuffer.java:1533) at com.microsoft.sqlserver.jdbc.SQLServerConnection.connectHelper(SQLServerConnection.java:1042) at com.microsoft.sqlserver.jdbc.SQLServerConnection.login(SQLServerConnection.java:817) at com.microsoft.sqlserver.jdbc.SQLServerConnection.connect(SQLServerConnection.java:700) at com.microsoft.sqlserver.jdbc.SQLServerDriver.connect(SQLServerDriver.java:842) at java.sql.DriverManager.getConnection(DriverManager.java:582) at java.sql.DriverManager.getConnection(DriverManager.java:185) Caused by: javax.net.ssl.SSLException: java.lang.RuntimeException: Could not generate DH keypair at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:190) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1747) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1708) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.handleException(SSLSocketImpl.java:1691) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1222) at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1199) at com.microsoft.sqlserver.jdbc.TDSChannel.enableSSL(IOBuffer.java:1483) 我在网上各种搜索发现大家都建议升级到jdk7+版本来解决,虽然这样一劳永逸,但是由于生产环境用的是1.6版本并不能轻易升级(很无奈,怪系统太旧了。。。),或者是使用低版本的SQL Server(2012版本或更低版本),但是博主希望的是在1.6版本下且所有SQL Server版本都能使用(还不是因为生产是1.6哇!orz)。由此开始了解决版本问题的漫漫长路。
下载上述列出的两个包后放入到jdk目录下jre\lib\ext
修改jre\lib\security\java.security:
找到“List of providers and their preference orders (see above):”下的security.
使用Unity简单实现RayMarching 前言 最近在玩ShaderToy,发现各种酷炫的效果都是只用数学公式计算出来的,心中膜拜之情溢于言表同时也深深自省:为啥不好好学数学呢😂。
附上ShaderToy链接:https://www.shadertoy.com/
效果 简单的使用RayMarching实现了一个兰伯特模型,接下来应该会持续研究RayMarching的😀
RayMarching算法思想 从相机发射n条射线,射线有一个采样的步长。当射线处在体纹理中时,每个步长采一次样,获取纹理值(实际上表示该点的密度值),计算光照,然后和该条射线当前累积的颜色值进行混合。
关于Ray tracing、Ray marching 、Ray casting的区别可以看看这个链接
https://www.zhihu.com/question/29863225
实现步骤 首先我们看一下RayMarch的过程,下面是pixel shader部分
float4 frag (v2f i ) : SV_TARGET { float3 worldPosition = i.worldPos; float3 viewDirection = normalize(i.worldPos - _WorldSpaceCameraPos.xyz); float3 lightDirection = normalize(UnityWorldSpaceLightDir(i.worldPos)); return raymarch (_WorldSpaceCameraPos.xyz,viewDirection,lightDirection); } 可以看到RayMarch需要一个发射起始点rayOrigin和一个光线方向rayDirection,通过DistanceFunction方法绘制形状
float4 raymarch (float3 rayOrigin, float3 rayDirection,float3 lightDir) { for (int i=0; i<256; i++) { float ray = DistanceFunction(rayOrigin); if(_Limit != 0) { if (distance(rayOrigin,ray*rayDirection)>250) break; } if (ray < _MinDistance) return float4 (lighting(rayOrigin,lightDir,rayDirection),1.
本文翻译自:Correct modification of state arrays in ReactJS
I want to add an element to the end of a state array, is this the correct way to do it? 我想在state数组的末尾添加一个元素,这是正确的方法吗? this.state.arrayvar.push(newelement); this.setState({arrayvar:this.state.arrayvar}); I am concerned that modifying the array in-place with push might cause trouble - is it safe? 我担心通过push就地修改数组可能会引起麻烦-是否安全? The alternative of making a copy of the array, and setState ing that seems wasteful. 复制数组和setState替代方法似乎很浪费。 #1楼 参考:https://stackoom.com/question/1m9h9/在ReactJS中正确修改状态数组
#2楼 The React docs says: React文档说: Treat this.
文章目录 Mysql 批量修改四种方式效率对比环境信息测试数据pom 依赖数据库初始化测试数据 批量修改方案第一种 for第二种 case when第三种 replace into第四种 ON DUPLICATE KEY UPDATE 测试代码效率比较总结 Mysql 批量修改四种方式效率对比 环境信息 mysql-5.7.12
mac pro
idea(分配最大内存2g)
测试数据 pom 依赖 <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.12</version> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.1.2</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency> </dependencies> 数据库 CREATE TABLE `people` ( `id` bigint(8) NOT NULL AUTO_INCREMENT, `first_name` varchar(50) NOT NULL DEFAULT '', `last_name` varchar(50) NOT NULL DEFAULT '', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 初始化测试数据 //初始化10w数据 @Test void init10wData() { for (int i = 0; i < 100000; i++) { People people = new People(); people.