如果遇到 http://localhost:8080/test访问出现这个异常This application has no explicit mapping for /error, so you are seeing this as a fallback.
可是已经检查了路径没有错误,那很有可能就是springboot没有扫描到自定义的controller
1.首先检查一下启动类和自定义类的位置是否正确,以确保springboot能够自动加载。 注意:springboot会自动扫描启动类同一个父目录下以及同一个父目录的子目录(侄子目录)的所有组件
2.检查一下controller类的注释是否正确 在controller类,用的注释是@RestController或者是@Controller + @ResponseBody,而非@Controller。
@RestController:所有方法定义的Response的响应体是String或者json时使用
@Controller + @ResponseBody:想要做页面跳转时使用,
如果需要部分方法返回值是String和json,则在类上添加 @Controller,在需要返回 String 和 json 的方法上添加 @ResponseBody 注解;
3.查看import的包是否正确 @RequestMapping("/test")
import org.springframework.web.bind.annotation.RequestMapping;
@RestController
import org.springframework.web.bind.annotation.RestController;
4.@RequestMapping(“xxx”) 的URL路径书写问题 注意不要有空格,并且必须在前面加上 “/”
5.检查项目启动端口配置是否正确
1.插件介绍 Day And Night插件。
该插件增加了根据用户的日程设置自动更改主题和配色方案的可能性。
2.安装方式 第一种方式,是在IDEA上搜索插件进行安装,会适配当前IDEA的版本。
第二种安装方式是使用离线插件进行安装。
插件下载地址:https://plugins.jetbrains.com/plugin/12006-day-and-night
3.使用方法 注意勾选"Enable automatic theme changes"才表示启用,可以在这里配置更换时间和主题。
前言 最近在做一个关于TCP的实验,需要了解TCP的seq和ack的发送机制,看了很多文章之后,再结合着实际的测试,归纳出了seq和ack的计算方法
这里不得不说一句,关于怎么计算seq和ack网上的教程和文章实在是太少了,一搜TCP,出来的就是三次握手和四次挥手,难道TCP只需要握手和挥手就行了吗。
结论 先说结论:
在已经建立好连接的TCP上(只考虑数据包和ack包),seq和ack的计算规则为
本次要发送的包的 seq = 上一个发送的包的seq + 上一个发送的包的长度(不含包头)
本次要发送的包的 ack = 上一个接收到的包的seq + 上一个接收到的包的长度(不含包头)
分析 按照我的理解,seq和ack都是指针 。seq指示要发送的包在窗口中的起始位置 ,ack指示已经接收的包的位置
下面我就用我wireshark抓的包和画的实例图一起分析一下
第一个包: 第一个包是 客户端 发向 服务器 的数据包,长度为 517 字节
首先,seq和ack的值都是1,这是握手后的状态。
然后,第一个包对应TCP流行图的第四行
此时要发送的数据包的起始位置是1,还没有已经接收到的数据包,所以ack 也为 1。
第二个包 再第一个包发完之后,客户端的seq(下一个要发送数据的其实位置)要后移 517 字节
第二个包是 服务器 发向 客户端 的ack包
服务器的接收窗口收到数据,所以ack = 已收到的字节 = 1 + 517 = 518 = 上一个收到的包的seq + 包长
由于服务器并没有发送数据,所以seq(下一个要发送数据起始位置)保持不变
客户端接收到了ack包,但是这个包没有数据,所以客户端的接收窗口不变。
第三个包 第三个包是 服务器 发往 客户端 的数据包 长度为 96
seq(发送数据的起始位置)= 1;
关于TabLayout+ViewPager2的使用以及相关问题点 1.前言2.特点3.代码及说明3.1.先上效果图3.2.代码如下 4.问题点4.1.导入依赖冲突4.2.默认选中问题4.3.源码 5.最后 1.前言 最新项目需要用到TabLayout+ViewPager实现对应的功能,后来发现ViewPager的实现方法被废弃掉了(虽然还可以用,但有坑后面说),Google推荐用新一点的ViewPager2来代替,下面来谈谈我用到的。 2.特点 实现标题栏和内容联动切换用多个TabLayout关联多个fragment页面 3.代码及说明 3.1.先上效果图 3.2.代码如下 3.2.1.首先在app的build.gradle文件下加入依赖
implementation 'androidx.viewpager2:viewpager2:1.0.0' implementation "com.google.android.material:material:1.1.0" 3.2.2.activity的布局如下:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> //这里省略了toolbar ... <com.google.android.material.tabs.TabLayout android:id="@+id/tab_layout" android:layout_width="match_parent" android:layout_height="wrap_content" app:tabBackground="@color/transparency_color" app:tabIndicator="@color/text_FB6137" app:tabIndicatorColor="@color/text_FB6137" app:tabMode="scrollable" app:tabRippleColor="@color/transparency_color" app:tabSelectedTextColor="#333333" app:tabTextColor="@color/text_normal_color"> </com.google.android.material.tabs.TabLayout> <androidx.viewpager2.widget.ViewPager2 android:id="@+id/viewPager" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginTop="@dimen/margin_10" /> </LinearLayout> 3.2.3.activity类的主要代码如下
private String[] mTitles = {"关注","收藏","点赞👍"}; @Override public void initData() { for (int i = 0; i < mTitles.length; i++) { mTabLayout.addTab(mTabLayout.newTab().setText(mTitles[i]), false); } mTabLayout.
九连环是一种流传于山西省的传统民间的智力玩具,由九个圆环相连成串,以解开为胜。
九连环的九个环,一环扣一环地套在钗上。除了第 1 号环可以随时装上或卸下以外,其它环装上或卸下的条件是:在它的前面仅有紧靠它那一个环在钗上。即:当第 1 ~ i−2 号环都不在钗上,第 i−1 号环在钗上,这时可以装上或卸下第 i 号环。
输入格式
环数 操作(U表示装上, D表示卸下)
输出格式
装上或卸下九连环的操作步骤
每行显示一步操作,具体格式为:
环号: U或D (U表示装上,D表示卸下)
#include<stdio.h> //1~i-2不在杆上,i-1在杆上,i可装上或取下 void down(int n); void on(int n){ if(n>1) on(n-1); //i-1装在杆上 if(n>2) down(n-2); //i-2从杆上卸下 printf("%d: U",n); //输出装上 if(n>2) on(n-2); //i-2装在杆上 } void down(int n){ if(n>2) down(n-2); //i-2从杆上卸下 printf("%d: D",n); //输出卸下 if(n>2) on(n-2); //i-2装上杆上 if(n>1) down(n-1); //i-1从杆上卸下 } int main(){ char a[2]; scanf("%c %c",&a[0],&a[1]); //cin>>a[0]>>a[1]; int n=a[0]-'0'; if(a[1]=='U') on(n); else down(n); return 0; }
1. FFMpegSDK下载 下载FFMpegSDK,我在官网上找了好久,现在应该在官网上下载不了,于是就在CSDN上使用积分下载了一下,下载链接:FFMpegSDK
下载解压后:
把shared里面的bin文件复制到dev文件中
bin文件中的.dll文件
复制后的dev文件
2. 建立vs工程 建立头文件
配置属性页>>VC++目录>>包含目录
配置属性页>>VC++目录>>库目录
把刚才的dev中include路径和lib路径分别放入包含目录和库目录中。
配置属性页>>链接器>>输入>>附加依赖项
把lib文件夹里面的lib文件添加进附加依赖项中
avcodec.lib
avdevice.lib
avfilter.lib
avformat.lib
avutil.lib
postproc.lib
swresample.lib
swscale.lib
把bin中的文件复制到项目文件中,把测试视频也放入
环境配置完成
注意
属性页中的两点:
字符集一定改成多字节的
SOL检查改成否
3. 程序 获取视频流程序:
int getStream(AVFormatContext **fmt_ctx, AVCodecContext **dec_ctx, const char* file_name) { int video_stream_index = -1; int ret; bool decoder_init = false; //打开视频文件 if ((ret = avformat_open_input(fmt_ctx, file_name, NULL, NULL)) < 0) { av_log(NULL, AV_LOG_ERROR, "fail to open input file.\n"); return ret; } //获取流信息 if ((ret = avformat_find_stream_info(*fmt_ctx, NULL)) < 0) { av_log(NULL, AV_LOG_ERROR, "
在很多语言中,都会利用“目录”来规范开发者分层的逻辑。
比如Javaweb中,会将目录分为Controller,Service,Dao,Model等等。
利用目录的形式对开发者进行约束,能够使代码整体结构更加清晰,功能分工更加明确。
我一直“以为”我对分层的感受能力还是很强的,但是回顾上星期写的代码,才让我感觉我对分层的理解一直停留在表面。
大家都知道:
在逻辑上,可能使用概念分层,比如AO,DAO;
在功能上,可能使用模块名进行约束,比如xxx_order、xxx_log;
进一步到代码上,利用目录进行分层,比如xxx_logic、xxx_model;
但是,我觉得上述的方式对于开发者来说(尤其是团队协作),都太宽泛了,对实际开发行为上难以进行“接口级别的约束”,但团队开发,互调接口却是很常见的。
如果在一开始并没有明确、协商好接口的参数返回值,就需要开发者自己理解不同层面的接口应该传递哪种粒度的对象。(我觉得主导者预先设计好接口是必要的,但是执行者自己也能理解其深意也是必须的)。
以我当前参与的项目为例,我需要实现model层(我理解为数据访问层)的逻辑功能,(代码)分层如下:
顶层的Account提供给外部使用,封装了账户的所有操作(流水只是账户变动的附加记录,理论上也是Account本身的熟悉),Account再利用AccountTable操作具体的账户表,利用DetailTable操作具体的流水表。
分层非常清晰,但是真正写起来会有很多“操作粒度”层面的问题(设计者没有提供接口的参数,需要我自己去思考)。
比如:
修改时的幂等校验,放在Account里面还是两个Table对象里面?为什么?可以将查询的参数filter对外提供吗?在接口上作为参数传递进来(filter类似一个Map,相当于mysql where条件的实例)不同的数据状态,在Account就进行(统一)分支还是下沉到两个Table中?
…… 上面的问题似乎跟分层无关,但是我觉得这是“概念分层”无法掌控的细粒度分层。
如果把幂等校验放在Account里面,需要同时对AccountTable和DetailTable进行幂等校验,这时候需要操作两次数据库。将“意外拦截在了最外层”似乎很美好。
但是,当幂等校验通过后,进入到两个Table中之后,又要重复操作一次数据库,拿到在Account就已经拿到的对象,这显然非常不好,当然可以选择在Account就把参数传递下去,但是一开始没想到呢?
我一开始就是把filter提供给了外部,这样对于查询,我只需要写一个接口,外部想要查询什么,自己构造filter即可。但是这个很容易想到,破坏了功能上的封装性,调用者需要熟悉库表结构才能准确操作该接口,这显然加大了整体的开发难度。
我一开始是在Account中进行统一分层,但是统一分层会使得局部代码快速膨胀,分支过多难以理解,结构不清晰,最终选择各个方法自行处理状态分支。
我觉得,分层应该不仅仅是宏观层面的概念,不能停留在目录分层的层面。
对个人来说,实现时的逻辑分层更重要,开发阶段就应该注意逻辑分层的抉择,尽量满足开闭原则,才能写出容易理解、结构清晰、易扩展的代码。
svn简单使用 1.安装svn,自行百度,然后准备下拉!
填入svn地址!
进入到svn
选择下拉的文件进行checkout下拉
选择导出文件位置:
进行导出,然后修改文件
上传:(先进行add,在commit)
其他操作:
没了!!!(其他高级操作不会,比如代码冲突如何合并,忘了)
crm:用户关系管理系统 CRM 系统模块划分 环境搭建与测试 1.新建项目
2.引坐标,插件
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.2.2.RELEASE</version> </parent> <!-- web 环境 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- aop --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency> <!-- freemarker --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-freemarker</artifactId> </dependency> <!-- 测试环境 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!-- mybatis --> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.1.1</version> </dependency> <!-- 分⻚插件 --> <dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper-spring-boot-starter</artifactId> <version>1.2.13</version> </dependency> <!-- mysql --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <!-- c3p0 --> <dependency> <groupId>com.
这系列的文章是我对Pytorch入门之后的一个总结,特别是对数据集生成加载这一块加强学习
另外,这里有一些比较常用的数据集,大家可以进行下载:
需要注意的是,本篇文章使用的PyTorch的版本是v0.10.0
《深度学习常用的数据集,包括各种数据跟图像数据》
《kaggle猫狗大战[包含训练(25000张猫狗照片)和测试数据集(12500张猫狗照片)》
目录
一、加载已被集成在Pytorch中的数据集 1、torchvision和torchvision.datasets:数据集
2、torchvision.transforms和torchvision.transforms.Compose:图像预处理
torchvision.transforms.ToTensor()
torchvision.transforms.Normalize(mean, std, inplace=False) 3、torch.utils.data.DataLoader和torch.utils.data.Dataset
torch.utils.data.DataLoader
torch.utils.data.Dataset
二、加载自定义数据集
1、torchvision.datasets.DatasetFolder
2、torchvision.datasets.ImageFolder
三、加载本地kaggle猫狗数据集
一、加载已被集成在Pytorch中的数据集 在这第一大块的内容中,可以了解到几个函数:
torchvision和torchvision.datasets
torchvision.transforms和torchvision.transforms.Compose
torch.utils.data.DataLoader / DataLoaderIter和torch.utils.data.Dataset
1、torchvision和torchvision.datasets:数据集 《PyTorch如何加载数据集(自定义数据集)》这篇博客通过代码展示了Pytorch加载数据集的两种方法,对于已被集成在Pytoch内的数据集:比如CIFAR-10,CIFAR-100,MNIST等等,此类数据集可以直接使用Pytorch的内置函数(torchvision.datasets.XXX来直接加载)
Pytorch中官方文档对torchvision的解释:torchvision — Torchvision 0.10.0 documentation (pytorch.org)
这个Pytorch中的一个库,torchvision包包含了一些比较流行的数据集(datasets)、模型架构(model architectures)和用于计算机视觉常见的图像转换(image transformations for computer vision)
另外这里还有一些比较常见的库,例如:
torchtext:包含数据处理的实用工具和自然语言处理方面的的流行数据集torchaudio:包含一些音频I/O,音频方面的转化和流行的数据集…… Pytorch中官方文档对torchvision.datasets的解释:torchvision.datasets — Torchvision 0.10.0 documentation (pytorch.org)
所有的数据集都是torch.utils.data.Dataset的子类,就是说这些数据集已经实现了__getitem__()“返回索引”和__len__“返回长度”的方法。因此它们都可以传递给torch.utils.data.Dataset,它可以使用torch.multiprocessing并行加载多个样本
比如:
imagenet_data = torchvision.datasets.ImageNet('path/to/imagenet_root/') # 图片集的路径 data_loader = torch.utils.data.DataLoader(imagenet_data, batch_size=4, shuffle=True, num_workers=args.nThreads) 所有的数据集都使用相同的API,同时都用两个常见的参数transform和target_transforms去将输入(X)和标签(Y)分别进行张量转换
不过你也可以使用base classes创造自己的数据集
回到这里来……
对于加载已被集成在Pytoch内的数据集,我们以CIFAR为例(通过下面程序进行加载 torchvision.datasets.CIFAR10):
对于其中参数如下:
目录
大概就是:
说一下我的案例
下面开始引入主题:如果利用replace替换包
先解释下go mod 的 replace 关键字是怎么使用的
为什么需要 replace?
replace怎么用?
参数说明:
大概就是: 1、我遇到了 go get 不到包的情况
2、需要用 go.mod 的 replace 来解决因为go get 不了远程包,然后需要下载远程包,如果远程包有go.mod,那你就只能再通过 replact来引入远程包的问题。(重点,主题)
说一下我的案例 我需要下载腾讯tpns的go sdk包 地址:https://cloud.tencent.com/document/product/548/58319 选择go就会进入下图页面
然后我尝试使用 go get 去下载
go get git.code.tencent.com/tpns/tpns-server-sdk/gosdk 结果报错,那我就去下载sdk包文件到我本地,我直接本地使用总可以了吧?
下载后的样子是这样的,一个文件gosdk,然后里面有各种文件。如下图:
然后我把它放在我项目中的pkg(一般包我都会放这里)
他也没有报错,也可以调用。
但是当我bee run 或者 go run 的时候,就提示报错了
报错的意思就是找不到这个下载下来的gosdk包
因为它里面有一个mod文件, 一般是不能mod包引入另一个mod包的,只能通过go.mod文件中replace来做引入
下面开始引入主题:如果利用replace替换包 我看到我下载的远程包里面有个go.mod文件写着包名:git.code.tencent.com/tpns/tpns-server-sdk/gosdk
所以我首先去我的本地go mod 目录中,创建以下路径,然后把gosdk包移动进去,如下图:
先解释下go mod 的 replace 关键字是怎么使用的 为什么需要 replace? 答案:手动添加go get 不出来的地址
replace怎么用? 1、需要下载你go get 的那个包到本地
目录
一、第1问
1.1 图像预处理MATLAB程序
1.2 龙格库塔法求解微分方程初始化函数MATLAB程序
1.3 不考虑飞船飞行角度调整时计算轨迹并绘图MATLAB程序 二、第2问
2.1 考虑飞船飞行角度调整时计算轨迹并绘图MATLAB程序
2.2 实现粗避障MATLAB程序
2.3 实现细避障MATLAB程序
一、第1问 1.1 图像预处理MATLAB程序 %% 图像处理 A=imread('附件3 距2400m处的数字高程图.tif'); surf(A); set(gca,'FontSize',22); shading interp; colorbar; colormap gray; figure B=imread('附件4 距月面100m处的数字高程图.tif'); mesh(B); set(gca,'FontSize',22); shading interp; colorbar; colormap gray; 1.2 龙格库塔法求解微分方程初始化函数MATLAB程序 %微分方程组 function df=odefun(t,y,ai) G=6.67259e-11;%引力常量 M=7.3477e22;%月球质量 m0=2400;%飞行器质量 r=1737.013e3;%月球半径 a=15e3;%近月点距离 b=100e3;%远月点距离 Fmax=7500;%最大推力 rA=r+a;%椭圆短半轴 rB=r+b;%椭圆长半轴 VB=sqrt(2*G*M*(rA/(rB*(rA+rB))));%远月点速度 VA=(rB/rA)*VB;%近月点速度 df=zeros(4,1); yy=y(1);dy=y(2);xx=y(3);dx=y(4); m=7500/3087*t; df(1)=dy; df(2)=G*M/(yy^2)-Fmax*sind(ai)/(m0-m); df(3)=dx; df(4)=-Fmax*cosd(ai)/(m0-m); % df(1)=dy; % df(2)=-G*M/(xx^2+yy^2)*cosd(atand(xx/yy))+Fmax*sind(ai)/(m0-m); % df(3)=dx; % df(4)=-G*M/(xx^2+yy^2)*sind(atand(xx/yy))-Fmax*cosd(ai)/(m0-m); end 1.
Given a linked list, swap every two adjacent nodes and return its head. You must solve the problem without modifying the values in the list's nodes (i.e., only nodes themselves may be changed.)
Example 1:
Input: head = [1,2,3,4] Output: [2,1,4,3] Example 2:
Input: head = [] Output: [] Example 3:
Input: head = [1] Output: [1] Constraints:
The number of nodes in the list is in the range [0, 100].
介绍 MySQLJavaDATEjava.sql.DateTIMEjava.sql.TimeYEARjava.sql.DateDATETIMEjava.sql.TimestampTIMESTAMPjava.sql.Timestamp Date A date. The supported range is ‘1000-01-01’ to ‘9999-12-31’. MySQL displays DATE values in ‘YYYY-MM-DD’ format, but allows you to assign values to DATE columns using either strings or numbers.
只记录日期信息,表示范围为1000-01-01 至 9999-12-31。
MySql 按照YYYY-MM-DD 的方式进行该类字段的显示。添加该类字段数据,即可以使用字符串类型,也可以使用数字类型
由于Date类型的字段只记录日期信息,所以如果添加的数据中包含了时间信息,该时间信息将会自动被截断。
如果要保存时间信息,可以考虑使用DateTime类型。
经过测试,发现如下2种方式可以对Date类型字段进行填充:
按字符串:
insert into time_table(CreateDate) values(‘2007-04-09’)
按数字:
insert into time_table(CreateDate) values(20070409)
获取可以用java.sql.Date类型获取
DateTime A date and time combination. The supported range is ‘1000-01-01 00:00:00’ to ‘9999-12-31 23:59:59’. MySQL displays DATETIME values in ‘YYYY-MM-DD HH:MM:SS’ format, but allows you to assign values to DATETIME columns using either strings or numbers.
题目: Given n pairs of parentheses, write a function to generate all combinations of well-formed parentheses.
Example 1:
Input: n = 3 Output: ["((()))","(()())","(())()","()(())","()()()"] Example 2:
Input: n = 1 Output: ["()"] Constraints:
1 <= n <= 8 解法: 解法一:
其实这个跟上一个电话号码的题类似,我的思路是假设原字符串为(),则新加入的一对括号有三个位置,第一个字符之前(最前面)、第二个字符之前(中间)和第二个字符之后(最后面)。假设原字符串为()(),则新加入的一对括号有五个可能的位置,即第一个字符之前、第二个字符之前......第四个字符之后。
但是由于我用了两个集合,所以空间占用较多,仅少于10.75%的python3提交者
def generateParenthesis(self, n: int) -> List[str]: r=set(['()']) s=set() i=1 while(i<n): for item in r: for j in range(0,len(item)): str_list = list(item) str_list.insert(j, '()') s.add(''.join(str_list)) r=s.copy() s.clear() i+=1 return list(r) 解法二:
linux之粘贴代码或者注释时,被强制都改为注释的解决办法 直接通过vim打开脚本,然后粘贴进去后,发现,内容全部乱序,如有注释也会被之后改成注释,故此可通过以下方法:
sudo cat > /tmp/test.py <<eof import os,sys import pexpect for line in open('fstab'): str1 = line.split(' ') ext4_name = str1[0] ext4_file = str1[1] # print(line) print(f'------{ext4_name} {ext4_file}--------') print(ext4_name) print(ext4_file) process = pexpect.spawn(f'sudo mkfs.ext4 {ext4_name}') process.expect('anyway? (y,N)') process.sendline('y') process.expect('~$') process.sendline(f'sudo mount {ext4_name} {ext4_file} ') while process.expect('mount(2) system call failed: Structure needs cleaning.'): process = pexpect.spawn(f'sudo mkfs.ext4 {ext4_name}') process.expect('anyway? (y,N)') process.sendline('y') process.expect('~$') process.sendline(f'sudo mount {ext4_name} {ext4_file} ') eof
解决办法 文章目录 解决办法1、控制面板---程序---程序与功能---启用或关闭windows功能2、此电脑---右键---管理---服务与应用程序---服务,禁用下列服务,如图3、win+R,输入gpedit.msc4、打开win+X(Windows PowerShell选择管理员)5、控制面板---程序---程序与功能---查看已安装的更新 1、控制面板—程序—程序与功能—启用或关闭windows功能 首先,检查Hyper-v是否关闭,如下图即可
然后,启用Windows虚拟机监控平台与虚拟机平台,我第一次没有启用虚拟机平台,导致总是失败。如下图
2、此电脑—右键—管理—服务与应用程序—服务,禁用下列服务,如图 3、win+R,输入gpedit.msc 计算机配置—管理模板—系统—Device Guard–打开基于虚拟化的安全—禁用
4、打开win+X(Windows PowerShell选择管理员) 输入 bcdedit /set hypervisorlaunchtype off
5、控制面板—程序—程序与功能—查看已安装的更新 找到最新的更新,删除。
测试运行python文件异常现象 django.core.exceptions.ImproperlyConfigured: Requested setting LOGGING_CONFIG, but settings are not configured. You must either define the environment variable DJANGO_SETTINGS_MODULE or call settings.configure() before accessing settings. 解决方法: from django.conf import settings settings.configure(DEBUG=True) 测试运行服务出现WARNINGS:提示 1:URL namespace 'djdt' isn't unique. You may not be able to reverse all URLs in this namespace 在对应的URL.py文件中添加 app_name = ''
1、类介绍 java.util.concurrent.CountDownLatch
一个同步辅助类,在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待。
用给定的计数 初始化 CountDownLatch。由于调用了 countDown() 方法,所以在当前计数到达零之前,await 方法会一直受阻塞。之后,会释放所有等待的线程,await 的所有后续调用都将立即返回。这种现象只出现一次——计数无法被重置。如果需要重置计数,请考虑使用 CyclicBarrier。
2、使用场景 在一些应用场合中,需要等待某个条件达到要求后才能做后面的事情;同时当线程都完成后也会触发事件,以便进行后面的操作。 这个时候就可以使用CountDownLatch。CountDownLatch最重要的方法是countDown()和await(),前者主要是倒数一次,后者是等待倒数到0,如果没有到达0,就只有阻塞等待了。
3、方法说明 COUNTDOWN public void countDown()
递减锁存器的计数,如果计数到达零,则释放所有等待的线程。如果当前计数大于零,则将计数减少。如果新的计数为零,出于线程调度目的,将重新启用所有的等待线程。 如果当前计数等于零,则不发生任何操作。
AWAIT public boolean await(long timeout,
TimeUnit unit)
throws InterruptedException
使当前线程在锁存器倒计数至零之前一直等待,除非线程被中断或超出了指定的等待时间。如果当前计数为零,则此方法立刻返回 true 值。 如果当前计数大于零,则出于线程调度目的,将禁用当前线程,且在发生以下三种情况之一前,该线程将一直处于休眠状态:
由于调用 countDown() 方法,计数到达零;或者其他某个线程中断当前线程;或者已超出指定的等待时间。 如果计数到达零,则该方法返回 true 值。
如果当前线程:
在进入此方法时已经设置了该线程的中断状态;或者在等待时被中断, 则抛出 InterruptedException,并且清除当前线程的已中断状态。
如果超出了指定的等待时间,则返回值为 false。如果该时间小于等于零,则此方法根本不会等待。
参数:
timeout - 要等待的最长时间
unit - timeout 参数的时间单位。
返回:
如果计数到达零,则返回 true;如果在计数到达零之前超过了等待时间,则返回 false
抛出:
InterruptedException - 如果当前线程在等待时被中断
自从java5中引入注解以来,注解的使用就变得非常普遍,并在各个框架和项目中广泛使用,不过注解在同一个地方不能多次使用。为此,JDK8引入了重复注解的概念,允许在同一个地方使用同一个注解。在JDK8中使用@Repeatable注解定义重复注解。
重复注解的使用步骤:
1、定义重复注解容器注解
@Retention(RetentionPolicy.RUNTIME) @Interface Mytests{ MyTest[] value; } 2、定义一个可以重复的注解
@Retention(RetentionPolicy.RUNTIME) @Repeatable(MyTests.class) @interface MyTest{ String value(); } 3、配置多个重复的注解
@MyTest("tbc") @MyTest("tba") @MyTest("tbb") public class Demo1{ @MyTest("mbc") @MyTest("mba") publiv void test() throws NoSuchMethodException{ } } 4、解析得到指定注解
案例:
//1、定义注解的容器 @Retention(RetentionPolicy.RUNTIME) @interface MyAnno { MyAnnotation[] value(); } //2、定义重复注解 @Retention(RetentionPolicy.RUNTIME) @Repeatable(MyAnno.class) @interface MyAnnotation { String value(); } //使用注解 @MyAnnotation("类上的注解1111") @MyAnnotation("类上的注解2222") @MyAnnotation("类上的注解3333") public class AnnotationTest { @Test @MyAnnotation("方法上的注解1111") @MyAnnotation("方法上的注解22222") public void test() throws NoSuchMethodException { //得到类上的注解 MyAnnotation[] tests = AnnotationTest.
图1:智慧校园物联网管理平台建设方案
一、智慧校园背景
近年来国家为了加快推进教育现代化、教育强国建设,以及积极推动“互联网+教育”的普及,国家教育部及国家标准委相继出台了《教育信息化2.0行动计划》、《中小学数字校园建设规范(试行)通知》及《智慧校园总体框架》等政策及标准。力争到2022年基本实现“三全两高一大”的发展目标,即教学应用覆盖全体教师、学习应用覆盖全体适龄学生、数字校园建设覆盖全体学校,信息化应用水平和师生信息素养普遍提高,建成“互联网+教育”大平台。
在教育部发布的《教育信息化2.0行动计划》文件中明确指出“智慧教育创新发展行动”要以人工智能、大数据、物联网等新兴技术为基础,依托各类智能设备及网络,积极开展智慧教育创新研究和示范,推动新技术支持下教育的模式变革和生态重构。
《中小学数字校园建设规范(试行)通知》中明确,数字校园建设应达成如下目标:一是实现校园环境数字化。利用云计算、大数据、物联网、移动通讯、人工智能等信息技术,实现从基础设施(网络、终端、教室等)、资源(教材、图书、讲义等)到应用(学习、教学、管理、生活等)的数字化。
同时国家市场监督管理总局、中国国家标准化管理委员会发布的《智慧校园整体框架》已在2019年1月1日起正式实施,该框架标准要求学校实现智能感知、智能控制、智能管理。
传统的校园管理方式已经不适应现代化教学的需要,基于物联网技术集智慧课堂、环境调节、用电安全、智慧消防等及远程控制于一体的新型现代化智慧校园、智慧教室系统在逐步的推广运用。
图2:目录
1.智慧校园2.0政策标准
2.智慧校园2.0体系架构
3.智慧校园智能感知定义
4.物联网相关的技术
5.智慧校园设备及安全管理常见问题
6.智慧校园物联网解决方案
二、智慧校园2.0政策标准
图3:智慧校园政策和标准
教育信息化2.0行动计划是在历史成就基础上实现新跨越的内在需求。是顺应智能环境下教育发展的必然选择。是充分激发信息技术革命性影响的关键举措。教育信息化2.0行动计划是加快实现教育现代化的有效途径。没有信息化就没有现代化,教育信息化是教育现代化的基本内涵和显著特征,是“教育现代化2035”的重点内容和重要标志。
《中小学数字校园建设规范(试行)》是深入贯彻落实党的十九大精神,积极推进“互联网+”行动,提升中小学校信息化建设与应用水平,推动信息技术与教育教学的深度融合,切实加快全国教育信息化进程,以教育信息化支撑和引领教育现代化,服务教育强国建设而制定的法规。
《智慧校园总体框架》(GBT36342-2018)于2018年6月7日正式发布,其从智慧校园总体系统架构、智慧教学环境、智慧教学资源、智慧校园管理、智慧校园服务、信息安全体系等六大方面对智慧校园建设作了规范及标准指导
三、智慧校园2.0体系架构
图4:智慧校园2.0总体架构
智慧校园的建设包括校园基础设施、智慧教学环境、智慧教学资源、智慧教学管理以及智慧教学服务5大部分。以及智慧校园信息化安全保障系统。
四、智慧校园智能感知定义
图5:智慧校园智能感知定义
在智慧校园中分别对智慧教学环境、智慧校园管理以及智慧校园服务中要求实现智能化感知、智能化控制、智能化管理、智能化互动反馈、智能化数据分析、智能化视窗等功能分别用于支持教学、科研活动的现实空间环境或虚拟拟空间环境。用于实现校园信息管理的系统。用于实现校园信息化服务的系统。
智慧校园还需要具备智能监测能自动获取服务网络、视频监控设备或其他感知设备的各种状态信息、监测信息,并利用相关技术,根据一定策略实现系统的自动监测、诊断、告警和修复的一种自动化的工作行为。
图6:智慧教学环境智能感知定义
在智慧教室中能够实现对环境内所有装备(硬件设备)及状态的信息采集,对环境指标及活动情境的识别、感知和记录,对教学设备的控制和管理,且能实现对控制全过程及效果的监视,能够实现环境内各类信息或数据的生成、采集、汇聚和推送,便于实现对环境内的所有装备(软硬件设备)、环境指标及教学活动进行管理,同时具备基于室内自然光、照明、空气质最、温度及湿度等环境数据实现智能调节控制的条件。
五、物联网相关的技术
图7:物联网相关技术
红外传感技术
红外传感技术在实现远距离温度监测与控制方面,红外温度传感器以其优异的性能,满足了多方面的要求。随着便携式红外传感器的体积越来越小,价格逐渐降低,在食品、采暖空调和汽车等领域也有了新的应用,红外传感具有小型化、数字通信、维护简单等优点。
红外传感技术可以感应人体信息,并且也能控制空调、加湿器、投影仪等,相比较于WiFi稳定性更强,能耗更低、维护更简单;劣势在于使用场景相对单一。
蓝牙技术
蓝牙目前已经成为智能手机的标配通信组件,其迅速发展的原因包括:
(1)低功耗。这是蓝牙4.0的大杀器~使用纽扣电池的蓝牙4.0设备可运行一年以上,这对不希望频繁充电的可穿戴设备具有十分大的吸引力。当前基本世面上的可穿戴设备基本都选用蓝牙4.0方案。
(2)智能手机的普及。近年来支持蓝牙协议基本成为智能手机的标配,用户无需购买额外的接入模块。
值得关注的是蓝牙4.2版本近期推出,加入mesh组网功能,向Zigbee发出了强有力的挑战。
劣势:虽然蓝牙技术有低功耗的优势,但是蓝牙工作在2.4G频段,传输距离比较近一般在10米以内,若想实现蓝牙信号全覆盖,需要部署很密集的蓝牙发射器,成本较高,不适用于大型场合和企业场景。
WiFi技术
WiFi协议和蓝牙协议一样,目前也得到了非常大的发展。由于近几年家用WiFi路由器、企业WIFI部署以及智能手机的迅速普及,WiFi协议在互联网金融领域也得到了广泛应用。WiFi协议最大的优势是可以直接接入互联网,并且给金融办公人员、营业点顾客提供便捷的接入网络服务,同时也为未来打造智能无人营业网点做好了基础网络部署。相对于Zigbee,采用WiFi方案省去了额外的网关,相对于蓝牙协议,省去了对手机等移动终端的依赖。
WiFi虽然传输容量大,传输数据稳定,但是功耗成为其在物联网领域应用的一大瓶颈,同时WiFi传输距离比较近介入终端数量也较少,所以,WiFi非常适用于办公、营业网点大并发、大流量终端如平板电脑、无线取号机等设备接入使用,但是不适用于传输距离远、终端数量多、低功耗的物联网传感器终端接入场景。
Zigbee协议
Zigbee协议的最佳应用场景是无线传感网络,比如水质监测、环境控制等节点之间需要自组网传输数据的工业场景中。在这些场景中Zigbee协议的优势发挥的非常明显。目前国内外很多厂商也将Zigbee运用在智能家居方案中,比如小米发布的“小米智能家居套装”。
但是Zigbee协议也有不足,主要就是它虽然可以方便的组网但不能接入互联网,所以Zigbee网络中必须有一个节点充当路由器的角色(比如小米智能家居套装中的智能网关),这提高了成本并且增加了用户使用门槛。同时由于Zigbee协议数据传输速率低,对于大流量应用如流媒体、视频等,基本是不可能。
LoRo协议
LoRa的全称是Long Range (远距离),是一种低功耗、远距离的局域网无线标准。LoRa协议具有以下特点,
低功耗:LoRa采用Aloha方法进行通讯,只在节点有数据要发送的时候采取向网络同步数据。
远距离:城镇可达2-5 Km , 郊区可达15 Km。
速率:LoRa的最高速率只有37.5Kbps,但这个速率对应的传输距离只有几十米;要支持更远的距离,速率必然降低;通常在0.3Kbps~11Kbps之间;(1Kb=1Kbit)
NBIOT协议
NB-IoT,Narrow Band Internet of Things,窄带物联网,是一种专为万物互联打造的蜂窝网络连接技术。顾名思义,NB-IoT所占用的带宽很窄,只需约180KHz,而且其使用License频段,可采取带内、保护带或独立载波三种部署方式,与现有网络共存,并且能够直接部署在GSM、UMTS或LTE网络,即2/3/4G的网络上,实现现有网络的复用,降低部署成本,实现平滑升级。
六、智慧校园设备及安全管理常见问题
图8:智慧校园设备及安全管理常见问题
校园设备繁多,难以统一实现智能化感知、控制、管理;
校园能耗大,缺乏统一用电分析管理;
校园用电安全事故频发难以防范;
校园环境状况发生污染时难以实时感知并预防;
校园消防安全难以实时反应各项消防设备工作状态;
ive 插入数据的时候,不能直接运行,报错
错误原因:
namenode内存空间不够,JVM剩余内存空间不够新job运行所致
错误提示
Starting Job = job_1594085668614_0006, Tracking URL = http://kudu:8088/proxy/application_1594085668614_0006/ Kill Command = /root/soft/hadoop-3.2.1/bin/mapred job -kill job_1594085668614_0006 Hadoop job information for Stage-1: number of mappers: 0; number of reducers: 0 2020-07-07 09:43:24,559 Stage-1 map = 0%, reduce = 0% Ended Job = job_1594085668614_0006 with errors Error during job, obtaining debugging information... FAILED: Execution Error, return code 2 from org.apache.hadoop.hive.ql.exec.mr.MapRedTask MapReduce Jobs Launched: Stage-Stage-1: HDFS Read: 0 HDFS Write: 0 FAIL Total MapReduce CPU Time Spent: 0 msec 解决办法:
下面分析读取excel的两种方法
1. 用readxl包
install.packages("readxl") library(readxl) data<-read_excel("C:/Users/Admin/Desktop/data.xlsx",sheet=1,na="NA") 2.用clipboard复制
打开EXCEL,全选里面的内容,点击复制(不能剪切),然后在R中输入一下命令:
data <- read.table("clipboard", header = T, sep = '\t') 运行这行代码
结果如下:
一:Mobx介绍 mobx——简单、可扩展的状态管理库. 通过透明的函数响应式编程使得状态管理变得简单和可扩展
使用原理:
名词概念:
State:状态,应用依赖的最小状态集,没有任何多余的状态,也不需要通过其他状态计算而来的中间状态;
Computed value:计算值,是根据state推导计算出来的值;
Reaction:响应,受state影响,会对state的变化做出一些更新ui、打印日志等反应;
Action:动作,建议是唯一可以修改状态的方式;
Mobx整体是一个观察者模式,存储state的store是被观察者,observable是观察者。当action改变中的state的store之后,computed value和reactin会自动根据state的改变做最小化更新,需要注意的是computed value采用延迟更新的方式,只有待更新的computed value被使用时才会被重新计算,否则computed value不会被重新计算,将被自动回收。
二:安装 第一步:创建一个react项目
npx create-react-app mobx-study // 进入当前app cd mobx-study 第二步:创建安装mobx的环境
方法一
1、配置package.json,需要先将隐藏的webpack配置暴露出来
npm run eject // 需要注意的是 运行之前要将代码先提交一遍,也就是说git commit一次 git add. git commit -m "" 因为使用creata-react-app脚手架构建react项目的时候package.json,只有三个依赖,分别是react,react-dom,react-scripts,像webpack,babel等等都是被creat react app封装到了react-scripts这个项目当中,包括基本启动命令 都是通过调用react-scripts这个依赖下面的命令进行启动的,creat react app搭建出来的项目默认支持以下命令:start以开发模式启动项目,build将整个项目进行构建,test进行测试,eject,会将原本creat react app对webpack,babel等相关配置的封装暴露出来,而至于说为什么要提交一下,是因为是脚手架添加了.gitignore这个文件,但是没有本地仓库
2、安装插件
npm install --save-dev babel-plugin-transform-decorators-legacy // 修饰符的插件 npm install @babel/plugin-proposal-decorators // 装饰器的一个插件 3、然后在package.json文件中配置babel
"babel": { "plugins":[ [ "@babel/plugin-proposal-decorators", { "legacy":true } ], [ "
webpack打包的入口 在vue-cli3中查看webpack的配置信息,输入vue inspect > output.js
entry 入口,告诉webpack要使用哪个模块作为构建项目的起点,默认为./src/main.js entry: { app: [ './src/main.js' ] } output 出口,告诉webpack在哪里输出它打包好的代码以及如何命名,默认为./dist output: { path: '/Users/zhangzhenkun/Desktop/JS高级/VueTest/vue_test/dist', filename: 'js/[name].js', publicPath: '/', chunkFilename: 'js/[name].js' } loader和plugin的区别 Loader 本质就是一个函数,将一个语言转换为另一个语言。webpack自身只支持js和json这两种格式的文件,对于其他文件需要通过loader将其转换为commonJS规范的文件后,webpack才能解析到
css-loader:加载 CSS
style-loader:把 CSS 代码注入到 JavaScript 中,通过 DOM 操作去加载 CSS
image-loader:加载并且压缩图片文件
Plugin 就是插件,在打包前和打包后对结果再次进行操作。是用于在webpack打包编译过程里,在对应的事件节点里执行自定义操作,比如资源管理、bundle文件优化等操作。
uglify-webpack-plugin:丑化代码
ignore-plugin:忽略部分文件
babel-polyfill:es5转换为es6
语义化代码 意义:根据内容的结构化(内容语义化),选择合适的标签(代码语义化)便于开发者阅读和写出更优雅的代码的同时让浏览器的爬虫和机器很好地解析。作用: 在没有CSS的情况下,页面也能呈现出很好地内容结构、代码结构和搜索引擎建立良好沟通,有助于爬虫抓取更多的有效信息便于团队开发和维护,语义化更具可读性 新增的语义化标签:header footer nav audio video Vue路由守卫 路由守卫执行顺序:
路由守卫可以简单描述为路由跳转过程中的一些钩子函数,在路由跳转的过程中通过定义一些函数执行一些操作。
完整的导航解析流程: 导航被触发。在失活的组件里调用 beforeRouteLeave 守卫。调用全局的 beforeEach 守卫。在重用的组件里调用 beforeRouteUpdate 守卫 (2.2+)。在路由配置里调用 beforeEnter。解析异步路由组件。在被激活的组件里调用 beforeRouteEnter。调用全局的 beforeResolve 守卫 (2.
目录: 版本说明问题原因解决办法 一、版本说明 本机系统: Mac 二、问题 2.1、打开终端时,出现以下提示信息 complete:13: command not found: compdef 三、解决办法,参考这里 3.1、原因如下 Compdef 基本上是 zsh 用于加载自动完成的函数。需要激活完成系统。
如果您使用的是 oh-my-zsh 之类的东西,那么这已经解决了,否则您需要将以下内容添加到您的 ~/.zshrc
3.2、解决办法 # 输入以下命令 code ~/.zshrc # 编辑器此时打开了`.zshrc`文件 # 将以下代码加入到文件内容顶部 autoload -Uz compinit compinit 可以像这样直接使用 compdef 函数手动注册完成函数 compdef 。但是在使用 compdef 之前,需要在上下文中自动加载 compinit。
3.3、再次打开终端,错误不再显示 加入内容如下图
写给自己的随笔,有问题欢迎指出
目录
前言
一、什么是组件的生命周期呢?
二、挂在阶段
1、constructor(props)
2、static getDerivedStateFromProps(props, state)
3、render()
4、componentDidMount()
5、componentWillMount()
三、更新阶段
1、shouldComponentUpdate(nextProps, nextState)
2、getSnapshotBeforeUpdate(prevProps, prevState)
3、componentDidUpdate(prevProps, prevState, snapshot)
4、UNSAFE_componentWillUpdate(nextProps, nextState) 旧
5、UNSAFE_componentWillReceiveProps(nextProps) 旧
四、卸载阶段
1、componentWillUnmount()
总结
前言 前面两篇文章简单地介绍了 React 中的 JSX 语法、状态组件、绑定事件、设置 state 等基本操作,这篇文章将继续通过一些实例介绍 React 中的基础知识点生命周期。
文章开始之前我们来认识两张图:
旧版本:
新版本:
一、什么是组件的生命周期呢? 1、组件从创建到死亡它会经历一些特定的阶段。
2、React组件中包含一系列钩子函数(生命周期回调函数),会在特定的时刻调用。
3、我们在定义组件时,会在特定的生命周期回调函数中,做待定的工作。
简单来说:一个组件从创建到最后消亡所经历的各种状态,就是一个组件的生命周期
从组件被创建,到组件挂载到页面上运行,再到页面关闭组件被卸载,这三个阶段总是伴随着组件各种各样的事件,那么这些事件,统称为组件的生命周期函数
在React中,我们可以将其生命周期分为三个阶段:
挂载阶段
更新阶段
卸载阶段
不同阶段将对应不同的钩子函数来处理组件的状态。
二、挂在阶段 首先是挂载阶段,当组件实例被创建并插入DOM中时,将依次调用以下生命周期函数
constructor
static getSerivedStateFromProps
render
componentDidMount
1、constructor(props) 在React组件挂载之前,会调用它的构造函数,在这个函数中我们可以拿到组件传递的props,通常,在React中,构造函数仅用于以下两种情况:
通过给this.state赋值对象来初始化内部state
为事件处理函数绑定实例
注意: 在 constructor() 函数中不要调用 setState() 方法
避免将 props 的值复制给 state
近期把组装机的黑苹果升级到了 Big Sur 11.5.2
AMD 5600X
ASUS TUF B550M PLUS WI-FI
RX580
然而蓝牙一直不出现,USB 设备列表里没有 蓝牙 HCI
USB Map 这个东西简直是黑苹果的噩梦。这是 OpenCore 的 USB Map 文档
https://dortania.github.io/OpenCore-Post-Install/usb/manual/manual.html
文档里提到了蓝牙,但问题在于,怎么知道蓝牙在哪个端口上?
反复折腾了好几天,就是不得要领。直到出现了这个工具的出现,简单好用
https://github.com/USBToolBox/tool
这个工具可以在 Windows/Windows PE/MacOS 下使用,但由于 MacOS 11.3 以后 XhciPortLimit 不起作用且 MacOS 有端口数量限制,所以还是在 Windows 10 下使用以启用全部功能。
1 运行程序,选择 Discover Ports 等待检测出列表。
2 轮番在每个空闲的 USB 端口上插入一个USB设备,等待列表中出现插入的设备,拔出插入下一个 USB 端口。程序会自动记录已经检测识别出的端口。
3 所有端口检测完成后,回到主菜单,选择 Ports screen.
4 按 K 创建 kext
5 把生成的 kext 复制到 EFI/OC/Kexts 文件夹中,更新 config.plist。
python3 之高阶函数 一、定义二、实例 一、定义 什么是高阶函数?满足以下任意一个条件,都可以称之为高阶函数:
1、函数接收的参数是一个函数名;
作用:在不修改函数的源代码的前提下,可以为函数添加新功能。
不足:会改变函数的调用方式。
2、函数的返回值是一个函数名;
作用:不修改函数的调用方式。
不足:不能为函数添加新功能。
二、实例 1、定义一个函数,求任意2个数值的绝对值之和。
def add(x, y, f): return f(x) + f(y) print(add(-5, 6, abs)) # abs 是一个函数名,表示取值的绝对值 # 改变了函数的调用方式 输出的结果:
11 2、同时满足条件1、2 的写法。
import time def foo(): time.sleep(1) print("from the foo") def test_f(func): # 接收的参数是个函数名 return func # 返回一个函数名 foo = test_f(foo) # 函数foo的内存地址 print(foo) foo() # 执行函数foo, 这样就实现了不改变原函数的调用方式 输出的结果:
<function foo at 0x000002C2909D7288> from the foo
原 文:Line breaks and blank spaces
译 者:Xovee
翻译时间:2021年8月19日
换行、换页、空白空间 一般来说,我们不推荐你改变默认的 LaTeX 文档结构。当然,我们有时候也有这个需求。所以,在本文中,我们将解释如何在文档中插入空行,以及插入任意的空白。
文章目录 换行、换页、空白空间介绍换行换页水平空白空间垂直空白空间参考指南 介绍 分割文字的最佳方法是创建一个新的段落。你只需要在代码中添加一个空白行就可以了:
\documentclass{article} \begin{document} This paragraph contains no information and its purpose is to provide an example on how to start a new paragraph. As you can see, single line break in the code acts as a space in text. However, leaving an empty line starts a new paragraph. \end{document} 这并不是唯一的添加换行的办法,我们接下来介绍另外两种方法。
换行 \documentclass{article} \usepackage[utf8]{inputenc} \begin{document} Something in this document.
使用template不影响页面结构,只能结合v-if使用。
目录
如何使用LATEX3
基本语法
参数类型
声明变量
使用变量
声明函数
实例
实例1
实例2
实例3
实例4
实例5
实例6
实例7
查阅函数文档
宏展开
控制宏展开的意义
方法一:选择正确的函数变体
方法二:使用\exp_args:函数
方法三:使用\cs_generate_variant:Nn函数
实例
实例1
实例2
如何使用LATEX3 基本语法 \usepackage{expl3}启用LATEX3语法:\ExplSyntaxOn关闭LATEX3语法:\ExplSyntaxOffs注意事项: 所有空格及换行都会被忽略下划线(_)和冒号(:)等同于英文字母 参数类型 tl 凭据表str 字符串int整型fp浮点数seq队列dim尺度/长度bool布尔型N接收一个命令,传递命令本身n 接收一个凭据表
p接收参数列表(#1#2)V与N类似,但是传递命令的值o 与n类似,但是对凭据表内的内容进行一次展开x与n类似,但是对凭据表的内容进行递归展开T/F 与n类似,用于判断语句中,根据判断结果执行T/F代码c接收一个凭据表,返回以其为名字的命令 声明变量 使用new结尾的函数
\bool_new:N\int_new:N\seq_new:N\dim_new:N\fp_new:N 使用变量 使用use结尾的函数
\bool_use:N\int_use:N\seq_use:N\dim_use:N\fp_use:N 声明函数 使用\cs_set:Npn来声明函数
\documentclass{article} \usepackage{ctex} \usepackage{expl3} \begin{document} \ExplSyntaxOn \cs_set:Npn \my_function:n #1{ 你输了: #1 } \par\my_function:n {一} \par\my_function:n {二} \ExplSyntaxOff \end{document} 实例 实例1 \documentclass{article} \usepackage{expl3} \begin{document} \ExplSyntaxOn %LaTex3 代码 \ExplSyntaxOff \end{document} 实例2 \documentclass{article} \usepackage{expl3} \begin{document} \ExplSyntaxOn \int_new:N \l_my_tmpa_int \int_new:N \l_my_tmpb_int \int_set:Nn \l_my_tmpa_int {200} \int_set:Nn \l_my_tmpb_int {10} \int_eval:n {\l_my_tmpa_int+\l_my_tmpb_int} \ExplSyntaxOff \end{document} 实例3 \documentclass{article} \usepackage{expl3} \begin{document} \ExplSyntaxOn \int_step_inline:nn {20}{ #1,\quad } \ExplSyntaxOff \end{document} 实例4 \documentclass{article} \usepackage{expl3} \begin{document} \ExplSyntaxOn \int_step_inline:nnn {10}{20}{ #1,\quad } \ExplSyntaxOff \end{document} 实例5 计算1+2+3+.
1、Jenkins安装 1.1、配置java环境变量,使用的是jdk1.8的,上传jdk包到/usr/local/java目录下 #创建java下载安装目录 mkdir -p /usr/local/java #编辑profile文件,配置java环境变量 vim /etc/profile export PATH=$PATH:$HOME/bin:/usr/local/java/jdk/bin #应用到环境变量中 source /etc/profile 1.2、去官网下载Jenkins包,并运行 #在Jenkins.war包的目录下,执行下面命令,启动Jenkins nohup java -jar jenkins.war --httpPort=38080 & 1.3、安装依赖及安装配置git yum -y install curl-devel expat-devel gettext-devel openssl-devel zlib-devel gcc perl-ExtUtils-MakeMaker wget https://mirrors.edge.kernel.org/pub/software/scm/git/git-2.9.5.tar.gz tar xf git-2.9.5.tar.gz -C /usr/local/src cd /usr/local/src/git-2.9.5/ make prefix=/usr/local/git all make prefix=/usr/local/git install 2、maven下载安装配置 2.1、下载maven包 wget https://dlcdn.apache.org/maven/maven-3/3.8.2/binaries/apache-maven-3.8.2-bin.tar.gz 2.2、cp包+解压+环境变量 mkdir /usr/local/maven/ cp apache-maven-3.8.2-bin.tar.gz /usr/local/maven/ tar xf apache-maven-3.8.2-bin.tar.gz vim /etc/profile export PATH=/usr/local/maven/apache-maven-3.8.2/bin:$PATH source /etc/profile mvn --version 3、docker安装gitlab部署搭建 3.
import torch import torch.nn as nn embedding1 = nn.Embedding(10,3) embedding1.weight Parameter containing: tensor([[-0.9116, 0.5195, -1.3509], [ 0.5670, 0.8024, -0.0373], [-0.8223, -1.2181, -0.6713], [-1.2734, -1.0591, -1.1202], [-0.4734, 1.8297, 0.3880], [ 0.5687, 0.3136, 0.7541], [ 1.0070, -0.0197, -0.1715], [ 2.1003, 0.6229, 0.6720], [-0.1729, -0.6555, 0.2904], [-1.6015, -1.3011, -0.5837]], requires_grad=True) embedding2 = nn.Embedding(10,3,padding_idx=0) embedding2.weight Parameter containing: tensor([[ 0.0000, 0.0000, 0.0000], [-0.5784, -1.5044, -1.7400], [-1.1197, 0.8234, -0.6458], [ 0.8204, 2.0259, -0.9619], [ 0.1317, -0.
zlib 很重要的一个library,很多开源的软件都会用这个,按照官方编译比较麻烦,尤其在windows下,耗时耗力,介绍一个简单的方法,其实很多库都可以这么做
过程 直接打开vs2015,vs2017 建立一个工程,把源代码拷贝进去,
设置为静态库,添加预处理器编译条件
_DEBUG
_CONSOLE
_WINDOWS
_CRT_SECURE_NO_DEPRECATE
_CRT_NONSTDC_NO_DEPRECATE
_SCL_SECURE_NO_WARNINGS
_VARIADIC_MAX=10
_WIN32_WINNT=0x0601
NO_FSEEKO
直接编译成功,纯c的代码很容易就可以用了,当然,这样缺少的是汇编这一部分。
上一篇《TVM的“hello world“基础流程 I》中基于一个最基本的case介绍了TVM中计算的定义与schedule的构建。这篇沿用上一篇中的case,继续介绍接下去的一个重点部分,就是编译。
有了前面构建的schedule之后,接着就需要编译并生成目标代码了。这个工作主要由tvm.build()和relay.build()两个函数来完成。它们的区别在于应用目标的范围,前者用于单个算子,后者用于整个网络。由于网络可看作由算子组成,后者会调用前者。本例中是针对单个算子的,因此这里使用的是前者:
tgt = tvm.target.Target(target="llvm", host="llvm") fadd = tvm.build(s, [A, B, C], tgt, name="vecadd") 其中最主要的build()函数定义在driver/build_module.py文件中。该函数基于给定参数构建出可调用的目标函数。按照官方介绍里的说法,它主要做两个工作 :
Lowering:将high-level的循环嵌套结构转换成最终的low-level的IR。Codegen:从low-level的IR生成目标机器代码。 该函数的第一个参数是前面构建出来的schedule,第二个参数是函数的参数列表,第三个参数是target。它提供用于lowering和codegen所需的目标平台信息。代码中对应的Target对象定义在target.*文件中。其构造函数有两个参数,其中第一个参数target指示目标平台的配置。其中的配置项比如:
kind: 平台类型,它基本决定了生成的代码是在什么处理器上运行。注册的target kind详细见target_kind.cc,有llvm, c, cuda, nvptx, romc, opencl, metal, vulkan, hexagon等。keys: 如kind是opencl的话,key可以是mali, opencl, gpu。device:对应实际运行的设备,它会添加到keys后面。libs:外部库,如cblas, cudnn, cublas, mkl这些。… 另外参数host与target类似,但它用于指示host平台。比如taret平台为cuda的话,毕竟GPU还是不能完全脱离CPU运行,因此还需要host的代码做胶水,如内存分配,kernel启动这些。默认为llvm。
Lowering过程可以单独用tvm.lower()函数完成,如:
m = tvm.lower(s, [A, B, C], name="vecadd") rt_mod = tvm.build(m, target="llvm") 也可以通过tvm.build()函数完成(因为它一进去就会先调用lower()函数)。lower()函数的主要流程相关代码:
lower(sch, args, name="main", ...) // driver/build_module.py // Handle add_lower_pass, if any. lower_phases0 = ... ... // According to the given schedule, form a function (in IRModule).
参考资料: https://blog.csdn.net/yangwu007/article/details/112650904
https://www.it610.com/article/1298641633968979968.htm
https://github.com/google-ar/arcore-android-sdk/releases
————————————————————————
增强现实(Augmented Reality,简称 AR),是一种实时地计算摄影机影像的位置及角度并加上相应图像的技术,这种技术的目标是在屏幕上把虚拟世界套在现实世界并进行互动。
AR 技术不断完善,展现设备也在更迭。头戴与移动式设备是目前两大主要的 AR 呈现系统。关于头戴式设备不是本文研究的话题,本文主要介绍移动式设备,例如:智能手机。
移动式设备则为人们体验 AR 提供了较为便捷的工具。一部智能手机更是能够促进 AR/VR 产业的发展,其配备的陀螺仪、加速计、微型高分辨率屏幕等组件构成了 AR/VR 设备的必要架构。过去十年人们对智能手机的高涨需求也为这些配件的大规模生产与升级产生推力,从而带来更出色的硬件创新与成本的降低。就底层逻辑而言,AR 是利用手机的前置与后置摄像头得以实现的。拿起智能手机就能将数字对象与现实场景相融合,打开通往“新世界”的大门。 那么如何使用智能手机来开发AR应用呢,需要怎样部署开发环境。本文以android设备为例进行介绍。
能运行AR的android机型有特定要求,不是所有的android机型都能运行AR应用,哪些机型支持见列表(谷歌),见链接:https://developers.google.cn/ar/devices
提示:
如果无法打开该网页,可以下载链接中的资料,里面能看到支持AR支持哪些设备
链接:https://pan.baidu.com/s/1sVo3QzzC1hovLLEA5Iq3AQ 提取码:z7zr
场景一: 如果有符合能够开发与运行AR应用的android真机,可以参考这个进行相关开发部署。
链接:https://developers.google.cn/ar/develop/java/quickstart
场景二: 如果没有符合能够开发与运行AR应用的android真机,那么可以使用android模拟器来测试,androidstudio中有一些符合需求的模拟器可供使用。
由于我也没有符合需求的android真机,因此我也使用android模拟器来测试,因此针对场景二进行介绍。
①开发环境部署,具体步骤见链接:https://developers.google.cn/ar/develop/java/emulator
提示:
如果无法打开该网页,可以下载链接中的资料,里面能看到使用android模拟器运行AR的开发环境部署的介绍。
链接:https://pan.baidu.com/s/1wVlZo4V2nxsTyYVdjeaXBA 提取码:g9z8
或者
链接:https://pan.baidu.com/s/17m9TH_Swa2x02Jh9lD_KGQ 提取码:h64g
基于链接中的介绍,几点需要注意,否则运行AR案例时提示“This device does not support AR”错误:
选择SDK Platforms标签,并勾选显示软件包细节,在相应的Android版本下选择Google APIs Intel x86 Atom System Image以及 API Level 27或更高(例如:30); 选择SDK Tools选项卡并添加Android Emulater 27.2.9或更高版本(例如:30.8.4); 只支持基于x86的安卓模拟器架构。其他架构,如arm64-v8a、armabi-v7,目前都不支持。 那么在新建模拟器时选择x86cpu架构的模拟器,我选用的模拟器如下:
需要给android模拟器安装Google Play Services for AR,那么需要下载对应的x86的apk文件,我已将其下载下来,见链接: 链接:https://pan.baidu.com/s/1LzSkbz0nPKjiBu59Hf8Tig 提取码:h17w ②运行AR案例。比如:在androidstudio加载arcore sdk中的示例(例如:augmented_image_java)
<v-row no-gutters dense style="border-bottom:none!important;"> <v-col cols="3" class="mt-2"> <v-subheader> <span class="red--text">*</span> 类型 </v-subheader> </v-col> <v-col class="d-flex" cols="12" sm="6"> <v-select :items="types" :label="value_type ? '' : '请选择'" item-text="name" item-value="id" v-model="value_type" @change="getvalue_typeSelected(value_type)" ></v-select> </v-col> </v-row> <script> export default { data(){ return { types: [ { id: "STRING", name: "字符串类型", }, { id: "BOOLEAN", name: "布尔值", }, { id: "INTEGER", name: "数字类型", }, { id: "DATETIME", name: "日期时间类型", }, { id: "DATE", name: "日期类型", }, ], } }, methods:{ getvalue_typeSelected(val) { this.
打开很久没用过Deepin系统电脑,发现可以更新系统(兴高采烈),更新系统之后(难过),出现Minimal BASH-like line editingis supported.
临时解决方案 一、查找系统安装的分区 ls 列出所有的磁盘分区信息,如:(hd0,gpt1),(hd0,gpt5),(hd1,gpt3),(hd1,gpt2)
二、查看各个分区的文件 1、boot单独分区
ls (hd0,gpt1)/grub 2、boot没有单独分区
ls (hd0,gpt1)/boot/grub 以(hd0,gpt1)为例,注:需要测试所有分区。
如果遇到列出很多文件,且文件扩展名为.mod和.lst和.img,还有一个文件是grub.cfg。假设(hd1,gpt3)符合上述情况,则表示系统安装在(hd1,gpt3),这个分区。
三、关联grub文件并进入系统 1、关键grub文件
set root=(hd0,gpt5) set prefix=(hd0,gpt5)/boot/grub 2、进入系统
normal 永久解决方案 注:需要进入系统之后在终端里面输入
cp /boot/efi/EFI/deepin /boot/efi/EFI/UOS 最后,重启计算机即可。
面试官:有如下学生成绩表:students_grades
查询每门课程grades前两名的学生姓名及成绩,要求输出列格式如下:
name, number, course, grade
这里需要使用开窗函数/分析函数:over()
什么是开窗函数:
开窗函数/分析函数:over()
开窗函数也叫分析函数,有两类:一类是聚合开窗函数,一类是排序开窗函数。
开窗函数的调用格式为:
函数名(列名) OVER(partition by 列名 order by列名) 有时候一组数据只返回一组值是不能满足需求的,如我们经常想知道各个地区的前几名、各个班或各个学科的前几名。这时候需要每一组返回多个值。用开窗函数解决这类问题非常方便。
上面这道题的sql就用到了over()开窗函数:
1、先用开窗函数将所有成绩查询出来并排序
select g.*, row_number() over(partition by g.course order by g.grade desc) number from grade g 结果如下:
2、再取前两名的成绩
SELECT * FROM ( SELECT g.*, row_number() over ( PARTITION BY g.course ORDER BY g.grade DESC ) number FROM grade g ) gg WHERE gg.number <=2 几个排序函数row_number() over()、rank() over()、dense_rank() over()、ntile() over()的区别
(1) row_number() over():对相等的值不进行区分,相等的值对应的排名相同,序号从1到n连续。
小波分析克服了短时傅里叶变换在单分辨率上的缺陷,具有多分辨率分析的特点。下面对小波分析的基本理论进行介绍,包括连续小波变换、离散小波变换、多分辨分析和小波包分析,最后介绍在小波分析中常用的小波。
小波变换采用随频率的时间-频率窗口,是进行信号时频分析和处理的理想工具。在利用小波分析信号分析时,在低频部分采用较低的时间分辨率,提高频率分辨率;在高频部分,采用较低的频率分辨率来换取精确的时间定位。小波包分解与小波分解相比,是一种更精细的分解方法,不仅对低频部分进行分解,对高频部分也进行分解。
小波变换速度快,适合信号的在线分析。小波分析能够通过变换充分突出问题某些方面的特征,因此,小波变换在许多领域都得到了成功的应用。
小波变换的实质是将信号在一个时域和频域上均具有局部化性质的平移伸缩小波权函数进行卷积,从而将信号分解成位于不同时间和频率上的各个成份。满足允许条件:
离散小波变换( discrete wavelet transform,DWT)是指对尺度因子a和平移因子b进行离散化,而不是时间的离散化。离散小波变换的一个重要问题是如何降低计算量和数据量,因为如果对尺度因子a和平移因子b离散的间隔小,那么计算量和数据量都是相当惊人的。
离散小波变换的一个突破性成果是Mallat于1989年在多分辨分析的基础上提出的快速算法:Mallat算法Mallat享法在小波分析中的作用相当于快速傅立叶变换( FFT)在傅立叶分析中的作用。Mallat算法由小波滤波器H、G和h、g对信号进行分解和重构。Mallat分解算法为
对信号f(t)进行离散小波的3层分解,近似系数和细节系数。
在MATLAB的命令行窗口输入:help wavelet,可以查询MATLAB的小波工具箱中的所有函数,以及小波工具箱,的版本。在MATLAB 2010a中小波工具箱的版本为4.5。用户在命令行窗口输入;wavedemo可以查看例子程序。采用函数wavemngr()可以获取所有的小波。通过函数waveinfo()可以获取小波的信息。
1.分解和重构 在MATLAB中,采用函数cwt()进行一维连续小波分解,该函数的常用调用格式为:coefs=cwt(s,scales, ‘wname’):该函数对信号s进行尺度为scales的连续小波分解,小波为wname,返回值coefs为系数。coefs=cwt(s, scales, ‘wname’, ‘plot’):该函数通过参数plot显示变换后的图形。
在MATLAB中,采用函数dwt()进行一维小波的单层分解,该函数的常用调用格式为:[cA,cD]=dwt(X, ‘wname’):该函数采用小波wname进行单层分解,cA为近似系数,cD为细节系数。[cA, cD]=dwt(x,‘Wname’, ‘mode’,MODE):该函数设定扩展模式为MODE.在MATLAB中,采用函数wavdec()进行一维小波的多层分解。
在MATLAB中,利用函数idwt()进行单层小波重构,该函数的调用格式为:X=idwt(cA, cD, ‘wname’),cA为近似系数,cD为细节系数,wname为采用的小波。利用函数waverec()进行多层小波的重构。在进行小波的重构时,小波的类型必须和分解时保持一致。
2.小波分解和重构 二维小波非常适合进行图像的分析和处理。图像的单层二维小波分解,将图像分解为4个原图1/4大小的图像,左上的图像为两个维度都采用低通滤波后的结果;右上的图像为横向采用低通滤波,纵向采用高通滤波后的结果;左下的图像为横向采用高通滤波,纵向采用低通滤波后的结果;右下的图像两个维度都采用高通滤波后的结果。
在MATLAB中,采用函数dwt2()进行二维小波的单层分解,该函数的调用格式为:[cA, cH, cV, cD]=dwt2(X,‘wname’),该函数采用小波wname,对信号X进行单层分解。其中cA为近似系数,cH、CV和C加无小 节系数、垂直细节系数和对角细节系数.MATLAB中,采用函数idwt2()进行二维小波的单层重构,该函数的调用格式为:X=idwt2(cA,cH, cV, cD,‘wname’).
在MATLAB中米用出双ae ec sy=wavedec2(X,N,‘wname’),该函数采用小波wanme对信号X进行二维小波的N层分解。利用函数waberec2()进行二维小波的多层重构,该函数的调用格式为:X=waverec2(C, s, ‘wname’),利用小波wname进行二维小波的多层重构。
在MATLAB中,采用函数wpdec()进行一维小波包分解该函数的调用格式为:T=wpdec(, N, ‘wname’):该函数对信号X进行N层的小波包分解,采用的小波为wname,返回值T为小波包树;T=wpdec(X,N, ‘wname’, E, P):该函数采用参数设置采用的熵,默认为’Shannon’.
在MATLAB中,通过函数wpcoef()获取小波树上某个节点的小波包系数。
在MATLAB中,采用函数wpsplt()将小波树上的节点进一步分解。
在MATLAB中,采用函数wpjoin(()进行小波包树上的节点进行合并。
在MATLAB中,采用函数besttree()获取最优小波树。
在MATLAB中,通过函数wprec()进行一维小波包的重构,该函数的调用格式为:X=wprec(T),其中T为小波包树,返回值X为重构的信号。
在MATLAB中,采用函数wpdec2()进行二维小波包的分解,该函数的调用格式为:T=wpdec2(X,N, ‘wname’)该函数采用wname小波,对数据X进行二维N层小波包分解。同一维小波分解类似,采用函数wpcoef( )获取二维小波包树上某个节点的系数;采用函数wpsplt()进行二维小波包树的进一步分解;利用函数wpjoin()进行二维小波包树上节点的合并;利用函数besttree()获取最优的二维小波包树。通过函数wprec2()进行二维小波包的重构,该函数的调用格式为:X=wprec2(T)其中T为二维小波包树,X为重构后的二维数据。
在MATLAB中,采用函数wenergy()计算进行归一化后的小波能量。该函数可以用于一维小波和小波包。该函数的调用格式为:[Ea, Ed]=wenergy(c, L):该函数用于计算一维小波的能量。=wenergy(T):该函数用于计算小波包的能量。在MATLAB中,采用函数wentropy()计算小波包的嫡。
3.GUI工具箱 下面介绍小波工具箱的另一种实现方式,即GUI工具。小波工具箱的GUI工具界面友好,在解决特定问题时非常的直观和灵活,提供了大量的例子程序,而且可以非常方便的进行数据的导入和导出。用户不用编写程序,就采用小波分析对一维信号或二维图像进行压缩和去除噪声等。
edit wavemenu %%命令行运行指令
在小波工具箱的GUI界面中,二维小波分析工具包括:二维小波分解(Wavelet 2-D)和二维小波包分解((WaveletPacket 2-D)。下面介绍其中的二维小波分解。
半透shader什么时候用到呢
1.如果主角被东西挡住,摄像机要不拉近要不把挡住的物体半透
2.很多游戏用到残影,一般残影都是半透的,然后慢慢透明
从左到右
1.使用标准材质球
2.使用半透材质球
3.使用外发光的半透材质球
4.使用内发光和外发光的材质球
shader比较简单直接上代码
这些都是surface shader
1.半透shader
Shader "Snoopy/AlphaBase" { Properties { _MainTex("Particle Texture", 2D) = "white" {} _Color("Color", Color) = (1,1,1,1) } SubShader { Tags{ "Queue" = "Transparent" "IgnoreProjector" = "True" "RenderType" = "Transparent" } //这里加一个pass为了不会穿透叠自己的颜色,可以取消这个pass看看效果 Pass { ZWrite On ColorMask 0 } CGPROGRAM //使用alpha通道 #pragma surface surf Lambert alpha struct Input { float2 uv_MainTex; }; sampler2D _MainTex; fixed4 _Color; void surf(Input IN, inout SurfaceOutput o) { float4 col = tex2D(_MainTex, IN.
解决方案如下:选择左上角菜单,将编译器由默认的pdfLaTex改为XeLaTex继续编译即可解决问题
当组件在一屏内不会有什么问题,但是当弹出框超过一屏需要滚动时,select的下拉选项会出现 错位,不在selcet组件上下,因为.ivu-select-dropdown自带的有 position:absolute的样式,所以 我给它的上一级设置position: relative;在给他设置top:40px ;使弹出框固定在select组件的位置, 不过有一个小问题,就是弹窗的展开方向被固定住了。 /deep/ .ivu-select{ position: relative; .ivu-select-dropdown{ top:40px !important; } }
前言 这是坚持更新的第四天,前两天更新了数学建模的一些基础模型,今天我们做一个数学建模的实例。
了解BP神经网络的同学知道,BP神经网络的用途之一就是用来做预测,但是由于BP神经网络是一种有监督的学习方式,在进行预测之前我们需要一些数据作为训练集。如果需要对短视频中用户的行为发生的概率进行预测,那么我们必须要知道一些用户行为发生的概率。
贝叶斯分类器通常是用来解决‘是’或者‘不是’的问题,但是和其他分类器有所不同的是他是通过概率来进行判断的,这就很好的对应了BP神经网络中所需的概率。
下面我们以今年腾讯提供的大数据挑战赛中的数据为数据集,结合BP神经网络和贝叶斯分类器来对用户的行为进行预测。
预测模型 由于数据集比较大(百万级别的数据),程序运行出来也需要一定的时间,本文只选取很小的一部分数据做实验,可以说明问题即可,具体数据如下所示:
userid代表用户,feedid代表视频;read_commend:当取值为1时代表查看了评论,0时代表没有看评论;comment:评论;play:视频播放时长;stay:视频停留时长,click_ava:查看头像,forward:分享(具体什么意思忘了,不过不要紧)follow:转发;favorite:收藏,like:点赞
朴素贝叶斯判别器模型 根据给定的数据集我们可以利用朴素贝叶斯分类器判断是否点赞,及点赞发生的概率,假设给定一条数据如下
为了避免朴素贝叶斯模型中出现概率为0的情况,我们对其中的参数进行拉普拉斯修正,朴素贝叶斯模型所需要的参数及其计算过程如下:
P=p(like)*p(read_comment|like)*p(comment|like)*p(play|like)*p(stay|like)*p(click_ava|like)*p(forward|like)*p(follow|like)*p(favorite|like);
其中p(A|B)表示条件概率,在B发生的条件下A发生概率,根据以上数据,我们可以直接计算其需要的参数:
%%使用matlab读取数据 useraction=readmatrix('useraction','outputtype','string'); %%把字符型转化为double型数据 useraction=str2double(useraction) %%统计矩阵的维数 [N,M]=size(useraction); %%计算p(like),并对p(like)进行拉普拉斯修正 Like=find(useraction(:,7)~=0); p(like)=(length(like)+1)/(N+2); %其余的条件概率我们只简单举个例子 %%对于离散型变量comment来说 Comment=0; for i=1:N if useraction(i,6)~=0&&useraction(i,7)~=0 Comment=Comment+1; end end p(commnet)=(Commnet+1)/(N+2); 对于连续型随机变量满足以下计算公式:
其中的u_ci,和theta_ci表示第c类样本的均值和方差,在本模型中就代表播放时间和停留时间的均值和方差。
选取一部分数据通过贝叶斯模型进行计算作为BP神经网络的输入(训练集)
BP神经网络 我们构建三层的BP神经网络,将用户的各项指标的值和朴素贝叶斯计算出来的概率作为训练集,通过输入新的数据,可以预测用户对新的视频的点赞的概率。假设通过贝叶斯模型得到的训练集数据如下:
训练代码如下:
P=[1,1,0,1,0,1;0,1,0,0,0,1;358,258,53,88,62,135;455,400,53,157,62,227;0,0,0,1,1,1;1,1,1,0,1,0;0,1,0,1,0,0;0,0,0,1,0,0]; T=[0.2,0.3,0.05,0.8,0.4,0.5]; [p1,minp,maxp,t1,mint,maxt]=premnmx(P,T); net=newff(minmax(P),[8,6,1],{'tansig','tansig','purelin'},'trainlm'); %设置训练次数 net.trainParam.epochs = 5000; %设置收敛误差 net.trainParam.goal=0.0000001; %训练网络 [net,tr]=train(net,p1,t1); %输入数据 a=[1;1;32;34;0;0;1;0]; %将输入数据归一化 a=premnmx(a); %放入到网络输出数据 b=sim(net,a); %将得到的数据反归一化得到预测数据a c=postmnmx(b,mint,maxt); c 具体图像
总结 在实现上述过程中时,可以发现其实神经网络的效果其实有时候并不是令人那么满意,有兴趣的同学可以看一看大家对BP神经网络的改进。其次,其实如果同学们动手做了这个建模的话,其实单单一个贝叶斯判别器也可以实现一定的预测效果,但是不同用户的数据不同,不能把所有用户当成一个用户来处理,真正用贝叶斯模型去做“预测”的时候,可能需要搭建很多模型,特别是对数据很大的时候,比如有几万个用户的数据,你可能就要考虑几万个不同的模型,虽然程序实现起来不是特别难,但是贝叶斯模型始终是一个判别模型,做预测还是不太合适(个人观点)。
也有同学会问既然不同用户要不同考虑,那加上一个神经网络就不需要考虑用户之间的区别了吗?答案是否定的,加上神经网络我们依然要考虑这一点。所以,最后,我对这个模型的改进之处做了一些思考
1、为了结果的准确性,对不同用户的概率进行平均或其他方式的处理。
2、利用遗传算法或者其他数值算法对BP神经网络进行改进,提高最终结果的准确性和稳定性。
今天是客户要求的最后期限,可突然发现一种操作方式下,程序会很容出现线程大面积卡住。
程序开了数十个线程,每个都会ping一个ip。
于是有人说是线程太多,有人说是发包太多,还有说是usleep会导致卡死。
gdb连接上卡死的程序:
gdb main pid
info threads
发现确实很多程序处于usleep。
网上很多说用select的,同事给了一段用select的,结果最基本的sleep时间都远远不对(估计是什么低级错误)。我也不喜欢select,因为效率低。
后来换了naosleep,
void sleepSelect1(unsigned int us, char* file, int line) { struct timespec ts1; struct timespec ts = { us / 1000000, (us % 1000000) * 1000 }; while ((-1 == nanosleep(&ts, ts1)) && (EINTR == errno)); } 结果还是会全面卡住,而且似乎更快,
后来换pthread_cond_timedwait:
void sleepSelect2(unsigned int us, char* file, int line) { pthread_mutex_t *mutex = malloc(sizeof(pthread_mutex_t)); pthread_cond_t *cond = malloc(sizeof(pthread_cond_t)); memset(mutex, 0, sizeof(pthread_mutex_t)); memset(cond, 0, sizeof(pthread_cond_t)); struct timespec *deadline=malloc(sizeof(struct timespec)); struct timeval *now=malloc(sizeof(struct timeval)); gettimeofday(now,NULL); long nanoseconds = (us % 1000000) * 1000; deadline->tv_sec = now->tv_sec + seconds; deadline->tv_nsec = now->tv_usec * 1000 + nanoseconds; if( deadline->tv_nsec >= 1000000000L ) { deadline->tv_nsec -= 1000000000L; deadline->tv_sec++; } pthread_mutex_lock(mutex); pthread_cond_timedwait(cond,mutex,deadline); pthread_mutex_unlock(mutex); free(deadline); free(now); free(mutex); free(cond); } 同样会大面积卡住在 pthread_cond_timedwait。而且发现把sleep(50)这样专用 cond_timedwait会直接卡住。
root 36355 36343 0 Aug19 ? 00:00:00 /usr/sbin/sendmail -FCronDaemon -i -odi -oem -oi -t -f root root 36360 36355 0 Aug19 ? 00:00:01 /usr/sbin/postdrop -r root 37174 1626 0 00:00 ? 00:00:00 CROND root 37209 37174 0 00:00 ? 00:00:00 /usr/sbin/sendmail -FCronDaemon -i -odi -oem -oi -t -f root root 37214 37209 0 00:00 ? 00:00:01 /usr/sbin/postdrop -r root 38574 1626 0 00:10 ? 00:00:00 CROND root 38599 38574 0 00:10 ?
Python列表推导式 一.为什么要学习列表推导式 母鸡啊 1.列表推导式可以说在Python程序开发时应用广泛。
2.列表推导式可以使用非常简洁的方式来快速生成满足特定需求的列表,且代码具有非常强的可读性。
3.Python的内部实现对列表推导式做了大量优化,可以保证很快的运行速度。
二.开始学习列表推导式了 快醒醒 1.语法:[表达式 for 变量 in 序列或迭代对象]
列表推导式在逻辑上相当于一个循环,但形式更加简洁
2.具体操作:
①简单举例
>>> list = [x*x for x in range(10)] >>> print(list) [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] >>> print(sum(list)) 285 ②使用列表推导式实现嵌套列表的平铺
>>> vec = [[1,2,3],[4,5,6],[7,8,9]] >>> list = [num for elem in vec for num in elem] >>> print(list) [1, 2, 3, 4, 5, 6, 7, 8, 9] ''' 在这个列表推导式中有两个循环,其中第一个循环为外循环,执行得慢; 第二个循环为内循环,执行得快。 ''' #用循环实现其等价写法: vec = [[1,2,3],[4,5,6],[7,8,9]] result= [] for elem in vec: for num in elem: result.
git init 在当前目录下新建一个git代码库
git init [project-name] 新建一个目录,将其初始化为git代码库
git clone [url] 下载一个项目和它的整个代码历史
git config --list 显示当前的git配置
git config -e [--global] 编辑git配置文件 git config [--global] user.name "[name]" 修改配置设置提交代码时的用户信息,例如:git config --global user.name "bryan sun"
git add [file1] [file2] ... 添加指定文件到缓存区
git add [dir] 增加指定目录到缓存区,包含子目录
git add . 增加当前目录的所有文件到存储区
git status 查看缓存区文件
git rm --cached [file] 删除缓存区的指定文件,不删除物理文件
git rm --cached -r [dir] 删除缓存区指定目录下的所有文件,不删除物理文件
git rm --f [file] 删除缓存区的指定文件,物理文件删除(不会回收到垃圾桶),慎重操作
git rm --f -r [dir] 删除缓存区指定目录下的所有文件,物理文件删除(不会回收到垃圾桶),慎重操作
判断是否为undefined // 方法一 var a=undefined; if (typeof(a) == "undefined"){ console.log("undefined"); } // 方法二 var a=undefined; if(a === undefined){ console.log("undefined") } 判断是否为null var b= null; if (!b && typeof(b)!="undefined" && b!=0){ console.log("null"); } 需要注意以下写法
var a=undefined; var b=null; if(a==null){ // 成立 console.log("成功输出") } if(a===null){// 不成立,无输出 console.log("成功输出") } if(b===null){// 成立 console.log("成功输出") } 简单说明下"“和”=":==是用来检测两个操作数是否相等的,是“值比较”,===是严格校验两个操作数是否严格相等,包括“值比较”和“类型比较”。
判断是否为NaN var c= 0/0; if (isNaN(c) ){ console.log("NaN"); } NaN 表示非法,如果把 NaN 与任何值(包括其自身)作比较结果均是 false,所以不能使用 == 或 === 运算符判断某个值是否是 NaN。
公式 ="0x"&RIGHT("00"&DEC2HEX(A3),2)
解释 "0x",左侧加上0x
DEC2HEX(A3),把A3数据转换成十六进制,此时1会变成1,10会变成a,没有补零
RIGHT("00"&DEC2HEX(A3),2),十六进制的值左侧加上00,然后取右侧两位
问题 需要根据保留的位数来决定补多少零
其他 可以不用补零
="0x"&DEC2HEX(A3)
故事背景:
以前也碰到过类似的问题,当时由于时间和工作问题就暂时搁置了这个问题,最近想在本地电脑备份数据库却频繁遇到这个问题。
原因:
以前我是用的windows7,当时什么都配置好了的,现在换了Windows10,就用不了了。
解决思路:
开始以为是mysql权限的问题,我又新建了用户重新赋予了所有权限,结果还是不行。网上看了一些帖子,感觉都不是我的问题,不过进过耐心寻找发现了蛛丝马迹(其实这个方法我之前用过,只是时间久了没想起来)。最后的思路就是用管理员身份启动Navicat。
测试:
用管理员身份启动Navicat后,再新建备份和设置计划任务,测试成功。事实证明,这个情况跟mysql用户权限没有关系!
END
jetson上推出的最新的工具jetson-io,这个工具极大的方便了开发者使能jetson上的种种接口,如SPI I2C GPIO等。
官方的文档链接:https://docs.nvidia.com/jetson/l4t/index.html#page/Tegra%20Linux%20Driver%20Package%20Development%20Guide/hw_setup_jetson_io.html
打开终端输入:
/opt/nvidia/jetson-io/jetson-io.py
如果不是root权限,命令前加sudo
然后报错了:
解决方法:
执行如下命令:
find /opt/nvidia/jetson-io/ -mindepth 1 -maxdepth 1 -type d -exec touch {}/__init__.py \;
重新执行 /opt/nvidia/jetson-io/jetson-io.py
选中 Configure 40-pin expansion header 之后
按空格键,即可配置一些外设了。
之后选择: Save and reboot to reconfigure pins 即可。
xavier 40引脚图;
跟据日期字段,为表格增加年、 月、日3个字段 = Table.FromRows( List.Transform(Table.ToRows(ZCESRSET_Table),each _ & [a=_{0}, b=List.Transform({Date.Year,Date.Month,Date.Day},each _(a))][b]) ,Table.ColumnNames(ZCESRSET_Table)&{"交易日期年","交易日期月","交易日期日"} ) 上述公式分解: 基础数据类型 种类文本Nullnull逻辑true false数字0 1 -1 1.5 2.3e-5时间#time(09,15,00)Date#date(2013,02,26)DateTime#datetime(2013,02,26, 09,15,00)DateTimeZone#datetimezone(2013,02,26, 09,15,00, 09,00)Duration#duration(0,1,30,0)文本“hello”二进制#binary(“AQID”)列表{1, 2, 3}记录[ A = 1, B = 2 ]表格#table({“X”,“Y”},{{0,1},{1,0}})Function(x) => x + 1类型type { number } type table [ A = any, B = text ] List.Transform相当于For循环 {Date.Year,Date.Month,Date.Day}是数组,”each _“中的”下划线“就形参,指向数组中的每个值,这里的值是Date.Year、Minth、Day函数。#date(2021,8,19)是日期格式的值。“_(#date(2021,8,19))”,是函数执行,函数的参数正是这个日期值。注意:在List.Transform()的作用域中,只能用下划线做形参"_",如果像下面这种情况,循环中有循环,那么内层循环中的下划线就是指向内层数组的值的,如果要引用外层的值,下面借助记录Record的方法来构造是可以的。 = List.Transform({Date.Year,Date.Month,Date.Day},each _(#date(2021,8,19))) 借助记录Record,返回待拼接的数组 相当于有个匿名字典{‘a’:‘2021-8-19’,‘b’:[2021,8,19]}[‘a’],我们要获取中b的值,b的值是一个数组。a=_{0}是获取a的第一项。 [a=_{0}, b=List.Transform({Date.Year,Date.Month,Date.Day},each _(a))][b] Table.ToRows() 表函数,将表的第1-n行数据,对应放进第1-n个数组里面,每个数组里就是各行每列的值,最后返回这n个数组拼起来的二维列表。 总结:增加3列的思路正是将表对象,转为二维列表,将每行的子列表,去增加年、月、日这3个元素,最后再转会表对象。
列表增加元素,用”&“符号连接,不过元素要放在数组里,实际是数组和数组的连接~ Table.ColumnNames() 表函数,返回表格对象的标题数据,放在一维列表里。 Table.FromRows(arr,list) 将二维列表转为表格对象,arr是二维列表,list是标题的一维数组。注意:power query中的数组是用花括号"{"包裹的,而不是中括号”[“,中括号包裹的是Record,这个有点像字典,它必须是一维的,如果你想二维那就要把每个Record装在列表里。。 常用方法 方法结果Text.
最长公共子序列运用十分广泛,例如人脸识别,相似度比较等方面。子序列表示原字符串在不改变字符的相对顺序的情况下删除某些字符(也可以不删除任何字符)后组成的新字符串。
比如:“abc”,“ac”是子序列,但“ca”不是
实现代码:
/** * 最长公共子序列 * * @param a * @param b */ public int longestCommonSubsequence(String a, String b) { // a b c b a // b 0 1 1 1 1 // c 0 1 2 2 2 // a 1 1 2 2 3 int[][] dp = new int[b.length() + 1][a.length() + 1];//加一行一列处理方便 for (int i = 0; i < b.length(); i++) {//遍历行 char col = b.
使用grafana创建图表时,出现错误提示:
Column metric must be of type UNKNOWN, TEXT, VARCHAR, CHAR. metric column name: metric type: INT4 but datatype is int64 意思是指准备作为metric的字段为数值类型,不支持。
需要将选择的字段数值修改为字符格式使用。
方法一:
select cast(字段 as varchar) from 表名 方法二:
select convert(varchar(50),字段) from 表名
最近洗数据的时候出现了这个错误,查了下,记录
这是两个series类型数据进行对比的时候其中有一个index不连续造成的报错,解决方式就是重设index
df.reset_index(drop=True)
在项目开发过程中,我使用的是IEDA2021的新版,由于需要使用Lombok插件,发现通过setting->plugin里面搜索Lombok居然不存在。后来去官网发现了问题,这是因为lombok官方还没有更新Lombok版本至2021版的,所以暂不支持在IDEA中安装Lombok插件。
但是我确实需要使用Lombok,并且不想再重新安装IDEA2020版,因为那样太麻烦,需要整个项目环境全部重新配置,该怎么办呢?下面是我的解决办法,希望对你有所帮助:
一、进入官网下载
官方网址:
Versions: Lombok - IntelliJ IDEA & Android Studio Plugin | Marketplace (jetbrains.com)
选择最新版本下载,下载后会得到一个压缩包。
二、修改压缩包中的plugin.xml配置文件
直接打开我们已经下载好的压缩包,不要解压!!!找到lombok-plugin-2020.2.jar文件,使用压缩工具将它打开,注意,这里不能解压,因为你解压了去修改里面的文件后就无法还原成jar包了。直接打开即可修改里面的文件保存!
打开后找到META-INF文件
这个文件里面有个叫plugin.xml的配置文件,我们使用记事本打开它即可编辑
修改idea-version since-build="XXX" until-build="XXX",这里我的是已经修改完成后的效果,2020版的Lombok应该是202,将这两处修改为IDEA对应的版本号即可。IDEA版本号的查看方式:Help->About
三、将压缩包文件导入IDEA
打开我们的IDEA,点击setting->plugin,然后点右上角的一个设置按钮,如下图所示
将我们修改完成后的压缩包导入进来即可,完美解决Lombok的安装问题!
欢迎留言交流以及指出笔者的不足之处,谢谢!
1.编辑脚本内容
#!/bin/bash # while true do Process_ID=`ps -ef |grep 'java-0.0.1-SNAPSHOT.jar' |grep -v grep |awk '{print $2}'` Cookie_DIR=/home/test kill -9 $Process_ID cd $Cookie_DIR nohup java -jar java-0.0.1-SNAPSHOT.jar.jar & -Xmx256M sleep 1h done 2.将脚本上传至服务器,与jar包同目录
3.为start.sh脚本文件添加执行权限,执行命令:chmod u+x start.sh,u代表所有者,x代表执行权限。 + 表示增加权限。
4.后台启动start.sh,执行命令
nohup /home/test/start.sh &
提要 此文分别就qt生成纯代码的动态库,含有ui文件的动态库以及含有资源文件qss文件和切图的动态库。
实现 1.纯代码的生成qt库。即没有ui文件的项目。
打开QtCreate,新建文件,选择library.
接下来填写项目的名称,选择生成的路径,然后到下图所示步骤。
选择共享库,包含的模块采用默认的Core,由于这里只能选择一个模块,后面再在pro文件中添加所需的模块。类名可以自己修改。然后下一步后到了选择编译器,根据自己需要选择,然后再下一步。到此生成了项目。
如下图:
打开pro文件,可以看到此时不包含gui模块,因为我们此项目不需要ui界面,所以不改动这个,不过可以通过DESTDIR 参数来指定生成的动态库的位置,这里指定的生成的动态库保存在工程目录下的生成的文件夹mydll下。
QT -= gui TEMPLATE = lib DEFINES += ONEDLL_LIBRARY CONFIG += c++11 # The following define makes your compiler emit warnings if you use # any Qt feature that has been marked deprecated (the exact warnings # depend on your compiler). Please consult the documentation of the # deprecated API in order to know how to port your code away from it.
作者:柒穆雨
链接:https://www.zhihu.com/question/266905252/answer/1291113683
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
ps一部分作品集:
PS可以实现的功能分为两大块:一块是图像处理功能,一块是绘图功能。
图像处理功能:
是指用计算机对图像进行分析,以达到所需结果的技术。又称图片处理、影像处理、照片处理、后期处理、P图、PS。
图像绘制功能:
是要用PS创造出全新的图片,这不仅仅要求用户掌握PS的操作,还要具备一定的美术和绘画基础这样更容易上手。
ps:美术和绘画基础仅限于容易上手,并不代表没有这方面的基础九不能做设计学习ps,希望大家不要误解。
首先你是希望前期艰难一点少赚点,后期厚积薄发,持续乐观收入?还是希望细水长流,比较平均的收入?
前者进入电商公司,设计公司。现在的美工需求还是比较大的,但是如果是没有什么修图经验和比较好的作品案例,前期会收入非常低,非常难熬。但是这段时间只要不怕苦,你会快速积累经验,所有的理论转化成实用的技巧。有一段时间之后,慢慢的可以接一些私单外快(身边有朋友在家待业接兼职单,一单少则五六百,多的一单一两万),收入逐步提高。有个几年之后,可以选择自己开工作室,也可以往高级的设计师发展。
后者就是老老实实找一份工作,有一份稳定收入前提,将修图作为副业。但是经验累积很慢,所以这个需要自己私下的大量练习研究,需要一定的主动性积极性。整体上收入会慢慢增加,虽然比不上前者一单收入那么丰厚,但是经过长时间之后,副业收入还是可能会超过主业。
方法一:块选择模式
1. 插入注释:
① 按 “Esc” 进入命令行模式
② 按 “Ctrl + v” 进入可视化块模式
③ 利用上下左右键调整需要注释的行数及行的宽度
④ 再按 “Shift + i” 进入插入模式
⑤ 输入注释符号,如:“#”、“//”
⑥ 再次按 “Esc” ,即可完成多行注释 【一定要记得这一步哦~】
2. 取消注释:
① 按 “Esc” 进入命令行模式
② 按 “Ctrl + v” 进入可视化块模式
③ 利用上下左右键调整需要注释的行数及行的宽度
④ 再按d即可完成去注释
方法二:sed替换
1. 插入注释:
① 按 “Esc” 进入命令行模式
② 输入以下命令:
:起始行,结束行s/^/注释符号/g 2. 去注释:
① 按 “Esc” 进入命令行模式
② 输入以下命令:
:起始行号,结束行号s/^注释符号//g
1.使用npm安装
npm install dingtalk-jsapi --save 2.在所需要的界面js,引入
import * as ddcode from "dingtalk-jsapi"; 3\
scanCode(){ ddcode.biz.util.scan({ type: String , // type 为 all、qrCode、barCode,默认是all。 onSuccess: function(data) { //onSuccess将在扫码成功之后回调 /* data结构 { 'text': String} */ console.log(data.text) }, onFail : function(err) { alert('失败') } }) } html:
<view class="scanCode" onTap="scanCode">扫一扫</view>
Date对象 https://www.w3school.com.cn/js/js_obj_date.asp Date() 返回当日的日期和时间。 getDate() 从 Date 对象返回一个月中的某一天 (1 ~ 31)。 getDay() 从 Date 对象返回一周中的某一天 (0 ~ 6)。 getMonth() 从 Date 对象返回月份 (0 ~ 11)。 getFullYear() 从 Date 对象以四位数字返回年份。 getYear() 请使用 getFullYear() 方法代替。 getHours() 返回 Date 对象的小时 (0 ~ 23)。 getMinutes() 返回 Date 对象的分钟 (0 ~ 59)。 getSeconds() 返回 Date 对象的秒数 (0 ~ 59)。 getMilliseconds() 返回 Date 对象的毫秒(0 ~ 999)。 getTime() 返回 1970 年 1 月 1 日至今的毫秒数。 getTimezoneOffset() 返回本地时间与格林威治标准时间 (GMT) 的分钟差。 getUTCDate() 根据世界时从 Date 对象返回月中的一天 (1 ~ 31)。 getUTCDay() 根据世界时从 Date 对象返回周中的一天 (0 ~ 6)。 getUTCMonth() 根据世界时从 Date 对象返回月份 (0 ~ 11)。 getUTCFullYear() 根据世界时从 Date 对象返回四位数的年份。 getUTCHours() 根据世界时返回 Date 对象的小时 (0 ~ 23)。 getUTCMinutes() 根据世界时返回 Date 对象的分钟 (0 ~ 59)。 getUTCSeconds() 根据世界时返回 Date 对象的秒钟 (0 ~ 59)。 getUTCMilliseconds() 根据世界时返回 Date 对象的毫秒(0 ~ 999)。 parse() 返回1970年1月1日午夜到指定日期(字符串)的毫秒数。 setDate() 设置 Date 对象中月的某一天 (1 ~ 31)。 setMonth() 设置 Date 对象中月份 (0 ~ 11)。 setFullYear() 设置 Date 对象中的年份(四位数字)。 setYear() 请使用 setFullYear() 方法代替。 setHours() 设置 Date 对象中的小时 (0 ~ 23)。 setMinutes() 设置 Date 对象中的分钟 (0 ~ 59)。 setSeconds() 设置 Date 对象中的秒钟 (0 ~ 59)。 setMilliseconds() 设置 Date 对象中的毫秒 (0 ~ 999)。 setTime() 以毫秒设置 Date 对象。 setUTCDate() 根据世界时设置 Date 对象中月份的一天 (1 ~ 31)。 setUTCMonth() 根据世界时设置 Date 对象中的月份 (0 ~ 11)。 setUTCFullYear() 根据世界时设置 Date 对象中的年份(四位数字)。 setUTCHours() 根据世界时设置 Date 对象中的小时 (0 ~ 23)。 setUTCMinutes() 根据世界时设置 Date 对象中的分钟 (0 ~ 59)。 setUTCSeconds() 根据世界时设置 Date 对象中的秒钟 (0 ~ 59)。 setUTCMilliseconds() 根据世界时设置 Date 对象中的毫秒 (0 ~ 999)。 toSource() 返回该对象的源代码。 toString() 把 Date 对象转换为字符串。 toTimeString() 把 Date 对象的时间部分转换为字符串。 toDateString() 把 Date 对象的日期部分转换为字符串。 toGMTString() 请使用 toUTCString() 方法代替。 toUTCString() 根据世界时,把 Date 对象转换为字符串。 toLocaleString() 根据本地时间格式,把 Date 对象转换为字符串。 toLocaleTimeString() 根据本地时间格式,把 Date 对象的时间部分转换为字符串。 toLocaleDateString() 根据本地时间格式,把 Date 对象的日期部分转换为字符串。 UTC() 根据世界时返回 1970 年 1 月 1 日 到指定日期的毫秒数。 valueOf() 返回 Date 对象的原始值。 var time = new Date() // 用\对/符号进行转义 console.
官网:https://www.npmjs.com/package/vue-countdown
demo:https://www.helloweba.net/javascript/585.html
使用方式:https://blog.csdn.net/weixin_43526371/article/details/110517581?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522162934182816780357272285%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=162934182816780357272285&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_v2~rank_v29-5-110517581.first_rank_v2_pc_rank_v29&utm_term=vuex-persist+%E6%80%8E%E4%B9%88%E4%BD%BF%E7%94%A8&spm=1018.2226.3001.4187
https://blog.csdn.net/jacklam200/article/details/3336815
1、torch1.8.0的bug
RuntimeError: radix_sort: failed on 1st step: cudaErrorInvalidDevice: invalid device ordinal
升级1.8.1解决
2、torch1.8.1的bug
问题1解决之后又会出现类似下面的错误
/pytorch/aten/src/ATen/native/cuda/IndexKernel.cu:142: operator(): block: [0,0,0], thread: [13,0,0] Assertion index >= -sizes[i] && index < sizes[i] && "index out of bounds" failed. /pytorch/aten/src/ATen/native/cuda/IndexKernel.cu:142: operator(): block: [0,0,0], thread: [16,0,0] Assertion index >= -sizes[i] && index < sizes[i] && "index out of bounds" failed. /pytorch/aten/src/ATen/native/cuda/IndexKernel.cu:142: operator(): block: [0,0,0], thread: [19,0,0] Assertion index >= -sizes[i] && index < sizes[i] && "
直接拿出大学时候的51单片机就开始回顾总结吧。首先关于什么是单片机,我觉得解释起来没那么麻烦,原来学习的时候听这些人说的高大上,然后自己就为了学个这个还有多次入门,多次放弃,多次从入门到放弃,现在想来真是傻透了,其实单片机是啥,其实就是一个可以编写程序然后让它能输出高低电平的东西,其实就是这么简单,不用想的特别复杂。至于51单片机,其实就是有个单片机类叫做51单片机,至于具体的谁care呢,至于C语言,学过两天就能搞,实在不行就再拿本书翻翻呗,当然我也会回顾,但不是现在啦,用到哪儿实在不会了再去查呗,边回忆边学习。那就直接开始吧。
1. 硬件
首先单片机编程是一个先由硬件再到软件的过程,要编程就需要先看一个东西,叫做开发板原理图,我们首先第一个回忆的是led灯,那先打开开发板原理图:
我们可以看到VCC在左边,之后经过一个二极管然后经过电阻到达p20到p27口。那其实就是说假如我们右边给了一个低电平,那么我们就可以让led灯亮起来,那其实说来就是说这样我们就能点亮一个led灯了。
2. 软件:
那我们可以试着先点亮一个灯,程序如下
/* 点亮一个led灯程序 */ #include "reg52.h" sbit led = P2^0; void delay(int xus){ while(x--); } void main(){ while(1){ led = 0 delay(10000000); led = 1; delay(10000000) } } 至于为啥会有“reg52.h”头文件,其实就是说你为了能操作这个芯片,其实它内部是有一些寄存器的,你需要去包含它,这个头文件里面就有对应的寄存器的声明。sbit是C语言不存在的一个数据类型,其实就是定义P2^0这个位,while循环里面就是先给它一个低电平,延迟一段时间再给它一个高电平,这样就能使得这个led灯亮灭。
接下来我们其实还可以同时点亮多个led灯,很多人都可能会想到使用API来写这个,关于API其实就是一些大神写好的函数,就比如我上面的写的delay函数一样,我们直接调用就好了,但是我觉得才开始还是可以考虑自己写一个比较好,下面就是我写的关于led流水灯的内容:
#include "reg52.h" unsigned char led = 0xff; void delay(int xus){ while(xus--); } void main(){ int i; while(1){ for(i = 0;i < 8;i++){ P2 = led & (~(1 << i)); delay(1000000); } } } 哈哈,其中还是有些位运算比较难的,但是位运算还是需要学会吧,关于这个位运算这种东西还是可以多算,就很快就会有感觉啦。当然还是有些小公式需要记住,比如把某一位置0,或者是某一位置1,这个比较简单,就不回顾啦。
使用dom4j解析xml 实现效果实现 实现效果 使用dom4j,实现将一个books.xml,解析为book类的对象:
1、xml文档
2、book类的信息
3、转化后的情况
实现 1、导入dom4j的相关jar包,以及用于单元测试的相关jar包
2、xml文档的内容:
<?xml version="1.0" encoding="UTF-8"?> <books> <book sn="SN12341232"> <name>辟邪剑谱</name> <price>9.9</price> <author>班主任</author> </book> <book sn="SN12341231"> <name>葵花宝典</name> <price>99.99</price> <author>班长</author> </book> </books> 3、book类的情况:
package com.athanchang.pojo; import java.math.BigDecimal; /** * @author zhangmengfei * @create 2021-08-18 21:20 */ public class book { private String sn; private String name; private BigDecimal price; private String author; //get()、set() //构造器 //快捷键:alt+shift+s public book(String sn, String name, BigDecimal price, String author) { this.
畸变 In geometric optics, distortion is a deviation from rectilinear projection; a projection in which straight lines in a scene remain straight in an image. It is a form of optical aberration.
畸变是像差的一种,它在感官上给人一种错觉(即原本直线变成了曲线),但图像的信息不会丢失。
本文主要介绍畸变的两种处理方式,一种是去畸变,一种是预畸变。
去畸变 根据相机的畸变系数,利用opencv中的undistort函数或者initUndistortRectifyMap和remap相结合即可完成畸变的去除,非常的简单。但是大多数情况下,对于手里的相机,我们是不知道相机的畸变系数,这时候就需要进行畸变标定。
畸变标定 获取畸变系数,通常有以下几种方法:
通过相机的参数规格中得到(几乎是废话)基于3D/2D点的映射关系(如,张正友标定大法)基于3D世界中直线在图像中仍是直线(如,铅锤法)其他行业内的高精度标定方法 opencv中采用的是张正友标定法,通过拍摄一系列棋盘格图像,通过多视图几何推导出内参和外参的解析解作为优化的初值,畸变系数初值为0,然后利用LM优化算法,以重投影误差为目标进行优化。
opencv可以对14个畸变系数进行标定,分别为:
k1 k2 k3 k4 k5 k6 径向畸变系数 p1 p2 切向畸变系数 s1 s2 s3 s4 薄棱镜畸变系数 t1 t2 倾斜图像传感器的梯形畸变(Matrix for trapezoidal distortion of tilted image sensor) 其畸变公式,从形式上看布朗模型和除法模型( Fitzgibbon)的结合
x d i s t = x ∗ 1 + k 1 ∗ r 2 + k 2 ∗ r 4 + k 3 ∗ r 6 1 + k 4 ∗ r 2 + k 5 ∗ r 4 + k 6 ∗ r 6 + p 1 ∗ ( 2 ∗ x ∗ y ) + p 2 ∗ ( r 2 + 2 ∗ x 2 ) + s 1 ∗ r 2 + s 2 ∗ r 4 x_{dist} = x * \frac{1 + k1 * r^2 + k2 * r^4 + k3 * r^6}{1 + k4* r^2 + k5 * r^4 + k6 * r^6} + p1 * (2*x*y)+p2*(r^2+2*x^2)+s1*r^2+s2*r^4 xdist=x∗1+k4∗r2+k5∗r4+k6∗r61+k1∗r2+k2∗r4+k3∗r6+p1∗(2∗x∗y)+p2∗(r2+2∗x2)+s1∗r2+s2∗r4
封装 go语言中可以简单地看作对struct的封装
type Person struct { name string } type Student struct { name string } type Teacher struct { name string } 继承 go语言中没有继承,但可以通过“匿名组合”实现继承
结构体继承,方法继承,方法重写
//父类 type Person struct { name string age int } type Student struct { Person //匿名继承 //*Person //指针作为匿名字段 //p Person//别名继承 height string //子类和父类字段重名 name string } type Teacher struct { Person //匿名继承 //*Person //指针作为匿名字段 //p Person//别名继承 sex string } //基本类型不能作为对象直接使用,为基本类型绑定方法,需要起别名才可以 type newint int func (i newint) add(a newint) newint { return a + 1 } //方法继承和重写(给结构体绑定方法) //*代表是否可以读写(修改),*代表接收者为指针 func (p *Person) eat(){ fmt.
Nextjs中ts语法中使用全局变量 1、项目根目录增加文件cons.ts const globalAny: any = global; globalAny.Cons = { cndDomain: "https://xxxxxx" } export { } 增加一个声明文件,写入以下代码
declare const Cons: any; 2、_app.tsx中引入文件 import '../cons' import type { AppProps } from 'next/app' function MyApp({ Component, pageProps }: AppProps) { return <Component {...pageProps} /> } export default MyApp 3、其他文件中使用 <Image src={`${Cons.cndDomain}/static/logo2.png`} alt="--" width={140} height={40} />
目录
一.ARP协议概述
二.ARP相关命令
三.原理演示
四.ARP攻击原理
总结
一.ARP协议概述
1.局域网中主机的通信
IP地址与mac地址,ARP缓存包含IP与mac映射
arp -a 获取本地主机ARP缓存
2.ARP协议及使用场合(工作原理)
Address Resolution Protocol ,正向地址解析协议
将一个已知的目标IP地址解析成对应的MAC地址
数据传输通讯地址:源IP,源MAC,目标IP,目标MAC
使用场合:已知目标IP,未知MAC时使用
工作原理:PC1已知PC2的IP地址,未知PC2的MAC时候用。PC1发送ARP广播给二层交换机,二层交换机接收到ARP广播消息后无条件泛洪处理,连接到二层交换机下的所有PC都将接收到此广播消息,每个PC都会把自身的IP地址和目标IP地址进行比对,若一致则接收此广播消息,并回数据包给PC1,PC1接收到返回的数据包后会记录下PC2的IP和MAC地址,记录到ARP缓存中;若不一致则丢弃处理。
RARP:反向地址解析协议
使用场合:已知目标mac,未知目标IP使用用
二.ARP相关命令
1.windows下的ARP命令
arp -a 查看ARP缓存表
arp -d ip地址或* 清除ARP缓存
arp -s IP地址 MAC地址 ARP绑定
2.华为内的arp命令
<A>/[A]display arp 查看ARP
[A]arp static 192.168.0.11 aaaa-aaaa-aaaa 捆绑ARP
<A>reset arp static 清除静态ARP
<A>reset arp all 清除所有ARP
三.原理演示
1需求分析
对等网的环境
PC1和PC2的第一次通信
实现步骤
1使用ipconfig /all 查看PC1和PC2的MAC地址
2用“arp -a”查看ARP缓存
3在PC1上ping PC2后,再用“arp -a”查看ARP缓存表
四.ARP攻击原理
1.欺骗其他所有计算机
根据手册,BOOT0引脚的使用,需要nBOOT_SEL为0;当nBOOT_SEL为1时,启动模式完全由Option Bytes控制。
STM32系列芯片程序启动方式分为下面三种:
Main Flash memory 从主Flash启动,正常的工作模式;System memory 从系统存储器启动,串口ISP下载程序;嵌入式SRAM 从内存启动,用于调试; Option Bytes配置,下面举例配置nBOOT_SEL的方式:
//nBOOT_SEL置0 FLASH_OBProgramInitTypeDef OBInit; HAL_FLASHEx_OBGetConfig(&OBInit); OBInit.USERConfig &= (~OB_USER_nBOOT_SEL); HAL_FLASH_Unlock(); HAL_FLASH_OB_Unlock(); HAL_FLASHEx_OBProgram(&OBInit); HAL_FLASH_OB_Lock(); HAL_FLASH_Lock(); //nBOOT_SEL置1 //OBInit.USERConfig |= OB_USER_nBOOT_SEL;
1、Vuex目录结构 讲解这些属性之前,我们先看项目的store目录结构和主要代码:
app/index/store/index.js代码:
import Vue from "vue"; import Vuex from "vuex"; import mutations from "./mutations"; import actions from "./actions"; Vue.use(Vuex); const state = { userInfo: null, role: "", currentSearch: {} }; export default new Vuex.Store({ state, actions, mutations, modules: {} }); app/index/store/mutation-type.js代码:
export const SET_USER_INFO = "SET_USER_INFO"; export const SET_ROLE = "SET_ROLE"; export const SET_CURRENT_SEARCH = "SET_CURRENT_SEARCH"; app/index/store/mutation.js代码:
import * as types from "./mutation-types"; export default { [types.SET_USER_INFO](state, userInfo) { state.
嵌入式要学习哪些内容?
嵌入式概括一下就是写程序,用软件控制硬件。嵌入式的学习应该是自上而下的。 1.语言先行
首先是写代码,写用户的应用程序。每种语言的使用目的是不同的,我们嵌入式选择的语言是C语言。
所以首先要学习C语言的基本语法,C库提供了大量的函数,我们可以调用以实现一些功能。所以还要熟悉C库的常用函数。
C语言一定要学好,它是基础。Linux内核大部分也是用C语言实现的。
2.系统认知
在学习C语言的过程中,可以适当学会Linux系统的基本使用。你可能没有听说过Linux,但你肯定听说过windows,系统有很多共通之处。可以在学习过程中对比理解。
而且Linux系统提供了C语言的编辑器gcc,你可以在系统上写完代码之后,在系统上编译并运行,这样,在学习C语言的阶段你也熟悉了Linux系统的使用。
3.数据结构
当你学完了C语言的基本语法,此时你的c语言水平只是入门阶段。你还要学习一门没有新知识的课程----数据结构。这门课程就是大量的使用指针、数组、结构体、函数。经过这个阶段你才能算是掌握了C语言。
而且后面学习内核的过程中,内核中也是有大量的链表之类的数据结构的。
4.内核
Linux的内核包括以下几个部分:进程管理、内存管理、网络堆栈、虚拟文件系统、设备驱动等。
内核是一个系统最重要的部件。想要真正的认识它需要你一步一步的积累。这个阶段推荐大家先依次学习文件IO、进程线程、网络编程。
你要学习这些功能实现的相关函数,即上图中的系统调用接口。我们要用系统提供的函数,写代码实现对应的功能。可以先不深究这些功能是如何实现的。先学会应用。
5.设备驱动
驱动是硬件和应用程序之间的桥梁,如果一个应用程序要操作硬件,必须要有驱动。
一句话总结:驱动就是根据相应的硬件,写出驱动程序作为调用接口提供给用户,用户使用该接口就可实现控制硬件的目的。
其次,在驱动的学习中,我们会慢慢学习内核。内核的各种模块,内核源码等等。
6.硬件
对于一个嵌入式工程师来说,能够看懂电路图即可。即只需要掌握基本的电路知识,看懂电路图。至于开发板的画图、布线、腐蚀、焊接等步骤,可以不必深入研究。这些技能是属于硬件工程师们的要求。
7.关于其他
首先,一个程序员双语很重要,你学习了面向过程的C语言,推荐大家掌握一门面向对象的语言,可以是c++、java或者python都可。
其次,你要单独实现一个完整的项目,UI界面部分必不可少。做页面可以用qt、可以用网页、也可以用手机端。这可以使你自己做的项目更加完善。
最后,前面我们说到嵌入式硬件是很多种类的,建议大家也学习一下不需要系统的裸机开发STM32.也是属于嵌入式的范畴。
使用jQuery实现展示列表的全展示与精简展示 实现效果代码 实现效果 (1)列表的全部展示(此时,可以对部分强调内容实现 加亮)
(2)列表的精简展示(实现对于部分列表内容的展示)
代码 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>品牌展示练习</title> <style type="text/css"> * { margin: 0; padding: 0; } body { font-size: 12px; text-align: center; } a { color: #04D; text-decoration: none; } a:hover { color: #F50; text-decoration: underline; } .SubCategoryBox { width: 600px; margin: 0 auto; text-align: center; margin-top: 40px; } .SubCategoryBox ul { list-style: none; } .
以FMCW体制的雷达为例
一、从原始信号处理的角度出发
根据TI公司那位经典印度老哥的视频,距离分辨率可以如此计算:
假设FMCW的Slope为 S S S,那么在一个chirp内接收到的两个相差时间为 δ t \delta t δt的信号所对应的频率可以写为
δ t ⋅ S = δ B \delta t \cdot S = \delta B δt⋅S=δB
这样问题就转化成了频率区分的问题,于是
δ t ⋅ S = δ B ≥ f m i n = 1 / T \delta t \cdot S = \delta B \geq f_{min}=1/T δt⋅S=δB≥fmin=1/T,其中 T T T为观察时长,即ChirpDuration。
如此:
δ d = c / 2 ⋅ δ t ≥ c / ( 2 B ) \delta d =c/2 \cdot \delta t \geq c/(2B) δd=c/2⋅δt≥c/(2B)(当然同时还需要考虑本身的快时间采样率上限)。
你可能会想到,可以用 bgsave 避免阻塞啊。这里我就要说到一个常见的误区了,避免阻塞和正常处理写操作并不是一回事。此时,主线程的确没有阻塞,可以正常接收请求,但是,为了保证快照完整性,它只能处理读操作,因为不能修改正在执行快照的数据。
Redis 会使用 bgsave 对当前内存中的所有数据做快照,这个操作是子进程在后台完成的,这就允许主线程同时可以修改数据。
packer 是TK的几何管理机制之一。几何管理器用于指定小部件在其容器中的相对位置。packer 采用定性关系规范–above, to the left of, filling,等–并为您确定准确的放置坐标。
任何主部件的大小由内部“从部件”的大小决定。packer用于控制从部件在主部件中的位置,从部件被打包到主部件中。您可以将小部件打包到frame中,将frame打包到其他frame中,以实现您希望的布局类型。此外,一旦配置被打包,该配置就被动态调整以适应对配置的增量变化。
注意,部件在用几何图形管理器指定了几何图形之后才会出现。忽略几何规范是一个常见的早期错误,然后当小部件创建后却什么也没有出现时会感到惊讶。一个部件只有在应用了packer的pack()方法之后才会出现。
以下是一些例子:
fred.pack() # defaults to side = "top" fred.pack(side="left") fred.pack(expand=1) pack(self, cnf={}, **kw)
Pack a widget in the parent widget. Use as options:
after=widget - pack it after you have packed widget
anchor=N S E W (or subset) - position widget according to
given direction
before=widget - pack it before you will pack widget
expand=bool - expand widget if parent size grows
官网:https://www.sonarqube.org/
1.sonar简介 sonar是一款静态代码质量分析工具,支持Java、Python、PHP、JavaScript、CSS等25种以上的语言,而且能够集成在IDE、Jenkins、Git等服务中,方便随时查看代码质量分析报告。
sonar通过配置的代码分析规则,从可靠性、安全性、可维护性、覆盖率、重复率等方面分析项目,风险等级从A~E划分为5个等级;
同时,sonar可以集成pmd、findbugs、checkstyle等插件来扩展使用其他规则来检验代码质量。
2.sonar组成 一个sonar项目主要有以下四个组件构成:
一台SonarQube Server启动3个主要过程:
Web服务器,供开发人员,管理人员浏览高质量的快照并配置SonarQube实例
基于Elasticsearch的Search Server从UI进行后退搜索
Compute Engine服务器,负责处理代码分析报告并将其保存在SonarQube数据库中
一个SonarQube数据库要存储:
SonarQube实例的配置(安全性,插件设置等)
项目,视图等的质量快照
服务器上安装了多个SonarQube插件,可能包括语言,SCM,集成,身份验证和管理插件。
在构建/持续集成服务器上运行一个或多个SonarScanner,以分析项目。
3.sonarquebe安装 1.jdk下载 sonar7.9.6需要jdk11以上版本,因此我们采用jdk11,下载后上传服务器
2.安装postgresql数据库 yum install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm yum install -y postgresql13-server /usr/pgsql-13/bin/postgresql-13-setup initdb systemctl enable postgresql-13 systemctl start postgresql-13 创建数据库
#先切换到postgres用户 su - postgres # 执行创建指令 psql create user sonarqube with password 'sonarqube'; create database sonarqube owner sonarqube; grant all on database sonarqube to sonarqube; \q su - 3.下载sonar社区版 https://binaries.
使用jQuery实现动态添加和删除行 实现效果代码 实现效果 代码 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Untitled Document</title> <link rel="stylesheet" type="text/css" href="styleB/css.css" /> <script type="text/javascript" src="../../script/jquery-1.7.2.js"></script> <script type="text/javascript"> $(function () { //代码优化 /* * 创建一个用于复用的function函数 * 绑定delete的的单击事件 */ var deleteFun = function () { 在事件响应的function函数中,有一个this对象。这个this对象,就是当前正在响应的事件的DOM对象 //我们可以通过this,获取它的父元素,的父元素。就可以知道要删除的是哪一行 var $trObj = $(this).parent().parent(); //这一行的第一个td的标签中间的值 var name = $trObj.find("td:first").text(); //当用户点击了确定,就返回true; //当用户点击了取消,就返回false。 //confirm是JavaScript的确认提示框函数,你给它传什么,它就提示什么 if(confirm("确认是否删除["+ name +"]选项?")){ //点击了确定----要删除 $trObj.remove(); } //return false:可以阻止元素的默认行为 return false; } //先做添加功能----给submit按钮绑定单击事件 $("
前言 在设计GUI的时候可以使用三种方法包装盒定位各个组件在容器或窗口中的位置,这三个方法又称之为窗口控件配置管理员(Widget Layout Manager)
(1)pack方法
(2)grid方法
(3)place方法
实践一 pack()方法 虽然称为pack方法,其实在tkinter中这是一个类别,也是最常用的控件配置管理方法,使用的是相对位置的概念处理控件配置,语法如下:
pack(options,……)
options的参数可以是side,fill,padx/pady,ipadx/ipady,anchor
实践1.1 side参数 side参数可以垂直或水平配置控件,看示例:
import tkinter as tk #作者昵称:不在纯真的秋天 ID:h20050621 root = tk.Tk() root.title("小胡编程") label1 = tk.Label(root,text="春天的希望 肖申克的救赎", bg="yellow") label2 = tk.Label(root,text="夏日沉沦 纳粹高徒", bg="lightblue") label3 = tk.Label(root,text="不在纯真的秋天 尸体", bg="green") label1.pack() label2.pack() label3.pack() root.mainloop() 结果:
这是最简单的使用方式,默认的不加任何参数。也可以增加side参数设置组件的排列方式,参考数值:
TOP 这是默认值,由上到下排列
BOTTOM 由下到上排列
LEFT 由左到右排列
RIGHT 由右到左排列
注意:如果你的导入包方式是这样的:import tkinter as tk,则需要在参数前面加上(tk.)准确来说是as 后面跟的是什么就是什么加上一点。如果你没有加as 直接写的import tkinter 则需要加上
tkinter. 。但如果是from tkinter import * 则不需要加上前缀。
示例:
点击上方“小白学视觉”,选择加"星标"或“置顶”
重磅干货,第一时间送达 之前给大家介绍了TOF 与双目结构光的对比,那在深度相机的应用方案种还有结构光的摄像方案。今天小编就跟大家来聊一聊结构光,顺便也捋一捋这三者的对比。
结构光
结构光技术就是使用提前设计好的具有特殊结构的图案(比如离散光斑、条纹光、编码结构光等),然后将图案投影到三维空间物体表面上,使用另外一个相机观察在三维物理表面成像的畸变情况。如果结构光图案投影在该物体表面是一个平面,那么观察到的成像中结构光的图案就和投影的图案类似,没有变形,只是根据距离远近产生一定的尺度变化。但是,如果物体表面不是平面,那么观察到的结构光图案就会因为物体表面不同的几何形状而产生不同的扭曲变形,而且根据距离的不同而不同,根据已知的结构光图案及观察到的变形,就能根据算法计算被测物的三维形状及深度信息。
结构光3D成像技术主要由4大部分组成:
1)不可见光红外线(IR)发射模组:用于发射经过特殊调制的不可见红外光至拍摄物体。
2)不可见光红外线(IR)接收模组:接收由被拍摄物体反射回来的不可见红外光,通过计算获取被拍摄物体的空间信息。
3)镜头模组:采用普通镜头模组,用于2D彩色图片拍摄。
4)图像处理芯片:将普通镜头模组拍摄的2D彩色图片和IR接收模组获取的3D信息集合,经算法处理得当具备3D信息的彩色图片。
双目视觉 Vs 结构光 Vs TOF
下表是双目立体视觉、结构光、TOF三种可以测量深度(距离)的技术方案综合比较:
(点击看大图)
从上述的对比分析来看,TOF方案具有响应速度快,深度信息精度高,识别距离范围大,不易受环境光线干扰等优势。因此想要在移动端直接实现深度的测量,最有竞争力的就是TOF方案了。
典型手机
典型代表手机:联想Phab 2。
目前可以买到的具备直接深度测量的智能手机只有Google和联想合作的联想Phab 2,2016年11月推出,是全球首款支持Google Project Tango技术的手机,其深度相机采用TOF技术方案,由PMD公司提供。
华硕也宣布将在2017年会推出带深度相机的手机Zenfone AR,号称是全球首款同时支持Google Project Tango(AR)和Daydream(VR)的手机。
iPhone8也将会使用深度相机,果然收购PrimeSense公司是有目的的,我们拭目以待。
深度相机应用
深度相机的应用范围非常广泛:比如未来几年将会迅速商业化的手势识,以及活体人脸识别、空间测距、三维重建、AR(增强现实)等领域。
1、手势识别。
TOF深度相机可以将人脸、身体、手臂、手指从背景中分离,并且这种分割置信度较高,不受自然光变化的影响,同时能够实时性处理,所以这将在智能交互领域大有用武之地。预计最近几年会迅速进入消费级电子产品中。
2、真实的AR游戏体验。
如下图是Phab 2的AR游戏展示。由于在二维图像中融合了实时的深度信息,所以AR游戏的体验比较真实。比如虚拟出来的一只猫,通过实时的空间深度感知,它可以“感受”到空间的相对位置关系,当它走到桌子边缘的时候,会很自然地跳到地面上,这在之前的AR游戏中是难以实现的。
3、三维空间测量。
由于能够实时获得深度信息,所以实现三维空间测量也是顺其自然的。比如在室内装修领域,可以方便的将各种虚拟的家具以真实的尺寸摆放到现实环境中,用户拿着手机就可以体验家居放在室内的360°真实效果,这无疑将是一个令人激动的应用场景。
4、三维扫描/重建。
可以用于三维物体和k建模和机器人视觉导航和定位。比如你看到一座非常喜欢的雕塑,就可以利用手机上的彩色相机+深度相机对它扫描一周,结合相应的算法就可以生成该雕塑的三维模型数据,利用三维打印机就可以方便的打印出一个三维的雕塑复制品出来。
5、更广泛的其他应用。
融入了深度信息的三维影像可以用于活体人脸识别,避免传统二维人脸识别的安全隐患;可以更加方便进行人体三维测量,从而推动虚拟在线试衣行业的发展等。
随着深度测量技术的发展,必然还有出现更多有趣的应用场景。
下载1:OpenCV-Contrib扩展模块中文版教程
在「小白学视觉」公众号后台回复:扩展模块中文教程,即可下载全网第一份OpenCV扩展模块教程中文版,涵盖扩展模块安装、SFM算法、立体视觉、目标跟踪、生物视觉、超分辨率处理等二十多章内容。
下载2:Python视觉实战项目52讲
在「小白学视觉」公众号后台回复:Python视觉实战项目,即可下载包括图像分割、口罩检测、车道线检测、车辆计数、添加眼线、车牌识别、字符识别、情绪检测、文本内容提取、面部识别等31个视觉实战项目,助力快速学校计算机视觉。
下载3:OpenCV实战项目20讲
在「小白学视觉」公众号后台回复:OpenCV实战项目20讲,即可下载含有20个基于OpenCV实现20个实战项目,实现OpenCV学习进阶。
交流群
欢迎加入公众号读者群一起和同行交流,目前有SLAM、三维视觉、传感器、自动驾驶、计算摄影、检测、分割、识别、医学影像、GAN、算法竞赛等微信群(以后会逐渐细分),请扫描下面微信号加群,备注:”昵称+学校/公司+研究方向“,例如:”张三 + 上海交大 + 视觉SLAM“。请按照格式备注,否则不予通过。添加成功后会根据研究方向邀请进入相关微信群。请勿在群内发送广告,否则会请出群,谢谢理解~
1【问题引出】
在 Springboot 项目中,通常会有一个启动类,而启动类中通常会有一个名为 @SpringBootApplication 的注解(如下图所示),而此注解就是 Springboot 项目启动类的核心注解。
我们打开 @SpringBootApplication 注解源码,可以看到,在源码中有一个 @Inherited 的注解,那么这个注解,它的作用是什么呢?
2【@inherited 源码】
在了解该注解作用之前,我们不妨看看该注解的英文解释和源码定义,这样会更加有利于我们对该注解的理解。
(2.1)inherited 翻译
首先我们看翻译(来自百度翻译),可见 @inherited 有着 "继承","继任" 的意思。
(2.2)@inherite 源码
然后,我们打开 inherited 的源码,可以看到:
(1)该注解作用于整个程序运行中(@Retention(RetentionPolicy.RUNTIME);
(2)该注解只能修饰注解(@Target({ElementType.ANNOTATION_TYPE})),因此,它是一个元注解。
再了解到上面的情况后,我们就可以对 @inherited 注解进一步探究了。
3【举例说明】
既然它是一个有着关于"继承"的注解,那么我们便可以联想到,Java类之间也有继承的关系,我们不妨创建两个类,让他们为父子关系,然后创建两个注解,作用于类上,两个注解之间唯一不同的区别就是有无 @Inherited修饰。
我们创建父类 Father 和 子类Child,作为实验类。
(3.1)Father 类
(3.2)Child 类(继承 Father 类)
另外,我们再自定义两个注解,@HasInherited 和 @NoInherited,用于验证结果,前者注解包含@Inherited 注解,后者反之。
由于注解定义需要指明作用范围,以及作用的生命周期,那么我们不妨指定两个注解均作用于类上和整个代码运行生命周期中,让两者的唯一区别就是有无 @Inherited 注解。
(3.3)@HasInherited (有 @Inherited 注解)
(3.4)@NoInherited(无 @Inherited 注解)
4【测试验证】
(4.1)创建 Test 测试类
我们再写一个测试类 Test,用于获取实验类(Father 和 Child)上所有的注解信息。
package com.
网站名称地址简介语言推荐指数备注Book4Uhttp://www.book4you.sk/外文下载网站斯洛伐克语⭐⭐⭐BookYardshttps://www.bookyards.com/en/welcome主要面向教师的门户网站,其中的书籍,教育材料,信息和内容都是免费提供,以教辅资料最多。英语★★★搬书匠http://www.banshujiang.cn/主要提供编程类书籍的下载中文★★★Z-Libraryhttps://z-lib.org/无英语★★★★知轩藏书http://www.zxcs.me/专门收录网络小说的,全校对版,不用注册就可以下载中文★★★★Ireadehttp://www.iread.cf/网站不对外搜索引擎开放,站内的资源只能通过站内搜索搜到,一般搜不到的书就会来这碰碰运气,要登录中文★★★我爱书籍http://www.52book.me/分类详细,书还算比较齐全中文★★★伴读https://www.bandubook.com/一个电子书百度云资源专搜网站中文★★★书享家http://shuxiangjia.cn/整合了上百个电子书下载网站中文★★★鸠摩搜索https://www.jiumodiary.com/强推!专业搜书的聚合搜索引擎,众多电子书资源一站式的整合搜索。尤其鸠摩搜索的界面,可爱又简洁。提供各种电子书格式,text、PDF、mobi、epub等等都有,每条分享点开就是网盘链接,非常简单粗暴。推推推!中文/英文★★★★★每日书单https://shudan.vip/主页界面不错,分类放置资源的形式很适合不知道看什么书的人随便逛逛。中文★★★★★ePUBee电子书库http://cn.epubee.com/books/电子书版本、格式都很多,可以一键添加进网站个人账户,再进行下载。好用,推荐!中文★★★★图书资源 – 书https://bookfere.com/ebook推荐它的原因不是可以下载书,事实上书伴现在已经不提供电子书下载了。但是干货特别多,有各种下载网站的入口,基本把比较权威和好用的电子书下载网站全收录了,还做了简单地分类和介绍,赞!中文★★★★B–OK.xyzhttp://b-ok.xyz/s/?q=Sapiens%3AA+brief+history+of+humankind&yearFrom=&yearTo=&language=&extension=&t=0喜欢看英文原版的推荐使用,全英文网站,查找当然也需要英文啦。号称世界最大的电子图书馆,下载的电子书是mobi、epub格式。英语★★★★Library Genesishttp://gen.lib.rus.ec/功能很强大的下载网站,收录各大下载网站,颇有一种一站在手,天下我有的储存量。俄罗斯人做的超强英文电子书库,搜索结果非常清晰规范。支持各种电子书格式,对爱看英文原版书的童鞋很友好,强推!英语★★★★★Project Gutenberghttp://www.gutenberg.org/ebooks/4351对电子书的分类非常细致,但似乎电子书比较旧,或者是我的“打开方式”不太对,我搜索的几本畅销书都没搜到。大家可以一起研究下。英语★★★Libgen Online Libraryhttps://libgen.pw/search?q=A+brief+history+of+humankind很简单直接的下载网站,电子书版本多,下载也比较方便,格式也比较全,PDF、epub、mobi等等都有,还不错。英语★★★★AvaxHomehttps://avxhm.se/还不错,种类齐全,一些畅销书都可以搜到。不太舒心的是需要收费,还不便宜,实在找不到免费资源,接受付费渠道的童鞋可以试试。英语★★★点书网http://dianbook.cc/forum.php?fromuid=3299资源数量质量都很好,但是付费。中文★★★文叔叔https://www.wenshushu.cn/about用来分享电子书非常方便,当然你也可以分享其它资源。不限速,比百度爽多了!中文★★★★★ BookSChttp://booksc.org/无英语★★★新浪爱问共享资料http://ishare.iask.sina.com.cn/无中文★★★★苦瓜书盘https://kgbook.com/和我的小书屋差不多,现仅提供epub下载中文★★★★走读派http://zoudupai.com/kindle电子书资源中文★★★★西林街https://xilinjie.cc/聚合全网各种来源并分类,也是搜索引擎,不止有电子书,期刊、报纸等都可以搜索。中文★★★众人搜索网http://www.renrensousuo.com/除了电子书,一些学习资料、文献也可以搜到,功能比较多。中文★★★周读http://www.ireadweek.com/无中文★★★DigiLibrarieshttps://digilibraries.com/英文下载,适合kindle英语★★★★书格https://shuge.org/可以看到一些旧典籍,很有格调的网站中文★★★Baen Free Libraryhttps://www.baen.com/allbooks/category/index/id/2012主要是奇幻、科幻类小说。英语★★★蚂蚁搬书http://www.mybanshu.com/KindleMate官方网站,阅读极客的聚集地中文★★★★好读http://www.haodoo.net/无中文★★★kindle漫画http://www.kindlecomic.net/高清kindle格式漫画下载中文★★★★古籍馆https://www.gujiguan.com/中国最大的古籍图书馆中文★★★Feedbookshttp://www.feedbooks.com/无英语★★★★亚马逊免费kindle电子书https://www.amazon.cn/Kindle%E5%85%8D%E8%B4%B9%E7%94%B5%E5%AD%90%E4%B9%A6/b?node=116175071无中文/英文★★★★VOL.moehttps://vol.moe/漫画迷值得拥有中文★★★★Open Libraryhttps://openlibrary.org/英文原版书的免费电子资源英语★★★★Manybookshttp://manybooks.net大部分英文原版书都是免费的英语★★★亿年书海http://www.inien.com/w/#/Index支持不同尺寸、格式的电子书下载中文★★★ 掌上书苑https://www.soepub.com/下载需要书币,电子书可以推送到kindle中文★★★七彩英语http://www.qcenglish.com/英文原版书下载英语★★★kindlesharehttps://kindleshare.cn/无中文★★★mlookhttps://www.mlook.mobi/member/login要登录英语★★★书单网https://www.shudan.vip网站收录了30多个电子书网站的下载资源,只要搜索一次书名,就可以获得多个网站提供的关于此书的下载地址,让搜书更简单!中文★★★★Mobilismhttps://forum.mobilism.org/viewforum.php?f=19英文原版书下载,推荐英语
NumPy 采用科学计数法,方便了数据展示,但对于人而言,不太便于观察,需要取消它,
压制Numpy输出精度:
np.set_printoptions(suppress=True)
如果要在windows下连接虚拟机上的Hadoop集群,就必须要保证windows下有java环境和hadoop环境。
一、环境准备 1、jdk1.8
2、idea2019
3、Linux上hadoop集群,版本为hadoop2.6.0-cdh5.14.2
二、win10上安装hadoop环境 1、下载hadoop包
网站链接:
https://archive.apache.org/dist/hadoop/common/
本文下载版本为:hadoop2.6.0-cdh5.14.0
解压在本地路径:D:\soft\hadoop-2.6.0-cdh5.14.0
2、配置hadoop环境变量
计算机—属性—高级系统设置—高级—环境变量
(1)系统变量—新建HADOOP_HOME变量,变量值为hadoop解压安装路径:D:\soft\hadoop-2.6.0-cdh5.14.0
(2)系统变量—编辑Path,添加:D:\soft\hadoop-2.6.0-cdh5.14.0\bin
3、下载hadoop.dll和winutils.exe
在windows下运行hadoop还需要hadoop.dll和winutils.exe这两个文件,各版本下载地址https://github.com/cdarlint/winutils,也可以通过https://pan.baidu.com/s/1hrNXq3y#list/path=%2F下载。下载完成之后,将hadoop.dll和winutils.exe文件放到hadoop文件夹下的bin目录下,并且需要将hadoop.dll复制一份到C:\Windows\System32。
4、修改D:\soft\hadoop-2.6.0-cdh5.14.0\etc\hadoop文件下的配置文件
(1)修改hadoop-env.cmd文件
(2)修改core-site.xml文件
<configuration> <property> <name>fs.default.name</name> <value>hdfs://node01:9000</value> </property> <property> <name>hadoop.tmp.dir</name> <value>/export/servers/hadoop-2.6.0-cdh5.14.0/hadoopDatas/tempDatas</value> </property> <!-- 缓冲区大小,实际工作中根据服务器性能动态调整 --> <property> <name>io.file.buffer.size</name> <value>4096</value> </property> <!-- 开启hdfs的垃圾桶机制,删除掉的数据可以从垃圾桶中回收,单位分钟 --> <property> <name>fs.trash.interval</name> <value>10080</value> </property> <property> <name>hadoop.proxyuser.hue.hosts</name> <value>*</value> </property> <property> <name>hadoop.proxyuser.hue.groups</name> <value>*</value> </property> <property> <name>hadoop.proxyuser.admin.hosts</name> <value>*</value> </property> <property> <name>hadoop.proxyuser.admin.groups</name> <value>*</value> </property> <property> <name>hadoop.proxyuser.httpfs.hosts</name> <value>*</value> </property> <property> <name>hadoop.proxyuser.httpfs.groups</name> <value>*</value> </property> </configuration> (3)修改hdfs-site.xml文件
在使用Tomcat时,IDEA调试运行,报错说是端口号被占用。
打开终端,输入 sudo lsof -i:端口号。 比如我是输入 sudo lsof -i:8080
然后会出现该端口号的情况
这个PID 59801就是你需要的
然后直接 sudo kill 59801,这样就把它关掉了。
再重启一下tomcat,就ok了
基本概念 先讲一讲基本概念和开发思路。只要把概念和思路理清楚了,就能融会贯通。
DMA 直接存储器访问。这个不用多说了。
burst 关于burst这个词,很多文献中都翻译为“突发”。从中文字面上,不太好理解。本文中还是使用burst这个词。
burst是一次DMA传输中的最小触发单元。每当DMA通道触发时进行的数据传送。触发源可以是外设事件或者软件触发。每次传输最多可以达到32个字。这个数量称为burst数量。(说明,为了理解上的方便,这里先不关心寄存器设置值与概念值的偏差。实际上,burst数量=BURST_SIZE+1。)
burst有个传输计数器(BURST_COUNT),用于表示当前还有多少个字没有完成。burst开始时,将burst数量加载到burst计数器。传输过程中每传一个字,计数器减一,一直减到0,代表burst完成。
burst还有一个状态标志(BURST_STS),burst开始时由硬件置1,完成后归0.
在burst传输过程中,每传输一个字,源地址和目的都会增加一个步长(BURST_STEP)。这个步长是个16位的有符号整数,也就是说,步长既可以是正数,也可以是负数,范围为-4096~+4095. 源地址步长和目的地址步长是分别可设的,对应着2个寄存器:SRC_BURST_STEP和DST_BURST_STEP。
transfer 一次完整的DMA数据传输称为transfer,可以包含多个burst. 所包含的burst数量称为transfer数量。
与burst类似,transfer也有传输计数器(TRANSFER_COUNT)、传输状态(TRANSFER_STS)、传输步长(SRC_TRANSFER_STEP和DST_TRANSFER_STEP)。
另外,一个transfer对应着一次完整的DMA传输,可以使能本通道的DMA中断。中断可以发生在transfer的开始,也可以发生在transfer结束。
DMA控制 有2个标志位用于控制DMA通道的传输:RUN和HALT。都是写1有效。当RUN写入1时,启动DMA传输,RUNSTS标志位由硬件置1,表示DMA正在运行。当HALT写入1时,停止DMA传输,RUNSTS标志位清零。
单次模式(ONESHOT)和连续模式(CONTINUOUS) 单次模式针对burst有效。
禁止单次模式时(ONESHOT=0),每一次burst都需要外设事件触发。如果transfer中包含N个burst,则需要N个外设事件的触发脉冲,才能完成一次DMA传输。
使能单次模式时(ONESHOT=1),只要一个外设事件的触发脉冲,就可以完成一次transfer中的N个burst。
连续模式针对transfer有效。
禁止连续模式时(CONTINUOUS=0),当启动DMA传输后,只完成一次transfer。完成后RUNSTS自动清零。要开启下一次transfer,需要再次启动DMA传输(RUN写入1)。
使能连续模式时(CONTINUOUS=1),一旦启动DMA,则RUNSTS一直为1,DMA通道一直在运行(也要等待外设事件触发才会进行数据传输),直到HALT写入1才停止运行。
典型场景 假定现在ADC的转换结果需要由DMA来传送到内存中。
为简单起见,ADC只转换2路。ADC结果分别为ADCResultA和ADCResultB。
简单用法 简单用法:每次DMA传输时,只需要将两个ADC结果输送到内存中。
在此场景中,需要配置的有:
burst数量为2;burst源地址步长SRC_BURST_STEP为1;burst目的地址步长DST_BURST_STEP为1.
burst传输过程分为2步:第1步将ADC结果A保存到内存A中;然后源址加1,指向ADC结果B,目的地址也加1,指向内存B;再将ADC结果B保存到内存B中。
高级用法 为了方便滤波,每次DMA传输时,需要对A和B进行4次采样,并把采样结果(共2*4=8个字)传送到内存里8个字的数组中。
在此场景中,需要配置的有:
burst数量为2;burst源地址步长SRC_BURST_STEP为1;burst目的地址步长DST_BURST_STEP为4. 因为burst传输的第2步中,内存要增加4个字(比如从A1到B1)。
transfer数量为4;
传输过程如下图所示:
第1个burst传输时,把ADC的结果保存到A1和B1;
第2个burst传输时,把ADC的结果保存到A2和B2;
第3个burst传输时,把ADC的结果保存到A3和B3;
第4个burst传输时,把ADC的结果保存到A4和B4。
地址WRAP 问题的提出 在上述的传输过程中,如果仔细分析的话:
首先,在第1个burst传输的第1小步,源地址指向ADCResultA,目的地址指向A1;数据从A保存到A1;
然后,源地址加一,指向ADCResultB;目的地址加4,指向B1;数据从B保存到B1.
第一次burst传输完成。
再然后呢?
再然后就是第二次burst传输了。但是,源地址怎么才能再一次指向A呢?目标地址也应该回到A2啊。怎么办?
方案一:使用transfer步长 配置源地址transfer步长SRC_TRANSFER_STEP为-1(0xFFFF);配置目的地址transfer步长DST_TRANSFER_STEP为 -3(0xFFFD).
方案二:使用地址WRAP DSP提供了一种“回绕”或者叫做“换行”的机制:Wrap。
源地址和目的地址可以分别配置WRAP_SIZE和WRAP_STEP。
WRAP_SIZE对应的是burst数量。当完成WRAP_SIZE个burst传输时,就发生地址WRAP。此时,在起始地址的基础上增加WRAP_STEP,重新使用该地址作为下一次burst传输的地址。这里的“起始地址”就是第一次burst的地址。
比如,上例中,可以配置源地址和目的地址的wrap_size都为1,也就是每完成一次burst传输都发生一次地址wrap。源地址的wrap_step为0,也就是回到第一次的源地址ADCResultA。目的地址的wrap_step为1,也就是说,在第一次的目的地址A1的基础上加1,变成A2.
地址指针及传输控制 涉及到的地址寄存器有8个。源地址和目的地址各4个。两种地址的处理逻辑完全相同,下面只选一种来讲述。
这4个地址中,有2个是活动地址(当前正在使用的有效地址),另2个是影子地址。又可以分为当前地址和起始地址。它们之间的关系如下:
一共是4个地址和3个步长(burst步长、transfer步长和wrap步长)
影子地址 首先看影子地址。这2个寄存器一般在程序初始化时由软件写入,指向外设或者内存的起始位置(比如,源地址指向ADC_ResultA,目的地址指向内存数组的开头)。在程序运行过程保持不变。
配置这个地址的库函数为:
// // DMACH1AddrConfig - DMA Channel 1 Address Configuration // void DMACH1AddrConfig(volatile Uint16 *DMA_Dest,volatile Uint16 *DMA_Source) { EALLOW; // // Set up SOURCE address: // DmaRegs.
53.上下移动图层
使用上下拖拽图层是大家都习惯的方式,键盘党的选择通常是快捷键:Cmd/Ctrl+]/[ ,鼠标和快捷键的组合会快很多。
54.填充快捷键
你可以使用Opt/Alt+ Backspace 按键来为某个图层填充上前景色,使用Cmd/Ctrl+Backspace 填充背景色,如果你想仔细设置的话,使用Shift+Backspace快捷键调出填充控制面板。
55.50%灰度的图层
在很多时候,新建一个有50%灰度的图层是很有用的。这个图层可以轻易的减淡或者加深,添加纹理或者光晕,可以以非破坏式的方式优化图像,新建一个图层,然后选择 编辑->填充 ,然后设置混合模式为叠加。
56.图层组快捷键
图层组是非常有用的,不过你并不一定非地去点击图层组图标去新建,然后将图层移进去。你只需要选中需要成组的图层,然后拖拽到这个图标上就好了,快捷键也是不错的选择:Cmd/Ctrl+G。
57.编辑多个文本图层
经常编辑文本图层的同学应该知道文本工具菜单栏最右边的按钮可以调出字符设置面板,所以当你要一次调整多个文本图层的时候,就只需要按住Cmd/Ctrl 选中多个文本图层,然后在字符设置面板中一次搞定多个图层的设置。
58. 图层蒙板视图
按住Alt/Opt按键,然后点击某个蒙板的缩略图,然后就可以图像视图和蒙板视图之间来回切换,按住Shift按键这么操作则可以启用或者关闭蒙板。
59. 选择相似图层
这是用来帮你选择同类型图层的,比如选中全部的形状图层或者文本图层,你需要做的就是进入菜单,选择->选取相似 就可以了!
60. 更改透明度
当你不适用画笔工具的时候,你可以使用数字键快速设置图层的透明度,数字1就是10%,数字5是50%,数字0是100%。
61. 快速调用笔刷
快速打开笔刷面板的快捷键是F5。
62. 混合火焰效果
A: 复制火焰
打开一个人物肖像图片和一个普通的火焰图片,使用移动工具,使用自动选择图层,并且显示变换控件。将火焰图片拖放到肖像图片上,模式选择混合模式。
B: 位置和扭曲
单击边款,改变火焰的图层,调整大小,旋转,定位。在调整状态下,鼠标右键点击调出菜单,选择“扭曲”,调整火焰姿态。使用快捷键Cmd/Ctrl+J 复制图层,通过叠加图层调整效果。
63. 使用右键选择更多功能
为了保证PS的易用性,绝大多数的PS工具在使用过程中,可以通过右键调用更多的功能。当然,有人喜欢用快捷键,有人喜欢调整顶部菜单或者侧边栏,但是如果你喜欢使用鼠标的话,这是不二选择。
token是什么?
token携带在请求头中,只有登录请求不需要携带token,登录成功后把token返回给前端,以后的请求前端需要携带这个token来才能请求成功!否则请求被拦截……
为什么要用它?
token的目的是减轻服务器压力,减少数据库请求。
如果没有token做一层拦截的,每次请求都会去请求数据库,如果恶意请求,很可能击垮数据库…
如何实现呢?
拦截器:写一个类实现HandlerInterceptor接口,重写preHandle方法,在方法里实现拦截逻辑
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { // 如果是OPTIONS则结束请求 if (Objects.equals(request.getMethod(), HttpMethod.OPTIONS.name())) { response.setStatus(HttpStatus.OK.value()); return false; } String token = request.getHeader("token"); if (!hasText(token)) { handleErrorResponse(response, ResponseResultEnum.PARAM_ERROR, "can't getHeader token "); return false; } if (TEST_TOKEN.equals(token)) { return true; } } catch (JwtException e) { log.trace(e.getMessage(), e); handleErrorResponse(response, ResponseResultEnum.TOKEN_INVALID); return false; } return true; } 这里的拦截,是拦截所有请求,而我们在实际开发中,要有拦截白名单,比如:登录接口
那么如何写拦截白名单呢?
写一个配置类,实现WebMvcConfigurer接口,重写addInterceptors方法
@Configuration public class WebConfig implements WebMvcConfigurer { private final TokenInterceptor tokenInterceptor; public WebConfig(TokenInterceptor tokenInterceptor) { this.
老规矩,先挂官网链接
https://www.npmjs.com/package/idb-js
关于indexDB 是什么,用到什么地方我就不再解释,百度多得很,只说我在使用的过程中的一些问题
官网解释:
引入及简单使用 安装:
npm install idb-js --save 使用:
第一步:引入db import Idb from 'idb-js' // 引入Idb 第二步:引入数据库配置 import db_student_config from './db_student_config' 第三步:载入配置,数据库开启成功拿到数据库实例进行操作 Idb(db_student_config).then(student_db => {...}) 数据库实例 db 方法 (拣选几条常用)
close_db - 关闭数据库delete_db - 删除数据库clear_table - 清空某张表的数据insert - 添加单条或者多条数据query - 查询匹配到的数据queryAll - 查询某张表的所有数据delete - 删除数据update - 修改数据 官网举例 数据库配置
// in db_student_config.js export default { dbName: "student", // *数据库名称 version: 1, // 数据库版本号(默认为当前时间戳) tables: [ // *数据库的表,即ObjectStore { tableName: "
1974年Hoppensteadt首先在文[1]中建立和研究了具有年龄结构的传染病模型.至今,具有年龄结构的 传染病模型的研究已有许多成果(见[2]-[5]等),但这些模型大多不考虑染病年龄、潜伏期等对疾病传播 的影响.这就不能准确的描述某些具有较长潜伏期和病程的传染病(麻疹、肺结核等)的传播,因此建立 和研究具有生理年龄、潜伏期和染病年龄的传染病模型具有重要意义.目前,同时具有生理年龄、染病 年龄、潜伏期的传染病模型研究结果较少,只有一些特殊问题的结果,如文[6]-[7]研究了具有生理年龄和 染病年龄的传染病模型,文[8]-[9]建立和研究了同时具有潜伏期、染病年龄和生理年龄的无免疫型SEIS传 染病模型及其解的适定性.本文针对麻疹、肺结核等疾病,将人群分为S(易感类)、E(潜伏类)、I(染病 类)、R(治愈类)四类人群,利用K-M仓室模型原理(见文[10]),易建立同时具有生理年龄、染病年龄、潜 伏期的SEIR模型 。
这里总结了五个模型,分别是SI模型,SIS模型,SIR模型,SIRS模型,SEIR模型。
这几种模型的特点先介绍一下。
首先定义SEIR:
S为易感者 (Susceptible),指未得病者,但缺乏免疫能力,与感染者接触后容易受到感染;
E为暴露者 (Exposed),指接触过感染者,但暂无能力传染给其他人的人,对潜伏期长的传染病适用;
I为感病者 (Infective),指染上传染病的人,可以传播给 S 类成员,将其变为 E 类或 I 类成员;
R为康复者 (Recovered),指被隔离或因病愈而具有免疫力的人。如免疫期有限,R 类成员可以重新变为 S 类。
一、SI模型
该模型只考虑易感者和感病者,感病者不断去感染易感者。
随着时间推移,该模型感染者越来越多直到所有人都感染。
其微分方程为:
其中beta为感染率。
二、SIS模型 该模型依然只考虑易感者和感病者,感病者不断去感染易感者,这里感病者会得到治疗恢复成易感者,不过恢复后依然可能得病。
随着时间推移,该模型感染者和易感者会达到动态平衡。
其微分方程为:
其中beta为感染率,gamma为治愈率。
三、SIR模型
该模型考虑易感者、感病者与康复者,其中感病者不断感染易感者,而感病者又不断接受治疗成为康复者,康复者因为得到抗体不会再成为易感者。
随着时间推移,该模型康复者越来越多,最终所有人都成为康复者。
其微分方程为:
其中beta为感染率,gamma为治愈率。
四、SIRS模型
该模型考虑易感者、感病者与康复者,其中感病者不断感染易感者,而感病者不断接受治疗成为康复者,康复者获得抗体能够抵抗一段时间,不过最终还是会成为易感者。
该模型和SIS模型很像,区别就是康复者能够抵抗一段时间,也就是有一定的复感率,而SIS模型的复感率为1。
随着时间推移,该模型同样会达到一个动态平衡。
其微分方程为:
其中beta为感染率,gamma为治愈率,alpha为复感率。
五、SEIR模型
该模型四种参与者全部考虑,其中感病者不断感染易感者,易感者得到病毒会成为潜伏者,潜伏者依然能够使易感者感染,潜伏者有一定概率自己痊愈,感染者接受治疗也能够痊愈,痊愈后不再能够感染该病。
随着时间推移,该模型最终也是所有人都会成为康复者。
其微分方程为:
其中beta为感染率,gamma1为潜伏期康复率,gamma2为患者康复率,alpha为潜伏期转阳率。
function Message_Spread_Mode tic load 'Data\Link.txt'; %读入连接矩阵 % load '\Data\Point_X.txt'; %读入横坐标 % load '\Data\Point_Y.txt'; %读入纵坐标 %-------------------------------------------------------------------------% %状态分布及状态转移概率SEIR %0:易感状态S(Susceptible) P_0_1; (P_0_3:预免疫系数) %1:潜伏状态E(Exposed) P_1_0;P_1_2;P_1_3 %2:染病状态I(Infected) P_2_0;P_2_3 %3:免疫状态R(Recovered) P_3_0 %-------------------------------------------------------------------------% %计算各用户节点的度 De=sum(Link); %用户节点的度 %------------——————----参数设置与说明--------------------------------% [M N]=size(Link); %连接矩阵的规模 I_E=0.
第一步:将创建好的两个.ui文件通过pyuic转译成.py文件
(主窗口为MainWindow.ui 子窗口为subWindow.ui)
第二步:新建一个switchWindow.py文件
第三步:编写代码,如下
from MainWindow import Ui_MainWindow from subWindow import Ui_Form from PyQt5 import QtWidgets from PyQt5.QtWidgets import QWidget,QApplication,QMainWindow # 主窗口 class firstWindow(QMainWindow,Ui_MainWindow): # 初始化 def __init__(self, parent=None): super(firstWindow, self).__init__() self.setupUi(self) self.subWindow = secondWindow() self.connecter() def show_subWindow(self): self.subWindow.show() # 点击主窗口中的按钮,调用子窗口 def connecter(self): self.pushButton.clicked.connect(self.show_subWindow) # 子窗口 class secondWindow(QWidget,Ui_Form): def __init__(self, parent=None): super(secondWindow, self).__init__() self.setupUi(self) self.lineEdit.setText('子窗口被打开了') if __name__ == '__main__': import sys app = QtWidgets.QApplication(sys.argv) mainWindow = firstWindow() mainWindow.show() sys.
1. solr简介 1.1 官网介绍 Solr是一个基于Lucene的Java搜索引擎服务器。Solr提供了层面搜索、命中醒目显示并且支持多种输出格式(包括XML/XSLT和 JSON格式)。 它易于安装和配置,而且附带了一个基于HTTP的管理界面。 Solr已经在众多大型的网站中使用,较为成熟和稳定。Solr包装并扩展了Lucene,所以Solr的基本上沿用了Lucene的相关术语。 更重要的是,Solr 创建的索引与Lucene搜索引擎库完全兼容。 通过对Solr进行适当的配置,某些情况下可能需要进行编码,Solr可以阅读和使用构建到其他 Lucene应用程序中的索引。 此外,很多Lucene工具(如Nutch、Luke)也可以使用 Solr创建的索引。 总结一下solr是一个java搜索引擎服务器(是一套war程序),内部集成了Lucene(apache提供的一些对搜索引擎做支持的jar包).
1.2 什么是Solr Solr 是Apache下的一个顶级开源项目,采用Java开发,它是基于Lucene的全文搜索服务器。Solr提供了比Lucene更为丰富的查询语言,同时实现了可配置、可扩展,并对索引、搜索性能进行了优化。
Solr可以独立运行,运行在Jetty、Tomcat等这些Servlet容器中,Solr 索引的实现方法很简单,用 POST 方法向 Solr 服务器发送一个描述 Field 及其内容的 XML 文档,Solr根据xml文档添加、删除、更新索引 。Solr 搜索只需要发送 HTTP GET 请求,然后对 Solr 返回Xml、json等格式的查询结果进行解析,组织页面布局。Solr不提供构建UI的功能,Solr提供了一个管理界面,通过管理界面可以查询Solr的配置和运行情况。
1.3 solr功能 保存数据建立索引,维护索引数据检索(全文检索、高亮检索、精确搜索等) 1.4 solr 依赖环境 jdk 1.7+tomcat7+Solr4.10.3 1.5 下载 从Solr官方网站(http://lucene.apache.org/solr/ )下载Solr4.10.3,根据Solr的运行环境,Linux下需要下载lucene-4.10.3.tgz,windows下需要下载lucene-4.10.3.zip。
Solr使用指南可参考:https://wiki.apache.org/solr/FrontPage。
下载lucene-4.10.3.zip并解压:目录介绍如下:
bin:solr的运行脚本contrib:solr的一些贡献软件/插件,用于增强solr的功能。dist:该目录包含build过程中产生的war和jar文件,以及相关的依赖文件。docs:solr的API文档example:solr工程的例子目录:example/solr:
该目录是一个包含了默认配置信息的Solr的Core目录。example/multicore:
该目录包含了在Solr的multicore中设置的多个Core目录。example/webapps:
该目录中包括一个solr.war,该war可作为solr的运行实例工程。
licenses:solr相关的一些许可信息 2. Solr的安装及配置 2.1 3.2.Solr整合tomcat #1.说明:我的所有软件都是安装在/usr/local/install目录中 mkdir -p /usr/local/install #2.将solr-4.10.3.tgz.tgz包使用工具上传至Linux的/usr/local/install目录中 #3.进入/usr/local/install目录中 [root@localhost ~] cd /usr/local/install/ #4.
1.从主菜单打开你的编辑器选择 File-Import Setting.选择你下载的jar文件;
2.等待重启之后进行配置:打开File-Settings-Editor-Colors and fonts 然后选择你安装的主题即可完成
1.导入主题: 打开File-Settings-Editor -> 选择 Color Scheme -> Color Scheme Font
修改 字体大小 Editor -> Color Scheme -> Color Scheme Font 修改 颜色 Editor -> Color Scheme -> Java
前言 刚开始学习深度学习,CUDN和CUDNN是必不可少的工具。前前后后装了很多次,总算积累了一些经验。
1、CUDN和CUDNN版本的选择 因为我的电脑是15年寒假的买的电脑,显卡是英伟达的950,属于比较老款,在刚开始装的时候担心自己显卡版本不行,然而纯属我过度担心了。
首先打开英伟达的控制面板,右上角–帮助–选择系统信息。选择–组件–,就可以看到自己电脑驱动支持的CUDA信息。我的是11.4。其实这个是和你电脑显卡驱动有关的。你用英伟达的Geforce Experience 把驱动更新一下,你的也会是11.4。我建议把驱动更新一下,这样后面的软件好装。
之后就可以进行CUDN和CUDNN的安装了
CUDN和CUDNN安装 可以直接在百度搜一下CUDNN和CUDNN安装,会直接显示英伟达的官网界面。我们要装的CUDN版本为11.4。关于CUDNN的版本的选择,官网标的很清楚
具体的安装我给一位博主的链接,讲的非常好
链接: https://blog.csdn.net/shuiyixin/article/details/99935799?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522162903269216780269891772%2522%252C%2522scm%2522%253A%252220140713.130102334…%2522%257D&request_id=162903269216780269891772&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduend~default-8-99935799.first_rank_v2_pc_rank_v29&utm_term=cudnn%E5%AE%89%E8%A3%85&spm=1018.2226.3001.4187.
tensorflow的安装 对于tensorflow的安装有两种办法,一个是利用anaconda安装,一个是利用pip安装,我提供一种pip安装的办法
首先要确定tensorflow安装版本,tensorflow与CUDA版本对应见下图
这是tensorflow官网给出的对应,目前只写到了2.4.0,但是tensorflow截止到今天已经更新到了2.6.0。官网链接如下
链接: https://tensorflow.google.cn/install/source_windows.
因为tensorflow在官网下载很慢,给出了清华镜像的下载方式,
链接: https://pypi.tuna.tsinghua.edu.cn/simple/tensorflow/.
至于GPU版本的tensorflow,我在论坛上看到有人说,tensorflow 2.0版本之后的CPU和GPU版本的就合在一起了,对此我也不知道可不可信,但是我也安装了GPU版本的,没有做测试。清华镜像下载链接如下链接: https://pypi.tuna.tsinghua.edu.cn/simple/tensorflow-gpu/.
cp39代表你python版本为3.9,后面的为你系统信息,选一个就可以了,直接点击会下载一个压缩包似的文件。不用解压。进入你下载文件的位置,在文件位置输入cmd,可以直接进入这个文件夹位置的cmd命令窗口。
然后输入命令
pip install XXXXX(XXXX,是刚刚下载文件的名称,记住是全名称,包括点后缀) 之后就会开始安装tensorflow
tensorflow安装之后的验证 下面代码不仅可以验证tensorflow安装成功,还可以用来确认你的代码有没有调用你的Gpu。
import tensorflow as tf gpus = tf.config.list_physical_devices("GPU") if gpus: tf.config.experimental.set_memory_growth(gpus[0], True) #设置GPU显存用量按需使用 tf.config.set_visible_devices([gpus[0]],"GPU") print(gpus) 运行结果:
2021-08-15 21:46:41.844192: I tensorflow/stream_executor/platform/default/dso_loader.cc:53] Successfully opened dynamic library cudart64_110.dll 2021-08-15 21:46:52.957965: I tensorflow/stream_executor/platform/default/dso_loader.cc:53] Successfully opened dynamic library nvcuda.dll 2021-08-15 21:46:55.637641: I tensorflow/core/common_runtime/gpu/gpu_device.