在学习华为云计算IP-SAN存储这一块时,碰到了VLAN间路由,特地再次复习
一、实验拓扑
二、实验需求
PC1和PC3属于VLAN 10 ,PC2和PC四属于VLAN 20,实现不同VLAN之间的相互通讯
三、实验过程
1、配置三层交换机SW1
SW1:
sys
sys sw1
vlan b 10 20 int vlan 10 ip add 192.168.10.1 24
int vlan 20 ip add 192.168.20.1 24
int g 0/0/1
port link-type trunk
port trunk allow-pass vlan 10 20
int g 0/0/2
port link-type trunk
port trunk allow-pass vlan 10 20
q
2、配置二层交换机SW2
SW2:
sys sys sw2
vlan b 10 20 int g 0/0/1
port link-type trunk
今天敲代码的时候发现,出现了这样一个情况:
我在我在main方法中调用了一个函数,并且这个函数没有用static修饰,就像这样:
这样报错了!!!
我虽然学Java 的时间也不多,但这个问题也帮助我更深刻的理解了一些东西。
我的方法体中间没有加上static,加上static之后就不报错了,像这样:
那么,为什么一定要加main呢?在Java的main主函数中调用别的函数的时候应该怎么办呢?
先解释这个:
用static修饰的方法,无须产生类的实例对象就可以调用该方法。
没有static修饰的方法,需要产生一个类的实例对象才可以调用该方法。
static变量是存储在静态存储区的,不需要实例化。
在main函数中调用函数只能调用静态的。如果要调用非静态的,那么必须要先实例化对象,然后通过对象来调用非静态方法。
弗洛伊德算法求最短路径 输出路径 弗洛伊德算法其实比较好理解
这里我用邻接矩阵的储存方法来写
一.算法思想 1.1
如果我们要用邻接矩阵来写代码的话,就要储存他的权值信息
这里我们用map[][]这个二维数组来储存
其次要输出他的最短路径
就用path[][]来储存
int map[100][100]; int path[100][100]; 1.2
初始化这个储存权值邻接矩阵
由于是无环图,自己到自己是 0
剩下的边的权值我们赋值为MAX
for(int i=1; i<=n; i++) for(int j=1; j<=n; j++) if(i==j) map[i][j]=0; else map[i][j]=max; 1.3
读入边的信息
如果两个结点i,j之间有权值,就把他赋值给map[i][j]
并且这个时候将j赋值给path[i][j]
cout<<"输入点1到点2的距离"<<endl; for(int i=1; i<=m; i++) { cin>>t1>>t2>>t3; map[t1][t2]=t3; map[t2][t1]=t3; path[t1][t2]=t2; } 这个路径的赋值如果在后面有更优解
将会更新这个值,如果没有,那说明i直接到j就是最短的
1.4 核心算法
这个核心算法使用一个三重循环来一个一个找最优解
第一重循环控制中转结点k
第二重控制起始结点i
第三重控制终止结点j
如果我们发现i->k->j的路径小于i->j的
那我们就更新路径,将path[i][j]=path[i][k]
同时权值邻接矩阵更新`map[i][j]=map[i][k]+map[k][j]
for(int k=1; k<=n; k++) for(int i=1; i<=n; i++) for(int j=1; j<=n; j++) if(map[i][k]+map[k][j]<map[i][j]) { map[i][j]=map[i][k]+map[k][j]; path[i][j]=path[i][k]; } 1.
过滤器:
依赖于servlet容器。在实现上基于函数回调,可以对几乎所有请求进行过滤,但是缺点是一个过滤器实例只能在容器初始化时调用一次。使用过滤器的目的是用来做一些过滤操作,获取我们想要获取的数据,比如:在过滤器中修改字符编码;在过滤器中修改HttpServletRequest的一些参数,包括:过滤低俗文字、危险字符等。
拦截器:
依赖于web框架,在SpringMVC中就是依赖于SpringMVC框架。在实现上基于Java的反射机制,属于面向切面编程(AOP)的一种运用。由于拦截器是基于web框架的调用,因此可以使用spring的依赖注入(DI)进行一些业务操作,同时一个拦截器实例在一个controller生命周期之内可以多次调用。但是缺点是只能对controller请求进行拦截,对其他的一些比如直接访问静态资源的请求则没办法进行拦截处理。
配置web.xml,/ 和 / 的区别*:上面说的只能拦截controller,所以jsp路径不能一起拦截,会认为也是controller,就出错了。< url-pattern > / </ url-pattern > 不会匹配到.jsp, 只针对我们编写的请求;即:.jsp 不会进入spring的 DispatcherServlet类 。< url-pattern > /* </ url-pattern > 会匹配 *.jsp,会出现返回 jsp视图 时再次进入spring的DispatcherServlet 类,导致找不到对应的controller所以报404错。
1、初识MySQL JavaEE:企业级Java开发 Web
前端(页面:展示:数据)
后台 (连接点:连接数据库JDBC,连接前端(控制视图跳转,给前端传递数据))
数据库(存数据,Txt,Excel,Word)
只会写代码,学好数据库,基本混饭吃:
操作系统,数据结构与算法!当一个不错的程序猿!
离散数学,数字电路,体系结构,编译原理。+实战经验,优秀程序猿
1.1为什么学数据库 1、岗位需求
2、现在的世界,大数据时代,得数据者得天下
3、被迫需求:存数据
4、数据库是所有软件体系中最核心的存在 DBA
1.2 什么是数据库 数据库:(DB,DataBase)
概念:数据仓库,软件,安装在操作系统之(windows,Linux。mac)上的!SQL,可以存储大量的数据,500万!
作用:存储数据,管理数据 Excel
1.3 数据库分类 关系型数据库:(SQL)
MySQL, Oracle, sql Server, DB2, SQLite通过表和表之间,行和列之间的关系进行数据的存储 非关系型数据库:(NoSQL) Not Only SQL
Redis, MongDB非关系型数据库,对象存储,通过对象自身的属性来决定。 **DBMS(数据库管理系统) **
数据库的管理软件,科学有效的管理我们的数据,维护和获取MySQL ,数据管理系统! 1.4 MySQL简介 MySQL是一个**关系型数据库管理系统**
前世: 瑞典MySQL AB 公司
今身: 属于 Oracle 旗下产品
MySQL是最好的 RDBMS (Relational Database Management System,关系数据库管理系统) 应用软件之一。
开源的数据库软件
体积小,速度快,总体拥有成本低,招人成本比较低。
中小型网站,或者大型网站,集群
官网: https://www.mysql.com/
1.5连接数据库 命令行连接!
mysql -u root -p123456 --连接数据库 update mysql.
被动健康检查
关于Nginx的健康检查,简单的场景下可以直接使用ngx_http_upstream_module模块自带的被动式的健康检查,简单示例如下:
http { # ..........省略其它 upstream clusterA { server 10.68.60.100:8001 max_fails=2 fail_timeout=30s; server 10.68.60.101:8001 max_fails=2 fail_timeout=30s; server 10.68.60.110:8001 max_fails=2 fail_timeout=30s; } server { listen 8080; server_name clusterA; keepalive_timeout 60; proxy_set_header X-Forwarded-Host $host; proxy_set_header X-Forwarded-Server $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $host:$server_port; location / { # 默认是60s,设置与后端服务器建立连接的超时时间。应该注意这个超时一般不可能大于75秒。 proxy_connect_timeout 60; # 默认60s,定义从后端服务器读取响应的超时。此超时是指相邻两次读操作之间的最长时间间隔,而不是整个响应传输完成的最长时间。如果后端服务器在超时时间段内没有传输任何数据,连接将被关闭。 proxy_read_timeout 60; # 默认60s, 定义向后端服务器传输请求的超时。此超时是指相邻两次写操作之间的最长时间间隔,而不是整个请求传输完成的最长时间。如果后端服务器在超时时间段内没有接收到任何数据,连接将被关闭。 proxy_send_timeout 60; proxy_pass http://clusterA; proxy_set_header X-Forwarded-Host $host; proxy_set_header X-Forwarded-Server $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $host:$server_port; } } 关键配置项如下:
问题出现 打开File—> settings—> plugins 搜索插件时,会发下有时插件市场加载过慢,或者打不开的情况,如下图所示:
原因分析 IDEA的插件市场加载不出来,是由于IDEA的网络安全机制造成的,类似于windows的防火墙,IDEA误认为你的网络不安全,不给你连接,本质为公司的网络被IDEA认为不安全。
解决方案 先检查网络设置,是否有防火墙拦截,是否可以正常访问https://plugins.jetbrains.com/查看你的idea 版本 ,不同版本设置有些不同,这里以2019.2.x后的版本为例打开 Setting–》Appearance & Behavior --》Syetem Setting–》HTTP Proxy,
勾选auto-detect proxy seting和automatic proxy xxxx 并设置URL为:http://plugins.jetbrains.com/ 。
具体操作如图:
安装如上操作基本可以打开了。若还是打不开,就选择用浏览器访问https://plugins.jetbrains.com/search 将需要的插件下载到本地,然后再从本地安装插件也可满足需要。如同所示:
完美解决!如有帮助,喜欢关注点个赞再走吧
欢迎关注我的公众 号(牧码心),获取很多精彩文章和学习资料!
#include<stdio.h> #include<math.h> double fact(int n) { int i; double sum = 1.0; for(i = n;i > 0;i--){ sum *= i*1.0; } return sum; } int main() { int i; double x; double sum = 0.0; scanf("%lf",&x); if(x < 0||x > 5){ return 0; } double n = 1.0; for(i = 1;fabs(n) >= 0.00001;i++){ sum += n; n = pow(x,i)/fact(i); } printf("%.4lf",sum); return 0; } 想了很久,知道阶乘返回会溢出,所以改成double,但x = 5就是过不了,后来才明白,原来是循环出问题,每一次加的项是上一次的项,当下一次项不满足时就不会进入循环了,因此sum += n;和n = pow.
前言:前段时间,压测遇到一个问题,在压测的时候,tps波动很频繁。
使用xshell远程连接到应用服务器,通过top命令看了下服务器资源情况,cpu波动也很频繁,其它服务器都正常。
打开JvisualVM,双击对应的应用进程
然后进入Sampler,在cpu波动的时候点击cpu进行抽样
抽样进行一段时间后(一般1-2分钟即可),点击“stop”,然后点击“snapshot”生成快照
接着按照“Total Time(CPU)”排序,看哪些线程最耗费cpu,因为我们用的是dubbo框架,所以,我们要分析的业务线程就是DubboServerHandler。分析的时候,我们需要多看几个DubboServerHandler线程,双击指定线程就可以看这个线程的调用栈以及耗时情况,看看这些线程在哪里比较耗费cpu。
通过分析发现,在Dubbo远程调用的时候验证参数的时间比我们处理业务的时间还长。
结合Dubbo官方文档得知,Dubbo的参数验证这个特性是比较耗费性能的,而我们的接口参数使用了javax.validation注解来验证参数。
最终,我们的调优方案是在调用的时候使用validation=“false”,即禁止使用参数验证这个特性后,tps就平稳多了,且cpu也正常了。
Dubbo官方文档:http://dubbo.apache.org/zh-cn/docs/user/maturity.html
目录
Vue介绍
传统的JavaScript
Nodejs搭配Vue
Nodejs的作用
什么是 NPM
为什么要使用 NPM
npm方法安装vue
配置淘宝镜像
别人node项目如何运行
自己搭建Nodejs环境
创建服务端
安装express
写后端启动文件 app.js
打包并部署
小总结
Vue搭配其他后端语言
Vue介绍 vue是许多的js框架中,我们可以只使用vue+nodejs进行项目开发,,也可以使用vue搭配后端语言进行项目开发。
首先介绍前一种nodejs开发
nodejs是一个服务js平台,有npm,grunt、express等强大的代码与项目管理应用。还有webpack,v8等强大的功能。
传统的JavaScript 传统的js是运行在浏览器上的,因为浏览器内核分为两个部分:
渲染引擎---渲染HTML和CSS,JavaScript 引擎---负责运行 JavaScript, Chrome 使用的 JavaScript 引擎是 V8,它的速度非常快且性能好。 Nodejs搭配Vue 服务端,使用nodejs搭配express 框架配合搭建提供一个API服务,以及服务端渲染,客户端则选择 vuejs 开发前端页面,vue-router做路由,vuex做状态管理 , axios 做ajax请求
Nodejs的作用 Node.js 是一个运行在服务端的框架,它的底层就使用了 V8 引擎。我们知道 Apache + PHP 以及 Java 的 Servlet 都可以用来开发动态网页,Node.js 的作用与他们类似,只不过是使用 JavaScript 来开发,它大大提升了开发的性能以及便利。使用node开发还可以使用配套的npm包管理工具:
什么是 NPM npm 基于 Node.js ,就像 pip 基于 Python, gem 基于 Ruby, pear 基于 PHP 。
自然语言中使用批处理时候, 每个句子的长度并不一定是等长的, 这时候就需要对较短的句子进行padding, 填充的数据一般是0, 这个时候, 在进行词嵌入的时候就会进行相应的处理, nn.embedding会将填充的映射为0
其中padding_idx就是这个参数, 这里以3 为例, 也就是说补长句子的时候是以3padding的, 这个时候我们液晶padding_idx设为3
import torch import torch.nn as nn embed = nn.Embedding(10, 3, padding_idx=3) # padding_idx 默认是0 embed.weight 你会看到所以为3的向量为0, 让我们再举个栗子
x = torch.tensor([[2, 2, 3, 3], [1, 2, 5, 4]]) embed(x) 有两个句子, 长度是4, 但是第一个句子长度只有2, 另外其是由3来padding的, 这时候通过embedding我们可以看到:
映射后是0了,这样继续进行后续的计算了
目录 一、js输出二、js事件三、js对象最后 今天是刘小爱自学Java的第81天。
感谢你的观看,谢谢你。
话不多说,开始今天的学习:
学前端有一个非常权威的组织,也就是w3c,其有个专门的教程文档,特别的全面。
我研究了下其文档,发现竟然连Python的教程都有,Java倒是一直显示“即将上线”。
当然官方文档存在的最大意义在于遇到不懂的知识点了可以通过它找到对应的讲解。
至于学习最好还是跟着某些专业教程来,既能少走许多弯路,也能节省许多时间。
一、js输出 这一块跟着文档学一学,对其有一定的了解,之后还是跟着教程走。
w3c网站将代码模板都给写好了,自己只需要做修改代码测试就可以了,十分方便。
1.innerHTML
document有一个方法getElementById(),见名知意,该方法是根据id获取对应的元素。
id是demo,那么获取id为demo的内容,上图中也就是1024。
但是为何输出又是“刘小爱”了呢?
原来还有个innerHTML,这是一个属性,相当于给id为“demo”的元素重新赋值了。
其中还有一个属性叫innerText,这个是只能修改元素内部的纯文本。
2.window.alert()
alert,警示的意思,也就是说调用alert方法,会弹出一个警示框来显示数据。
3console.log()
使用该方法可以将内容输出到浏览器控制台。
浏览器按F12即可打开浏览器控制台。
console,控制台的意思。
这个也就相当于IDEA中的控制台,只不过只是浏览器里面的,代码编写如下:
此外,昨天还学了一个专门输出的语句document.writeln(),就不再赘述了。
其实js中的所有知识点都可以在文档中学习。
但我这边主要还是学Java,不可能花大量的时间去学js,只学一个大概。
以后遇到问题,查文档能看懂即可。
二、js事件 事件是指浏览器或用户做的某些事情。
举几个例子:鼠标单击、双击某个按钮;键盘按着(不停地在输入);键盘弹起(输入结束)…
事件有好多个,暂且只学常用的几个。
①单击事件(全名函数注册)
onclick,即为单击的意思。
在input标签中有一个属性叫onclick,单击一下该按钮,会触发对应的事件。
也就是会调用onclick对应的那个函数,上图中就是click01函数。
所以点下按钮,click01函数执行,弹出警示框。
注意:函数名不能为click。
②双击事件(匿名函数注册)
ondblclick,它比onclick多一个dbl。dbl,double的简写,点两下单击,所以是双击。
这样记忆下来也就清晰好记多了。
其使用的是匿名注册,它的特点在于input标签中不用设置对应的函数名了。
而是用对应的id将该标签和匿名函数联系起来。
这样的好处在于耦合度低。
如果出了什么意外,只需要删除匿名函数即可,对input标签本身不用修改。
但是使用匿名函数也会有一个问题:
一开始是将script标签放在了input标签下面,现在将其移动到head标签中做一个测试,会发现:
单击事件能够触发,但是双击事件不能触发。
为什么会这样呢?我个人的理解是:
全名函数是直接在input标签(也就是HTML中)触发的事件;而匿名函数是在js中触发的事件。
这样匿名函数就会有一个执行顺序问题:
页面是从上到下执行的,当加载到js中双击事件的时候,对应的input标签都还没有加载呢。
那如何解决这个问题?
要么将script标签放在input标签后面,要么采用如下方法:
③页面加载事件
window.onload。根据其意思就能理解其表示的是网页加载完事件。
这是什么意思呢?
本来页面是从上到下依次执行的,当它加载到该事件的时候,相当于页面已经加载完了。
所以就算input标签在script标签的后面,也能触发事件。emm…暂且就是这样理解的。
三、js对象 学一学js中内置的几种常用对象
1数组对象
①关于数组遍历
在Java中数组直接打印是一串地址,但是在js中数组是可以直接打印的,数字之间用逗号隔开。
至于数组遍历,js和Java中一样,也是for循环遍历数组中的每一个元素,索引位从0开始。
②关于数组越界
在Java中,数组的长度确定后是不可变的,所以会出现越界问题。
但是在js中,数组的长度竟然是可变化的。
原文转载自:
https://www.jb51.net/article/132425.htm
这篇文章主要介绍了mysql 获取昨天日期、今天日期、明天日期以及前一个小时和后一个小时的时间,需要的朋友可以参考下:
1、当前日期
1
select DATE_SUB(curdate(),INTERVAL 0 DAY) ;
2、明天日期
1
select DATE_SUB(curdate(),INTERVAL -1 DAY) ;
3、昨天日期
1
select DATE_SUB(curdate(),INTERVAL 1 DAY) ;
4、前一个小时时间
1
select date_sub(now(), interval 1 hour);
5、后一个小时时间
1
select date_sub(now(), interval -1 hour);
6、前30分钟时间
1
select date_add(now(),interval -30 minute)
7、后30分钟时间
1
select date_add(now(),interval 30 minute)
取得当天:
SELECT curdate();
mysql> SELECT curdate();
+------------+
| curdate() |
+------------+
| 2013-07-29 |
+------------+
取得当前日期:
mysql> select now();
在开发网页获取微信用户信息的时候,公众号平台需要一个服务器的地址,但是现在都是在本地先测试项目的,并没有服务器的域名地址,所以需要设置一个能够访问本地项目的域名.
介绍个软件 Ngrok
首先下载软件
官网地址:https://ngrok.com
我的资源地址mac版的:https://download.csdn.net/download/qq_30323473/12581398
我的电脑是mac的 所以下载的是mac版本的 也支持windows和linux
下载后在mac中创建个文件夹 然后把下载后的文件解压到这个文件夹中
接下来打开命令行窗口 mac快捷键 command+空格 输入ter回车 就出来了
然后进入这个ngrok目录(不知道怎么找这个目录的话 就把文件拖到窗口中 就会生成这个文件的目录 前边加个cd 把最后边的文件名称删除掉)
然后执行命令
$ ./ngrok authtoken 1eINOCJRgfp1IH7opE38G0yoeOd_59MN5KpcnLsNpEBhev5FW 运行此命令会将您的身份验证令牌添加到默认配置文件。这将使您可以使用更多功能和更长的会话时间。正在运行的隧道将列在仪表板的状态页面上。 ngrok.yml
然后在执行
$./ngrok help 在执行
$./ngrok http 80 80端口可以改成你自己项目的端口 比如8081
回车就成功了
箭头所指向的就是随机生成的域名啦 你就能够通过域名+项目名访问自己本地的项目啦
谢谢观看 如有写的不对的地方 请留言 我会及时更正
Tarjan算法讲解的博客网上找到三篇比较好的,现在都转载了,个人只研究了第一篇,正如博主所说,讲的标比较详细,清晰,剩下两篇也可以看一下.
卿学姐视频讲解 https://www.bilibili.com/video/av7330663/ 以下内容转自:http://www.cnblogs.com/uncle-lu/p/5876729.html 全网最详细tarjan算法讲解,我不敢说别的。反正其他tarjan算法讲解,我看了半天才看懂。我写的这个,读完一遍,发现原来tarjan这么简单!
tarjan算法,一个关于 图的联通性的神奇算法。基于DFS(迪法师)算法,深度优先搜索一张有向图。!注意!是有向图。根据树,堆栈,打标记等种种神(che)奇(dan)方法来完成剖析一个图的工作。而图的联通性,就是任督二脉通不通。。的问题。
了解tarjan算法之前你需要知道:
强连通,强连通图,强连通分量,解答树(解答树只是一种形式。了解即可)
不知道怎么办!!!
神奇海螺~:嘟噜噜~!
强连通(strongly connected): 在一个有向图G里,设两个点 a b 发现,由a有一条路可以走到b,由b又有一条路可以走到a,我们就叫这两个顶点(a,b)强连通。
强连通图: 如果 在一个有向图G中,每两个点都强连通,我们就叫这个图,强连通图。
强连通分量strongly connected components):在一个有向图G中,有一个子图,这个子图每2个点都满足强连通,我们就叫这个子图叫做 强连通分量 [分量::把一个向量分解成几个方向的向量的和,那些方向上的向量就叫做该向量(未分解前的向量)的分量]
举个简单的栗子:
比如说这个图,在这个图中呢,点1与点2互相都有路径到达对方,所以它们强连通.
而在这个有向图中,点1 2 3组成的这个子图,是整个有向图中的强连通分量。
解答树:就是一个可以来表达出递归枚举的方式的树(图),其实也可以说是递归图。。反正都是一个作用,一个展示从“什么都没有做”开始到“所有结求出来”逐步完成的过程。“过程!”
神奇海螺结束!!!
tarjan算法,之所以用DFS就是因为它将每一个强连通分量作为搜索树上的一个子树。而这个图,就是一个完整的搜索树。
为了使这颗搜索树在遇到强连通分量的节点的时候能顺利进行。每个点都有两个参数。
1.DFN[]作为这个点搜索的次序编号(时间戳),简单来说就是 第几个被搜索到的。%每个点的时间戳都不一样%。
2.LOW[]作为每个点在这颗树中的,最小的子树的根,每次保证最小,like它的父亲结点的时间戳这种感觉。如果它自己的LOW[]最小,那这个点就应该从新分配,变成这个强连通分量子树的根节点。
ps:每次找到一个新点,这个点LOW[]=DFN[]。
而为了存储整个强连通分量,这里挑选的容器是,堆栈。每次一个新节点出现,就进站,如果这个点有 出度 就继续往下找。直到找到底,每次返回上来都看一看子节点与这个节点的LOW值,谁小就取谁,保证最小的子树根。如果找到DFN[]==LOW[]就说明这个节点是这个强连通分量的根节点(毕竟这个LOW[]值是这个强连通分量里最小的。)最后找到强连通分量的节点后,就将这个栈里,比此节点后进来的节点全部出栈,它们就组成一个全新的强连通分量。
先来一段伪代码压压惊:
tarjan(u){ DFN[u]=Low[u]=++Index // 为节点u设定次序编号和Low初值 Stack.push(u) // 将节点u压入栈中 for each (u, v) in E // 枚举每一条边 if (v is not visted) // 如果节点v未被访问过 tarjan(v) // 继续向下找 Low[u] = min(Low[u], Low[v]) else if (v in S) // 如果节点u还在栈内 Low[u] = min(Low[u], DFN[v]) if (DFN[u] == Low[u]) // 如果节点u是强连通分量的根 repeat v = S.
1、主题导出:首先你得把已有得主题导出到桌面(获取其他盘中).
2、主题导入:找到刚刚导出的文件,添加进来重启IDEA即可。
另外要是不知道你IDEA中所有的主题在哪里,可以看这篇文章,介绍了下载和导入主题的详细教程分享。
有用点赞,手留余香。
1、首先你得去网站上下载IDEA主题,推荐这个下载网站,当然你也可以去其他网站上下载主题的。
地址:http://www.soft-hub.cn/idea/list.html?page=2
对了,这个网站不仅可以下载主题哦!
打开网站界面:
2、下载代码主题,下载到目录随便都可以,但一会得找得到,下载得到一个jar包:
3、打开你安装的IDEA进行导入主题:
4、之后就是自动重启你的IDEA,然后你就会你心仪的代码主题风格了。
5、最后要是打开发现不是你需要的风格咋搞呢?比如像我一样。。。
一万只那什么在咆哮!这风格太辣眼睛了,虽然可以调节,但是我觉得还是不太适合我啊。
6、所以就有了删除或者更换你刚刚添加的主题介绍了。
① 首先说一下设置字体和字体大小,看看你刚刚导入的主题还有没有挽救的机会。
② 这里可以查看你所有的主题,可以对其进行删除和选择使用操作。
另外不知道怎样导出主题,可以查看这篇文章。
有疑问,请留言!有用点赞,手留余香。
dijkstra算法求最短路径 这个算法的思想和弗洛伊德算法有一点点相似,都是找一个中转站
1. 准备工作 1.1
我们的目的是要找到起始节点到各个结点的最小值,同时输出路径
因此我们定义几个数据变量
#include<iostream> #include<string.h> #define MAX 10000000 using namespace std; int maps[100][100]; int dis[100];//用来存储点到原点的距离 int flag[100];//用来判断点是否遍历过 string path[100]=""; maps就是两点之间的路径
dis就是两个结点之间的最小距离,最后要进行输出的
flag就是用来标记这个结点是否被遍历过
路径我们储存在path中
1.2
由于我们的路径是储存在path中,在最后输出的路径是string类型,但是结点我设置的是int型
(其实也可以用模板写,这样结点就不一定是int的,我这里就不多写了)
所以我们之后写一个int转string的函数
string i_to_s(int num) { int j=0; char str1[20]=""; string str2=""; while (num > 0) { str1[j] = num % 10 + '0'; num = num / 10; j++; } for (int i = strlen(str1) - 1; i >= 0; i--) { str2 += str1[i]; } return str2; } c++有一个函数是 to_string(),直接可以把int转为string的,但是好像要设置编译环境,我不太懂这个,如果你的编译环境可以的话,能直接用这个函数,就不用单独写上面这函数了
目录
有效数字
浮点型
整型
运算
BigDecimal的加减乘除
工具类
Bigdecimal判断是否等于0
四舍五入
使用Math中四舍五入的方法
使用BigDecimal对象的方式
使用DecimalFormat对象的方式
使用String.format方式
注:随机数
注:整数相除保留两位小数
注:double 类型的运算跟实际结果有误差
注:long类型进行相加运算,值溢出的解决方法
有效数字 左边第一个不是0的数字起,到精确到的位数止,所有的数字都叫做这个数的有效数字。
浮点型 float的范围为-2^128 ~ +2^128
double的范围为-2^1024 ~ +2^1024。
float:2^23 = 8388608,共七位,最多能有7位有效数字,但绝对能保证的为6位,也即float的精度为6~7位有效数字。
double:2^52 = 4503599627370496,共16位,同理,double的精度为15~16位。
f是float,没有后缀默认是double
浮点数无法精确表示,bigdecimal不含任何误差
大数值:BigInterger,BigDecimal 运算符:add subtract multiply divide mod
整型 二进制:前缀为0b或0B。如0b101=5
八进制:前面加上一个0。八进制只有0~7八个数。如八进制的343,要写为0343
十进制:正常写
十六进制:前缀为0x或0X。如0x343=3*256+4*16+3=835
运算 除数和被除数为整数时,为整数除法
/做除,%取余
++a 先加1,后运算
a++ 先运算,后加1
位运算符:不短路
BigDecimal的加减乘除 下面为BigDecimal的用法:
序号方 法类型描 述1public BigDecimal(double val)构造将double表示形式转换为BigDecimal2public BigDecimal(int val)构造将int表示形式转换为BigDecimal3public BigDecimal(String val)构造将字符串表示形式转换为BigDecimal4public BigDecimal add(BigDecimal augend)普通加法5public BigDecimal subtract(BigDecimal subtrahend)普通减法6public BigDecimal multiply(BigDecimal multiplicand)普通乘法7public BigDecimal divide(BigDecimal divisor)普通除法 工具类 import java.
AAPT: \\?\C:\Windows\System32\config\systemprofile\.android\build-cache\eb8810c9ed7d0229582090839eb229e4938e96dc\output\res\drawable-hdpi-v4\abc_textfield_search_default_mtrl_alpha.9.png ERROR: Unable to open PNG file
解决方法:
在项目的gradle.properties指定buildCache目录
android.buildCacheDir=F\:/android-studio/build-cache
在嵌入式开发中,在设备运行的时候出现网络挂载问题时候,经常需要临时修改设备的ip地址,子网掩码,MAC地址,网关等,可以使用ifconfig eth0修改网卡的配置信息。
ifconfig显示网络设备信息
[root@localhost ~]# ifconfig
eth0 Link encap:Ethernet HWaddr 00:50:56:BF:26:20 inet addr:192.168.120.204 Bcast:192.168.120.255 Mask:255.255.255.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:8700857 errors:0 dropped:0 overruns:0 frame:0
TX packets:31533 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000 RX bytes:596390239 (568.7 MiB) TX bytes:2886956 (2.7 MiB)
lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0
UP LOOPBACK RUNNING MTU:16436 Metric:1
RX packets:68 errors:0 dropped:0 overruns:0 frame:0
TX packets:68 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0 RX bytes:2856 (2.
jakarta ee
这个月我们在做一些不寻常的事情。 通常,我们会直接浏览过去一个月的十大新闻文章。 但是,由于它们非常重要,所以我们必须包含两篇最新新闻文章。 他们可能没有获得点击次数来创建列表,但是我们非常喜欢它们,因此不得不在这里放置它们。 荣誉奖 这么久的Java EE,欢迎您使用Jakarta EE! 自Eclipse Enterprise for Java发布以来已经过去了五个月,现在我们终于有了一个以前称为Java EE的技术名称。 EE.next品牌传奇始于2017年底,现已结束。 该社区受邀通过GitHub Issue记录进行提名,并且有很多很棒的建议,但是“最终,选择过程有效地归结为从Eclipse Foundation可以代表其注册并持有商标的建议中识别出这些名称。社区”,韦恩·比顿(Wayne Beaton)在第二个GitHub问题中写道。 新品牌名称为Jakarta EE (经Apache Software Foundation许可使用)。 Eclipse基金会执行总监Mike Milinkovich在最近的博客文章中宣布了这一消息。 经过17个月的努力和215个不同人员的6800多次提交,Spring Boot 2.0终于面世了。 让我们看看有什么新功能和值得注意的功能-是的,Java 9支持是其中的一部分。 Pivotal的Phil Webb在最近的博客文章中宣布,Spring Boot 2.0是自1.0年前发布以来的第一个主要版本,是1.0版本的发布,它也是Spring Boot的第一个GA版本,该版本提供对Spring Framework 5.0的支持。 现在,回到我们定期排定的前十名! 开关案例语句是用于编程控制的强大工具。 在本文中,Sreeram Sceenivasan讨论了可以在Python中使用switch-case语句的问题。 随着JDK 9和NetBeans的发行过渡到Apache,您应该等待还是转移到其他开发环境? 因为NetBeans IDE 8.2不支持JDK 9,所以那些想要使用JDK 9的人确实需要做出一些选择。 在本教程中,Michael Gruczel使用一个简单的示例来演示如何使用Spring Boot设置基于REST的微服务。 Java EE应用程序服务器和整体软件体系结构的时代几乎消失了。 硬件不再进步,但互联网流量仍在增长。 平台必须支持横向扩展。 必须将负载分配给多个主机。 基于微服务的体系结构可以为此要求提供解决方案。 除了更好的扩展性之外,微服务还提供了更快的开发周期,根据负载动态扩展和改进了故障转移行为。 Angular 6应该很快发布。 随着我们越来越接近大结局,我们开始看到正在逐渐成为一个很棒的版本的点点滴滴。 Beta.6在这里。 2015年11月,Dirk Lemmermann(自由职业者)和我(Alexander Casall)举行了有关JavaFX真实世界应用程序的JavaOne会议。 我们展示了许多我们为客户开发的应用程序,或者我们在开发中做出贡献的应用程序。 本文通过显示我们讨论过的应用程序来总结演讲。 此外,我询问了其他JavaFX开发人员是否希望将其应用程序贡献到此博客文章中。 Angular 4已发布。 在本文中,Karsten Sitterberg和Thomas Kruse展示了所有创新,给出了迁移技巧,并猜测了Angular 5的外观。 公司正努力寻找足够的能够进行ML和深度学习编码的程序员。 你准备好了吗? 这是Java机器学习库的五个精选。 角形五角形甜甜圈5.
公有属性 (float)angle:角度,表示关键点的方向,-1为初值。
(int)class_id:当要对图片进行分类时,我们可以用class_id对每个特征点进行区分,未设定时为-1,需要靠自己设定
(int)octave:代表是从金字塔哪一层提取的得到的数据。
(Point2f)pt:关键点的点坐标
(float)response:响应程度,代表该点强壮大小—response代表着该关键点how good,更确切的说,是该点角点的程度。
(float)size:该点直径的大小
公有成员函数 三个构造函数
KeyPoint () : 默认构造函数
KeyPoint (Point2f _pt, float _size, float _angle=-1, float _response=0, int _octave=0, int _class_id=-1)
参数 _pt : 关键点的x和y坐标 _size : 关键点直径 _angle : 关键点方向 _response:关键点上的关键点检测器响应(即关键点的强度) _octave : 已检测到关键点的pyramid octave _class_id: 关键点ID KeyPoint (float x, float y, float _size, float _angle=-1, float _response=0, int _octave=0, int _class_id=-1)
参数 x : 关键点的x坐标 y : 关键点的y坐标 _size : 关键点直径 _angle : 关键点方向 _response:关键点上的关键点检测器响应(即关键点的强度) _octave : 已检测到关键点的pyramid octave _class_id: 关键点ID size_t hash () const
文章目录 官网适用Windows版本官方文档下载、安装与启动使用实例重要提示基本恢复步骤如何选择模式并判断文件系统常用参数命令行语法默认模式示例段模式示例(/ r)签名模式示例(/ x) 常见问题一些帮助使用正确的语法?在命令示例中是什么意思?为什么收到此消息:“源和目标不能引用相同的物理分区?”为什么恢复操作需要这么长时间?为什么要从操作系统驱动器中恢复其他文件?什么是$ Recycle.Bin文件夹?如果目标驱动器已满怎么办?我无法恢复文件,现在怎么办? 官网 https://www.microsoft.com/zh-cn/p/windows-file-recovery/9n26s50ln705?activetab=pivot:overviewtab
适用Windows版本 Windows 10 2004及更高版本
官方文档 https://support.microsoft.com/en-us/help/4538642/windows-10-restore-lost-files
下载、安装与启动 打开Win10应用商店,(开始->Microsoft store)搜索“Windows File Recovery”。
如果是首次安装,页面上还会出现一个“获取”按钮,如果之前已经安装过,那么这里会变为“安装/打开”。首次安装时请点击“获取”按钮
从“开始”菜单中打开Windows File Recovery
如果UAC提示,请单击“ 是”以管理员身份运行。
最后点击面板上的“启动”按钮,启动Windows File Recovery,里接下来的操作都是dos命令行操作,不知道后续会不会有官方或第三方gui界面支持
使用实例 数据恢复是份精细活,所以最好核对好每个步骤再进行操作
重要提示 如果要增加恢复文件的可能性,请尽量避免使用设备。在Windows文件系统中,已删除文件使用的空间被标记为可用空间,这意味着文件数据仍然存在并可以恢复。但是,任何使用设备的人都可能创建文件,这些文件可能随时覆盖这部分可用空间。
基本恢复步骤 如何选择模式并判断文件系统 以下信息可以帮助您确定拥有的文件系统以及使用的模式。
文件系统
Windows支持几种文件系统,具体取决于存储设备或操作系统。仅在签名模式下支持从非NTFS文件系统恢复文件。要查看自己设备文件系统,请在此电脑中对想查看的驱动器右键,然后选择“ 属性”
下表是一般情况下的各类文件系统
文件系统示例FAT和exFATSD卡,闪存或U盘(<4GB)ReFSWindows Server和Windows Pro工作站版NTFS计算机(HDD,SSD),外部硬盘驱动器,闪存或U盘(> 4GB) 使用下表可以帮助您决定使用哪种模式。如果不确定,请从默认模式开始。
文件系统情况推荐模式NTFS最近删除默认前几天删除首先尝试段模式,然后再签名格式化磁盘后首先尝试段模式,然后再签名损坏的磁盘首先尝试段模式,然后再签名FAT,exFAT,ReFS参见下表签名 文件扩展名文件类型ASFwma, wmv, asfJPEGjpg, jpeg, jpe, jif, jfif, jfiMP3mp3MPEGmpeg, mp4, mpg, m4a, m4v, m4b, m4r, mov, 3gp, qtPDFpdfPNGpngZIPzip, docx, xlsx, pptx, odt, ods, odp, odg, odi, odf, odc, odm, ott, otg, otp, ots, otc, oti, otf, oth 常用参数 下表总结了每个基本命令行参数和开关的用途。
内容来源于微信公众号:大神编程。已经过原文作者授权。
更新时间:2020-11-5
因为OpenJudge题库和一本通题库很多题都是一样,所以很多链接都是直接使用一本通的题解,完全不影响。
为什么要转载:
动画、图文结合。我看了部分文章,一些我觉得很简单的题,但从中学到了以前没有学过的知识点和细节,重点是从中学习别人思维方式。让更多的同学能学到更多的知识。 官方的QQ群:893157498(已取消,有微信群)
这是我建的QQ群:795233394
欢迎各位志同道合的同学们^_^
已更新的题目颜色是蓝色,点击相应的题目名称即可查看该题的详细题解。
因NOI系列赛事将不再支持Pascal和C语言,只支持C++,所以所有题解不会使用Pascal,而使用C/C++。使用C语言是为了让部分学C语言的同学有所适应,并且部分题解会使用C/C++,主要让学C语言的同学可以对比两者,有利于由C转C++。不过后面或许不再使用C语言,只使用C++。
目录
1.1编程基础之输入输出(10题)
1.2编程基础之变量定义、赋值及转换(10题)
1.3编程基础之算术表达式与顺序执行(20题)
1.4编程基础之逻辑表达式与条件分支(21题)
1.5编程基础之循环控制(45题)
1.6编程基础之一维数组(15题)
1.7编程基础之字符串(35题)
1.8编程基础之多维数组(25题)
1.9编程基础之顺序查找(15题)
1.10编程基础之简单排序(10题)
1.11编程基础之二分查找(10题)
1.12编程基础之函数与过程抽象(10题)
1.13编程基础之综合应用(51题)
2.1基本算法之枚举(37题)
2.2基本算法之递归和自调用函数(13题)
2.3基本算法之递归变递推(6题)
2.4基本算法之分治(7题)
2.5基本算法之搜索(36题)
2.6基本算法之动态规划(59题)
2.7基本算法之算法效率(12题)
1.1编程基础之输入输出(10题) 01:Hello, World!
02:输出第二个整数
03:对齐输出
04:输出保留3位小数的浮点数
05:输出保留12位小数的浮点数
06:空格分隔输出
07:输出浮点数
08:字符三角形
09:字符菱形
10:超级玛丽游戏
1.2编程基础之变量定义、赋值及转换(10题) 01:整型数据类型存储空间大小
02:浮点型数据类型存储空间大小
03:其他基本数据类型存储空间大小
04:填空:类型转换1
05:填空:类型转换2
06:浮点数向零舍入
07:打印ASCII码
08:打印字符
09:整型与布尔型的转换
10:Hello, World!的大小
1.3编程基础之算术表达式与顺序执行(20题) 01:A+B问题
02:计算(a+b)*c的值
03:计算(a+b)/c的值
04:带余除法
05:计算分数的浮点数值
06:甲流疫情死亡率
07:计算多项式的值
08:温度表达转化
09:与圆相关的计算
10:计算并联电阻的阻值
11:计算浮点数相除的余数
12:计算球的体积
13:反向输出一个三位数
关于
内容来源于微信公众号:大神编程。已经过原文作者授权。
题目:
1100:金币
超详细动画图文题解链接
题解目录(不断更新中)
喜欢信息学奥赛的同学们,可以一起交流学习哦
官方QQ群:893157498
我的QQ群:795233394
关于
内容来源于微信公众号:大神编程。已经过原文作者授权。
题目:
1099:第n小的质数
超详细动画图文题解链接
题解目录(不断更新中)
喜欢信息学奥赛的同学们,可以一起交流学习哦
官方QQ群:893157498
我的QQ群:795233394
可能这类工具书自己看的有点多了,里边的内容对自己都差不太多了,想再进一步从这类书籍获取特别突破性的知识点已经不太符合自己的预期了。不过这本书感觉作为一本入门书籍,确实是一个不错的选择,语言简单朴实,尤其是其提到了的 最少必要知识(MAKE) 理念,在现在信息轰炸的时代,确实十分必要可行。如何合理规划出最少必要知识,并进而快速掌握,从而触类旁通,进一步扩展知识圈,是一个非常不错的想法。
反思,一方面自己应该对现在所学内容要进一步归类整理,另一方面,也该做出一些改变,尝试新的知识圈,拓展思维和动手能力。
《Python极简讲义:一本书入门数据分析与机器学习》 作者:张玉宏,出版社:电子工业出版社,出版时间:2020-04,ISBN:9787121387043
ArrayBlockingQueue,LinkedBlockingQueue,LinkedBlockingDeque原理分析 什么是阻塞队列队列Queue接口核心方法阻塞队列BlockigQueue接口核心方法ArrayBlockingQueue模拟实现生产者消费者初始化队列添加元素(生产者)获取元素(消费者) LinkedBlockingQueue初始化队列添加元素(生产者)获取元素(消费者) LinkedBlockingDeque初始化队列添加元素(生产者)从First添加从Last添加 获取元素(消费者)从First获取从Last获取 总结 什么是阻塞队列 阻塞队列有两个特点:
当队列中没有元素时,从队列中获取元素会被阻塞当队列满了时,添加元素会被阻塞 阻塞队列常用于生产者和消费者的场景,生产者是向队列里添加元素,消费者则从队列里取元素。
队列Queue接口核心方法 阻塞队列,本质上来说还是属于队列,也就是说阻塞队列继承了队列的功能,这里我们先来看看Queue接口中的几个核心方法:
方法功能add(e)添加一个元素,成功返回true,如果空间满了则抛出异常offer(e)添加一个元素,成功返回true,如果空间满了则返回false,处理有界队列时优于add方法remove()检索并移除队列头元素,成功则返回移除的元素,如果队列为空则抛出异常poll()检索并移除队列头元素,成功则返回移除的元素,如果队列为空则返回nullelement()检索并返回队列头元素,如果队列为空则抛出异常peek()检索并返回队列头元素,如果位列为空则返回null 这几个方法是队列接口所提供的,然而这些方法并不会阻塞,所以需要重新定义阻塞队列的接口,下面我们看看阻塞队列中的核心方法。
阻塞队列BlockigQueue接口核心方法 方法功能put(e)添加一个元素,成功返回true,如果空间满了则阻塞等待offer(e,time,unit)添加一个元素,成功返回true,如果空间满了则阻塞指定时间,到达指定时间还没空间则返回nulltake()检索并移除队列头元素,成功则返回移除的元素,如果队列为空则阻塞poll(time,unit)检索并移除队列头元素,成功则返回移除的元素,如果队列为空则阻塞指定时间,到达指定时间后队列还是空则返回nulldrainTo(Collection)一次性获取队列所有元素放到指定的集合中,并返回转移个数drainTo(c,n)一次性获取队列中指定个数的元素放到指定的集合中,并返回转移个数remainingCapacity()返回队列中理想情况下可添加元素个数 在Java中,提供了7种常用的阻塞队列。
ArrayBlockingQueue:由数组结构组成的有界阻塞队列LinkedBlockingQueue:由链表结构组成的有界阻塞队列PriorityBlockingQueue:支持优先级排序的无界阻塞队列DelayQueue:使用优先级队列实现的无界阻塞队列SynchronousQueue:不存储元素的阻塞队列LinkedTransferQueue:由链表结构组成的无界阻塞队列LinkedBlockingDeque:由链表结构组成的双向阻塞队列 ArrayBlockingQueue ArrayBlockingQueue是一个用数组实现的有界阻塞队列。此队列按照先进先出(FIFO)的原则对元素进行排序。默认情况下采用非公平锁的方式实现,可以通过构造器传参控制是采用公平锁还是非公平锁实现。先看看ArrayBlockingQueue类图关系:
可以看到有3个构造器,其实最终都是会调用上图中第二个构造器进行初始化,第三个构造器在初始化之后会再进行赋值(如果传入的Collection不为空)。
ArrayBlockingQueue nonFairQueue = new ArrayBlockingQueue(10);//默认非公平锁实现 ArrayBlockingQueue fairQueue = new ArrayBlockingQueue(10,true);//true表示公平锁 模拟实现生产者消费者 package com.zwx.concurrent.queue.block; import java.util.concurrent.ArrayBlockingQueue; public class ArrayBlockingQueueDemo { public static void main(String[] args) throws InterruptedException { ArrayBlockingQueue<Integer> queue = new ArrayBlockingQueue(100);//默认非公平锁实现 new Thread(new ConsumerThread(queue)).start(); Thread.sleep(2000); new Thread(new ProcuctThread(queue)).start(); } } class ProcuctThread extends Thread{ private ArrayBlockingQueue queue; public ProcuctThread(ArrayBlockingQueue queue) { this.
这是java 三大特性之一:多态的表现
即 接口声明的变量 被赋值为该接口实现类的对象的引用
如 List list = new ArrayList( );
这里 List 是接口, ArrayList 是List 的实现类
实现多态的方式有三种:重写、接口、抽象类和抽象方法。 这里是接口的多态特性,并且使用的是动态绑定(后期绑定)
Volumes配置管理 容器中的文件在磁盘上是临时存放的,这给容器中运行的特殊应用程序带来一些问题。首先,当容器崩溃时,kubelet 将重新启动容器,容器中的文件将会丢失,因为容器会以干净的状态重建。其次,当在一个 Pod 中同时运行多个容器时,常常需要在这些容器之间共享文件。 Kubernetes 抽象出 Volume 对象来解决这两个问题。Kubernetes 卷具有明确的生命周期,与包裹它的 Pod 相同。 因此,卷比 Pod 中运行的任何容器的存活期都长,在容器重新启动时数据也会得到保留。 当然,当一个 Pod 不再存在时,卷也将不再存在。也许更重要的是,Kubernetes 可以支持许多类型的卷,Pod 也能同时使用任意数量的卷。卷不能挂载到其他卷,也不能与其他卷有硬链接。 Pod 中的每个容器必须独立地指定每个卷的挂载位置。 Kubernetes 支持下列类型的卷:
awsElasticBlockStore 、azureDisk、azureFile、cephfs、cinder、configMap、csidownwardAPI、emptyDir、fc (fibre channel)、flexVolume、flockergcePersistentDisk、gitRepo (deprecated)、glusterfs、hostPath、iscsi、local、nfs、persistentVolumeClaim、projected、portworxVolume、quobyte、rbdscaleIO、secret、storageos、vsphereVolume emptyDir卷: 当 Pod 指定到某个节点上时,首先创建的是一个 emptyDir 卷,并且只要 Pod 在该节点上运行,卷就一直存在。 就像它的名称表示的那样,卷最初是空的。 尽管Pod 中的容器挂载 emptyDir 卷的路径可能相同也可能不同,但是这些容器都可以读写 emptyDir 卷中相同的文件。 当 Pod 因为某些原因被从节点上删除时,emptyDir 卷中的数据也会永久删除。
emptyDir 的使用场景:
缓存空间,例如基于磁盘的归并排序。为耗时较长的计算任务提供检查点,以便任务能方便地从崩溃前状态恢复执行。在 Web 服务器容器服务数据时,保存内容管理器容器获取的文件。 默认情况下, emptyDir 卷存储在支持该节点所使用的介质上;这里的介质可以是磁盘或 SSD 或网络存储,这取决于您的环境。 但是,您可以将 emptyDir.medium 字段设置为 "Memory",以告诉 Kubernetes 为您安装 tmpfs(基于内存的文件系统)。 虽然tmpfs 速度非常快,但是要注意它与磁盘不同。 tmpfs 在节点重启时会被清除,并且您所写入的所有文件都会计入容器的内存消耗,受容器内存限制约束。
目录: 1、在线逻辑分析仪简介2、HDL 实例化调试探针流程(实验-闪烁灯)3、Hardware Manager中观察调试信号4、网表插入调试探针流程(实验-闪烁灯) 1、在线逻辑分析仪简介 在线逻辑分析仪借用了传统逻辑分析仪的理念以及大部分的功能,并利用 FPGA 中的逻辑资源,将这些功能植入到 FPGA 的设计当中。一般地,在线逻辑分析仪的应用原理框图如下图所示:
待测设计(Design Under Test,DUT)就是用户逻辑,它和片内的在线逻辑分析仪都位于 FPGA中。在线逻辑分析仪通过一个或多个探针(Probe)来采集希望观察的信号,然后通过片内的 JTAG 硬核组件,来将捕获到的数据传送给下载器,进而上传到 Vivado IDE 以供用户查看。Vivado IDE 也能够按照上述数据路径,反向地向 FPGA 中的在线逻辑分析仪传送一些控制信息。
在 Vivado 中,在线逻辑分析仪的功能被称为“集成逻辑分析器(Integrated Logic Analyzer,ILA)”,它以 IP 核的形式来加入到用户设计中。。Vivado 提供了三种具有不同集成层次的插入 ILA 方法,主要为以下两种:
第一种方法是直接在 HDL 代码中例化一个 ILA IP 核,也被称为“HDL 实例化调试探针流程”,这是集成层次最高的方法。ILA IP 核可以在 IP Catalog(IP 目录)中找到,并对其进行配置,以符合所需的调试需求。这是最直接的方法,但其灵活性也较差。在调试工作完毕之后,还需要在 HDL 源代码中删除 ILA IP核,然后重新综合并实现,以生成最终的比特流。
第二种方法是在综合后的网表中,分别标记要进行调试观察的各个信号,然后通过一个简单的“Setup Debug”向导来设置各个探针和 ILA IP 核的工作参数,然后工具会根据用户设置的参数,自动地生成各个ILA IP 核。这个方法也被称为“网表插入调试探针流程”。在此流程中,用户不需要修改 HDL 源代码,并且能够单独控制每个 ILA IP 核以及每个探针,这样就提供了很大的灵活性。用户设置的调试信息会以 Tcl XDC 调试命令的形式保存到 XDC 约束文件中,在实现阶段,Vivado 会读取这些 XDC 调试命令,并在布局布线时加入这些 ILA IP 核。在调试工作完毕之后,用户就可以在综合后的网表中删除 ILA IP 核,或者在XDC 文件中删除调试命令,然后再对设计进行实现,以生成最终的比特流。
官方文档 https://axkibe.github.io/lsyncd/
https://github.com/axkibe/lsyncd
lsyncd简介 Lsyncd使用lua语言对inotify和rsync进行封装,使用文件系统事件接口(inotify或fsevents)来监视对本地文件和目录的更改,Lsyncd将这些事件整理几秒钟,然后生成一个或多个进程以将更改同步到远程文件系统,默认同步方法是rsync。是一种轻量级的实时镜像解决方案,不需要新的文件系统或块设备,Lysncd不会妨碍本地文件系统性能
可以通过配置文件实现细粒度的自定义。自定义操作配置甚至可以从头开始编写,从shell脚本到用Lua语言编写的代码
Lsyncd 2.2.1在所有源计算机和目标计算机上都需要rsync> = 3.1。
安装 在ubuntu和debian,lsyncd已经收入到其官方镜像源中,直接使用apt-get安装即可
apt-get install rsyncd
lsyncd配置 lsyncd的配置是用lua语言编写,一般为/etc/lsyncd.conf,常用的主要是两部分:
setting部分
里面是全局变量,–后面的表示注释,常见配置如下:
settings { logfile = "/var/log/lsyncd/lsyncd.log", --日志文件 pidfile = "/var/run/lsyncd.pid", --记录进程ID的文件,可以不用配置 statusFile = "/var/log/lsyncd/lsyncd.status", --运行状态文件,包括记录一些监控目录的变更信息 statusInterval = 5, --将lsyncd的状态写入上面的statusFile的间隔,默认10秒 nodaemon = true, --表示不启用守护模式,默认 inotifyMode = "CloseWrite", --指定inotify监控的事件,默认是CloseWrite,还可以是Modify或CloseWrite or Modify maxProcesses = 5, --同步进程的最大个数。假如同时有10个文件需要同步,而maxProcesses=5,则最大能看到有5个rysnc进程 maxDelays = 1, --累计到多少所监控的事件激活一次同步,即使后面的delay延迟时间还未到 inist = ture, --keep running at startup although one or more targets failed due to not being reachable.
1.我们先来看一下,在Chrome浏览器更新的时候,提示检查更新时出错:无法启动更新检查的提示信息 2.然后在打开的Windows10的运行窗口中输入services.msc后点击确定按钮运行该命令。 3.这时会打开Windows10的本地组策略编辑器窗口中,在窗口中找到Google更新服务的设置项。 4.右键点击该设置项,在弹出菜单中选择属性的菜单项。 5.接下来在的更新服务属性窗口中,我们点击启动按钮。 这样我们再次更新Chrome浏览器,就可以正常更新了。 如果以上在第3步为找到Google (gupdate)那你就点下面链接下载谷歌浏览器,根据自己电脑的位数下载,不会看自己电脑的可以这百度搜索一下,很简单.(提醒一下,下载前记得在控制面板里删除谷歌浏览器) 最新更新: 83.0.4103.61(正式版本) (64 位) 32位 https://www.google.cn/chrome/?platform=win&extra=stablechannel&standalone=1 64位 https://www.google.cn/chrome/browser/desktop/index.html 下载后会有这个图片,双击就ok,第一次安装后可能谷歌无法使用,再次双击就ok
Secret配置管理 Secret 对象类型用来保存敏感信息,例如密码、OAuth 令牌和 ssh key。敏感信息放在 secret 中比放在 Pod 的定义或者容器镜像中来说更加安全和灵活。Pod 可以用两种方式使用 secret: 作为 volume 中的文件被挂载到 pod 中的一个或者多个容器里。当 kubelet 为 pod 拉取镜像时使用。 Secret的类型: Service Account:Kubernetes 自动创建包含访问 API 凭据的 secret,并自动修改pod 以使用此类型的 secret。Opaque:使用base64编码存储信息,可以通过base64 --decode解码获得原始数据,因此安全性弱。kubernetes.io/dockerconfigjson:用于存储docker registry的认证信息。 serviceaccout 创建时 Kubernetes 会默认创建对应的 secret。对应的 secret 会自动挂载到Pod 的 /run/secrets/kubernetes.io/serviceaccount 目录中。 kubectl exec nginx -- ls /var/run/secrets/kubernetes.io/serviceaccount 每个namespace下有一个名为default的默认的ServiceAccount对象 kubectl get Secret ServiceAccount里有一个名为Tokens的可以作为Volume一样被Mount到Pod里的Secret,当Pod启动时这个Secret会被自动Mount到Pod的指定目录下,用来协助完成Pod中的进程访问API Server时的身份鉴权过程。 kubectl get pods -o yaml Opaque Secret 其value为base64编码后的值 从文件中创建Secret 如果密码具有特殊字符,则需要使用 \ 字符对其进行转义
默认情况下 kubectl get和kubectl describe 为了安全是不会显示密码的内容,可以通过以下方式查看: 练习:
注意 1、一般电池用到20%左右,就需要充电了,不要等到0时再充电,太伤电池了。
2、关闭不必要的系统服务
3、将笔记本电池选择为节能模式
4、关闭不必要的程序,之开启所需程序
5、长时间不用时,启用睡眠模式或者休眠模式或者是直接关机。
笔记本清尘的注意事项 1、要先关闭电源以及卸载电池(也可以直接将电池里面的电,放完,就不用卸掉电池了)。
在对笔记本进行清灰的时候,win7系统用户先关闭电源,,并且卸掉笔记本上的电池,这样在清灰过程中,对计算机损坏才会降低到最小的范围。
2、释放静电
在卸掉笔记本电源以后,为了安全着想,最好能够释放一下静电,重新按一下电源开机键,计算机内残留的静电就会被直接释放出去了。
笔记本电脑电池充不进电的原因及解决方法 电脑 :戴尔
1、软件冲突导致。笔记本系统自带电池管理软件,如果充电有异常,软件则会阻止电池充电。
2、笔记本电池有问题。可以重启电脑,重新插拔充电器,判断是否充电有效。
3、尝试进入bios,在power项目中找到“start battery calibration”选项,根据提示进行修复,只是时间较长。
4、也可能是充电器坏了,导致充电不正常。
5、根据软件,检测电池的性能。
6、回想一下笔记本使用有几年了,如果时间长了,可以去售后那里检测并维修一下。
7、
8、
9、
10、
参考链接 :
http://www.udaxia.com/wtjd/1697.html
http://www.udaxia.com/wtjd/1422.html
ConfigMap配置管理 1. configMap作用及使用场景 ConfigMap用于保存配置数据,以键值对形式存储。ConfigMap 资源提供了向 Pod 注入配置数据的方法。旨在让镜像和配置文件解耦,以便实现镜像的可移植性和可复用性。 典型的使用场景:
填充环境变量的值设置容器内的命令行参数填充卷的配置文件 2. ConfigMap的创建 创建方式:
使用字面值创建使用文件创建使用目录创建编写configmap的yaml文件创建 字面值创建:
kubectl create configmap my-config --from-literal=key1=config1 --from-literal=key2=config2 使用文件创建:
kubectl create configmap my-config-2 --from-file=/etc/resolv.conf 使用目录创建:
kubectl create configmap my-config-3 --from-file=test 编写configmap的yaml文件
kubectl create -f cm-test.yaml 4. 如何使用configmap: 通过环境变量的方式直接传递给pod通过在pod的命令行下运行的方式作为volume的方式挂载到pod内 使用configmap设置环境变量
vim pod1.yaml kubectl create -f pod1.yaml vim pod2.yaml kubectl create -f pod2.yaml 使用conigmap设置命令行参数
vim pod2.yaml 通过数据卷(volume)使用configmap
vim pod3.yaml 5. configmap热更新 vim pod4.yaml kubectl create -f pod4.yaml 查看
修改
==> 学习汇总(持续更新)
==> 从零搭建后端基础设施系列(一)-- 背景介绍
摘要:为什么要写这篇文章?因为从网上搜索"索引失效的原因"时,要么是一些片面的总结性用语,例如"如果条件中有or,即使其中有条件带索引也不会使用",要么就是对着一些例子搭配explain进行笼统的解释。导致我经常看过就忘,究其根本原因就是没理解透彻,所以我经过从官方文档、博客和书籍等,来探究其内部索引使用的原理。鉴于内容较多,分为上下两篇进行分析,上篇主要了解索引原理以及查询优化器的概念,下篇根据上篇学到的知识并结合查询优化器,对于各种索引失效场景进行分析以及SQL调优思想总结。另外,会有一篇专门分析查询优化器的文章。
一、索引是个什么东西?
其实我觉得字典、图书馆的类比已经挺形象的了。就拿字典来说,如果你想查"hello"这个单词,是不是第一反应是先去目录那找到"H"开头的单词,接着在"H"下面继续跳到第二个字母是"E"的单词,依次类推,跳几次就能很快定位到这个单词了。但是跟这个单词相关联的仅仅是一个页码N,所以我们接着跳到第N页,又发现这一页有很多单词,这时候我们只能依次遍历这一页,才能找到"hello"这个单词的详细释义。如下图所示
如果没有索引,我们如何找这个单词?很容易想象,在一本厚厚的字典里,一页一页的遍历查找,虽然有序的话,还是可以跳页,但是需要过滤的信息量太大。回到数据库中,其实思想也是一样的,相较于全表扫描,那通过索引定位是不是要快很多?所以数据库中才会造出那些个索引出来。 二、MYSQL中的B+树索引类型分类和原理分析
mysql中用的最多的就是B+树索引,那这些索引如何分类呢?大家肯定已经知道非常多的索引类型名词,眼花缭乱,群魔乱舞。其实吧,mysql中的索引其实就分为2大类分别是聚集索引和辅助索引,其它都是按照功能分类造的名词,不需要强行去背它,只要理解了这两类索引的区别即可。最后还有稍微特殊一点的联合索引会单独说一下。
MYSQL中的B+树是什么样的
先看一个非常简单的图
从图中可以得出以下几个结论
a.只有叶子节点称为数据节点,并且它存储了完整的数据
b.目录节点只存放能够找到下层目录节点和数据节点的信息
c.不管是目录节点还是数据节点,同一层次的节点用双链表相互连接
d.不管是目录节点还是数据节点,内部都用单链表连接
以上4个结论还比较表面,继续看一张比较详细的图
从图中可以得出以下几个结论(假设图中数据节点的记录分别是id和name两个字段)
a.所有的节点都是一个数据页
b.目录节点存放的记录信息只有key和对应的数据页
c.遍历数据节点能够得到按索引字段有序的记录
d.数据页内并不是直接依次遍历得到记录,而是通过页目录进行二分查找
mysql中的B+树就长这样了,这也为什么说索引即数据,指的就是索引(聚集索引和辅助索引结构都长这样,只是节点中的记录不一样。)中的每一个节点都是数据页。还有一点需要注意,mysql搜索的时候是按页搜索,定位到页之后才会将页中的数据加载到内存进行查找。因为页中的记录是通过二分查找+记录组内遍历,速度非常快,耗时忽略不计。
聚集索引
那什么是聚集索引?聚集索引的数据节点存放的是完整的记录。假设一个表有id、name和age字段,为了方便画图,name假设只有单个字母a~z。如下图所示
从图中又可以得到几个结论
a.聚集索引的数据节点按照主键id从左到右依次递增。
b.聚集索引的数据节点存放了完整的记录。
c.聚集索引的数据节点除了主键id是有序的,其它字段都是无序的。
辅助索引
那什么是辅助索引?可以想象一下,如果name这一列没有建立索引,根据name查找的时候,是不是得去遍历聚集索引下面的所有数据节点中的记录一一比较呢?那能有什么更快速的方法吗?答案就是为name建立一个索引,通过name定位到主键id,然后回到聚集索引中进行查找,这样速度就非常快。那可能有人会想问,为什么不直接为name建立一个聚集索引,这样就能直接在数据节点找到完整的记录信息了。是可以这么做,但是会增加空间消耗,重复存储冗余数据了。所以起名为辅助索引顾名思义,这个索引只起到一个辅助作用,真正查找数据还得回到聚集索引中找。如下图所示,为name建立一个辅助索引。
从图中又可以得到几个结论
a.数据节点中,从左到右,按照name从小到大排序。
b.数据节点中,只有name和主键id两列数据。
c.主键id在不同name中是乱序的。
例如查找name=’a‘的时候,会找到三条数据,对应的主键id是1、22、30。然后回到聚集索引中,根据主键一个个查找,一共要进行三次回表操作。
联合索引
联合索引也是辅助索引的一种,接下来以name和age建立一个联合索引。
从图中又可以得到几个结论
a.联合索引中,数据节点从左到右依次按照第一个字段从小到大排序。
b.联合索引中,数据节点中,第一个字段值相同,第二个字段按照从小到大排序。
c.联合索引中,能够单独使用第一个字段作为索引查询,但是不能单独使用第二个字段作为索引查询。
Q&A
什么是页目录?
先看一下<MYSQL技内幕:InnoDB存储引擎>这本书中的介绍
用大白话解释就是,一个数据页内会有很多记录,并且都是用单链表来连接,假设有1000条记录,如果没有页目录,最坏情况下,需要遍历1000次到最后一条记录。所以就想到了一种用少量空间换时间的办法,将1000条记录分成100组,每组记录数10条,然后用一个数组,将每一组的第一个地址偏移量存到数组中,当进行查找的时候,使用二分查找,定位到最后一组记录,再进行遍历,这样只需要遍历27次就能找到数据,时间上是不是大大减少了呢?用图来表示就像这样
例如现在要查找id=11,步骤是通过页目录二分查找,定位到0x20(9 < 11 < 13),然后从id=9依次遍历三次得到id=11这个结果。
再举个不是数字的例子
可以看到,页目录中存的是地址偏移,二分查找的时候,通过地址偏移拿到实际数据进行比较。
B+树的查找过程?
当初作为小白的我,天真的以为是将整颗B+树加载到内存中进行查找,现在才明白,其实是先在磁盘中查找到相应的页,然后才将这些页加载到内存中进行查找。可以细品mysql书籍里面经常说到多少多少次磁盘I/O查找,这不就是明着说B+树的查找过程是先在磁盘查找的吗?
三、什么是查询优化器?
那什么是查询优化器?那我们得先了解MYSQL的查询流程,从客户端提交到服务端执行都经历什么?
可以看到,提交引擎查询之前,会有一个查询优化的过程,在这一步,mysql真的是做了很多工作,可谓是绞尽脑汁帮用户"愚蠢的行为"买单。我们都知道explain这个关键字,可以帮助我们知道某条SQL语句的执行计划。而这个执行计划就是查询优化器经过优化后,最终选择的它认为的最优的执行计划。因为查询优化器内容实在太多,如果不细讲,会影响下篇分析索引失效的本质,所以在本篇最后,先将执行执行计划的各个参数含义列一遍,然后会专门写一篇查询优化器的原理分析。
官方文档里面的简单解释
四、总结
索引就像是一本字典的目录,能快速帮你定位到需要查找的数据,付出的代价就是字典的前面会多出几页甚至几十页的目录出来。为什么需要索引?为了快速定位数据呗。MYSQL B+树中的索引有哪些?聚集索引和辅助索引。B+树索引由目录节点和数据节点构成,这两种节点都称为数据页,因为它们使用的结构是一样的,只是存放的数据不同。数据页是由页目录和记录构成的,数据页中会有成百上千条记录,为了快速定位查找,牺牲了一些空间,造出了页目录,其实就是一个数组,然后将记录分成N组,将每组的偏移量存入数组,就能通过二分查找+记录组内遍历进行快速定位了。MYSQL查找的时候,会先从磁盘定位到需要用到的页,然后才加载到内存进行查找。查询优化器其实就是一个爱管闲事的玩意,不管你怎么造,它都会尽可能的帮你纠正,少走弯路。所以当你使用explain的时候,会发现很多奇奇怪怪的现象,和自己想的完全不一样。这时候就只有深入去探究它到底是如何进行优化的,才能掌握explain真正的威力。这里推荐一下官方文档、掘金小册中的从根儿上理解 MySQL和MYSQL技内幕:InnoDB存储引擎。我之前是先看的InnoDB存储引擎,但是比较难看懂,因为很多官话,然后遇到从根儿上理解 MySQL,作者用通俗易懂的语言,将书上和官方文档上的一些内容讲解出来,确实是不错。但是最全的还得是官方文档,这个是最难看懂的,但却是最权威的,所以我会将一些疑惑点,或者书上,其它作者没有讲清楚的点,自己去官方文档上找出来研究。这样下来,吸收日月精华,还有谁能阻挡?哈哈。再说一些额外的话,对于那些书籍、博客等讲解的知识,自己但凡有一点疑惑,都要自己去权威的官方文档中验证,当然了,如果你能看懂源码,这才是最权威的,但是太难了,只能退而求其次去官方文档中找答案了。
**
1、编写过滤器类—SqlFilter.java **
package com.yl.zp.controller; import java.io.IOException; import java.util.Enumeration; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.stereotype.Component; @Component public class SqlFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { // TODO 自动生成的方法存根 } @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest) request; HttpServletResponse res = (HttpServletResponse) response; //获得所有请求参数名 Enumeration params = req.
一个好用的GIF工具,能够进行图片压缩、裁剪、GIF制作的最佳工具!
大家好,我是小兮。每天给大家分享各种有趣、有用的网站、软件,偶尔还会开福利车,记得关注哦!
日常生活中,看到一个优美的风景,或者此刻心情舒畅,特别想拍照留念。所以手机里的照片慢慢变多,手机内存慢慢变少。
尤其是现在手机的摄像头像素越来越高,拍一张照片,画质清晰,大小都有5M-10M,小兮手机64GB内存早已容不下其他的照片存在。
有今天我们来介绍一款图片处理的工具,能在不影响画质的情况下进行图片压缩,将好看的照片的发到相亲相爱一家人的家族群里再也不怕老一辈的流量不够用了。
这个图片处理在线工具是小兮一直在用,而且始终坚持完全免费,以前这个在线工具叫GIF之家,目前已经更名为“图贴士”,功能还和原来一样强大!
而且这款工具还可以GIF制作,GIF裁剪和GIF合成。
图贴士
网站
JPG、PNG、GIF图片压缩
对于我们来说,能用到的图片格式基本就是JPG、PNG、和GIF这三种而已,可能有时想上传图片,会出现图片太大无法上传的问题,就需进行图片压缩了,其实压缩这些大图片也非常简单。
我们打开这个在线工具,点击选择图片,然后将需要压缩的图片导入,这个在线工具有个非常棒的功能就是“支持批量压缩”。
上传图片的时候,直接可以选择多张图片,然后你可以选择压缩的质量,数字越高压缩后的图片画质越好,默认是压缩70%。
压缩完成之后直接选择打包下载即可,没有任何下载限制。
图片压缩速度非常快,几秒上传之后立马就可以压缩完成,GIF图片压缩速度稍微慢一点,不过压缩效果是我见过最棒的一个,平时我制作好的GIF图片一般都会超过10M,通过它压缩后,基本不到5M,而且压缩后的画质区别不大。
小兮可怜兮兮的看着你
有趣、有用的软件、网站推荐
每次整理编辑图文推荐好东西都要花费2-3个小时,原创不易,小兮在此请大家里获取干货的同时,也请你用几秒的时间来这里打卡支持一下文中和底部,谢谢。
视频转GIF
目前这个在线工具支持MP4、OGG、WEBM三种视频格式转换GIF,其实我们常用的到视频格式也就是MP4。
点击长传视频,将电脑本地或者手机的视频直接导入。
上传后,你可以自定义修改生成GIF的尺寸,建议直接默认原图大小即可,然后选择GIF生成的时长,可以选择视频任意一段生成GIF。
相信很多伙伴都看到一些电影镜头的GIF,微博经常有一些精彩影视片段的GIF,其实就是直接通过GIF工具录制或者视频转换生成的。
注意:该因为是网站工具,所以小伙伴们使用的时候,记得将单独开一个浏览器进行图片的操作,不然电脑死机,真的很气人。
尽管如此,这款图片处理工具对于我们日常使用来说,已经是非常棒了~
软件/网站获取
你要是觉得文章写得不错、有趣或有用,就【置顶】或【星标】一下本公众号
关注公众号【悦美兮】,进入后台回复【0701】获取本文推荐的工具,回复关键词时不要有空格。
背景 最近项目中需要上传视频文件,由于视频文件可能会比较大,但是我们应用服务器tomcat设置单次只支持的100M,因此决定开发一个分片上传接口。
把大文件分成若干个小文件上传。所有文件上传完成后通过唯一标示进行合并文件。
我们的开发人员很快完成了开发,并在单元测试中表现无误。上传代码到测试环境,喔嚯!!!出错了。
经过一段时间的辛苦排查终于发现问题,测试环境多实例,分片上传的接口会被路由到不同的实例,导致上传后的分片文件在不同的机器,那么也就无法被合并。
知道了原因就好解决,经过一系列的过程最终决定修改网关把uuid相同的请求路由到相同的实例上,这样就不会出错了!
准备 由于是公司代码不方便透露,现使用本地测试代码。
准备:Eureka注册中心,Gateway网关,测试微服务
启动后服务如下两个测试的微服务,一个网关服务
gateway版本
<spring-cloud.version>Greenwich.SR2</spring-cloud.version> <spring-boot.version>2.1.6.RELEASE</spring-boot.version> 此处就说下我网关的配置。
#网关名 spring.cloud.gateway.routes[0].id=route-my-service-id #网关uri,lb代表负载均衡,后面是服务名,必须要和微服务名一致,不能错,错了肯定不能路由 spring.cloud.gateway.routes[0].uri=lb://my-service-id #断言,配置的路径 spring.cloud.gateway.routes[0].predicates[0]=Path=/my-service-id/v3/** #截取uri前面两个位置的 spring.cloud.gateway.routes[0].filters[0]=StripPrefix=2 分析 想要修改路由就要知道gateway是如何把我们的请求路由到各个微服务的实例上的。
gateway其实无非就是不同的过滤器,然后对请求进行处理,和zuul类似。gateway自带了很多过滤器。过滤器分为两种:
1、GlobalFilter 。顾名思义,全局过滤器,所有请求都会走的过滤器。常见的自带过滤器LoadBalancerClientFilter(负载均衡过滤器,后面我们就是修改这个地方)。
2、GatewayFilter。网关过滤器,该过滤器可以指定过滤的条件,只有达到了条件的才进入该过滤器。
如果想知道自带有哪些配置,我们可以查看gateway的自动注入类GatewayAutoConfiguration。
/** * @author Spencer Gibb */ @Configuration @ConditionalOnProperty(name = "spring.cloud.gateway.enabled", matchIfMissing = true) @EnableConfigurationProperties @AutoConfigureBefore({ HttpHandlerAutoConfiguration.class, WebFluxAutoConfiguration.class }) @AutoConfigureAfter({ GatewayLoadBalancerClientAutoConfiguration.class, GatewayClassPathWarningAutoConfiguration.class }) @ConditionalOnClass(DispatcherHandler.class) public class GatewayAutoConfiguration { @Bean public StringToZonedDateTimeConverter stringToZonedDateTimeConverter() { return new StringToZonedDateTimeConverter(); } @Bean public RouteLocatorBuilder routeLocatorBuilder( ConfigurableApplicationContext context) { return new RouteLocatorBuilder(context); } @Bean @ConditionalOnMissingBean public PropertiesRouteDefinitionLocator propertiesRouteDefinitionLocator( GatewayProperties properties) { return new PropertiesRouteDefinitionLocator(properties); } 省略.
链接: 借鉴.
// An highlighted block <template> <div class="div"></div> </template> <script> import 'echarts/lib/component/geo' import echarts from 'echarts/lib/echarts' import JSON from 'echarts/map/json/341200' export default { data () { return { shTempData: [{ name: '安徽阜阳宝龙开闭所', value: [116, 33] }] } }, created () { console.log(echarts) console.log(JSON) }, methods: { }, mounted () { let myChart = echarts.init(document.querySelector('.div')) myChart.on('click', (params) => { // window.location.href = '/#/overview' console.log(11111) }) echarts.registerMap('阜阳市', JSON, { }) // 这个是关键,之前拿到的青州各街道数据 // console.
点击,这个概括的比较全
我使用的是uni.requestSubscribeMessage其实和微信小程序用法一样,这个 【订阅消息】 你不管点击 取消 或者是 允许 只要接口调用成功它都走的是success回调,但是,你可以通过TEMPLATE_ID(订阅消息id) 去查看是否同意 订阅消息id所对应的模板消息。值包括’accept’、‘reject’、‘ban’。(这里可以根据回调函数返回是否同意订阅消息id所对应的值去进行后续操作)
uni.request({ url: '', method: '', header: { 'content-type': 'application/x-www-form-urlencoded', 'x-auth-token': uni.getStorageSync('token') || '' }, data: {}, sslVerify: false }).then(res => { var tmplIds=res; uni.requestSubscribeMessage({ tmplIds: tmplIds,//数组 success:(res)=>{ console.log(res[tmplIds[0]]);//值包括'accept':同意、'reject':拒绝、'ban':后台禁用 }, fail:(err)=>{ } }) }).catch(()=>{ });
之前在我的电脑上配置了libfreenect2和iai_kinect2,现在需要在工控机上重新安装这两个库,讲kinectV2相机安置在婴儿车上,然后使用我的ros下获取kinectV2相机的彩色图和灰度图的脚本,获取深度图和彩色图。
我成功的安装了libfreenect2
安装iai_kinect2的过程中也没有报错,但是当我要运行roslaunch kinect2_bridge kinect2_bridge.launch时,terminal中重复出现这样的错误: Failed to load nodelet '/kinect2_bridge` of type `kinect2_bridge/kinect2_bridge_nodelet` to manager
然后使用下面的方法解决
termibal 1: roscore
terminal2: rosrun kinect2_bridge kinect2_bridge _depth_method:=cpu _reg_method:=cpu
或者: roslaunch kinect2_bridge kinect2_bridge.launch depth_method:=opengl reg_method:=cpu
我之前在我电脑上测试的,使用roslaunch kinect2_bridge kinect2_bridge.launch,没有出现上述错误,我使用我的一个ros工程,同时订阅shd的彩色图和深度图,程序中设置的两者的帧率为30, 从代码运行时的打印输出可以看出,深度图和彩色图交替输出,两者帧率相当,采集几百帧下来,深度图和彩色图的帧数相差几十帧。
我在工控机上采用 rosrun kinect2_bridge kinect2_bridge _depth_method:=cpu _reg_method:=cpu的方式运行启动kinect相机,发现,彩色图的帧率还是30帧左右,但是,深度图的获取帧率只有彩色图的四分之一
而我换成 roslaunch kinect2_bridge kinect2_bridge.launch depth_method:=opengl reg_method:=cpu时,深度图和彩色图的获取帧率相当,偶尔深度图帧率快一些。
我只是记录了实验现象,也不知道时为啥。
XSS攻击通常指的是通过利用网页开发时留下的漏洞,通过巧妙的方法注入恶意指令代码到网页,使用户加载并执行攻击者恶意制造的网页程序。这些恶意网页程序通常是JavaScript,但实际上也可以包括Java、 VBScript、ActiveX、 Flash 或者甚至是普通的HTML。攻击成功后,攻击者可能得到包括但不限于更高的权限(如执行一些操作)、私密网页内容、会话和cookie等各种内容。
XSSFilter import javax.servlet.*; import javax.servlet.http.HttpServletRequest; import java.io.IOException; import java.util.ArrayList; import java.util.List; /** * 类 名: XSSFilter * 描 述: * 作 者: binglong180 * 创 建: 2020-06-24 10:28 * 邮 箱: binglong172@163.com */ public class XSSFilter implements Filter { /** * 不需要转义的url */ List<String> passList = new ArrayList<>(); @Override public void init(FilterConfig filterConfig) throws ServletException { passList.add("/image/upload"); passList.add("/adminLogin"); passList.add("/admin/annex/upload"); passList.add("/uscLogin"); } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest)servletRequest; String requestURI = request.
查看 JVM GC 日志 没有一丝耽搁,老王立刻调出了线上GC日志,在日志里,看到了一个“Metadata GC Threshold”的字样,类似于如下日志:
【Full GC(Metadata GC Threshold)xxxxx, xxxxx】
通过GC日志,老王立即定位到这次频繁的Full GC,实际上是JDK 1.8以后的Metadata元数据区导致的。
奇怪了,Metadata区域一般是放一些加载到JVM里去的类,为什么会被频繁的塞满,进而触发Full GC呢?
老王陷入了沉思,一旁的小猛和彪子只是静静的看着,大气也不敢出。。。
查看 Metaspace 内存占用情况 对啊,怎么把这茬给忘了”。老王突然的自言自语,把两个小弟吓了一跳。
思考中的老王根本没注意到两个小弟的反应,他迅速通过jstat,观察了一下Metaspace内存区域占用的波动曲线图,发现图像类似下面这样:
看起来Metaspace区域的内存呈现一个波动的状态,总是会先不断增加,达到一个顶点之后,就会把Metaspace区域给占满
占满之后,自然就会触发一次Full GC,Full GC会带着Metaspace区域的垃圾回收,所以接下来Metaspace区域的内存占用又变得很小了。
看着屏幕上的图像,老王心里一丝明悟。很明显系统在运行过程中,不停的有新的类产生被加载到Metaspace区域里,然后不停的把Metaspace区域占满。接着触发一次Full GC,回收掉Metaspace区域中的部分类。
然后这个过程不断循环,进而造成Metaspace区域反复被占满,然后反复导致Full GC的发生。
老王一边思考,一边在纸上画出了一张示意图:
到底是什么类在不停的加载? 那问题又来了,到底是什么类不停的被加载到JVM的Metaspace区域里去?老王又一次陷入了沉思。
不多会,他回过神来,在JVM启动参数中加入如下两个参数了:
-XX:TraceClassLoading -XX:TraceClassUnloading “老大,这两个参数有什么作用啊?”彪子忍不住好奇问道。
“这两个参数,顾名思义,就是追踪类加载和类卸载的情况,他会通过日志打印出来JVM中加载了哪些类,卸载了哪些类”,老王一边紧盯屏幕,一边解释道。
果然,加入这两个参数之后,在Tomcat的catalina.out日志文件中输出了一堆日志,里面显示类似如下的内容:
【Loaded sun.reflect.GeneratedSerializationConstructorAccessor from __JVM_Defined_Class】 明显可以看到,JVM在运行期间不停的加载了大量的名字叫做“GeneratedSerializationConstructorAccessor”类到Metaspace区域里去
看着这个莫名其妙的类,老王在之前的草图上又补充了几笔:
虽然不知道这是什么类,但是老王相信就是它的一直加载,导致 Metaspace 区域不停被占满,进而不停的引发Full GC
直觉告诉他,已经慢慢接近真相了!
为什么会频繁加载奇怪的类? “彪子,你马上百度一下这个类是什么?”老王指着刚才日志追踪到的这个奇怪的类名说道。
“好的好的”,彪子哪敢怠慢,三下五除二就百度了出来
“老大,这个类是Java执行反射机制时加载出的一个类,JVM会在反射调用一定次数之后动态生成一些类,刚才这个类就是其中之一,这个是JVM的一个底层优化机制”
彪子念完上面一段话,一脸懵逼,自己都不知道自己在说啥。。。
不停执行反射代码后动态生成的类。。。老王陷入沉思,边思考边在纸上又画出了一张图:
JVM 创建的奇怪类的玄机 经过短暂的思考后,老王一丝恍悟。想到了自己在公众号儒猿技术窝的专栏《从零开始带你成为JVM实战高手》里学过的如下知识:
JVM在反射过程中动态生成的类的Class对象,他们都是SoftReference软引用的,而软引用正常情况下不会回收,但是如果内存比较紧张的时候就会回收这些对象。
那SoftReference对象到底在GC的时候要不要回收,是怎么判断的呢?老王大脑继续飞速运转
对了,就是这个!老王一拍大腿,在纸上迅速写下了一个等式。
clock - timestamp <= freespace * SoftRefLRUPolicyMSPerMB
RIP协议距离向量算法——路由表更新 题目: 假定网络中的路由器B的路由表有如下的项目(这三列分别表示“目的网络”、“距离”和“下一跳路由器”):
B的路由表 目的网络距离下一跳路由器N17AN22CN68FN84EN94F 现在B收到从C发来的路由信息(这两列分别表示“目的网络”“距离”):
B收到C发来的路由信息 目的网络距离N24N38N64N83N95 解决步骤: 1.对新接收到的路由表进行更新,全部"距离"+1,且"下一跳路由器"都写成发送方路由器的名称(这里是C给B发的路由表,所以下一跳名称填C)
B收到C发来的路由信息(新表) 目的网络距离下一跳路由器N25CN39CN65CN84CN96C 2.开始对比新表和B的路由表
1.看目的网络
如果是新的目的网络,则直接把对应的各项信息填入表中;如果是相同的目的网络("新表"和"B路由表"对比),继续下面步骤。
2.看下一跳路由器
相同的目的网络为前提,看下一跳路由器。如果下一跳路由器相同,就更新(用新表的)。如果下一跳路由器不同,继续下面步骤。
3.看距离
如果距离不同,谁距离短,选谁来更新;如果距离相同,不更新。
路由器B更新后的路由表(答案) 目的网络距离下一跳路由器说明N17A无新信息,不改变N25C相同的下一跳,更新N39C新的项目,添加进来N65C不同的下一跳,距离更短,更新N84E不同的下一跳,距离一样,不改变N94F不同的下一跳,距离更大,不改变
目录
前言源码准备 源码内容尝试编译,保证源码没有问题编译 首先编译world.c编译并链接hello.c调试编译test.c结论 前言 关于gcc这三个参数,参考了诸多文档后,仍然理解上有偏差,仿照下面博客中的方法,自己调试了一波,总算是理解了。还是建议大家动手实践一下。
参考资料如下:
https://blog.csdn.net/q1302182594/article/details/42102961https://blog.csdn.net/openme_openwrt/article/details/7860580 源码准备 新建三个文件:test.c hello.c world.c ,其源码依赖关系为:test.c 依赖 hello.c;hello.c 依赖 world.c
源码内容 test.c
#include <stdio.h> void world(void); void hello(void) { printf("hello "); world(); } hello.c
#include<stdio.h> void hello(void); void main(void) { hello(); } world.c
#include<stdio.h> void world(void) { printf("world.\n"); } 尝试编译,保证源码没有问题 # -o 指定输出文件 [root@localhost testc]# ls hello.c test.c world.c [root@localhost testc]# gcc -o hehe *.c [root@localhost testc]# ls hehe hello.c test.c world.c [root@localhost testc]# .
Android Studio 基础 之 简单获取手机端所有图片 目录
Android Studio 基础 之 简单获取手机端所有图片
一、简单介绍
二、实现原理
三、注意实现
四、预览效果
五、实现步骤
六、关键代码
一、简单介绍 Android 开发中的一些基础操作,使用整理,便于后期使用。
本节介绍,获取移动端所有图片,这里主要是获得了图片的路径(绝对路径)和图片名称,方法不唯一,仅供参考。
二、实现原理 1、使用 Cusor 解析查询 cursor.getColumnIndex(MediaStore.Images.Media.DATA) 获取图片数据
2、 int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
String name = cursor.getString(column_index); 得到图片的据对路径
3、cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DISPLAY_NAME) 获取图片的名称
三、注意实现 1、因为要读取文件夹之类,所以需要读写权限
四、预览效果 五、实现步骤 1、打开Android Studio ,新建工程
2、按照步骤一步一步来,构建一个工程模块
3、编写脚本,获取移动端所有图片路径和名称
4、在 AndroidManifest.xml 添加 读写权限
5、连接设备,打包运行,给应用对应权限,效果如上
六、关键代码 1、MainActivity.java
package com.example.getallimages; import android.database.Cursor; import android.provider.MediaStore; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import java.text.SimpleDateFormat; import java.
作者 | Jake Zhang
链接 | https://juejin.im/post/5e92f11b6fb9a03c46493880
在写这篇文章之前本想着这个知识点涉及知识点太多太杂,找一篇大牛写的看看就算了,但是看了大概七八篇后,内心更纠结了——????????????真的好杂。。。记忆点找不到了,搞的心里乱乱的,大概是纠结症犯了。
所以还是动手总结一下,让自己有个可以抓取的记忆点,也让自己对这个知识点有个浅显的认知。
本文旨在讲述发生的流程,如想深究的可自行百度哦~,其中穿插的知识点及概念我会放到小框里或者贴参考链接。
先来个流程总述:
DNS解析:将域名解析成IP地址
TCP连接:TCP三次握手
发送HTTP请求
服务器处理请求并返回HTTP报文
浏览器解析渲染页面
连接结束:TCP四次挥手
1、DNS解析 在浏览器输入URL后,首先要经过域名解析。浏览器通过向 DNS 服务器发送域名,DNS 服务器查询到与域名相对应的 IP 地址,然后返回给浏览器,浏览器再将 IP 地址打在协议上,同时请求参数也会在协议搭载,然后一并发送给对应的服务器。
1.什么是URLURL(Uniform Resource Locator),统一资源定位符,用于定位互联网上资源,俗称网址。比如 http://www.w3school.com.cn/ht...,遵守以下的语法规则:`scheme://host.domain:port/path/filename`各部分解释如下:scheme:定义因特网服务的类型。常见的协议有 http、https、ftp、file,其中最常见的类型是 http,而 https 则是进行加密的网络传输。host:定义域主机(http 的默认主机是 www)domain:定义因特网域名,比如 w3school.com.cnport:定义主机上的端口号(http 的默认端口号是 80)path:定义服务器上的路径(如果省略,则文档必须位于网站的根目录中)。filename:定义文档/资源的名称 2. 什么是DNSDNS(domain name system,域名系统):因特网上域名和IP地址相互映射的分布式数据库;简单理解就是域名与IP地址的对照表,因为域名(如:www.google.com)对于我们而言,更便于记忆,但是机器却不擅长这种表达方式,因此需要将域名转换为IP地址,以便于机器识别, 这便有了DNS。 3. 根域名服务器根服务器是架设互联网的必须设施,管理互联网的主目录,全球共有13套根域名服务器 4. 递归查询客户端主机向本地域名服务器的查询是递归查询;所谓递归查询:客户端主机查询的域名地址无法在本地域名服务器中找到,因此本地域名服务器就以DNS客户端的身份向其他根域名服务器发起请求,进行查询,而不是让客户端主机去一直查询;递归查询的结果要么是返回的IP地址,要么是报错,表示无法查询到地址; 5. 迭代查询本地域名服务器向根服务器、顶级域名服务器和主机域名服务器发起的查询请求就是迭代的过程,如:本地域名服务器向根服务器发起查询请求,根服务器中会告诉本地域名服务器:”我这里没有你要找的内容,你去顶级域名服务器上找吧“,并将顶级域名服务器的地址返回给本地域名服务器,本地域名服务器接收到后,继续向顶级域名服务器发送请求;顶级域名服务器要么返回ip地址,要么告诉本地域名服务器下一步要向哪个权限域名服务器发送请求,直到找到ip地址或找不到ip返回报错信息,然后信息返回给客户端主机;下图给出了这两种查询的差别 递归过程:主机→本地DNS服务器→其他DNS服务器(如:我要找一个苹果吃,找到了A,问A有没有,A说我帮你去找B,B可能有,果真B有,然后B将苹果给了A,A再将苹果给我,这就是递归)迭代过程:本地DNS服务器→根服务器,本地DNS服务器→顶级域名服务器,本地DNS服务器→权限域名服务器;(如:我要找一个苹果,找到了A,A说我也没有,B可能有,你去找B吧;我又找B,B说我也没有,你去找C吧,我又去找C,终于找到了苹果,这就是迭代的过程) 2、TCP连接:TCP三次握手 在客户端发送数据之前会发起 TCP 三次握手用以同步客户端和服务端的序列号和确认号,并交换 TCP 窗口大小信息。
说明: Ack:应答 Fin:结束; 结束会话 Seq:一个数据段的第一个序列号 SYN:同步; 表示开始会话请求 第一次握手:客户端A将标志位SYN置为1,随机产生一个值为seq=X(X的取值范围为=1234567)的数据包到服务器,客户端A进入SYN_SENT状态,等待服务端B确认(第一次握手,由浏览器发起,告诉服务器我要发送请求了);
第二次握手:服务端B收到数据包后由标志位SYN=1知道客户端A请求建立连接,服务端B将标志位SYN和ACK都置为1,ack=X+1,随机产生一个值seq=Y,并将该数据包发送给客户端A以确认连接请求,服务端B进入SYN_RCVD状态(第二次握手,由服务器发起,告诉浏览器我准备接受了,你赶紧发送吧)。
第三次握手:客户端A收到确认后,检查ack是否为X+1,ACK是否为1,如果正确则将标志位ACK置为1,ack=Y+1,并将该数据包发送给服务端B,服务端B检查ack是否为Y+1,ACK是否为1,如果正确则连接建立成功,客户端A和服务端B进入ESTABLISHED状态,完成三次握手,随后客户端A与服务端B之间可以开始传输数据了(第三次握手,由浏览器发送,告诉服务器,我马上就发了,准备接受吧)。
为什需要三次握手?计算机网络》第四版中讲“三次握手”的目的是“为了防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误”。
书中的例子是这样的,“已失效的连接请求报文段”的产生在这样一种情况下:client发出的第一个连接请求报文段并没有丢失,而是在某个网络结点长时间的滞留了,以致延误到连接释放以后的某个时间才到达server。
关于
内容来源于微信公众号:大神编程。已经过原文作者授权。
题目:
1095:数1的个数
超详细动画图文题解链接
题解目录(不断更新中)
喜欢信息学奥赛的同学们,可以一起交流学习哦
官方QQ群:893157498
我的QQ群:795233394
【版权申明】非商业目的注明出处可自由转载
博文地址:https://blog.csdn.net/ShuSheng0007/article/details/107066856
出自:shusheng007
文章目录 概述关键概念如何使用创建Lookup创建MethodType创建MethodHandle调用MethodHandle 实际使用访问构造函数访问非private实例方法访问private实例方法访问非private类方法访问非private属性访问private属性增强MethodHandle 总结抒情 相关文章:
秒懂Java之反射
概述 众所周知,Java从最初发布时就支持反射,通过反射可以在运行时获取类型信息,但其有个缺点就是执行速度较慢。于是从Java 7开始提供了另一套API MethodHandle 。其与反射的作用类似,可以在运行时访问类型信息,但是据说其执行效率比反射更高,也被称为Java的 现代化反射。
官方对其定义如下:
A method handle is a typed, directly executable reference to an underlying method, constructor, field, or similar low-level operation, with optional transformations of arguments or return values.
在《深入理解Java虚拟机》第三版中,作者也提到了MethodHandle, 但作者更多是从JVM的层面理解它,认为其主要目的是为JVM设计的一套API,以支持其他JVM语言的反射能力,例如Groovy 、Scale、Kotlin 等。
本文主要从Java编程语言的角度来看一下如何使用这套API,至于其运行效率是不是真的比反射高,以及高多少都不会涉及,有兴趣的可以自行研究。
关键概念 Lookup
MethodHandle 的创建工厂,通过它可以创建MethodHandle,值得注意的是检查工作是在创建时处理的,而不是在调用时处理。
MethodType
顾名思义,就是代表方法的签名。一个方法的返回值类型是什么,有几个参数,每个参数的类型什么?
MethodHandle
方法句柄,通过它我们就可以动态访问类型信息了。
如何使用 当理解了上面几个关键概念后使用起来就比较简单了,总的来说只需要4步:
创建Lookup创建MethodType基于Lookup与MethodType获得MethodHandle调用MethodHandle 那我们接下来就按照上面4个步骤通过方法句柄来访问一下某个类里面的方法以及属性等。
首先提供一个目标类
public class HandleTarget { private String name = "
类的类getDeclaredField()方法 (Class class getDeclaredField() method) getDeclaredField() method is available in java.lang package.
getDeclaredField()方法在java.lang包中可用。 getDeclaredField() method is used to return a Field objects that indicate the given declared field of the class or an interface denoted by this Class object.
getDeclaredField()方法用于返回一个Field对象,该对象指示给定的类的声明字段或由此Class对象表示的接口。 getDeclaredField() method is a non-static method, it is accessible with the class object only and if we try to access the method with the class name then we will get an error.
https://github.com/jaywcjlove/linux-command
lastmodified
文件类long lastModified() (File Class long lastModified()) This method is available in package java.io.File.lastModified().
软件包java.io.File.lastModified()中提供了此方法。 This method is used to return the time when the file is last modified.
此方法用于返回上次修改文件的时间。 In other words, this method indicates the work by its name it returns the last modification time of the file and time will be measurable in milliseconds.
换句话说,此方法以名称表示工作,它返回文件的最后修改时间,该时间可以毫秒为单位。 The return type of this method is long so it returns the last modified time of the file and else returns 0L if the file does not exist or an exception occurs.
arcgis server如何发布依赖第三方库的GP服务并成功运行rest查询服务 问题概述和分析描述地理处理服务什么是地理处理工具如何制作地理处理工具有哪里途径可以制作地理处理工具 什么是地理处理服务发布GP工具使用 Python环境分析统一GP服务的环境 本文介绍:当我在桌面端的py文件制成的 脚本工具中,加载了一个第三方的库比如GDAL,:然后发布成GP(地理处理服务);那么web的server端怎么去运行这个GP服务工具的rest服务??
问题概述和分析描述 刚开始的脚本是这样的:
然后制作成这个的脚本工具
那如何制作呢? 参考:
如何由python脚本制成python工具:
ArcGIS Python如何将py脚本制作成python工具(自定义地理处理工具)
注:当然,上面博客链接描述的py文件,只是调用的arcmap库,这个在arcgis server的python环境中也是自带的有对应的库,那么如果我们引用第三方的库,就需要在server的环境下,也配置同样的库;
在桌面端是完全可以运行成功的:
但是发成GP服务后,提交get请求,就弹出这个错误:
但是报错为:
那么针对这么问题,应该如何解决呢:本博文,主要是针对这个问题进行讨论;
GP实际上是一种py脚本,可以运行在ArcMap中,可以运行在Server中,运行在Server中就作为一种服务功能,称之为Geoprocessor,很形象,地理处理器。
地理处理服务 地理处理服务的整个过程其实是包括:设计、制作、发布(或共享)和使用;
设计:是根据自己的业务逻辑层进行构建和设计;
制作:是如何制作地理处理工具;
发布:是如何发布地理工具,让其变为地理处理服务;
使用:是如何使用地理处理服务;
什么是地理处理工具 在现代 GIS 技术发展之前,**地理处理工具始终处在不断的演变之中。**这一时期,当地理分析人员尝试求解实际问题时,他们会聚在白板周围(那个时期也可能使用黑板)创建流程图和逻辑示意图,这与如今使用模型构建器创建的流程图和逻辑示意图非常相似。这些早期流程图中的任务逐渐演变为软件,并成为如今所见的一组核心地理处理工具。这是一个持续多年(且仍在继续)的重复过程,其间已将这些工具升级为一组随 ArcGIS 安装的简单基本运算符。
这些工具约有数百种,要了解各个工具的用法需花费一定时间。即使给定了确切的工具数量,任何一个单个文档也无法将所有工具都全部加以解释说明。本文档旨在指导您了解用于描述不同工具的使用目的和用途的各类其他文档。
可将地理处理视为一种语言,其中名词是地理数据(例如要素、表和栅格),而工具是动词(例如复制、裁剪和连接)。与任何语言一样,需要知道一些名词和动词才能进行交流,而本部分(及后续内容)向您介绍这些常见的地理处理动词(工具)。
最常用的 GIS 工具可自动执行一些以往手动完成的任务,例如,通过在一张地图上方叠加另一张地图来编译新地图,或者以物理方式将地图剪切成表示特定研究区域的各个部分,然后更改其投影。在此类手动执行的任务中,有些任务操作起来非常困难和复杂,以至于它们阻碍了地理知识和数据的宣传普及,而它们也是发明 GIS 的主要动力。
如何制作地理处理工具 要制作地理处理任务,通常要使用 模型构建器 或 Python 创建地理处理工具。您不必创建自己的工具,可以使用 ArcGIS 安装自带的多个系统工具中的任何一个。
下面详细介绍了各步骤:
选择一个或多个要作为服务中的任务的地理处理工具。可以使用 ArcGIS 所提供的若干系统工具中的一个,或者使用 ModelBuilder 或 Python 脚本创建自己的工具。
收集执行工具所需的输入数据。通常,这些数据集是 ArcMap 内容列表中的图层。
执行工具在结果窗口中创建结果。
如有必要,定义输入和输出数据集的符号系统。
将结果共享为地理处理服务。共享结果时,使用服务编辑器定义数据集的输入模式(如下所述)以及服务和其任务的其他属性。
有哪里途径可以制作地理处理工具 白话注释:就是任何用来做处理分析的工具,都可以认为是地理处理工具;
1、可以是单个的工具,
arcmap或者arcgis pro中的1400多个任意 的工具,这里就不一一罗列了;
使用 ObjectAnimator
通过使用 3.0 中引入的 ObjectAnimator,你可以通过几行代码实现 View 的任意一个属性动画。创建一个 Animator,设置任意一个可选的属性以及一些可选参数(比如 duration 和 repetition 参数),然后调用 start() 方法。例如,想要让一个叫做 myView 的对象做淡出动画,你可以这样做:
ObjectAnimator.ofFloat(myView, "alpha", 0f).start(); 这显然一点都不难,编写代码不难,理解起来也不难。你通过想要做动画的对象的信息、想要做动画的属性的名字以及动画的属性结束值。非常简单。
但是在我们看来它还可以被优化。尤其是,既然 View 的这些属性会非常频繁的被调用做动画,那么我们可以引入一些新的 API 使得让这些属性做动画更加的简单和易读(readable)。与此同时,我们还想提高这些属性做动画的性能特征。第二个原因值得被解释一下,下一段中的内容全都是关于它的。
在 3.0 的动画系统中,关于 View 的属性动画,有三个方面的性能值得提升。其中一个是,我们在一个没有固定的 “属性” 概念的语言中做属性动画。(One of the elements concerns the mechanism by which we animate properties in a language that has no inherent concept of “properties”.)另一个性能问题是关于同时对多个属性做动画的。当做淡出动画的时候,你只需要对 alpha 属性做动画。但是如果这个 View 正在移动,那它的 x 和 y (或者 translationX 和 translationY)属性也可能同时在做动画。还有其他的情况使得多个属性动画在同时执行。如果我们知道有多个属性动画在同时执行的画,那么这里就会有相当大的性能提升空间。
Android 运行时对于“属性”并没有概念,所以 ObjectAnimator 通过一种技术来将 表示属性名字的字符串 转换成 对目标对象执行 setter 方法。例如,在 View 类中 alpha 字符换会被转换成对 setAlpha() 方法的引用。这个功能的实现要么通过反射实现,要么通过 JNI;这两者都很可靠,但是都会有一些额外的开销。但是据我们所知,对于一些对象和属性,比如 View 的属性,我们应该可以做到更好。通过了解一些 API 和做动画的属性的相关信息,我们可以直接给相应的属性赋值,从而避免反射和 JNI 带来的额外开销。
挂载磁盘 新装的系统/dev/sdb没有挂载上,想挂载在/data目录,执行命令:
# mount /dev/sdb /data 通过df -h可以查看到/data目录。
在/data目录下做了一些工作(创建目录或文件),重启后通过df -h命令找不到/data目录了。
这是因为这个挂载是临时的。将挂载信息写入到fstab中,可以在每次启动时自动挂载
/etc/fstab内容示例:
# /etc/fstab: static file system information. # # Use 'blkid' to print the universally unique identifier for a # device; this may be used with UUID= as a more robust way to name devices # that works even if disks are added and removed. See fstab(5). # # <file system> <mount point> <type> <options> <dump> <pass> /dev/mapper/kean--vg-root / ext4 errors=remount-ro 0 1 # /boot was on /dev/sda1 during installation UUID=c0d4121c-a1d4-4ebb-aff2-2f5b503e1443 /boot ext2 defaults 0 2 #/dev/mapper/kean--vg-swap_1 none swap sw 0 0 /dev/mapper/cryptswap1 none swap sw 0 0 UUID=ed8b627f-0d79-40ac-871e-703f12ba9147 /data ext4 default 0 0 说明:
LVM逻辑卷管理与磁盘配额 LVM逻辑卷管理LVM(Logical Volume Manager)逻辑卷管理。LVM机制的基本概念逻辑卷创建1.准备物理设备(磁盘/分区)(fdisk)2.创建物理卷(PV)3.创建卷组(VG)4.创建逻辑卷(LV)5.创建文件系统(mkfs)也叫格式化6.进行挂载(mount)7.验证逻辑卷是否可用 逻辑卷的扩展 磁盘配额1.关闭安全防护2.挂载3.mount 查看,如果没有生效则重新挂载4.设置限额5.验证磁盘配额 LVM逻辑卷管理 LVM(Logical Volume Manager)逻辑卷管理。 逻辑卷是linux环境下对磁盘分区进行的管理的一种机制。
LVM是建立在磁盘和分区之上的一个逻辑层(类似于虚拟化技术),来提高磁盘分区管理的一个灵活性。
特点:
1.灵活的容量
2.可伸缩的存储池
3.在线的数据再分配
4.方便的设备命名
5.磁盘条带化
注意:
LVM屏蔽了底层磁盘的布局,便于动态调整磁盘容量
/boot分区不能应用LVM机制,存放引导文件
LVM机制的基本概念 PV:(Physical Volume)物理卷:
利用分区工具(fdisk)得到的普通分区,也可以是整块磁盘
包含许多PE(Physical extent基本单元),默认大小为4MBVG:(Volume Group)卷组:
由一堆PV组成的资源组,称为卷组LV:(Logical Volume)逻辑卷:
从VG里面动态划出一部分用于创建文件系统的空间称为LV
常用的LVM管理命令
逻辑卷创建 1.准备物理设备(磁盘/分区)(fdisk) #在虚拟机中添加俩块磁盘(/dev/sdb,/dev/sdc),并进行分区,更改分区类型为8e
2.创建物理卷(PV) 3.创建卷组(VG) 4.创建逻辑卷(LV) -n:指定卷组名
-L:指定卷组的大小
5.创建文件系统(mkfs)也叫格式化 6.进行挂载(mount) 创建挂载目录:
mkdir /mnt/data
一次性挂载:
mount /dev/vg01/lv01 /mnt/data
永久性挂载(vim /etc/fstab)
/dev/vg01/lv01 /mnt/data xfs defaults 0 0
mount -a
查看挂载:
df -hT
mount
7.验证逻辑卷是否可用 逻辑卷的扩展 注意:逻辑卷进行扩展之前先要查看卷组中是否有可用空间
此时虽然逻辑卷从原有基础上增加了2个G,但并没有生效,要对文件系统进行扩展才会生效
磁盘配额 1.
EasyPoi导出Excel可见我的此篇博客:
Easy Poi导入导出Excel
代码: String fileName = "人才事项统计报表.xls"; response.setHeader("Content-Disposition", "attachment;filename*= UTF-8''"+ URLEncoder.encode(fileName,"UTF-8")); 测试结果: 前端代码: 有些人加了这个导出文件名还是乱码,是因为前端用的导出方式不对
axios.get('/gss/exports/orders?pageNo=1&pageSize=10', { responseType: 'blob' }).then(res=>{ if(res.status == 200){ let blob = res.data; const fileReader = new FileReader(); // FileReader 对象允许Web应用程序异步读取存储在用户计算机上的文件的内容 fileReader.readAsDataURL(blob); // 开始读取指定的Blob中的内容。一旦完成,result属性中将包含一个data: URL格式的Base64字符串以表示所读取文件的内容 fileReader.onload = (event) => { // 处理load事件。该事件在读取操作完成时触发 // 新建个下载的a标签,完成后移除。 let a = document.createElement('a'); //如果使用兼容性高得xlsx,后端代码需要设置类型为XSSF,params.setType(ExcelType.XSSF); let _fileName = '人才事项统计报表.xlsx'; a.download = _fileName; a.href = event.target.result; document.body.appendChild(a); a.click(); document.body.removeChild(a); } } })
资源下载:https://download.csdn.net/download/qq_44895397/12561990 有需要的私聊我或者留言看到就会回复
SpringBoot第一谈(第一个SpringBoot项目、核心配置文件properties(yml、yaml)、集成jsp) SpringBoot第二谈SpringBoot的web开发(集成MyBtis、SpringBoot 下的SpringMVC、SpringBoot开发RESTFul风格、集成Redis) SpringBoot第三谈(Spring Boot 集成 Dubbo、Spring Boot 非 web 应用程序、SpringBoot 启动Logo修改关闭) SpringBoot第四谈(springboot使用拦截器、Servlet、过滤器Filter、Spring Boot 项目配置字符编码、SpringBoot打包部署、集成Logback日志) SpringBoot第五谈(SpringBoot集成Thymeleaf)
记录之前在使用idea编写Hive数仓UDF函数时遇到的一个问题,UDF函数编写完成之后测试运行没有问题,但是在打包的时候报错:
Failure to find org.pentaho:pentaho-aggdesigner-algorithm:pom:5.1.5-jhyde in https://repo.maven.apache.org/maven2 was cached in the local repository, resolution will not be reattempted until the update interval of central has elapsed or updates are forced
定位了很久,最后的解决办法是:
1)在Maven的settings.xml中添加以下mirror地址
<mirror> <id>nexus-aliyun</id> <mirrorOf>*</mirrorOf> <name>Nexus aliyun</name> <url>http://maven.aliyun.com/nexus/content/groups/public</url> </mirror> <mirror> <id>aliyunmaven</id> <mirrorOf>*</mirrorOf> <name>阿里云spring插件仓库</name> <url>https://maven.aliyun.com/repository/spring-plugin</url> </mirror> <mirror> <id>repo2</id> <name>Mirror from Maven Repo2</name> <url>https://repo.spring.io/plugins-release/</url> <mirrorOf>central</mirrorOf> </mirror> 2)在项目pom.xml文件中添加这个依赖
3)项目重新导入之后,再次打包:成功。
在开发中需要做一个点击回车按钮来实现登录的功能,使用到事件监听。 事件监听addEventListener()用法:(参照文献:菜鸟教程.)
addEventListener(event, function, useCapture)
参数一event:必须。字符串,指定事件名。
注意: 不要使用 “on” 前缀。 例如,使用 “click” ,而不是使用 “onclick”。
参数描述event必须。字符串,指定事件名。 “onclick”;注意: 不要使用 “on” 前缀。 例如,使用 “click” ,而不是使用 “onclick”。function必须。指定要事件触发时执行的函数;当事件对象会作为第一个参数传入函数。 事件对象的类型取决于特定的事件。例如, “click” 事件属于 MouseEvent(鼠标事件) 对象。useCapture可选。布尔值,指定事件是否在捕获或冒泡阶段执行。可能值:true - 事件句柄在捕获阶段执行;false- false- 默认。事件句柄在冒泡阶段执行 移除事件监听removeEventListener()用法:(参照文献:菜鸟教程.)
使用方法与addEventListener()相同
created () { // 绑定事件 window.addEventListener('keydown', this.keyDown) }, methods: { //登录 onSubmit () { //登录请求 }, //回车登录 keyDown (e) { // 如果是回车则执行登录方法 if (e.keyCode === 13) { this.onSubmit() } } } // 登录成功后销毁事件 destroyed () { window.
详细的FTP错误列表
110 Restart marker reply. In this case, the text is exact and not left to the particular implementation; it must read: MARK yyyy = mmmm where yyyy is User-process data stream marker, and mmmm server’s equivalent marker (note the spaces between markers and “=”).
重新启动标志回应。这种情况下,信息是精确的并且不用特别的处理;可以这样看:标记 yyyy = mmm 中 yyyy是 用户进程数据流标记,mmmm是服务器端相应的标记(注意在标记和等号间的空格) 120 Service ready in nnn minutes.
服务在NNN时间内可用 125 Data connection already open; transfer starting.
数据连接已经打开,开始传送数据. 150 File status okay; about to open data connection.
在Java中有时候需要使程序暂停一点时间,称为延时。普通延时用Thread.sleep(int)方法,这很简单。把它将当前线程挂起指定的毫秒数。如
try { Thread.sleep(1000);//单位:毫秒 } catch (Exception e) { } 注意:Thread.sleep(int)不能直接用,要做异常处理,try{}catch{}.
在这里需要解释一下线程沉睡的时间。sleep()方法并不能够让程序"严格"的沉睡指定的时间。例如当使用5000作为sleep()方法的参数时,线 程可能在实际被挂起5000.001毫秒后才会继续运行。当然,对于一般的应用程序来说,sleep()方法对时间控制的精度足够了。
但是如果要使用精确延时,最好使用Timer类:
Timer timer=new Timer();//实例化Timer类 timer.schedule(new TimerTask(){ public void run(){ System.out.println("退出"); this.cancel();}},500);//五百毫秒 这种延时比sleep精确。上述延时方法只运行一次,如果需要运行多次, 使用timer.schedule(new MyTask(), 1000, 2000); 则每间隔2秒执行MyTask()
请看下面图片,再开发某个功能的时候,因为粗心大意制造了一个 BUG ,本意是想随机生成一个数,从数组中取出值,这个随机产生的数在其他地方也可以使用,写着写着下面的程序产生了,你们知道下面程序的错误吗?
正确写法应该如下图这样,Random 随机产生的数要想重复使用,可以赋值给一个变量。其实我上图 Random 一共运行了三遍。
问题简介 在使用webstorm学习Nodejs时发现相关关键词没有提示且带有下划线,
在网上搜索了有关的解决方法,大致如下
1.依次点击webstorm中的file-Settings,在搜索框中输入Node会弹出如下窗口
Node interpreter是设置node存放位置的地址
Coding assistance for Node.js是勾选代码智能提示
如果你的Coding assistance for Node.js可以勾选,且勾选后查看代码有提示且没有下划线就代表成功
2.如果上述方法不行,则可以添加node提示包
具体步骤为:点击file-Settings,查找JavaScript
将Javascript language version手动设置为ECMAScript6
接着点击Libraries,点击右侧的Download
等加载完毕后找到node,选择Download and Install,Webstorm会下载node提示包
下载后记得勾选
点击OK后查看是否成功
1、想要去删除k8s中的一个指定命名空间,刚开始使用命令
kubectl delete ns 命名空间的名字 # 或者使用 kubectl delete ns 命名空间的名字 --force --grace-period=0 使用以上两种命令均无法成功删除命名空间,只会使命名空间的状态为Terminating状态
2、使用以下方法成功删除
1)使用命令
kubectl get namespace 命名空间的名字 -o json > devtesting.json 执行完这条命令后,当前文件夹会出现devtesting.json这个文件夹,打开这个文件,删除字段
spec和finalizers这两个字段包含的内容。
2)使用kubectl代理,执行命名
kubectl proxy --port=8080 使用一下命令进行测试
curl http://localhost:8080/api/ 3)使用http接口进行删除
curl -k -H "Content-Type: application/json" -X PUT --data-binary @devtesting.json http://127.0.0.1:8080/api/v1/namespaces/命名空间的名字/finalize 注意着里面的两个地方,一个是**.json文件一定要是刚才生成的文件;一个就是刚才操作的那个命名空间名字**。
成功删除所指定的命名空间。
关闭用户图形界面,使用tty登录。
sudo systemctl set-default multi-user.target
sudo reboot
开启用户图形界面。
sudo systemctl set-default graphical.target
sudo reboot
如果开机一直在命令行界面进不去图形界面,可以尝试以下办法:
查看当前启动方式
systemctl get-default
如果启动方式为 graphical.target ,则表示默认启动方式为进入图形界面,此时不需要再重新修改启动方式。(也就是说进不去图形界面与默认启动方式的设置无关)
此时多数情况可能与Ubuntu18.03中的桌面环境损坏有关
重新安装gdm3,然后重启,情况可能会解决(gdm3是是GNOME显示管理器)
sudo apt-get remove gdm3
sudo apt-get install gdm3
sudo reboot 有些人还利用了重新ubuntu-desktop解决,我用这个命令并没有解决,解决的办法还是重新安装gdm3。下面也列出来重新安装ubuntu-desktop的办法:
sudo apt-get --reinstall install ubuntu-desktop
6-6 计算两数的和与差 (10分)
本题要求实现一个计算输入的两数的和与差的简单函数。
函数接口定义:
void sum_diff( float op1, float op2, float *psum, float *pdiff );
其中op1和op2是输入的两个实数,psum和pdiff是计算得出的和与差。
在这里插入代码片 #include <stdio.h> void sum_diff( float op1, float op2, float *psum, float *pdiff ); int main() { float a, b, sum, diff; scanf("%f %f", &a, &b); sum_diff(a, b, &sum, &diff); printf("The sum is %.2f\nThe diff is %.2f\n", sum, diff); return 0; } void sum_diff( float op1, float op2, float *psum, float *pdiff ) { *psum=op1+op2; *pdiff=op1-op2; }
大数据hadoop部署实验 一、数据预处理 先将要处理的CSV文件通过x-shell传到Ubuntu中
(1) 删除文件第一行字段
#查询前十行 head -10 small_user.csv #删除第一行 sed -i '1d' small_user #再次查询前十行 head -10 small_user.csv (2)删除每行读取的文件第四个字段 、保留完整的时间格式,2014-12-12,删除每行时间末尾的空格和18,推荐使用字符串截取,并读取的文件每行随机增加省份字段,省份参照省份字典。
#使用vim编辑器新建了一个pre_deal.sh脚本文件 vim pre_deal.sh 在脚本文件中插入以下内容
#!/bin/bash #下面设置输入文件,把用户执行pre_deal.sh命令时提供的第一个参数作为输入文件名称 infile=$1 #下面设置输出文件,把用户执行pre_deal.sh命令时提供的第二个参数作为输出文件名称 outfile=$2 #注意,最后的$infile> $outfile必须跟在}’这两个字符的后面 awk -F "," 'BEGIN{ srand(); id=0; Province[0]="山东";Province[1]="山西";Province[2]="河南";Province[3]="河北";Province[4]="陕西";Province[5]="内蒙古";Province[6]="上海市"; Province[7]="北京市";Province[8]="重庆市";Province[9]="天津市";Province[10]="福建";Province[11]="广东";Province[12]="广西";Province[13]="云南"; Province[14]="浙江";Province[15]="贵州";Province[16]="新疆";Province[17]="西藏";Province[18]="江西";Province[19]="湖南";Province[20]="湖北"; Province[21]="黑龙江";Province[22]="吉林";Province[23]="辽宁"; Province[24]="江苏";Province[25]="甘肃";Province[26]="青海";Province[27]="四川"; Province[28]="安徽"; Province[29]="宁夏";Province[30]="海南";Province[31]="香港";Province[32]="澳门";Province[33]="台湾"; } { id=id+1; value=int(rand()*34); print id"\t"$1"\t"$2"\t"$3"\t"$5"\t"substr($6,1,10)"\t"Province[value] }' $infile> $outfile #执行pre_deal.sh脚本文件,对small_user.csv进行数据预处理 bash ./pre_deal.sh small_user.csv user_table.txt #查看前十行 head -10 user_table.txt (3)查看文件user_table.txt编码并转换导出文件编码
#先进入csv文件 vi user_table.txt #将编码变成utf-8 :set fileencoding 二、 将处理完成的数据上传至HDFS保存 先将hadoop启动
一,线上机器CPU 100%怎么排查定位解决?
1,定位耗费CPU的进程
top -c,显示进程列表,输入P按照使用率排序显示
2,定位耗费CPU的线程
top -Hp 453,数字是进程ID,然后输入P,按照CPU使用率排序显示
3,定位哪段代码导致CPU使用率过高
printf "%x\n" 1232 ,把线程的PID转换成16进制 jstack 343 | grep '0x41e8' -C5 -color
使用jstack打印进程的堆栈信息,而且通过grep 那个线程的16进制PID,找到那个线程关联的东西,这个时候可以再打印出的代码里看到是那个类的哪个方法导致这个cpu 100 % 的问题
二,磁盘空间快满了怎么办?
df -h 先查看,磁盘空间使用的情况
find / -size +1000M |xargs ls -lh,找到大于1000M的文件
或者du -h >fs_du.log,看各个目录的占用空间大小
不知道大家是否有这样一个经历: 就是大家的qq好像被别人登录了一样,群发给朋友,向朋友借钱的消息,有些身边的朋友还被骗取了大量的金额,别人又是如何知道自己的密码的呢?
现在都0202年了,想说的是QQ在密码防盗这块做得已经相当不错了,所以现在什么键盘记录想去偷QQ密码是很难的,不像许多年前什么灰鸽子?就算中了木马,也没法的,QQ的输入密码直接会从底层驱动接管。
但被盗的QQ号一样很多,这就关系到许多社工方面的东西了,比如什么QQ粘虫和钓鱼网站等等,这不是技术问题。黑客盗QQ确实是会批量地盗,不仅是盗QQ,黑客干什么都是批量地干,但这不等于说就是可以很轻松地盗一个特定的人的Q号。黑客的所谓入侵只是针对成千上万的计算机中那部分比较好入侵的罢了。
三步钓鱼盗号
1.用编程软件写一个刷钻刷枪刷装备等等的软件,看上去真就行了
2.上传到小学生群。
3.有人使用,账号密码自动发送到邮箱
(以前做过刷枪的很帅,很久没碰了就随便找图来发了)
三步之后你已经拿得了号主的密码,等号主下线睡觉的时候登陆
浅聊一下盗号,前几年才是盗号的黄金年代,为什么?那时候的QQ是用邮箱注册的,不需要手机号。
窃取账号和密码的方式很多,这里就给大家讲解一下最常见的一种 很多朋友都有QQ安全中心就是以防密码被盗,难道自己在qq安全中心就真的安全了吗?
不!你错了,window操作系统本身就出卖了你,我们来看一下下面的一张图
当我按下每一个数字时,终端的获取到了每一个数字,什么qq安全中心啊,都不起作用,别人直接获取到你的键盘输入,直接获取到你的密码,别人需要的是钱而不是你的qq
你的键盘在操作系统中就像一个公共场合一样,是公用的,每一个应用程序都可以使用,就像共享单车一样,这个人使用了下一个人继续使用但他都不属于你自己管理的而是属于windows操作系统来管理的,所以我们直接向windows操作系统获取键盘的输入
这是为什么我们来看下面这行代码
HWND window = GetForegroundWindow(); 获取当前的窗口,windows提供的函数接口,当用户打开那一个应用程序,我们直接向windows获取键盘按键
GetAsyncKeyState 获取键盘对应的字符编码
下面是简单的代码片段 #include <iostream> #include <Windows.h> #include <string> HWND PerWindow = NULL; int main(void) { char title[256]; while (1) { HWND window = GetForegroundWindow(); //获取当前窗口 if (window != PerWindow) { PerWindow = window; GetWindowText(window, title, 256); printf("\r\r当前活动窗口为:%s\r\n", title); } for (int key = '0'; key <= '9'; key++) { if (GetAsyncKeyState(key)&0x8000) { printf("
Element ui Table 嵌套单选多选 阻止@row-click事件冒泡 直接贴代码,主要是添加 @click.native.stop <el-table-column label="吃饭吗" height="100%" width="140" align="center"> <template slot-scope="scope"> <el-radio-group v-model="scope.row.calculateScore" @click.native.stop> <el-radio label="10">吃</el-radio> <el-radio label="20">不吃</el-radio> </el-radio-group> </template> </el-table-column>
Video.js 是一个通用的在网页上嵌入视频播放器的 JS 库,Video.js 自动检测浏览器对 HTML5 的支持情况,如果不支持 HTML5 则自动使用 Flash 播放器
在vue项目中使用Video.js
1.安装
npm install video.js npm install vue-video-player 2.在main.js中引入
import Video from 'video.js' import 'video.js/dist/video-js.css' Vue.prototype.$video = Video 3.使用
<template> <div class="container"> <head-title>Promotional video</head-title> <div class="content_video"> <div class="content_video"> <!-- 使用组件video-player --> <video-player class="video-player vjs-custom-skin" ref="videoPlayer" :playsinline="true" :options="playerOptions" ></video-player> </div> </div> </div> </template> <script> import HeadTitle from '../../../components/headtitle' // 组件内引用vue-video-player插件 import { videoPlayer } from 'vue-video-player' import 'video.js/dist/video-js.css' export default { name: 'HomeVideo', data () { return { playerOptions: { playbackRates: [0.
文章目录 思维导图IP协议的特点(不可靠与无连接)IP首部为什么 IP 首部中要有总长度字段?IP 首部校验和怎么计算的,与 ICMP,IGMP,TCP,UDP 的首部校验和有什么区别与共同点?IP 路由选择的过程是怎么样的?IP 路由选择的特性有什么?IP 搜索路由表的步骤如果路由表中没有默认项,而又没有找到匹配项,这时如何处理? 将网络互连起来的中间设备IP 地址的分类,如何划分的,及会计算各类地址支持的主机数 子网划分子网掩码选路的简单原理:简单路由表初始化路由表没有到达目的地的路由域间路由选择CIDR网际控制报文协议ICMP什么情况不会导致产生 ICMP 差错报文?四种ICMP差错报文两种询问报文ICMP的应用ICMP 重定向差错报文是怎么来的,在何种场合出现?重定向报文有什么规则?ping程序Traceroute 虚拟专用网VPNNAT路由器分组转发流程arp地址解析协议ARP 协议有什么弱点?ARP 代理的概念和应用场景免费 ARP数据链路层 MTU 的最大值和最小值是多少? 思维导图 思维导图下载
IP协议的特点(不可靠与无连接) 不可靠:指的是不能保证数据报能成功地到达目的地。
发生错误时候,丢弃该数据包,发送 ICMP 消息给信源端。 可靠性由上层提供。无连接:IP 不维护关于后续数据报的状态信息。
体现在,IP 数据可以不按顺序发送和接收。A 发送连续的数据报,到达 B 不一定是连续的,来回路由选择可能不一样,路线也不一样,到达先后顺序也不一样 IP首部 版本号:占4位,协议版本号IPV4或者IPV6。首部长度:首部长度,占4位区分服务:占8位,用来获得更好的服务,只有使用区分服务时,这个字段才起作用,一般情况不使用这个字段总长度:总长度值首部和数据之和的长度,总长度字段是16位,因而数据报的最大长度为2^16-1,当IP封装成以太网帧时,其长度不能超过最大传送单元MTU的值。标识:占16位,IP软件里面维持着一个计数器,每产生一个数据报,计数器就加1,并且将这个值赋给标识,这个标识不是为了记录IP数据报发送的顺序,而是当分片时,这个值被复制到所有数据报片里面,相同标识字段的值可以在分片后重新组装成原来的数据报标志:占3位,但目前只有两位有用
DF不分片标识,当DF=0时才可以分片
MF更多分片标识,MF=1表示后面还有分片,MF=0表示是最后一个分片片偏移:占13位,片偏移指出较长的分组在分片时,某片在原来分组中的相对位置。生存时间(8位):TTL,每次经过一个路由器时,TTL字段会减一,当TTL字段为零时,会丢弃该数据报,最大可以为225,如果将TTL设置为1,则只能在局域网上通信首部检验和:占16位,数据报每次经过一个路由器,路由器都要重新计算一下首部检验和,对首部每个16bit进行二进制反码求和,结果存在检验和字段中,当收到一份IP数据报时,同样对该数据报首部中每个16bit进行二进制反码求和,由于接收方在计算过程中包含了发送方的首部检验和,因此若没有在传输过程里面发生差错,那么结果应该为全1,发现差错时IP就丢弃该数据报,但是不产生差错报文,由上层去发现丢失的数据报并且进行重传。
10.源地址,目的地址:分别是32位 为什么 IP 首部中要有总长度字段? 因为一些数据链路(以太网)需要填充一些数据以达到最小长度。因为以太网帧的最小长度是 46 个字节,但是 IP 长度可能更短,所以需要总长度来确定 IP 数据部分的内容 IP 首部校验和怎么计算的,与 ICMP,IGMP,TCP,UDP 的首部校验和有什么区别与共同点? (1) 先把校验和字段置 0。
(2) 对首部中每个 16 位比特进行二进制反码求和。
(3) 结果存在检验和字段中。
(4) 收到一份 IP 数据包后,同样对首部中每个 16bit 二进制反码求和。
1) 进入安装目录下的bin文件夹下,如: C:\IntelliJ IDEA\bin, 打开idea64.exe.vmoptions文件,调高如下选项的数字部分
-Xms1024m
-Xmx2048m
2) File --> Settings --> Editor --> Code Editing --> 去掉 show quick doc on mouse move
3) File --> Settings --> Editor ->Inspections, 取消所有无关的选项
龙南县统计局:文明端午 你我同行
端午节是中华民族的传统节日,扶危济困更是中华民族的传统美德。为进一步做好精准扶贫工作,县统计局开展“精准扶贫、情暖端午”活动,局干部带着豆油和肥皂等物品走访慰问贫困户,为他们送去端午节的祝福,同时把党的关怀送进贫困户。 干部们每走访一户,都与各户深切交谈,对扶贫工作开展以来农户的生产、生活和健康情况进行深入细致的询问。此次活动,贫困户对县统计局高度赞赏,增进了干部们与贫困户之间的友情,让贫困户感受到了温暖和关爱,确保了精准扶贫取得惠民实效,为下一步扶贫工作更好的进行取得有利的保障。
Kubernetes是Google 2014年创建管理的,是Google 10多年大规模容器管理技术Borg的开源版本。它是容器集群管理系统,是一个开源的平台,可以实现容器集群的自动化部署、自动扩缩容、维护等功能。
通过Kubernetes你可以:
快速部署应用
快速扩展应用
无缝对接新的应用功能
节省资源,优化硬件资源的使用
Kubernetes 特点:
可移植: 支持公有云,私有云,混合云,多重云(multi-cloud)
可扩展: 模块化, 插件化, 可挂载, 可组合
自动化: 自动部署,自动重启,自动复制,自动伸缩/扩展
K8s总体架构
K8s集群由两节点组成:Master和Node。在Master上运行etcd,Api Server,Controller Manager和Scheduler四个组件。后三个组件构成了K8s的总控中心,负责对集群中所有资源进行管控和调度.在每个node上运行kubectl,proxy和docker daemon三个组件,负责对节点上的Pod的生命周期进行管理,以及实现服务代理的功能。另外所有节点上都可以运行kubectl命令行工具。
API Server作为集群的核心,负责集群各功能模块之间的通信。集群内的功能模块通过Api Server将信息存入到etcd,其他模块通过Api Server读取这些信息,从而实现模块之间的信息交互。Node节点上的Kubelet每隔一个时间周期,通过Api Server报告自身状态,Api Server接收到这些信息后,将节点信息保存到etcd中。Controller Manager中 的node controller通过Api server定期读取这些节点状态信息,并做响应处理。Scheduler监听到某个Pod创建的信息后,检索所有符合该pod要求的节点列表,并将pod绑定到节点列表中最符合要求的节点上。如果scheduler监听到某个Pod被删除,则调用api server删除该Pod资源对象。kubelet监听pod信息,如果监听到pod对象被删除,则删除本节点上的相应的pod实例,如果监听到修改Pod信息,则会相应地修改本节点的Pod实例。
Kubernetes主要由以下几个核心组件组成:
etcd保存了整个集群的状态;
apiserver提供了资源操作的唯一入口,并提供认证、授权、访问控制、API注册和发现等机制;
controller manager负责维护集群的状态,比如故障检测、自动扩展、滚动更新等;
scheduler负责资源的调度,按照预定的调度策略将Pod调度到相应的机器上;
kubelet负责本Node节点上的Pod的创建、修改、监控、删除等生命周期管理,同时Kubelet定时“上报”本Node的状态信息到Api Server里;
Container runtime负责镜像管理以及Pod和容器的真正运行(CRI);
kube-proxy负责为Service提供cluster内部的服务发现和负载均衡;
Kubernetes可以做什么?
使用Web服务,用户希望应用程序能够7*24小时全天运行,开发人员希望每天多次部署新的应用版本。通过应用容器化可以实现这些目标,使应用简单、快捷的方式更新和发布,也能实现热更新、迁移等操作。使用Kubernetes能确保程序在任何时间、任何地方运行,还能扩展更多有需求的工具/资源。Kubernetes积累了Google在容器化应用业务方面的经验,以及社区成员的实践,是能在生产环境使用的开源平台。
关于
内容来源于微信公众号:大神编程。已经过原文作者授权。
题目:
1072:鸡尾酒疗法
超详细动画图文题解链接
题解目录(不断更新中)
喜欢信息学奥赛的同学们,可以一起交流学习哦
官方QQ群:893157498
我的QQ群:795233394
一、算法题 LeetCode中有这样一个算法: 给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转。 示例 1: 输入: 123 输出: 321 示例 2: 输入: -123 输出: -321 示例 3: 输入: 120 输出: 21 注意: 假设我们的环境只能存储得下 32 位的有符号整数,则其数值范围为 [−231, 231 − 1]。请根据这个假设,如果反转后整数溢出那么就返回 0。 二、算法分析 个人解法 当第一次看到这个算法的时候,其实是不知道该如何做的,自己勉强使用了最笨的办法来实现,大致思路是,首先将int类型的整数变为字符串,然后通过不断的截取字符串来实现整数的反转,反转后的值先用long来接收,然后判断是否溢出了int的最大范围,最后将值再转换成int类型。 高人的解法 直接看图了: 其大致的思路就是通过不断递归整数整除10取余来获取最后一位数字,从而实现整体的整数的反转。 三、算法实现 按照大神的思路,自己来实现的第一版 public static int reverse(int x) { int res=0; while (x!=0){ res=res*10+x%10; x=x/10; } return res; } 问题:在程序运行的时候发现,如果入参的值比较大,如int值为-2^31时,会发生题目中所说的整数溢出情况。 所谓的整数溢出就是,整数值超出了int类型的最大范围。具体就是-2^31=-2147483648,当程序遍历到846384741之后,再将最后一位“2”反转的时候,反转后的值应该为-8463847412,此时的值超出了范围,最终的值变成了126087182。那么问题来了,为什么执行846384741*10的操作后结果为126087182?此处先卖一个关子,稍后再解释。 2. 第二版
public static int reverse(int x) { long res=0; while (x!
一、迟到的数据如何处理? Event Time语义下我们使用Watermark来判断数据是否迟到。一个迟到元素是指元素到达窗口算子时,该元素本该被分配到某个窗口,但由于延迟,窗口已经触发计算。目前Flink有三种处理迟到数据的方式:
(1)直接将迟到数据丢弃:会造成数据丢失
(2)将迟到数据发送到另一个流:输出到侧输出流,保证数据的完整性,可更新计算结果
(3)重新执行一次计算,将迟到数据考虑进来,更新计算结果:数据准确率高,保证数据完整性
二、业务实现:将迟到数据输出到侧输出流 import org.apache.flink.api.common.functions.{AggregateFunction} import org.apache.flink.streaming.api.TimeCharacteristic import org.apache.flink.streaming.api.functions.timestamps.BoundedOutOfOrdernessTimestampExtractor import org.apache.flink.streaming.api.scala._ import org.apache.flink.streaming.api.scala.function.WindowFunction import org.apache.flink.streaming.api.windowing.time.Time import org.apache.flink.streaming.api.windowing.windows.TimeWindow import org.apache.flink.util.Collector object AllowedLatenessDemo { def main(args: Array[String]): Unit = { val env = StreamExecutionEnvironment.getExecutionEnvironment // 使用eventTime env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime) val stream= env.socketTextStream("flink101", 8888) .map(line => { var arr = line.split(",") Log(arr(0).trim,arr(1).trim, arr(2).trim, arr(3).trim, arr(4).trim.toLong, arr(5).trim.toLong) }) val ds = stream.assignTimestampsAndWatermarks(new BoundedOutOfOrdernessTimestampExtractor[Log](Time.seconds(2)){ override def extractTimestamp(element: Log): Long = { element.callTime // EventTime } }) // 定义一个侧输出流的标签 val lateTag = new OutputTag[Log]("
若变量定义为int n;,当n的绝对值大于1时,则表达式1/n的值恒为 0。 √
因为int的值仍为int
若变量定义为double x;,则x % 2是符合C语言语法的表达式。×
?
添加数据
.append 往列表的结尾处添加一个元素
.insert 通过下标往列表的指定位置添加一个元素
.expend 往列表的结尾处 添加多个元素
删除数据
.remove 删除列表中的指定元素
.pop 删除指定下标位置的元素,默认删除列表中最后一个元素
.clean 删除列表中所有数据
查询数据
.index 在列表找到第一个匹配的元素,返回下标位置
.count 查询指定元素的数量
修改数据
用下标找到元素,重新赋值
li = [1,2,3,4,5,6]
li[2] = 33 # 修改一个元素
li[3],li[4],li[5] = 44,55,66 # 修改多个元素
具体使用案例与解释请参考https://blog.csdn.net/qq_30463497/article/details/101176865
torch.max()返回的是两个值, 第一个是最大值, 第二个是最大值所在的索引, 一般情况,我们都是求最大值所在的索引
import torch a = torch.tensor([[1, 5, 2, 1], [2, 6, 3, 8]]) print(a) res, index = torch.max(a, 1) print(res) print(index) 只用最大值索引求准确率:
# 准确率的计算 # 100个样本, 10 个类别 predict = torch.rand(100, 10) label = torch.randint(10, (100,), dtype=torch.int64) pred_y = torch.max(predict, 1)[1].numpy() y_label = label.numpy() accuracy = (pred_y == y_label).sum() / len(y_label) print("准确率:", accuracy) 结果为
准确率: 0.21 这里是取的随机数, 结果不重要
读文件的时候出现报错:UnicodeDecodeError: 'gbk' codec can't decode byte 0xbf in position 2: illegal multibyte sequence
看到gbk以为是文件编码问题,结果发现并不是,然后在网络上查找,发现只要加一个参数在读的时候将编码设置为utf-8即可
```
open(path, 'r', encoding='utf-8')
```
使用lib模式打包 在vue-cli官网中有指出如何使用lib模式构建代码。
当你运行 vue-cli-service build 时,你可以通过 --target 选项指定不同的构建目标。它允许你将相同的源代码根据不同的用例生成不同的构建。
lib模式默认是不含有Vue的,若原代码中有vue,则会将原代码中的vue删除。
注意对 Vue 的依赖
在库模式中,Vue 是外置的。这意味着包中不会有 Vue,即便你在代码中导入了 Vue。如果这个库会通过一个打包器使用,它将尝试通过打包器以依赖的方式加载 Vue;否则就会回退到一个全局的 Vue 变量。
要避免此行为,可以在build命令中添加--inline-vue标志。
vue-cli-service build --target lib --inline-vue 核心命令——将一个单独的入口构建为一个库:
vue-cli-service build --target lib --name myLib [entry] 这个入口可以是一个 .js 或一个 .vue 文件。如果没有指定入口,则会使用 src/App.vue。我们只需要在指定的入口文件中export我们需要的模块即可。
例如:
export {default as Button} from './button/button' export {default as Cascader} from './cascader/cascader' export {default as CascaderItems} from './cascader/cascader-items' export {default as GridRow} from './grid/row' export {default as GridCol} from '.
好像是已经过时的函数, 在pytorch0.4之前, view()进行改变形状时, 这个变量tensor的内存必须是连续的, 否则会失败, 但是现在可以了, 举例如下:
import torch x = torch.tensor([[1, 2, 0], [0, 0, 0], [0, 0, 0], [0, 2, 3]]) mask = x != 0 print("mask:\n", mask) x = x[mask] print("\nx:", x) print("\nx内存是否连续:", x.is_contiguous()) # 是否连续 # 如果不连续, 需要这样操作一下, 使其连续 x2 = x.contiguous() print("\n变性后:\n", x2.view(2, 2)) 结果如下
torch中的交叉熵损失函数使用案例
import torch import torch.nn.functional as F pred = torch.randn(3, 5) print(pred.shape) target = torch.tensor([2, 3, 4]).long() # 需要是整数 print(target.shape) # 交叉熵损失函数, 输入的参数是形状不一样的 # predict会在其内部进行softmax操作 loss = F.cross_entropy(pred, target) loss.item() 结果为:
需要注意的是, 传入的参数形状是不同的, predict是softmax之前的, 另外y需要是整形的, int也行
消息摘要 消息摘要(Message Digest)又称为数字摘要(Digital Digest)
它是一个唯一对应一个消息或文本的固定长度的值,它由一个单向Hash加密函数对消息进行作用而产生
使用数字摘要生成的值是不可以篡改的,为了保证文件或者值的安全
特点 无论输入的消息有多长,计算出来的消息摘要的长度总是固定的。例如应用MD5算法摘要的消息有128个比特位,用SHA-1算法摘要的消息最终有160比特位的输出
只要输入的消息不同,对其进行摘要以后产生的摘要消息也必不相同;但相同的输入必会产生相同的输出
消息摘要是单向、不可逆的
常见算法 - MD5 - SHA1 - SHA256 - SHA512 获取字符串消息摘要 package com.atguigu.digest; import javax.sound.midi.Soundbank; import java.security.MessageDigest; /** * DigestDemo1 * * @Author: 尚硅谷 * @CreateTime: 2020-03-17 * @Description: */ public class DigestDemo1 { public static void main(String[] args) throws Exception{ // 原文 String input = "aa"; // 算法 String algorithm = "MD5"; // 获取数字摘要对象 MessageDigest messageDigest = MessageDigest.getInstance(algorithm); // 获取消息数字摘要的字节数组 byte[] digest = messageDigest.
方法一: 找到如下字段:
kubectl edit namespaces Name 通过命令编辑,删除所标记字段既可,保存退出。其他资源有此状况,可以找下是否有此字段,如果不行使用第二种
方法二: 以namespace为 qqhc8 演示
# 获取namespace相关信息 kubectl get ns qqhc8 -o json >tmp.json # 开启内网api代理 kubectl proxy 编辑 tmp.json 去除spec里中间的3行信息,保存退出 "spec": { "finalizers": [ "kubernetes" ] }, # 更新 curl -k -H "Content-Type:application/json" -X PUT --data-binary @tmp.json http://127.0.0.1:8001/api/v1/namespaces/qqhc8/finalize 查看namespace,已经删除
本题要求实现一个计算输入的两数的和与差的简单函数。
函数接口定义:
void sum_diff( float op1, float op2, float *psum, float *pdiff );
其中op1和op2是输入的两个实数,*psum和*pdiff是计算得出的和与差。
裁判测试程序样例:
#include <stdio.h>
void sum_diff( float op1, float op2, float *psum, float *pdiff );
int main()
{
float a, b, sum, diff;
scanf("%f %f", &a, &b);
sum_diff(a, b, &sum, &diff);
printf("The sum is %.2f\nThe diff is %.2f\n", sum, diff);
return 0;
}
/* 你的代码将被嵌在这里 */
输入样例:
4 6
输出样例:
The sum is 10.00
The diff is -2.
sync.Mutex为互斥锁(也叫全局锁),Lock()加锁,Unlock()解锁。 sync.WaitGroup,创建一个任务,sw.Add(1),加一;任务完成的时候使用 sw.Done() 来将任务减一;使用 sw.Wait() 来阻塞等待所有任务完成。
package main import ( "fmt" "sync" ) var ( s = 0 syn = sync.Mutex{} sw = sync.WaitGroup{} ) func main(){ for i := 0; i < 100; i++ { for i := 0; i < 100; i++ { sw.Add(1) go func() { defer sw.Done() syn.Lock() s++ syn.Unlock() }() } } sw.Wait() fmt.Println(s) } 运行结果:
如果注释掉sync.Mutex,结果可能不正确:
package main import ( "fmt" "sync" ) var ( s = 0 syn = sync.
可使用的通配符说明:
_ 与任意单字符匹配 % 与包含一个或多个字符的字符串匹配 [ ] 与特定范围(例如,[a-f])或特定集(例如,[abcdef])中的任意单字符匹配。 [^] 与特定范围(例如,[^a-f])或特定集(例如,[^abcdef])之外的任意单字符匹配 示例:
WHERE RealName LIKE '_明%' --选取名字的第二个字符之后是 "明" 的人 WHERE RealName LIKE 'Ad%' --Ad开头 WHERE RealName LIKE '%[fk]%' --包含f或者k WHERE RealName LIKE '[[l-z]]%' --以字母l到z之间开头的人 WHERE RealName LIKE 'a[^d]%' --以a开头,第二个字母不为d 原文链接:https://blog.csdn.net/lqh4188/article/details/77749499
关于
内容来源于微信公众号:大神编程。已经过原文作者授权。
题目:
1057:简单计算器
超详细动画图文题解链接
题解目录(不断更新中)
喜欢信息学奥赛的同学们,可以一起交流学习哦
官方QQ群:893157498
我的QQ群:795233394
readyState document.readyState 返回当前文档的状态,属性如下:
uninitialized 还未开始加载loading 加载中interactive 已加载,文档与用户可以开始交互complete 加载完成 DOMContentLoaded 当 DOMContentLoaded事件触发时,仅当DOM加载完成,不包括样式表,图片,flash
onload 当 onload 事件触发时,页面上所有的DOM,样式表,脚本,图片,flash都已经加载完成了
根据执行时DOM是否已经装载完毕来决定是对回调函数进行同步调用还是异步调用。具体代码如下:
function onReady(fn){ var readyState = document.readyState; if(readyState === 'interactive' || readyState === 'complete') { fn() }else{ window.addEventListener("DOMContentLoaded",fn); } } onReady(function(){ console.log('DOM fully loaded and parsed '); })
众所周知,sprintf不能检查目标字符串的长度,可能造成众多安全问题,所以都会推荐使用snprintf.
自从snprintf代替了sprintf,相信大家对snprintf的使用都不会少,函数定义如下:
int snprintf(char*str, size_t size,constchar*format, ...); 函数说明:最多从源串中拷贝size-1个字符到目标串中,然后再在后面加一个 \0 。所以如果目标串的大小为size的话,将不会溢出。
函数返回值:若成功则返回欲写入的字符串长度,若出错则返回负值。
Result1(推荐的用法)
#include <stdio.h> #include <stdlib.h> int main() { char str[10]={0}; snprintf(str, sizeof(str), "0123456789012345678"); printf("str=%s\r\n", str); return 0; } root] /root/lindatest $ ./test str=012345678 Result2:(不推荐使用)
#include <stdio.h> #include <stdlib.h> int main() { char str[10]={0}; snprintf(str, 18, "0123456789012345678"); printf("str=%s\r\n", str); return 0; } root] /root/lindatest $ ./test str=01234567890123456 【情形一】:源串小于目标字符串
实际上源串为:"123\0",所以只将字符'1','2','3', '\0'拷到了目标串,返回值为源串的strlen为3
#include <stdio.h> #include <strings.h> #include <string.h> int main(void) { char a[10] = {'\0'}; int i = 0; int ret = 0; memset(a, 0, sizeof(a)); for(i = 0; i < 10; i++) { printf("
在正式进入主题之前,先要看看一些基本的理论。这里旨在明确这些基础的概念,好更深刻的进一步理解Netty。
首先,什么是IO?其实平常其实工作中用得也是比较多的了,这里简单做个总结。
I:InputStream,字节输入流 ,用于读取数据为字节流《Reads the next byte of data from the input stream》
O:OutputStream,字节输出流,用于将字节流写入到流《Writes the specified byte to this output stream》
流,啥是流?日常生活中,听过比较多的就是河流、水流、车流等等,这里就拿车流做比喻。
假定小C要结婚了,请了一个豪华车队,去新娘老家接新娘到酒店,于是就有了这么个概念:这里有一车队从新娘家,经过一路到达到酒店。这里有起始点,有结束点,可以理解为数据的产出点和数据的接收点。这个过程,可以理解为建立一个传输通道(车队走过的一路),通过流的方式,将数据从一个地方传输到了另外一个地方。当有这么一种情况,每一辆车只能载一个人,同时,一辆车装完一个人,然后就开车出发,然后下一辆车,在上一个人,出发,持续这么过程,可以理解为字节输入流(一个上车),到达目的地后,下一个人,可以理解为字节输出流(一个人下车)。这时候,可能就太慢了,于是新郎新娘决定,一辆车多上些人,把一家人的那种单独上一辆车,此时,可以理解为字符流(以字符的方式输入输出),与此同时,车队上满了之后,一个车队一起走,理解这种情况为缓冲流(一个车队可能就一次把人都带走了)。于是,流就可以简单分为字节流和字符流,同时两者都可以通过包含缓冲区的方式传输,也就都存在字节缓冲流和字符缓冲流。
下面看下其相互依赖关系(这里仅仅截取常用到的,实际并不仅仅这些,详细请查看API)
字节流:
字符流:
那么接下来家假设这么一种情况,小C邀请其好友小D全程协助车队出发到达这么一个过程,把小D全程协助的过程,称为线程,也就是小D线程来做这件事,于是车队上车开始,小D就只能在这里逐个看着每个车上乘客,然后沿着一条路到达酒店,假定这一路属于乡村公路,也就是单行道,往酒店走的,则只能往酒店走,反之亦然。
IO(BIO)、NIO、NIO2(AIO)
有需要的同学,可关注公众号“依荨”,不定期分享技术干货
基于上述过程,可以理解为传统IO的一个操作,也叫BIO,即同步阻塞IO,同步在于,读的时候不能写,写的时候不能读(类似上述过程,单行道车流),当然这里也可以用多线程去做一个伪异步,这里不过这种探讨;阻塞在于,读和写这个过程阻塞的,读/写需要线程把所有的数据全部读/写完毕,或者发生异常,这个线程才能结束(类似上述过程,小D全程协助时,在车队上乘客的时候,小D只能等着乘客都上车完毕后,他才能继续做下一步操作)。
同步阻塞IO在实际应用中,会存在很多弊端,用之前写的小demo(详情请见《基于socket通信编写的聊天工具》)为例,解释下这种同步阻塞存在的一些问题和弊端
看服务端的主要代码,在可以获取多个客户端连接的情况下,采用了多线程监听:
如果存在大量客户端连接的情况下,服务端是会开辟很多线程来监听并获取数据,首先多线程的线程间交替本身就很好系统性能,再者过多的服务端线程易造成堆栈溢出,创建线程失败等情况的发生,严重甚至发生服务器宕机等情况的发生
由于读写操作属于阻塞的(不仅仅是读写操作,还有上图中,等待连接的时候,也是线程阻塞的),那么就有可能存在大量连接的线程出现在一个阻塞的情况,服务端处理速度过慢,后续的客户端连接容易出现连接不上服务端的情况。同时写的时候不能读,读数据的时候不能写,这也是一种很不良好的体验。
如何比较良好的解决这些问题?
小C的新娘告诉他,现在政府新修建了高速公路,双向车道,于是车可以从上面过,同时基于双车道,车辆可以方便在接送切换,不需要再去遵循哪条路是来的路,哪条路是去的路,再者小D觉得这样子挨个守着太累而且费时,于是留下每个车师傅的电话,轮询的方式了解到车辆目前的状态(是否上好了人,是否到达目的地等等),方便指挥车辆的下一个操作。
对于上述改进的接送人操作,映射到JDK1.4以后的NIO,同样对传统的IO操作,进行类似的改进,相对于传统的流(单向乡间小道),变成了现在的通道Channel(牛叉的双向高速公路)传输数据,传统的阻塞读写操作(守候车辆上下人),变成了选择器-多路复用器Selector轮询当前通道Channel中的数据状态,进行后续IO操作(远程轮询车辆状态,安排工作)
通道(Channel)、多路复用器(Selector)是NIO(官方称为new IO,也称为non-blocking IO)的三大重要概念中的2种了,下面介绍下另外一个概念–缓冲区(buffer)
传统BIO数据读写主要针对字节/字符操作,而NIO读写数据则是针对缓冲区操作,任何的NIO都是操作缓冲区,缓冲区内部是数组,并且提供了对数据结构化访问及其维护读写位置信息
以下是几个常用的缓冲区的相互依赖关系:
这里用代码描述几个核心属性:
package com.lgli.nio.api; import java.nio.ByteBuffer; /** * NioApi properties * capacity:缓冲区中的最大容量 * limit:限制,缓冲区中最大可操作容量 * position:位置,当前操作的缓冲区的位置 * mark:标记,记录读取的缓冲区的位置 * @author lgli * @since 1.0 */ public class NioApi { public static void main(String[] args) { String str = "
java的接口中 可以定义 静态方法 网上查了许多的博客都说的是不可以,我们老师也说得是不可以。但我自己实验了一下,发现居然可以在接口中定义静态方法(static)惊奇(⊙o⊙)?难道是是我的jdk版本比较新的原因,后面的java规则发生了变动?
而且不仅java的接口中可以定义静态方法,抽象类中也可以。但是定义的静态方法在实现或者继承的子类中是不可见的。即在实现接口的类中,无法使用接口中的静态方法
interface fi { static void f1() { System.out.println("接口中可以定义静态方法"); }; } class fi2 implements fi { } abstract class fi1 { static void f1() { System.out.println("抽象方法中可以定义静态方法"); }; } public class Test1 { public static void main(String[] args) { Path p1 = Path.of("C:/Users/Maibenben/Desktop/测试/1.txt"); Path p2 = Paths.get("C:/Users/Maibenben/Desktop/测试/1.txt"); fi.f1(); fi1.f1(); } }
tomcat7/tomcat8.5/tomcat9都成功解决
找到tomcat目录下的/conf/logging.properties
找到这条语句:java.util.logging.ConsoleHandler.encoding = UTF-8
将UTF-8改成GBK
如果没有上面这条语句就直接加上java.util.logging.ConsoleHandler.encoding = GBK
重启tomcat
转载于:https://blog.csdn.net/huanying33333/article/details/91045064
仅供自己学习参考,谢谢