一.构造方法(constructor) 构造方法(也叫构造器)是一种特殊的方法,它的作用是对象的初始化。构造方法通常在类中,有参构造和无参构造两大构造方法。无参构造的构造方法由系统自动创建,也可由自己手动创建。有参的构造方法需由自己手动创建,当自己手动创建有参构造方法时,如果需要无参构造方法,也需自己手动创建。构造器的名称应该与类名一致,JAVA通过new关键字来调用构造器,从而返回该类的实例,是一种特殊的方法。
构造方法结构:
[修饰符] 类名 (形参列表){ //多条语句 } 在建立构造方法时,应注意以下几点:
1.构造方法名必须与类名一致。
2.通过关键字new来调用。
3.无参构造方法由系统自动创建,有参构造方法则需要手动创建。如果我们没有定义构造器,则编译器会自动定义一个无参的构造函数。如果已定义则编译器不会自动添加!
4.构造方法不能够加返回值。其自动返回初始化对象的地址。构造器虽然有返回值,但是不能定义返回值类型(返回值的类型肯定是本类),不能在构造器里使用return返回某个值。
class Point{ //创建一个类,类中包含对象的属性 double x,y; //属性 public Point double(_x,_y); //定义构造方法,方法名必须与类名Point相同,变量_x,_y { //将构造方法的变量赋给对象的属性,即将对象初始化 x=_x; //赋值是通过对象返回的地址来将其初始化的 y=_y; } void double GetDistance(Point p){ //定义一个GetDistance方法 return Math.sqrt.((x-p.x)*(x-p.x)+(y-p.y)*(y-p.y)) //返回两点之间的距离值 } } public class TestConstructor {//创建一个类 public static void main(String[] args){ Point p = new Point(3.0,4.0); //以类为模板创建对象 Point origin = new Point(0.0,0.0); System.out.println(p.GetDistance(origin)); //输出返回值 } } 输出:5.0
二.构造方法的重载 构造方法的重载与方法的重载相同,都是方法名相同而方法参数顺序,类型或个数不同。多个对象的初始化需要创建多个构造方法。方法名相同而表示含义不同,这叫做构造方法的重载。
public class User { //定义一个public类 int id; //field String name; int password; } public User(int id,String name){ //创建一个构造方法 super(); //构造方法开头通常是super() this.
解决IE浏览器下报错: Promise未定义 yarn add babel-polyfill
或者
npm install babel-polyfill --save
在加载Promise之前或公共js中引入
import Promise from 'babel-polyfill'; // 解决promise 在ie中未定义的问题 if (!window.Promise) { window.Promise = Promise; }
Object.assign不兼容IE问题 使用 Object.assign 在IE中报错
这是因为IE根本不支持 Object.assign 方法
可在调用之前 加入以下兼容代码
if (typeof Object.assign != 'function') { Object.assign = function(target) { 'use strict'; if (target == null) { throw new TypeError('Cannot convert undefined or null to object'); } target = Object(target); for (var index = 1; index < arguments.length; index++) { var source = arguments[index]; if (source != null) { for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } } return target; }; } 关于 Object.
实现效果
0 HTML
<template> <div class="content"> <header> <section class="head_goback" @click="goback"> <svg width="100%" height="100%" xmlns="http://www.w3.org/2000/svg" version="1.1"> <polyline points="12,18 4,9 12,0" style="fill:none;stroke:rgb(255,255,255);stroke-width:2"/> </svg> </section> <section class="title_head ellipsis"> <span class="title_text">扫描设备</span> </section> </header> <div class="Detail"> <div id="code"> <div style="width:16rem;height:12.8rem; background-color: #000; margin: 15% auto 5%; text-align: center"></div> </div> <p style="text-align: center">将二维码放入框内,即可自动扫描</p> <div style="text-align: center" class="sweep" @click="sweep">开始扫码</div> <div style="text-align: center" class="start" @click="next">识别失败,手动录入</div> </div> </div> </template> Tips:引包
npm install vue-awesome-mui -save 在main.js放入:
import Mui from 'vue-awesome-mui' Vue.
No CurrentVersion entry in Software/JavaSoft registry! Try re-installing Java and make sure R and Java have matchin
也许大多数和我一样,在第一次安装R的时候,都想通过R环境来读取Excel里面的数据,会涉及到Excel包的安装和调用,在要安装excel包的时候,它要求对xlsxjars,rJava也要进行安装,这三个包要进行一起安装,因为调用的时候都会一起调用。不然没办法用,不过只要在R的环境下输入这个命令就会自动全部下载好:install.packages("xlsx")
下载完后,也许大家会跟我刚开始一样:library(xlsx)
结果就会出现类似如下错误
Error : loadNamespace()里算'rJava'时.onLoad失败了,详细内容:
调用: fun(libname, pkgname)
错误: No CurrentVersion entry in Software/JavaSoft registry! Try re-installing Java and make sure R and Java have matching architectures.
看到错误这句话的时候,大家应该有所明白,rJava要求有JAVA的环境,所以我们要去下载JDK安装
这是ORACLE官网链接,
点击DOWNLOAD
选择Accept,然后大家根据自己的电脑系统来选择,这个就不需要多说了
下载完后直接安装JDK,我安装路径都是默认的,当然大家可以根据个人来选择路径安装,安装完后,在执行调包操作,如果没有出现错误,说明就好了
1,如果一端的Socket被关闭(或主动关闭,或因为异常退出而 引起的关闭),另一端仍发送数据,发送的第一个数据包引发该异常(Connect reset by peer)。
Socket默认连接60秒,60秒之内没有进行心跳交互,即读写数据,就会自动关闭连接。
2,一端退出,但退出时并未关闭该连接,另一端如果在从连接中读数据则抛出该异常(Connection reset)。
简单的说就是在连接断开后的读和写操作引起的。
Connection reset by peer的常见原因:
1)服务器的并发连接数超过了其承载量,服务器会将其中一些连接关闭;
如果知道实际连接服务器的并发客户数没有超过服务器的承载量,则有可能是中了病毒或者木马,引起网络流量异常。可以使用netstat -an查看网络连接情况。
2)客户关掉了浏览器,而服务器还在给客户端发送数据;
3)浏览器端按了Stop;
这两种情况一般不会影响服务器。但是如果对异常信息没有特别处理,有可能在服务器的日志文件中,重复出现该异常,造成服务器日志文件过大,影响服务器的运行。可以对引起异常的部分,使用try…catch捕获该异常,然后不输出或者只输出一句提示信息,避免使用e.printStackTrace();输出全部异常信息。
4)防火墙的问题;
如果网络连接通过防火墙,而防火墙一般都会有超时的机制,在网络连接长时间不传输数据时,会关闭这个TCP的会话,关闭后在读写,就会导致异常。 如果关闭防火墙,解决了问题,需要重新配置防火墙,或者自己编写程序实现TCP的长连接。实现TCP的长连接,需要自己定义心跳协议,每隔一段时间,发送一次心跳协议,双方维持连接。
5)JSP的buffer问题。
JSP页面缺省缓存为8k,当JSP页面数据比较大的时候,有可能JSP没有完全传递给浏览器。这时可以适当调整buffer的大小。
第1个异常是java.net.BindException:Address already in use: JVM_Bind。
该异常发生在服务器端进行new ServerSocket(port)(port是一个0,65536的整型值)操作时。异常的原因是以为与port一样的一个端口已经被启动,并进行监听。此时用netstat –an命令,可以看到一个Listending状态的端口。只需要找一个没有被占用的端口就能解决这个问题。
第2个异常是java.net.ConnectException: Connection refused: connect。
该异常发生在客户端进行 new Socket(ip, port)操作时,该异常发生的原因是或者具有ip地址的机器不能找到(也就是说从当前机器不存在到指定ip路由),或者是该ip存在,但找不到指定的端口进行监听。出现该问题,首先检查客户端的ip和port是否写错了,如果正确则从客户端ping一下服务器,看是否能 ping通,如果能ping通(服务服务器端把ping禁掉则需要另外的办法),则看在服务器端的监听指定端口的程序是否启动,这个肯定能解决这个问题。
第3个异常是java.net.SocketException: Socket is closed,该异常在客户端和服务器均可能发生。
异常的原因是己方主动关闭了连接后(调用了Socket的close方法)再对网络连接进行读写操作。
第4个异常是java.net.SocketException: (Connection reset或者 Connect reset by peer:Socket write error)。
该异常在客户端和服务器端均有可能发生,引起该异常的原因有两个,第一个就是如果一端的Socket被关闭(或主动关闭或者因为异常退出而引起的关闭),另一端仍发送数据,发送的第一个数据包引发该异常 (Connect reset by peer)。另一个是一端退出,但退出时并未关闭该连接,另一端如果在从连接中读数据则抛出该异常(Connection reset)。简单的说就是在连接断开后的读和写操作引起的。
第5个异常是java.net.SocketException: Broken pipe。该异常在客户端和服务器均有可能发生。
在第4个异常的第一种情况中(也就是抛出SocketExcepton:Connect reset by peer:Socket write error后),如果再继续写数据则抛出该异常。前两个异常的解决方法是首先确保程序退出前关闭所有的网络连接,其次是要检测对方的关闭连接操作,发现对方关闭连接后自己也要关闭该连接。
在我们使用solidworks设计产品的时候,我们常常会遇到需要把装配体分为若干个子装配体的情况,但进行这类操作后,往往会遇到一个问题,那就是我们在进行总装配的时候,会发现原来的子装配体中的约束不能够移动。今天我们分享让子装配也能够移动的方法。
1,用solidworks打开已经装配好的装配图。
2,打开子装配体,主轴组件,在子装配体中可以移动,
3,在总装配体中,主轴组件无法移动,
4,现在我们需要让子装配体在总装配体中也能够移动。我们打开总装图,在设计树中选择子装配体,并点击右键,找到零部件属性
5,打开零部件属性,并点击求解为命令下的,为柔性,点击确定
6,子装配体为可移动装配体,如图所示。
以上就是如何在solidworks中移动子装配体的办法,希望能够对大家有所帮助。
原文整理自网络。
如何用Java代码模拟一些如百度、QQ之类的网站登录?有两个方式,一是发送模拟请求,二是模拟浏览器操作,而这两种方式恰好在Java有开源实现,在这里介绍一个工具包,它是家喻户晓的HttpClient。
HttpClient 是 Apache Jakarta Common 下的子项目,至于它是干什么用的呢?简单来说就是:它像浏览器一样支持HTTP协议。既然支持HTTP协议,那意味着浏览器能发送的,它也能发送。我想大家都知道登陆的代码流程,大部分无非就是浏览器端以POST方式提交一个form表单,服务器端收到请求后,判断账户密码做相应处理并且返回结果给浏览器端。但是服务器端并不知道是什么给它发送一个请求,它只针对请求作出相应回应。那么我们就可以利用HttpClient模拟以POST请求方式发送一个表单,不过在这之前,先导入相关的Jar包。
commons-codec-1.3.jar
commons-httpclient-3.1.jar
commons-logging-1.1.1.
这三个jar是httpclient必须的jar包,当然你的版本号可以是其他的。
导入完以后,模拟一个HTML表单提交的过程:
首先要构建一个HttpClient,这个HttpClient就像一个浏览器,可以用来发送请求。
HttpClient client = new DefaultHttpClient(); //构建一个Client 假设百度的登陆服务器的地址为http://login.baidu.com/,接下来是构建一个POST请求
HttpPost post = new HttpPost("http://login.baidu.com/");//构建一个POST请求 //构建表单参数 List<NameValuePair> formParams = new ArrayList<NameValuePair>(); formParams.add(new BasicNameValuePair("username", "yourname")); formParams.add(new BasicNameValuePair("password", "yourpassword")); UrlEncodedFormEntity entity = new UrlEncodedFormEntity(formParams, "UTF-8");//将表单参数转化为“实体” post.setEntity(entity);//将“实体“设置到POST请求里 现在有POST请求,有表单,有参数 ,那下一步就是提交请求到服务器了
HttpResponse response = client.execute(post);//提交POST请求 这样就已经完整的模拟了一个浏览器发送POST请求到服务器。大家注意client.execute()完后,会返回一个HttpResponse.利用这个HttpResponse,我们可以获取到很多东西,如响应头,响应内容,响应Cookie,状态码,返回的输入流等等。下面代码是打印响应的内容:
HttpEntity result = response.getEntity();//拿到返回的HttpResponse的"实体" String content = EntityUtils.toString(result);;//用httpcore.jar提供的工具类将"实体"转化为字符串打印到控制台 System.out.println(content); 我们可以根据HttpResponse返回的状态码、内容等来判断我们是否已经成功登陆百度:
if(content.contains("登陆成功")){ System.out.println("登陆成功!!!"); } 附上完整代码以便大家测试:
try { HttpClient client = new DefaultHttpClient(); //构建一个Client HttpPost post = new HttpPost("
[Error] too many arguments to function ‘func1’(DEV编辑器)
代码: include <stdio.h> void func1(void);
int main(void)
{
/*char *p;
char **p1;
char a;
p = &a;
p1 = &p;
*/
int a = 4; int *p = &a; printf("p = %p.\n",p); func1(&p); printf("p = %p.\n",p); }
void func(void)
{
int *p2[5];
int *p3;
int **p4;
//p3 = p2;//类型 不匹配
p4 = p2; }
void func1(int **p)
{
//*p = 0x12345678;//
*p = (int *)0x12345678;//强制类型转换
该系列文章总纲链接:专题分纲目录 Android Framework 包管理子系统
本章关键点总结 & 说明: 导图是不断迭代的,这里主要关注➕installd部分。主要对installd守护进程进行分析,从main函数开始,主要解读了权限变更和部分命令(install、patchoat、movefiles)的解析流程。
1 installd启动分析
前面对PkgMS构造函数分析时介绍过一个Installer类型的对象mInstaller,它通过socket和后台服务installd交互,以完成一些重要操作。installd是一个native进程,其功能就是启动一个socket,然后处理来自Installer的命令,在init.rc中定义如下:
service installd /system/bin/installd class main socket installd stream 600 system system 在android安装、卸载、优化应用,创建/删除数据文件等操作都是由Intsalld来完成,那为什么不在PkgMS中做呢?因为PkgMS所属SystemServer进程,属于system用户组,没有root权限,而在文件系统中创建和删除文件都需要root权限,因此这里用installd来作为最后一步工作(后面会说明为什么installd用户组是install,却可以执行root操作)
1.1 installd核心main分析
主函数代码如下:
int main(const int argc, const char *argv[]) { char buf[BUFFER_MAX]; struct sockaddr addr; socklen_t alen; int lsocket, s, count; int selinux_enabled = (is_selinux_enabled() > 0); union selinux_callback cb; cb.func_log = log_callback; //SELINUX设置相关 selinux_set_callback(SELINUX_CB_LOG, cb); if (initialize_globals() < 0) {//初始化全局变量,安装应用需要的目录名 exit(1); } if (initialize_directories() < 0) {//初始化系统目录,创建所有用户的安装目录 exit(1); } if (selinux_enabled && selinux_status_open(true) < 0) { exit(1); } drop_privileges();//更改installd进程权限 //开始创建并监听本地socket lsocket = android_get_control_socket(SOCKET_PATH); if (lsocket < 0) { exit(1); } if (listen(lsocket, 5)) { exit(1); } fcntl(lsocket, F_SETFD, FD_CLOEXEC); //处理请求 for (;;) { alen = sizeof(addr); s = accept(lsocket, &addr, &alen); if (s < 0) { continue; } fcntl(s, F_SETFD, FD_CLOEXEC); for (;;) { unsigned short count; if (readx(s, &count, sizeof(count))) {//读取命令 break; } if ((count < 1) || (count >= BUFFER_MAX)) {); break; } if (readx(s, buf, count)) { break; } buf[count] = 0; if (selinux_enabled && selinux_status_updated() > 0) { selinux_android_seapp_context_reload(); } if (execute(s, buf)) break;//执行命令 } close(s); } return 0; } 1.
该系列文章总纲链接:专题分纲目录 Android Framework 包管理子系统
本章关键点总结 & 说明: 导图是不断迭代的,这里主要关注➕ 查询intent组件部分。主要对PkgMS查询组件的流程进行分析,通过intent找到对应的组件并返回。简介了intent和intentFilter,说明了查询的接口,同时对queryIntentActivities接口进行流程解读。
1 intent 和 intentFilter简介
1.1 intent简介
Intent中文是“意图”的意思,它是Android系统中很常用的概念;个人认为 这种基本思想源于对生活的抽象;人与人沟通用的是语言,表达的是意图,比如:
startActivity(Intent intent) startService(Intent intent) bindService(Intent intent) sendBrodcast(Intent intent) 之所以可以用使用intent表达意图,是因为只要用特定的某种格式就可以精确的表达“意图”,因此格式的设定非常关键,intent的属性分类如下:
启动类:有ComponentName(显式),Action(隐式),Category(隐式)。传值类:有Data(隐式),Type(隐式),Extra(隐式、显式)。启动模式类:有Flag,这意味着可以根据flag做不同的处理。 我们对比我们平时的沟通模式,启动类 对应 动词,传值类 对应 宾语,加起来就是一个动宾结构,而这就是语言中最核心的结构,“主谓宾” 是我们表达意图最常用、也是最熟悉的方式。那么根据是否有主语决定了 是显示调用还是隐式调用。而这也是intent分类的根源所在(以上仅为自己的知识积累所做的一个概述),intent的分类如下:
Explicit Intents(显示):这类Intent明确指明 主语。在代码中通过setComponent或setClass来锁定目标对象。处理这种Intent高效
Implicit Intents(隐示):这一类Intents只指明动宾关系,主语是一个范围。对于这类意图,处理相对复杂。
1.2 intentFilter简介
在与人沟通的模型中,找合适的人(与谁沟通)是一个很关键的事情,比如找对象、找合作伙伴、筛选简历等等,首先我们会给出筛选的原则,之后会根据筛选原则去和遇到的每个人去匹配,而在Android中这项工作被称为Intent Resolution。在做匹配工作时,将以Intent Filter 列出的3项内容为参考 标准,具体步骤如下:
匹配IntentFilter的Action,如果Intent设置的Action不满足IntentFilter的Action,则匹配失败。如果IntentFilter未设定Action,则匹配成功。检查IntentFilter的Category,匹配方法同Action的匹配,唯一有些例外的是Category为CATEGORY_DEFAULT的情况。检查Data。Data的匹配过程比较繁琐,因为它和IntentFilter设置的Data内容有关 这里IntentFilter中的Data可以包括两个内容:
URI:完整格式为“scheme://host:port/path”,包含4个部分,scheme、host、port和path。其中host和port合起来标示URI authority,指明服务器网络地址(IP & port)。由于URI最多可包含4个部分,因此要根据情况相应部分做匹配检查。Date type:指定数据的MIME类型(注意:URI中也可以携带数据的类型信息,所以在匹配过程中,还需要考虑URI中指定的数据类型) 2 通过intent查询组件
2.1 查询基础
PkgMS中很重的一项工作就是根据intent来查询处理Intent的续组件信息,处理Intent的查询接口如下:
queryIntentActivities queryIntentServices queryIntentReceivers queryIntentContentProviders 系统中响应某个intent的组件可能有多个,因此返回值是一个列表,android系统中用ResolveInfo类来表示所有组件,ResolveInfo定义如下:
public class ResolveInfo implements Parcelable { private static final String TAG = "
该系列文章总纲链接:专题分纲目录 Android Framework 包管理子系统
本章关键点总结 & 说明: 导图是不断迭代的,这里主要关注➕ PkgMS卸载应用部分。主要是删除应用的文件、数据和缓存数据。
卸载应用和安装应用的分析流程是极其类似的,因此会感觉有些代码有些重复但却不同,也是从adb uninstall命令开始分析。
1 卸载应用程序(从 adb unInstall 到PkgMS)
一般我们会使用adb uninstall 来安装应用,因此这里就从adb uninstall开始分析,adb命令,uninstall参数。直接看adb命令 处理install参数的代码,如下所示:
int adb_commandline(int argc, char **argv) { char buf[4096]; //... if (!strcmp(argv[0], "install")) { if (argc < 2) return usage(); return install_app(ttype, serial, argc, argv); } //... if (!strcmp(argv[0], "uninstall")) { if (argc < 2) return usage(); return uninstall_app(ttype, serial, argc, argv); } //... usage(); return 1; } 这里继续分析uninstall_app实现,代码如下:
该系列文章总纲链接:专题分纲目录 Android Framework 包管理子系统
本章关键点总结 & 说明: 导图是不断迭代的,这里主要关注➕ PkgMS安装应用部分。主要是三个步骤:从执行adb install 到复制文件,再到装载文件,最后到安装成功。
PackagerInstallerService特殊说明:PackagerInstallerService(PkgMIS)是android5.0中新加入的服务,一般通过PackagerInstallerService来分配一个SessinId,这个系统唯一的ID代表一次安装过程,如果一个应用的安装被中断了,比如设备重启,那么也可以通过这个ID来继续安装。Session的创建如下所示:
public int createSession(SessionParams params, String installerPackageName, int userId) { try { return createSessionInternal(params, installerPackageName, userId); } catch (IOException e) { throw ExceptionUtils.wrap(e); } } 该方法会返回个系统唯一值作为SessionID,如果希望再次使用Session,可以通过接口openSession打开,代码实现如下:
public IPackageInstallerSession openSession(int sessionId) { try { return openSessionInternal(sessionId); } catch (IOException e) { throw ExceptionUtils.wrap(e); } } 这里将返回一个IPackageInstallerSession(PackageInstallerSession的IBinder对象),在PackagerManagerService中用变量mSession来存所有的PackageInstallerSession对象。这些PackageInstallerSession对象保存了应用安装的相关数据,比如安装路径、安装进度等。。。
1 安装应用程序(从 adb install 到PkgMS)
一般我们会使用adb install 来安装应用,因此这里就从adb install开始分析,adb命令,install参数。直接看adb命令 处理install参数的代码,如下所示:
int adb_commandline(int argc, char **argv) { char buf[4096]; //.
该系列文章总纲链接:专题分纲目录 Android Framework 包管理子系统
本章关键点总结 & 说明: 导图是不断迭代的,这里主要关注➕ PkgMS关键文件部分即可。这里主要是对几个核心文件的各个标签进行解读和分析。
关于PkgMS,关键的文件比如:package.xml文件、packages.list文件、AndroidManifest文件的解析离不开文件构造的基础,本章节主要是对 这些文件进行解读。
1 package.xml文件解读
packages.xml里面记录了系统当中安装的APK的所有属性,权限等信息。当系统中的APK安装、删除、升级时,文件就会被更新
1.1 案例package.xml
1.2 标签解读
文件的模型如下所示:
<?xml version='1.0' encoding='utf-8' standalone='yes' ?> <packages> <version ... /> <version ... /> <permissions> <item name="xxxS" package="xxx" protection="xx" /> ... ... </permissions> <package xxx> ... </package> ... <shared-user xxx> ... </shared-user> ... <keyset-settings version="1"> ... </keyset-settings> </packages> packages.xml文件信息分为下面几部分:
permission块: 系统中所有定义的权限信息package块:系统中所有安装的app的详细信息shared-user块:所有系统定义的shareuser的信息keyset-settings块:已安装app签名的public key信息 1.2.1 permission标签解读
<permissions> ... <item name="android.permission.REMOTE_AUDIO_PLAYBACK" package="android" protection="2" /> ... </permissions> permission标签 定义了系统中所有的申明的权限信息息:
该系列文章总纲链接:专题分纲目录 Android Framework 包管理子系统
本章关键点总结 & 说明: 导图是不断迭代的,这里主要关注➕ PkgMS启动分析部分即可。在对PkgMS有一个基础了节的基础上,分析了SystemServer启动流程和构造器(对PkgMS来讲,这是核心部分)两部分。
PackageManagerService(后面简称PkgMS)主要负责系统中Package的管理,应用程序的安装、卸载、信息查询等。
特殊说明:
这里 ApplicationPackageManager类继承自PackageManager类。它并没有直接参与Binder通信,而是通过mPM成员变量指向一个IPackageManager.Stub.Proxy类型的对象。源码中是没有IPackageManager.java文件的。该文件是经aidl工具处理IPackageManager.aidl后得到的,输出在Android源码/out/target/。。。目录下 在Andorid5.0种,PkgMS有两个重要的变量mInstallService(属于PackageInstallerService类型,用于管理应用程序安装)和mInstaller(属于InstallerConnection类型,和Daemon进程installd通过socket进行通信,实际上apk的格式转换、建立数据目录等工作都是由InstallD来完成),都与应用安装有着密切的关系。关系如下图所示:
PkgMS由SystemServer创建,在SystemServer中有关PkgMS的启动,分成几个部分
@1 在SystemServer中startBootstrapServices中相关代码如下:
//SS->startBootstrapServices private void startBootstrapServices() { Installer installer = mSystemServiceManager.startService(Installer.class); //... PackageManagerService m = new PackageManagerService(context, installer,...); ServiceManager.addService("package", m);//注册PkgMS到ServiceManager中 //... mPackageManagerService = PackageManagerService.main(mSystemContext, installer,...); mFirstBoot = mPackageManagerService.isFirstBoot();//这里mFirstBoot会传递到WMS中 mPackageManager = mSystemContext.getPackageManager(); //... } @2 在SystemServer中startCoreServices中相关代码如下:
//SS->startCoreServices private void startCoreServices() { // Update after UsageStatsService is available, needed before performBootDexOpt. mPackageManagerService.getUsageStatsIfNoPackageUsageInfo(); } @3 在SystemServer中startOtherServices中相关代码如下:
//SS->startOtherServices private void startOtherServices() { //.
什么是 RPC ? RPC (Remote Procedure Call)即远程过程调用,是分布式系统常见的一种通信方法,已经有 40 多年历史。当两个物理分离的子系统需要建立逻辑上的关联时,RPC 是牵线搭桥的常见技术手段之一。除 RPC 之外,常见的多系统数据交互方案还有分布式消息队列、HTTP 请求调用、数据库和分布式缓存等。
RPC 在我们熟知的各种中间件中都有它的身影。Nginx/Redis/MySQL/Dubbo/Hadoop/Spark/Tensorflow 等重量级开源产品都是在 RPC 技术的基础上构建出来的,我们这里说的 RPC 指的是广义的 RPC,也就是分布式系统的通信技术。RPC 在技术中的地位好比我们身边的空气,它无处不在,但是又有很多人根本不知道它的存在。
RPC服务的基本架构:
一个完整的RPC架构里面包含了四个核心的组件,分别是Client ,Server,Client Stub以及Server Stub,这个Stub可以理解为存根。
客户端(Client),服务的调用方。服务端(Server),真正的服务提供者。客户端存根(Client Stub),存放服务端的地址消息,再将客户端的请求参数打包成网络消息,然后通过网络远程发送给服务方。服务端存根(Server Stub),接收客户端发送过来的消息,将消息解包,并调用本地的方法。 RPC主要是用在大型企业里面,系统繁多,业务线复杂,而且效率优势非常重要的一块,这个时候RPC的优势就比较明显了。
实际的开发当中是这么做的,项目一般使用maven来管理。比如我们有一个处理订单的系统服务,先声明它的所有的接口(这里就是具体指Java中的interface),然后将整个项目打包为一个jar包,服务端这边引入这个二方库,然后实现相应的功能,客户端这边也只需要引入这个二方库即可调用了。为什么这么做?主要是为了减少客户端这边的jar包大小,因为每一次打包发布的时候,jar包太多总是会影响效率。另外也是将客户端和服务端解耦,提高代码的可移植性。
同步调用与异步调用 什么是同步调用?什么是异步调用?同步调用就是客户端等待调用执行完成并返回结果。异步调用就是客户端不等待调用执行完成返回结果,不过依然可以通过回调函数等接收到返回结果的通知。如果客户端并不关心结果,则可以变成一个单向的调用。这个过程有点类似于Java中的callable和runnable接口,我们进行异步执行的时候,如果需要知道执行的结果,就可以使用callable接口,并且可以通过Future类获取到异步执行的结果信息。如果不关心执行的结果,直接使用runnable接口就可以了,因为它不返回结果,当然啦,callable也是可以的,我们不去获取Future就可以了。
流行的RPC框架 目前流行的开源RPC框架还是比较多的。下面重点介绍三种:
gRPC是Google最近公布的开源软件,基于最新的HTTP2.0协议,并支持常见的众多编程语言。 我们知道HTTP2.0是基于二进制的HTTP协议升级版本,目前各大浏览器都在快马加鞭的加以支持。 这个RPC框架是基于HTTP协议实现的,底层使用到了Netty框架的支持。Thrift是Facebook的一个开源项目,主要是一个跨语言的服务开发框架。它有一个代码生成器来对它所定义的IDL定义文件自动生成服务代码框架。用户只要在其之前进行二次开发就行,对于底层的RPC通讯等都是透明的。不过这个对于用户来说的话需要学习特定领域语言这个特性,还是有一定成本的。Dubbo是阿里集团开源的一个极为出名的RPC框架,在很多互联网公司和企业应用中广泛使用。协议和序列化框架都可以插拔是及其鲜明的特色。同样 的远程接口是基于Java Interface,并且依托于spring框架方便开发。可以方便的打包成单一文件,独立进程运行,和现在的微服务概念一致。(阿里集团内部已经不怎么使用dubbo,现在用的比较多的叫HSF。暂未开源。) HTTP服务 其实在很久以前,很多企业开发的模式一直定性为HTTP接口开发,也就是我们常说的RESTful风格的服务接口。
的确,对于在接口不多、系统与系统交互较少的情况下,解决信息孤岛初期常使用的一种通信手段;优点就是简单、直接、开发方便。利用现成的http协议进行传输。
接口可能返回一个JSON字符串或者是XML文档。然后客户端再去处理这个返回的信息,从而可以比较快速地进行开发。但是对于大型企业来说,内部子系统较多、接口非常多的情况下,RPC框架的好处就显示出来了。
首先是长链接,不必每次通信都要像http一样去3次握手,减少了网络开销;
其次,RPC框架一般都有注册中心,有丰富的监控管理;发布、下线接口、动态扩展等,对调用方来说是无感知、统一化的操作。
RPC服务和HTTP服务还是存在很多的不同点的,一般来说,RPC服务主要是针对大型企业的,而HTTP服务主要是针对小企业的,因为RPC效率更高,而HTTP服务开发迭代会更快。总之,选用什么样的框架不是按照市场上流行什么而决定的,而是要对整个项目进行完整地评估,从而在仔细比较两种开发框架对于整个项目的影响,最后再决定什么才是最适合这个项目的。一定不要为了使用RPC而每个项目都用RPC,而是要因地制宜,具体情况具体分析。
--------------------- 作者:Y仟仟 原文:https://blog.csdn.net/weixin_38410177/article/details/89394180 为什么有了Http请求,还要使用RPC调用 这个解释挺复杂的,但是我们可以简单的理解一下,毕竟,现在已经不是以前那个年代了。
还是先来看一下,没有PRC的时候,会怎么样。
在过去是这样的,包括现在很多对企业服务可能也是这样的,只有一个包部署在Tomcat里
那个时候,没什么需要用到RPC的场景。
然后当用户量大的时候呢?渐渐出现了负载均衡。
大概是这个样子。
负载均衡能解决的问题很多,但是还是不够好,比如说,只是某一个功能模块(假设是用户中心)被访问的次数特别频繁,我可不可以把这部分内容单独拿出去?用户中心的机器独立,给它单独的带宽,给他单独的服务器,给他单独的数据库?
不这么干其他的功能模块都干不下去了啊。
好比是原来是学校餐厅,可以同时供200个人用餐,但是修真院的饺子馆生意特别好,每次来吃饭的人都有5000人,占满了所有餐椅,排队几万米,餐厅的其他摊位肯定不乐意了吧?
比如说那个卖炒菜的,虽然我每天只有30来个人吃饭,那也是钱啊,你人这么多,想来我这边吃饭的人都找不着了。
大概的情景应该是这样的。
能理解么?
遇到这种场景怎么办?不可能不让修真院饺子馆开门啊,那最好的方式就是:
你可不可以搬出去?你不搬我们搬也行!(哭泣脸,反正我们是再也不要和你家饺子馆开在一起了,必须给我们一个说法)
那么,搬家之后的样子可能是这样的。
嗯啊。分是分开了,然后餐卡什么的还是在一起,还是和其他摊位一样,给大家提供就餐的功能。这就是分而治之,哪怕你修真院饺子馆关门了,也不影响我,这又叫分布式。
说到分布式,就问题就来了。
实现BeanFactoryPostProcessor重写postProcessBeanFactory()可以得到ConfigurableListableBeanFactory也就得到了spring应用的上下文环境
//获取到spring的上下文 private static ConfigurableListableBeanFactory beanFactory; @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { SpringUtils.beanFactory = beanFactory; } public static<T> T getBean(String beanName)throws Exception{ return (T)beanFactory.getBean(beanName); } public static<T> T getBean(Class<T> clz)throws Exception{ return (T) beanFactory.getBean(clz); } 通过Bean注入新的对象
/** * 执行周期性或定时任务 */ @Bean(name = "scheduledExecutorService") protected ScheduledExecutorService scheduledExecutorService() { return new ScheduledThreadPoolExecutor(corePoolSize, new BasicThreadFactory.Builder().namingPattern("schedule-pool-%d").daemon(true).build()) { @Override protected void afterExecute(Runnable r, Throwable t) { super.afterExecute(r, t); } }; } 然后通过getBean即可获取到对象的实例
【结论】 巨波公第3子登国公后裔在荆州 【分析推理】 巨波公有5子,分别是:
长子刘登科、次子刘登榜、三子刘登国、四子刘登堂、五子刘登祥,六子刘登荣。
网上信息,唯独不见三子登国信息。
(四川高县谱载还有2个儿子:登祥、登荣。登荣公移居四川高县)。
现在网络上,关于巨波的5个儿子,除了登国公,其他的4个儿子的后裔,都已经在网络上出来,特别明确。
三、长子登科公后裔介绍 3世祖巨波公,七房祖 巨波公(公元1247 年~公元1330年),名涛、号才、字牧村。官授浙江衢州府判官、左堂,四川学政。
巨波公生于南宋淳祐七年丁未(公元 1247 年) 四月初十日午时, 卒于元朝元至顺元年年庚午(公元 1330 年) 四月初十日酉时, 享寿84岁, 葬学堂背掌上悬球形。
妣曾氏、谢氏、梁氏、万氏;生4子次第如下:登科、登榜、登国、登堂、(四川高县谱载还有2个儿子:登祥(居博罗)、登荣。登荣公移居四川高县)。巨波公居广东惠州归善县(惠阳)学堂背。卒葬学堂背掌上悬珠形。后裔分居河源大埔围、梅县、大埔、平远、蕉岭、翁源、博罗、惠东、深圳南头西丽宫龙村、兴宁大坪、罗浮、罗岗、坜陂,江西瑞金、龙泉、会昌、赣州、福建漳州、汀州、武宁、永安,四川高县等处。
4世祖登科公(公元1266年~公元1338年),巨波公长子。
字漱荃、乐耕、族科。官授湖南常德府武陵县令。
生于南宋咸淳二年丙寅(公元 1266 年)二月初十日午时, 卒于元朝至元四年戊寅(公元1338 年) 九月初二日戌时, 享寿七十三岁, 葬瑞金县三角塘背龙形。
妣范氏、万氏;生2子:献夫、荣夫(未详)。(海丰谱记载生6子:1刘兰、又名文、献夫、居兴宁大坪;2刘益,字开元、又名武、荣夫、居大埔阴那山;3刘华、又名秀;4刘云、又名季;5刘澄;6刘济、又名富、移居高州、信宜。)由兴宁黄陂龙龟洞迁居江西瑞金县,居宁都瑞金县塘背。卒葬瑞瑞金县三角塘背龙形。后裔分居归善、宜春、梅县扶贵、古塘,大埔、惠阳、蕉岭,兴宁大坪兰坑里,罗岗德丰、坜陂大窝里及细窝里,罗浮岩前、上佑、江西信丰等处。
5世祖献夫公,由瑞金移居江西寻邬县丘坊村开基。妣杨、候氏;生4子:清海(仍居江西寻邬县丘坊村)、成海(移居麻岭)、受海(移居广西陆州)。献夫公葬留车峰山背。
6世祖受海公,妣曾氏;生3子:元福、元郁(未详)、元玉(未详)。受海公丘坊村禾场头转岗海螺形。
7世祖元福公,妣巫氏;生2子:法聪、法通(未详)。元福公葬兴宁罗浮蕉坑村半山塘仙人舞袖形,艮山坤向。妣葬罗浮岩前油房窝虎形甲山庚向。
8世祖法聪公,妣曾氏;生3子:潮宽(由且坊移居兴宁罗浮大塘尾)、潮深(移居兴宁罗浮上佑村)、潮渊(移居兴宁罗浮岩前村)。
9世祖潮宽公,又名法竹,由寻邬丘坊移居兴宁罗浮大塘尾建屋一座,妣于氏;生5子:珠、玄、同、珍、琪(1、2、3、5子未详)。潮宽公葬岩前大塘尾,妣葬罗岗榕树下茶亭左边。
10世祖珍公,字法高。妣赖氏;生4子:法孝、口口、口口、口口。祖妣合葬罗岗将军寨蜘蛛形巽山乾向。
11世祖法孝公,由兴宁罗浮大塘尾移居大坪黄坑村兰坑里开基建“汉兴围”、“兴孝庐”祖屋二座。妣丘、巫氏;生3子:法兴、口口、口口。祖妣各葬大坪兰坑里。
12世祖法兴公,妣张氏;生2子:法富、法贵。
13世祖法富公,庠生,妣袁氏;生3子:法魁、口口、口口。
14世祖法魁公,庠生,妣丘、游洲氏;生2子:仕贤、法日。
15世祖法日公,字仕俊,例贡生,妣袁氏;生3子:永庄、永源(住“贤兴庐”)、永久(未详)。法日公由大坪兰坑里移居罗岗山畲水口建“贤兴庐”。
16世祖永源公,诰职,妣钟氏;生6子:捷文、捷行、捷忠(未详)、捷信(移居江西奉新县)、捷泗(未详)、捷教(移居广西)。
17世祖捷文公,妣周氏;生5子:济瑞、巨瑞(止)、泗瑞、泌瑞(止)、潘瑞(止)。
18世祖济瑞公,妣黄、罗氏;生5子:元祯、元登、元甲、元祥、元勋。
19世祖元勋公(清大生),妣罗氏;生4子:国昌、国盛、国隆、国秀。
20世祖国昌公,妣钟氏;生7子:渊龙(移居湖广)、伯龙、巨龙、河龙(移居湖广)、洪龙、泾龙(未详)、渭龙(未详)。
21世祖洪龙公,妣罗氏;生3子:仁浪、仁波、仁思。,
22世祖仁波公(1830~1908),讳锋、诰职。在兰坑里建“贻光围”一座。妣罗、丘氏;生2子:义晃、义烨。
23世祖义烨公(1875~1958),妣龚氏;生5子:怀安、怀其、怀彰、怀善、怀庭(出嗣义晃)。
24世祖怀其公(1900~1972),配罗氏梅淑;生3子:伟章、伟勋、伟泉。生2女:桂招、银英。
25世伟泉,1938年生,高级政工师,上海市宝钢13冶教育处任科长。作家。配罗氏进招。1941年生,在上海工作,生2子:志东、志民。
26世志东,1966年出生,在上海渔品厂生产部任科长,配邓氏,在上海渔品厂财务部副科长。
26世志民,上海市吴淞水泥厂基建科干部。
五、次子登榜公后裔网上寻根 五、四子登堂公后裔介绍 共生六子:登科、登榜、登国、登堂、登祥、登益。 长:登科公 字乐耕,妣范氏。官授河南武安知县。原住江西瑞金塘背,分梅县大埔。生六子:兰、益(字开元,妣罗氏。为大埔阴那乡开基祖。原住梅县篷辣乡,忠园下角,因元初在乱散居各处。生四子:念一郎、念二郎、念三郎、念四郎)、华(字开万)、云、澄、济(字既元)。 注:念一郎公、念二郎公均因元兵作乱而离散失传,其裔孙有诗叹曰: 乱世茫茫不顾宗,失却次房刘大公。前唐后汉皆有谱,谁知程邑失祖踪。 次:登榜公 妣徐氏。进士出身,官江西会昌县,龙泉县知县。住龙泉县罗塘百家村,分上犹,程乡南口、黄坑、平远,又分丰顺、潮阳深溪。生七子:干清、法宪、钦郎、法明、钦三、法旺、万五郎(妣张氏,住梅县南口,分丰顺汤坑,又分潮阳洋乌都深溪)。 三:登国公 字陶发,号桂用,妣郭氏。进士出身,官四川重庆知府,裔住江西赣州府梅林南康崇义等处。生二子:仲清、仲平。 四:登堂公 字乐善,妣周氏、易氏。裔住江西信丰、万安,分武宁、永安、福建樟州、汀州,传至11世祖中兴公移居陆丰博美桥头,12世祖振川公裔居海丰鹅埠锡坑,又深圳市沙头径口村刘姓系巨波公元裔孙。 五:登益公 号益公,字裕能,邑庠生,妣罗氏,生一子:志南。居南雄府始兴县石井头。 清乾隆四十八年癸卯岁(1783)开七公16世孙文华殿太学士刘墉
java准确确计算两个日期相差天数:
public static int getDayDiffer(Date startDate, Date endDate) throws ParseException { //判断是否跨年 SimpleDateFormat yearFormat = new SimpleDateFormat("yyyy"); String startYear = yearFormat.format(startDate); String endYear = yearFormat.format(endDate); if (startYear.equals(endYear)) { /* 使用Calendar跨年的情况会出现问题 */ Calendar calendar = Calendar.getInstance(); calendar.setTime(startDate); int startDay = calendar.get(Calendar.DAY_OF_YEAR); calendar.setTime(endDate); int endDay = calendar.get(Calendar.DAY_OF_YEAR); return endDay - startDay; } else { /* 跨年不会出现问题,需要注意不满24小时情况(2016-03-18 11:59:59 和 2016-03-19 00:00:01的话差值为 0) */ // 只格式化日期,消除不满24小时影响 SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); long startDateTime = dateFormat.
文章目录 常见算法分治法递归法贪心法动态规划迭代法枚举法回溯法 常用的数据结构数据结构的种类数组链表堆栈队列 树形结构n叉树二叉树 图形结构哈希表 排序算法冒泡排序法选择排序插入排序希尔排序合并排序快速排序法基数排序法稳定性、数据搬移量、算法复杂度 查找顺序查找二分查找插值查找 哈希算法除留余数法平方取中法折叠法数字分析法碰撞与溢出问题的处理线性探测法平方探测法再哈希法 数组与链表算法矩阵矩阵相加矩阵相乘转置矩阵 建立单向链表单向链表的连接功能单向链表的节点删除单向链表的旋转 堆栈与队列算法用数组实现堆栈用链表实现堆栈汉诺塔问题的求解算法八皇后问题的求解算法用数组实现队列用链表实现队列双向队列优先队列 树形结构及其算法用数组实现二叉树用链表实现二叉树二叉树遍历中序遍历后序遍历前序遍历 二叉树的查找二叉树节点的插入二叉树节点的删除堆积树排序法 图的数据结构及其算法深度优先遍历法广度优先搜索 最小生成树Prim算法Kruskal算法 图的最短路径法Dijkstra算法A*算法Floyd算法 常见算法 分治法 递归法 需求1:阶乘函数
def factorial(n): if n==0: return 1 else: return n*factorial(n-1) print(factorial(5)) 需求2:斐波那契数列(Fibonacci Polynomial)
第0项为0,第1项为1,后面的项均为前两项之和。
def fib(n): if n==0: return 0 elif n==1: return 1 else: return(fib(n-1)+fib(n-2)) n=int(input("请输入要计算第几项斐波那契数列:")) for i in range(n+1): print("fib(%d)=%d"%(i,fib(i)))#%d为整数 贪心法 接下来的每一步走最佳
不能保证求得的最后解是最佳的。只能求满足某些约束条件下可行解的范围。
应用于找图的最小生成树(MST)、最短路径和哈夫曼编码
动态规划 用于研究多阶段决策过程的优化过程与求得一个问题的最佳解。
将大问题拆分成离散的子问题,且每个子问题有被储存起来。
需求:斐波那契数列问题
output=[None]*1000 #fibonacci的缓冲区 def fib(n): result=output[n] if result==None: if n == 0: result = 0 elif n == 1: result = 1 else: result = fib(n - 1) + fib(-2) output[n] = result return result fib(5) 有报错
二级联动加动态input输入框实现思路
需求:通过配置使数据库存储过程可以通过前台页面调用
1:二级联动下拉选(任务分类—任务代码);
2: 选择不同的任务带出相应存储过程的录入参数(input);
1. 数据结构 数据库存储过程配置表主要字段: 任务分类代码分类名称任务代码任务名称存储过程存过入参存过出参执行状态有效标志01基础数据同步0101同步平台机构GPINSERT.INSERTINTO[{‘index’:1,‘name’:‘日期’,‘type’:‘date’,‘value’:’?’}][{index:‘2’,type:‘str’,success:‘0’},{index:’’,type:‘str’,msg:’’}]01 字段说明 存储过程: 要执行的存储过程名存过入参: 格式jsonArray [{index:参数位置,type:参数类型,name:‘页面显示名称’,value:’参数值‘}] 注:参数类型(str-字符,date-日期) ,参数值(可为具体值或’?’,?代表需要去页面传入)存过出参:格式jsonArray [{index:参数位置,type:参数类型,success:成功标志,msg:返回错误信息}]
参数类型暂只支持str,一个参数位置不能既有success又有msg执行状态:状态校验,防止存过为执行完毕再次提交任务。 2. 程序设计 Action 层设计思路 查询配置好的是存过过程数据
将分类代码和分类名称已Map的形式存入request作为第一个下拉选资源。
将任务分类代码和任务代码相关数据关联以json字符串格式传入request,作为第二个下拉选资源,如:
{‘01’:[{‘taskName’:‘准备金挂账(挂本月)’,‘taskCode’:‘0102’}],‘02’:[{‘taskName’:‘手续费挂账’,‘taskCode’:‘0201’},{‘taskName’:‘手续费结转挂账’,‘taskCode’:‘0202’},{‘taskName’:‘手续费认证挂账’,‘taskCode’:‘0203’},{‘taskName’:‘赔款挂账’,‘taskCode’:‘0204’},{‘taskName’:‘不含税保费挂账’,‘taskCode’:‘0205’},{‘taskName’:‘车船税挂账’,‘taskCode’:‘0206’},{‘taskName’:‘保费增值税挂账’,‘taskCode’:‘0207’},{‘taskName’:‘保费结转挂账’,‘taskCode’:‘0208’},{‘taskName’:‘再保挂账’,‘taskCode’:‘0209’}],‘03’:[{‘taskName’:‘保险卡自动保费销数’,‘taskCode’:‘0301’},{‘taskName’:‘手续费自动实付’,‘taskCode’:‘0302’},{‘taskName’:‘见费失败自动实收’,‘taskCode’:‘0303’},{‘taskName’:‘赔款自动实付’,‘taskCode’:‘0304’},{‘taskName’:‘保费自动销数’,‘taskCode’:‘0305’},{‘taskName’:‘保单自动实收’,‘taskCode’:‘0306’}],‘04’:[{‘taskName’:‘手续费资金状态回写’,‘taskCode’:‘0401’},{‘taskName’:‘回写赔款资金支付状态’,‘taskCode’:‘0402’},{‘taskName’:‘见费失败资金回写状态’,‘taskCode’:‘0403’},{‘taskName’:‘保费退款资金状态回写’,‘taskCode’:‘0404’},{‘taskName’:‘赔款支付自动送资金’,‘taskCode’:‘0405’},{‘taskName’:‘保费集中支付送资金’,‘taskCode’:‘0406’},{‘taskName’:‘保费送资金’,‘taskCode’:‘0407’}],‘05’:[{‘taskName’:‘同步资金账户’,‘taskCode’:‘0501’},{‘taskName’:‘险种同步’,‘taskCode’:‘0502’},{‘taskName’:‘同步总账汇率’,‘taskCode’:‘0503’},{‘taskName’:‘同步平台机构’,‘taskCode’:‘0504’}],‘06’:[{‘taskName’:‘调用批改存储过程的定时任务’,‘taskCode’:‘0601’},{‘taskName’:‘调用批改存储过程的定时任务’,‘taskCode’:‘0602’},{‘taskName’:‘调用承保存储过程的定时任务’,‘taskCode’:‘0603’},{‘taskName’:‘调用承保存储过程的定时任务’,‘taskCode’:‘0604’}],‘99’:[{‘taskName’:‘微客手续费自动支付’,‘taskCode’:‘9901’},{‘taskName’:‘关联交易信息提取’,‘taskCode’:‘9902’},{‘taskName’:‘收付凭证自动送财务’,‘taskCode’:‘9903’},{‘taskName’:‘见费出单回写保单信息’,‘taskCode’:‘9904’}]}
将任务代码和参数数据关联以json字符串格式传入request,作为动态input资源,如:
{‘0102’:[{‘index’:1,‘name’:‘凭证类型’,‘type’:‘str’,‘value’:‘41’},{‘index’:2,‘name’:‘日期’,‘type’:‘str’,‘value’:’?’}],‘0201’:[{‘index’:1,‘name’:‘凭证类型’,‘type’:‘str’,‘value’:‘06’},{‘index’:2,‘name’:‘日期’,‘type’:‘str’,‘value’:’?’}],‘0203’:[{‘index’:1,‘name’:‘日期’,‘type’:‘str’,‘value’:’?’}],‘0204’:[{‘index’:1,‘name’:‘日期’,‘type’:‘str’,‘value’:’?’}],‘0205’:[{‘index’:1,‘name’:‘凭证类型’,‘type’:‘str’,‘value’:‘01’},{‘index’:2,‘name’:‘日期’,‘type’:‘str’,‘value’:’?’}],‘0206’:[{‘index’:1,‘name’:‘凭证类型’,‘type’:‘str’,‘value’:‘01’},{‘index’:2,‘name’:‘日期’,‘type’:‘str’,‘value’:’?’}],‘0207’:[{‘index’:1,‘name’:‘凭证类型’,‘type’:‘str’,‘value’:‘01’},{‘index’:2,‘name’:‘日期’,‘type’:‘str’,‘value’:’?’}],‘0208’:[{‘index’:1,‘name’:‘日期’,‘type’:‘str’,‘value’:’?’}],‘0209’:[{‘index’:1,‘name’:‘凭证类型’,‘type’:‘str’,‘value’:‘04’},{‘index’:2,‘name’:‘日期’,‘type’:‘str’,‘value’:’?’}],‘0301’:[{‘index’:1,‘name’:‘日期’,‘type’:‘str’,‘value’:’?’},{‘index’:2,‘name’:‘工号’,‘type’:‘str’,‘value’:‘0100000001’}],‘0302’:[{‘index’:1,‘name’:‘日期’,‘type’:‘str’,‘value’:’?’},{‘index’:2,‘name’:‘工号’,‘type’:‘str’,‘value’:‘0100000001’}],‘0303’:[{‘index’:1,‘name’:‘日期’,‘type’:‘str’,‘value’:’?’},{‘index’:2,‘name’:‘工号’,‘type’:‘str’,‘value’:‘0100000001’}],‘0304’:[{‘index’:1,‘name’:‘日期’,‘type’:‘str’,‘value’:’?’},{‘index’:2,‘name’:‘工号’,‘type’:‘str’,‘value’:‘0100000001’}],‘0305’:[{‘index’:1,‘name’:‘日期’,‘type’:‘str’,‘value’:’?’},{‘index’:2,‘name’:‘工号’,‘type’:‘str’,‘value’:‘0100000001’}],‘0306’:[{‘index’:1,‘name’:‘日期’,‘type’:‘str’,‘value’:’?’},{‘index’:2,‘name’:‘工号’,‘type’:‘str’,‘value’:‘0100000001’}],‘0503’:[{‘index’:1,‘name’:‘日期’,‘type’:‘date’,‘value’:’?’}],‘9903’:[{‘index’:1,‘name’:‘日期’,‘type’:‘date’,‘value’:’?’}],‘9904’:[{‘index’:1,‘name’:‘日期’,‘type’:‘date’,‘value’:’?’}]}
jsp 页面相关方法设计 任务分类代码select 增加值改变事件,方法传入分类代码,通过分类代码解析Action层传入的 任务分类代码—任务代码资源json数据,动态生成任务代码下拉选任务代码下拉选增加值改变事件,放入传入任务代码,通过分类代码解析Action层传入的任务代码—参数资源json数据,动态生成任务所需传入的input录入框。执行方法,单击执行函数将相关参数拼接为 参数json资源和任务代码一块传入后台。 3 程序源码及效果图 效果图
程序
自动任务处理 action
public void prepareAutoImplement(HttpServletRequest request, HttpServletResponse response) throws Exception { GpJobTasksDto dto = new GpJobTasksDto(); dto.setValidind("1"); dto.setObject_OrderBy(" TASKCODE "); List<GpJobTasksDto> gpJobTasksDtoList = ServiceManager.payment.getGpPaymentSystemService().findGpJobTasksDto(dto); Map<String,String> classificationMap = new TreeMap<String,String>(); StringBuffer jsonData = new StringBuffer("
1 前言 我们在前面几篇文章中对JNK/NDK做了一个入门的介绍,其中使用了Android.mk和Application.mk本地配置的方式进行NDK开发。但是其实在Android Studio 2.2之后便加入了CMake方式来编译NDK代码。
2 CMake CMake是一个跨平台的安装(编译)工具,可以用简单的语句来描述所有平台的安装(编译过程)。他能够输出各种各样的makefile或者project文件,能测试编译器所支持的C++特性,类似UNIX下的automake。谷歌从Android Studio2.2及更高版本使用NDK和CMake将C及C++代码编译到原生库中,其中通过Gradle便可方便地将SO库封装到APK中去。
3 Hello world 如果你是首次使用CMake,还要跟前面安装NDK一样,在Android Studio中的SDK管理页面勾选CMake项进行下载,操作如下面图:
待安装完毕后,便可以创建Native C++项目了。在【File】 – 【New Project】弹窗中,勾上【Include C++ support】项,如下图:
项目创建好以后我们可以看到和普通Android项目有几下不同地方,如下图:
1. app目录下多出一个.externalNativeBuidl目录。
2. main目录下多出一个cpp目录,其中里头有一个native-lib.cpp文件,这便是放置C/C++代码地方。
3. app目录下的buile.gradle内容里多出两项。能看出,第一项便上我们在新建项目时选择的C++版本和勾上的-fexceptions和-frtti项,它们分别是异常支持(-fexceptions)和运行时类型信息支持(-frtti); 第二项便是指定CMakeLists.txt文件。
4. app目录下还多出一个CMakeLists.txt文件,其内容如下:
3.1 CMakeLists.txt解说 我们看回上面CMakeLists.txt文件内容,里面去除注释就剩4行有效代码,我们来看看它们的含义。
cmake_minimum_required(VERSION major[.minor[.patch[.tweak]]][FATAL_ERROR]) 设置工程所需要的最低CMake版本,如上述最低版本是3.4.1。
add_library(<name> [STATIC | SHARED | MODULE] [EXCLUDE_FROM_ALL] source1 source2 ... sourceN) 添加一个库。如上述是:编译出一个动态库 native-lib,源文件只有 src/main/cpp/native-lib.cpp。参数说明:
<name> 表示添加一个指定名称的库文件。
[STATIC | SHARED | MODULE] 指定要创建的库的类型,STATIC对应的静态库(.a文件,编译时需要,相当于Windows中的lib文件)、SHARED对应共享动态库(.so文件,运行时需要,相当于Windows中的dll文件)、MODULE对应工程内的module。
[EXCLUDE_FROM_ALL] 若指定此属性,则对应的一些属性会在目录被创建时被设置,详细请查阅相应文档。
source1 source2 ... sourceN 指定源文件。
find_library(<VAR> name1 [path1 path2 .
思路: 非常套路性的一个东西,记录一下,防止遗忘
设\(f[i]\)表示以\(i\)为根,到其子树的叶节点的最大距离。
考虑如何用子节点更新父节点,
当前点到叶节点的最大距离=max{子节点到叶节点的距离+当前点到子节点的距离}。
设\(u\)为当前节点,\(v\)为\(u\)的子节点,\(dis(u,v)\)是从\(u->v\)这条路径上的距离
得到转移方程:
\[f[u]=max\{f[v]+dis(u,v)\}\]
如何维护以\(u\)为根的子树中的直径呢
以\(u\)为根子树的直径=max{u到叶节点的最大距离+子节点到叶节点的最大距离+\(u\)到叶节点的距离}
然后我们钦定一个节点为根,比如1
得到转移方程:
\[ans=max\{f[u]+f[v]+dis(u,v)\}\]
\(ans\)即为树的直径
需要注意的是,我们要在更新\(f[u]\)之前更新\(ans\),因为从u经过v到叶节点的路径是最长的路径,这样这条路径会被更新两次
这样做一定会选出u到叶节点最长的两条路径
分类讨论一下
更新\(f[u]\)的路径是\(u\)到叶节点的所有路径中最长的,次长的还未被选,那它会和次长(相等)的一同更新最大值更新\(f[u]\)的路径是\(u\)到叶节点的所有路径中次长的,最长的还未被选,那它会和最长的一同更新最大值更新\(f[u]\)路径不是最长也不是次长,那么\(f[u]\)就会被最长或次长的路径更新,然后在转化成上两种情况 代码 void dfs(int u, int fa) { for (int i = head[u]; ~i; i = e[i].nx) { int v = e[i].v; if (v == fa) continue; dfs(v, u); ans = max(ans, f[u] + f[v] + e[i].w); f[u] = max(f[u], f[v] + e[i].w); } } 练手题 #10155. 「一本通 5.2 例 3」数字转换
边权全为1的树的直径
1.概述 本文介绍几种处理Map中一个key对多个value的方法。在JDK标准Map实现中当我们尝试在一个key下插入多个value,那么后续的value会覆盖前面的value。
Map<String, String> map = new HashMap<>(); assertThat(map.put("key1", "value1")).isEqualTo(null); assertThat(map.put("key1", "value2")).isEqualTo("value1"); assertThat(map.get("key1")).isEqualTo("value2"); 2.将集合作为Value 当要处理一个key对多个value的情况,可以将所有value存放在一个集合中。
Map<String, List<String>> map = new HashMap<>(); List<String> list = new ArrayList<>(); map.put("key1", list); map.get("key1").add("value1"); map.get("key1").add("value2"); assertThat(map.get("key1").get(0)).isEqualTo("value1"); assertThat(map.get("key1").get(1)).isEqualTo("value2"); 这种方式处理有多种缺点并且容易产生错误。我们需要为每个key创建一个集合,同时检查集合是否存在并添加或删除值,在Java 8中可以利用compute()方法来简化代码。
Map<String, List<String>> map = new HashMap<>(); map.computeIfAbsent("key1", k -> new ArrayList<>()).add("value1"); map.computeIfAbsent("key1", k -> new ArrayList<>()).add("value2"); assertThat(map.get("key1").get(0)).isEqualTo("value1"); assertThat(map.get("key1").get(1)).isEqualTo("value2"); 3.使用Apache Commons Collections 添加依赖
<dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-collections4</artifactId> <version>4.1</version> </dependency> 3.1 MutiMap org.apache.commons.collections4.MultiMap接口定义了一个Map,每个key对应一个集合。
MultiMap<String, String> map = new MultiValueMap<>(); map.
1.增加字段
ALTER TABLE tableName ADD COLUMN columnName VARCHAR(20) DEFAULT NULL --增加一个字段,默认为空 ALTER TABLE tableName ADD COLUMN columnName VARCHAR(20) NOT NULL --增加一个字段,默认不能为空 2.删除字段
ALTER TABLE tableName DROP COLUMN columnName --删除一个字段 3.修改字段类型
ALTER TABLE tableName ALTER COLUMN columnName VARCHAR(10) --修改一个字段的类型 4.删除主键
Declare @Pk varChar(100); Select @Pk=Name from sysobjects where Parent_Obj=OBJECT_ID('tableName') and xtype='PK'; if @Pk is not null exec('Alter table tableName Drop '+ @Pk) 转载于:https://www.cnblogs.com/lovgge/p/5332026.html
AdminLTE点击左侧菜单局部切换右侧页面
参考下方代码,标签<li>中的target与<iframe>中的name保持一致,就可以实现点击左侧菜单局部切换右侧页面。
<li class="treeview"> <a href="#"><i class="fa fa-link"></i> <span>页面管理</span> <span class="pull-right-container"> <i class="fa fa-angle-left pull-right"></i> </span> </a> <ul class="treeview-menu"> <li><a href="/new1/" style="margin-left: 19px;" target="new">页面1</a></li> <li><a href="/new2/" style="margin-left: 19px;" target="new">页面2</a></li> </ul> </li> <iframe>中的src属性跳转的是默认页面
<section class="content container-fluid"> <iframe frameborder="0" scrolling="no" id="test" onload="this.height=100" name="new" src="/new3/" style="width: 50%"> </iframe> </section> 有问题欢迎留言或微信联系
近些天在学习SQLserver,过程中遇到了一些自己不知道东西,就随手记下来,以便以后忘了,还得再重新查,
今天说的是SQLserver的pivot(行转列)和unpivot(列转行),废话不多说先来看一下语法,
首先为了找到合适的场景,我随机写了一个SQL,代码如下
SELECT business_type, COUNT(business_type) FROM dbo.pd_product GROUP BY business_type 得到的结果如图,
就是一个简单地聚合运算,大家都会,下面我要在这个基础上写SQL行转列,就是将business_type这列的值转为列名,代码如下
pivot(行转列)
SELECT pi.* FROM ( SELECT business_type, COUNT(business_type) AS b FROM dbo.pd_product GROUP BY business_type ) p PIVOT ( sum(b) FOR business_type IN([doctor],[pni],[goods],[play],[mtt],[diet],[hotel],[site],[feeding],[tcm],[activity],[examination],[visit]) )pi 结果如图
pivot里面需要跟一个聚合函数,其次for后面是要行转列的行所对应的列名,in里面跟的是对应的行值,如果你写一个不存在的行值查询出来那一列就是null,温馨提示:SQL的[]这个中括号不能省哦
下面介绍unpivot(列转行)的语法,同样我是在之前的SQL上写的,这个需要你自己定义两列,因为我要将上图的结果还原回去,
SELECT type,num FROM ( SELECT pi.* FROM ( SELECT business_type, COUNT(business_type) AS b FROM dbo.pd_product GROUP BY business_type ) p PIVOT ( sum(b) FOR business_type IN([doctor],[pni],[goods],[play],[mtt],[diet],[hotel],[site],[feeding],[tcm],[activity],[examination],[visit]) )pi ) up UNPIVOT( num FOR type IN (doctor,pni,goods,play,mtt,diet,hotel,site,feeding,tcm,activity,examination,visit) )unp 结果如图
虚拟机中输入 ifconfig 命令,没有显示 eth0,只有 lo。
解决办法:
进入 /etc/sysconfig/network-scripts 目录,查看是否存在 ifcfg-eth0,有的话即网卡存在但未启动;输入 ifconfig -a,显示 eth0 和 lo;输入 ifconfig eth0 up 启用网卡,输入 ifconfig,只能看到 inet6 的地址,无 inet 地址;输入 vim ifcfg-eth0,修改该文件,把 ONBOOT=no 改为 yes;输入 service network restart,重启。 这时再输入 ifconfig,就会显示 eth0 的 inet 地址,可以正常连接了。
如何在windows系统自带命令查看硬件信息,怎样dos命令查看硬盘和内存/CPU信息?最直接的是:开始→运行→CMD打开命令提示符,在该窗口下输入systeminfo执行,即可看到几乎所有想知道的系统信息,甚至包括机器上已安装的网卡及其IP。 查看主板上内存条的数量。
wmic memorychip list brief 或者 wmic MEMPHYSICAL list brief
查看cpu wmic cpu list brief
查看物理内存
wmic memphysical list brief
查看逻辑内存
wmic memlogical list brief
查看缓存内存
wmic memcache list brief
查看虚拟内存
wmic pagefile list brief
查看网卡
wmic nic list brief
查看网络协议
wmic netprotocal list brief
如何在windows系统自带命令查看硬件信息?
对于在windows下查看系统信息大家一定不陌生了,我现在说几个最常用的方法,对命令感兴趣的朋友看看,(给菜鸟看的,老手就不要笑话我了,大家都是从那个时候过来的,^_^)。
一.图新Shell下:
1. 最直观的:(在运行里面输入CMD,以下命令都是在CMD下输入的:)
输入 sysdm.cpl, 系统属性.
2. 输入dxdiag
3.输入 start msinfo32,winmsd系统信息
3. 输入 devmgmt.msc,设备管理:
4. 输入 taskmgr (或按Ctrl+Alt+Esc) 在性能选项卡看物理内存和pagefile
5. 输入 winver 也可以查看内存大小 怎样dos命令(cmd命令)查看硬盘和内存/CPU信息?
VMware 介绍 VMware 是一种常用的、功能强大的虚拟机管理软件,可以模拟出多台计算机,实现在一台机器上同时运行多个独立的操作系统。
VMware 的主要特点:
同一台机器上可以同时运行多个操作系统;本机系统可以与虚拟机系统进行网络通信;可以随时修改虚拟机系统的硬件环境。 VMware 下载与安装 VMware Workstation 15 Pro for Windows(64 位)下载方式如下:
试用版地址:http://www.vmware.com/cn/products/workstation/workstation-evaluation.html
许可证密钥:5A02H-AU243-TZJ49-GTC7K-3C61N百度网盘(含镜像文件)地址: https://pan.baidu.com/s/1p_FB2Ew1Wz0IYvbxHAy1ww 提取码:ytj2 下载完后,直接双击安装,默认即可。完成后,启动,输入上面的密钥,激活后即可永久免费使用。
打开 VMware,点击新建虚拟机,弹出如下窗口,选择默认典型:
点击下一步,选择”稍后安装操作系统“:
点击下一步,这里选择 Linux 系统的 CentOS 版本:
点击下一步,虚拟机名称可以随便取,默认保存在 C盘,不建议放在 C盘,这里放到 D盘下某个目录,:
点击下一步,设置虚拟机最大硬盘空间大小,默认20G,但一般10G就够用了,这里设置10G:
点击下一步,点击”自定义硬件“可以设置改虚拟机中的硬件,一般默认就可以。如果需要修改,也可以创建完成虚拟机后,在虚拟机界面设置。这里直接点完成:
此时虚拟机就相当于一台真实的电脑,只不过还没有安装操作系统。在安装操作系统之前,如果有必要,可以更改该虚拟机的硬件设置(如:内存大小、处理器数量、网络适配器等)。可以单击 VMware 主界面刚创建好的虚拟机 CentOS6 下,设备中各个选项:
内存:默认 1G,建议不要超过真实机内存大小的一半。
处理器:默认 1,即处理器核心数为1(单核处理器),一般默认即可。可以和真实机的 CPU处理器的设置保持一致。
硬盘:刚刚分配的大小,默认只有一块,如果需要,可以添加一块或多块。
CD/DVD(IDE):光驱,关系到待会能否成功装上操作系统。在设备状态,可以看到”已连接“并没有被勾选,因为该虚拟机还未开机,开机后必须保证被勾选,否则检测不到光驱,也就没办法安装操作系统了。由于真实机没有物理光驱,也没有系统光盘,所有选择”使用 ISO 映像文件“,点击”浏览“,选择下载好的系统镜像文件,确定即可。
Linux 系统镜像文件下载地址: http://archive.kernel.org/centos-vault/
如:http://archive.kernel.org/centos-vault/6.6/isos/i386/ 选择 CentOS-6.6-i386-bin-DVD1.iso 即可(上面的百度网盘地址中有)。
网络适配器:关系到虚拟机的网络连接是否正常。
安装 Linux 操作系统 1.选择好镜像文件后,开启虚拟机,相当于打开电脑的电源启动。
开机同时按 Ctrl + G 或在虚拟机内单击,可使输入定向到虚拟机,然后迅速按 F2,可以打开 Linux 系统的 BIOS 界面。因为这里用光盘安装 Linux 操作系统,BIOS 默认第一启动项是硬盘启动。如果在真实机中通过光盘安装 Linux 操作系统,就需要在安装时,更改第一启动项为光盘启动。安装完成后,再改为硬盘启动。但是,在虚拟机中安装 Linux 操作系统时,无需更改 BIOS 启动项设置,虚拟机会自动识别和调整。
LaTeX 默认的第一段不是首行缩进的, 这不符合我们的中文习惯.
要实现首行缩进也很简单,
在导言区加入宏包首行 \usepackage{indentfirst} 就可以了. (LaTeX 学习博客 (http://latex.yo2.cn) , 白色印记.)
使用命令 设置 缩进的距离 \setlength{\parindent}{2em} ,
这里的 2em 表示缩进 2 个字符位置.
如果有一个段落你不想首行缩进, 在段落前使用命令 \noindent .
同样的, 你要保证这一段是首行缩进, 使用命令 \indent, 如果使用了 CJK 宏包, 还可以用\CJKindent.
trackback: http://latex.yo2.cn/articles/latex-indent.html
转载于:https://www.cnblogs.com/JohnShao/archive/2011/09/08/2171138.html
/root/software/hadoop-2.6.0-cdh5.15.1/etc/hadoop 第一步骤
vi core-site.xml
<configuration> <property> <name>fs.defaultFS</name> <value>hdfs://hadoop000:8020</value> </property> <property> <name>hadoop.tmp.dir</name> <value>/data/hadoop_repo</value> </property> </configuration> 第二步骤
<configuration> <property> <name>dfs.replication</name> <value>1</value> </property> <property> <name>hadoop.tmp.dir</name> <value>/root/software/tmp</value> </property> </configuration> 第三步骤
第四步骤
[root@hadoop000 ~]# vim ~/.bash_profile
[root@hadoop000 ~]# source ~/.bash_profile
[root@hadoop000 ~]# cd $HADOOP_HOME
[root@hadoop000 hadoop-2.6.0-cdh5.15.1]# cd bin
[root@hadoop000 bin]# ls
#启动HDFS 第一次执行的时候一定要格式化文件系统,不要重复执行 [root@hadoop000 bin]# hdfs namenode -format
说明成了
第五步骤
[root@hadoop000 sbin]# ./start-dfs.sh
第五步骤 关闭防火墙
[root@hadoop000 logs]# systemctl stop firewalld.service
[root@hadoop000 logs]# firewall-cmd --state
Idea常用配置 Idea常用配置关闭Idea自动更新字体大小编码Maven仓库和配置文件快捷键提示代码提示不区分大小写方法参数自动提示自动导包和导包优化取消自动保存类头注释去除 Xml 黄色背景 Idea常用配置 Idea是一款强大的开发利器,那么安装好后需要做哪些配置呢?为了便于下次配置,对一些常用配置进行记录。
关闭Idea自动更新 Idea安装好后,为了减少麻烦,可以关闭自动更新:
字体大小 编码 配置所有项目编码为 UTF-8:
Maven仓库和配置文件 对本地 Maven仓库进行配置:
快捷键提示 若习惯 Eclipse 中 Alt + / 提示快捷键,可以配置:
keymap 中可以根据需要自定义不同的快捷键组合。
代码提示不区分大小写 方法参数自动提示 自动导包和导包优化 取消自动保存 Idea 中会自动保存我们编写的代码,可以设置为手动保存,如果代码修改了,选项卡会有 * 号标记:
类头注释 去除 Xml 黄色背景
参考博客
2^n (n=1~500)
2^0=1
2^1=2
2^2=4
2^3=8
2^4=16
2^5=32
2^6=64
2^7=128
2^8=256
2^9=512
2^10=1024
2^11=2048
2^12=4096
2^13=8192
2^14=16384
2^15=32768
2^16=65536
2^17=131072
2^18=262144
2^19=524288
2^20=1048576
2^21=2097152
2^22=4194304
2^23=8388608
2^24=16777216
2^25=33554432
2^26=67108864
2^27=134217728
2^28=268435456
2^29=536870912
2^30=1073741824
2^31=2147483648
2^32=4294967296
2^33=8589934592
2^34=17179869184
2^35=34359738368
2^36=68719476736
2^37=137438953472
2^38=274877906944
2^39=549755813888
2^40=1099511627776
2^41=2199023255552
2^42=4398046511104
2^43=8796093022208
2^44=17592186044416
2^45=35184372088832
2^46=70368744177664
2^47=140737488355328
2^48=281474976710656
2^49=562949953421312
2^50=1125899906842624
2^51=2251799813685248
2^52=4503599627370496
2^53=9007199254740992
2^54=18014398509481984
2^55=36028797018963968
2^56=72057594037927936
2^57=144115188075855872
2^58=288230376151711744
2^59=576460752303423488
2^60=1152921504606846976
2^61=2305843009213693952
2^62=4611686018427387904
2^63=9223372036854775808
2^64=18446744073709551616
2^65=36893488147419103232
在springboot项目整合mybatis的时候,添加通用Mapper插件tk.mybatis,然后出现报错,错误信息:
说是找不到方法什么的,在找了很多资料后得出原因是:
tk.mybatis会自动引用依赖引入persistence-api-1.0.jar包,而persistence-api-1.0.jar的PersistenceUnitInfo类中并没有getValidationMode()方法,而在springboot(2.1.0.RELEASE)中自动引入的依赖persistence-api-2.2.jar包的PersistenceUnitInfo类则有实现getValidationMode()方法。此时两个类冲突了,导致报了错误。
解决方法就是在tk.mybatis中排除掉persistence-api-1.0.jar的自动依赖 <exclusions> <exclusion> <groupId>javax.persistence</groupId> <artifactId>persistence-api</artifactId> </exclusion> </exclusions>
面阵相机:实现的是像素矩阵拍摄。相机拍摄图像中,表现图像细节不是由像素多少决定的,是由分辨率决定的。分辨率是由选择的镜头焦距决定的,同一种相机,选用不同焦距的镜头,分辨率就不同。 像素的多少不决定图像的分辨率(清晰度),那么大像素相机有何好处呢?答案只有一个:减少拍摄次数,提高测试速度
线阵相机:顾名思义是呈“线”状的。虽然也是二维图像,但极长。几K的长度,而宽度却只有几个象素的而已。一般上只在两种情况下使用这种相机:一、被测视野为细长的带状,多用于滚筒上检测的问题。二、需要极大的视野或极高的精度。在第二种情况下(需要极大的视野或极高的精度),就需要用激发装置多次激发相机,进行多次拍照,再将所拍下的多幅“条”形图象,合并成一张巨大的图。因此,用线阵型相机,必须用可以支持线阵型相机的采集卡。 面阵相机:应用面较广,如面积、形状、尺寸、位置,甚至温度等的测量。
线阵相机:主要应用于工业、医疗、科研与安全领域的图象处理。典型应用领域是检测连续的材料,例如金属、塑料、纸和纤维等。被检测的物体通常匀速运动 , 利用一台或多台相机对其逐行连续扫描 , 以达到对其整个表面均匀检测。可以对其图象一行一行进行处理 , 或者对由多行组成的面阵图象进行处理。另外线阵相机非常适合测量场合,这要归功于传感器的高分辨率,它可以准确测量到微米。
3、优点对比:
面阵相机:可以获取二维图像信息,测量图像直观。
线阵相机:一维像元数可以做得很多,而总像元素较面阵相机少,而且像元尺寸比较灵活,帧幅数高,特别适用于一维动态目标的测量。而且线阵分辨率高,价格低廉,可满足大多数测量现场要求。
4、缺点对比:
面阵相机:像元总数多,而每行的像元数一般较线阵少,帧幅率受到限制,因此其应用面较广,如面积、形状、尺寸、位置,甚至温度等的测量。由于生产技术的制约,单个面阵的面积很难达到一般工业测量现场的需求。
线阵相机:要用线阵获取二维图像,必须配以扫描运动,而且为了能确定图像每一像素点在被测件上的对应位置,还必须配以光栅等器件以记录线阵每一扫描行的坐标。一般看来,这两方面的要求导致用线阵获取图像有以下不足:图像获取时间长,测量效率低;由于扫描运动及相应的位置反馈环节的存在,增加了系统复杂性和成本;图像精度可能受扫描运动精度的影响而降低,最终影响测量精度。
另:线阵相机与面阵相机的选型
首先了解一下线扫描系统,这个系统一般可用于被测物体和相机之间有相对运动的场合,通过线扫描相机高速采集,每次采集完一条线后正好运动到下一个单位长度,继续下一条线的采集,这样一段时间下来就拼成了一张二维的图片,也就类似于面阵相机采集到的图片,不同之处是高度可以无限长。接下来通过软件把这幅“无限长”的图片截成一定高度的图片,进行实时处理或放入缓存稍后进行处理。
视觉部分,包括线扫描相机,镜头,光源,图象采集卡和视觉软件; 运动控制部分,包括马达, 马达驱动器, 运动控制卡或PLC,为了保证采集的图象与输送带同步,有时还会需要编码器。 由于线扫描信息量大,所以需要一台高性能的工控机,配置大容量的内存和硬盘,主板要提供PCI、PCI-E或PCI-X插槽。 一般来说,一个面阵视觉系统的配置选型是按照这样的顺序进行的。: 相机+采集卡->镜头->光源 线阵项目也类似,根据系统的检测精度和速度要求,确定线阵CCD相机分辨率和行扫描速度,同时确定对应的采集卡,只是需要选线阵相机镜头接口(mount)时同时考虑镜头的选型,最后确定光源的选型。
线阵摄像机(线阵工业相机)的选型 计算分辩率:幅宽除以最小检测精度得出每行需要的像素
选定相机:幅宽除以像素数得出实际检测精度
每秒运动速度长度除以精度得出每秒扫描行数
根据以上数值选定相机
如幅宽为1600毫米、精度1毫米、运动速度22000mm/s
相机:1600/1=1600像素
最少2000像素,选定为2k相机
1600/2048=0.8实际精度
22000mm/0.8mm=27.5KHz
应选定相机为2048像素28kHz相机
线阵镜头的选型 为什么在选相机时要考虑镜头的选型呢?常见的线阵相机分辨率目前有1K,2K,4K,6K,7K,8K,12K几种,象素大小有5um,7um,10um,14um几种,这样芯片的大小从 10.240mm (1Kx10um) 到 86.016mm (12Kx7um)不等。很显然,C接口远远不能满足要求,因为C接口最大只能接 22 mm 的芯片,也就是1.3inch。而很多相机的接口为F,M42X1,M72X0.75等,不同的镜头接口对应不同的后背焦(Flange distance),也就决定了镜头的工作距离不一样。 1、光学放大倍率(β,Magnification) 确定了相机分辨率和像素大小,就可以计算出芯片尺寸(Sensor size);芯片尺寸除以视野范围(FOV)就等于光学放大倍率。β=CCD/FOV 2、接口(Mount): 主要有C、M42x1 、F、T2、Leica、M72x0.75等几种,确定了之后,就可知道对应接口的长度。 3、后背焦(Flange Distance) 后背焦指相机接口平面到芯片的距离,是一个非常重要的参数,由相机厂家根据自己的光路设计确定。不同厂家的相机,哪怕是接口一样,也可能有不同的后背焦。
有了光学放大倍率、接口、后背焦,就能计算出工作距离和节圈长度。选好这些之后,还有一个重要的环节,就是看MTF值是否足够好?很多视觉工程师不了解MTF,而对高端镜头来说就必须用MTF来衡量光学品质。MTF涵盖了对比度、分辨率、空间频率、色差等相当丰富的信息,并且非常详细地表达了镜头中心和边缘各处的光学质量。不仅只是工作距离、视野范围满足要求,边缘的对比度不够好,也要重新考虑是否选择更高分辨率的镜头。 线扫描线阵光源的选型 线扫描项目中,常用的光源有LED光源、卤素灯(光纤光源)、高频荧光灯。 卤素灯也叫光纤光源,特点是亮度特别高,但缺点也很明显--寿命短,只有1000-2000小时左右,需要经常更换灯泡。发光源是卤素灯泡,通过一个专门的光学透镜和分光系统,最后通过光纤输出,光源功率很大,可高达250瓦。卤素灯还有一个名字叫冷光源,因为通过光纤传输之后,出光的这一头是不热的且色温稳定,适合用于对环境温度比较敏感的场合,比如二次元量测仪的照明。用于线扫描的卤素灯,常常在出光口加上玻璃聚光镜头,进一步聚焦提高光源亮度。对于较长的线光源,还用几组卤素光源同时为一根光纤提供照明。 高频荧光灯,发光原理和日光灯类似,只是灯管是工业级产品,特点是适合大面积照明,亮度较高, 成本低,但荧光灯最大的缺点是有闪烁、衰减速度快。荧光灯一定需要高频电源,也就是光源闪烁的频率远高于相机采集图象的频率(对线扫描相机来说就是行扫描频率),消除图像的闪烁。专用的高频电源可做到60KHz。 LED光源是目前主流的机器视觉光源。特点是寿命长,稳定性好,功耗非常小。 1,直流供电,无频闪。
2,专业的LED光源寿命非常长。(如美国AI的寿命50000小时亮度不小于50%) 3,亮度也非常高,接近卤素灯的亮度,并且随着LED工艺的改善不断提高。(目前美国AI线光源亮度高达90000LUX) 3,可以灵活地设计成不同结构的线光源,如直射、带聚光透镜、背光、同轴以及类似于碗状的漫反射线光源。 4,有多种颜色可选,包括红、绿、蓝、白,还有红外、紫外。针对不同被测物体的表面特征和材质,选用不同颜色也就是不同波长的光源,获得更佳的图像。 线扫描相机、光源与被测物体之间的角度分析 以玻璃检测为例,需要检测的缺陷有:脏点、结石、杂质、气泡、刮伤,裂纹,破损等,其大致可以分成两类,一类在玻璃表面的,一类是玻璃内部的。不同的缺陷,在图象中表现的出的灰度不一样,有黑的,有白的,也有灰的,并且在不同的光源照射角度或者相机接受角度,缺陷的对比度会变化,如在一个角度时,某一种缺陷的对比度最好,但其他缺陷可能比较次,甚至根本看不到。这样也就需要大量的分析、组合,才能确定最后的光源选型和相机、光源和被测物体之间的相对角度。如下图所示,相机、光源在不同角度安装,分别测试。 结果发现: 脏点,正面光源或背光都较容易凸现; 结石和杂质,需要正面接近法线的照明或背面穿透照明; 气泡,形状不固定,且要分析形成的原因以及方向,采用背面照明; 刮伤和破损,正面低角度照明容易凸现。 裂纹,需要背面侧照 而且,以上缺陷并不是独立的,而是互相影响。统计、分析如下。 综合以上因素,最后选用背光斜射和正面照射结合,相机接近法线方向安装。 光源、镜头的调试 线扫描系统,对光源和相机来说,有效的工作区域都是一个窄条。也就是保证光源照在这个最亮的窄条与相机芯片要完全平行,否则只能拍到相交叉的一个亮点。所以机械安装、调试是比较费工夫的。同时由于幅宽比较宽,对于线光源有两个特别的要求,就是均匀性和直线性。因为线光源不同位置的亮暗差异,会直接影响图象的亮度高低,这一点LED比卤素灯更好控制。出光部分的直线性,取决于LED发光角度的一致性、聚光透镜的直线性以及线光源外壳的直线性。 由于现场环境比较复杂,客户总是希望花多一些时间去现场调试。但如我们前面讲到的相机、光源、被测物体的相对角度测试、分析,许多因素会直接影响到检测效果。所以我们建议先做实验室测试,有了方案之后,再去现场调试,这样会最有把握,也能提高调试效率。毕竟服务也是一种成本。 线扫描系统除了机械结构之外, 其主要组成部分还包括机器视觉和运动控制。
前言
小编最近在做前端功能的时候碰到了这么一个错误,错误描述为:Access to XMLHttp Request at...from origin has been blocked by policy,说实话,这个错误并没有怎么见过,甚至可以说是没见过,错误的中文含义就是:…访问XMLHttp的请求被策略阻止了。。
诶?我一直都这么写的啊,没什么问题啊,怎么今天不行了,检查一下也是本地的前后端联调,没毛病啊, localhost8080嘛,你看,下面这不是报错信息里写着呢。
其实仔细看看就发现问题了,天了噜,我竟然没有写http头,哈哈哈,多么low的错误,这可得记录下来,看一遍博客还能笑出声来,当笑话听呢。那http是什么呢?HTTP是一个简单的请求-响应协议,它通常运行在TCP之上。它指定了客户端可能发送给服务器什么样的消息以及得到什么样的响应,具体的我这篇博客可不好写太多了,还是去看百度百科学习吧,链接给你放一下子,省的自己去搜了,Http的百度百科链接
我估计是我写后端接口地址的时候走思了,嗯,可能神游了一番,然后把地址写成了这样,哈哈,希望小伙们写代码的时候要全神贯注啊,不要像小编一样神游太虚去了
总结
这个错误太简单了,记录一下帮助遇到了不会解决问题的朋友,同时,也算是程序路上的一个小调剂吧,难者不会,会者不难,Fighting!
**1.原因是object.java类是所有类的基类,称为父类/超类,java中所有的类都会继承该类,而该类的toString方法打印的就是内存地址.当System.out.println(X)的时候,实际打印的就是X.toString()方法的内容,如果X元素没有重写toString()方法那么就是内存地址值,如果重写了就是数组类型的字符串,**至于System.out.println(X)方法为什么会打印的就是X.toString()的内容,在下面以list和array做详细介绍.
2.list中打印的确是数组类型的字符串,原因是list类继承自下图中的AbstractList类,
该类又继承了AbstractCollection类,该类重写了toString方法.返回的是数组类型的字符串,如下图所示:
因此,list也继承了重写后的toString()方法.
我们再看一下System.out.println()方法,进入到println()方法发现,他打印的就是元素的toString()的内容,如下图所示:
进入上图方法中,点击valueof()方法,进入到下图中:
我们发现,其实System,out.println()方法打印的就是传入的该元素的toString()的值,在结合list中已经重写了该方法,因此打印的是数组类型的字符串.
3.数组为什么重写后还是内存地址,必须要用Ayyays.toString(数组)才能打印数组类型的字符串?
原因与list中原因是一致的,因为数组的Arrays类重写了toString()方法,而本身创建的数组没有重写toString()的方法,因此打印出来的就是内存值.
一、 集群概述 1、 什么是集群 一组各自相互独立且又相互依赖的,通过高速网络互联的计算机组成的一个计算机组, 以单一的系统模式加以管理, 为用户提供服务, 对用户来说, 用户只会认为对方是一个服务. 这个里面, 一组计算机的一台计算机就是集群的一个节点
2、 集群的特性 可伸缩性, 可靠性, 可管理性
3、 应用场景 例:
一台服务器,如果能够响应10000个并发,返回的状态码全部是200
如果现在有20000个并发 返回的状态码[ 200 304 301 500 404 ]
由以上例子说明,web服务已经达到瓶颈
解决这个问题的办法:
加配置: 加CPU, 加内存, 加带宽, 加SSD 这种解决方法称为“向上扩展”, 能够解决一时, 却不能持久一世[单台服务器上做动作]。
加服务器: 一台==>两台, 两台==>四台 四台==>8台 使用多台服务器同时为用户提供服务,而这一种解决方法则称为“横向扩展”或“向外扩展”。
向外扩展:就是集群。
4、 集群的种类 集群系统主要分为
负载均衡(Load Balance)集群,简称LB。
高可用(High Availability)集群,简称 HA 集群。
高性能计算(High Perfermance Computing)集群,简称 HPC 集群。
二、 LVS集群 1、 LVS LVS是Linux Virtual Server的简写,意即Linux虚拟服务器,是一个虚拟的服务器集群系统。本项目在1998年5月由章文嵩博士成立,是中国国内最早出现的自由软件项目之一,是根据iptables的实现来开发的,所以使用时候会和iptables相当类似
官网:http://www.linuxvirtualserver.org/
中文站点: http://zh.linuxvirtualserver.org/
2、 LVS集群工作结构图 负载调度器,:分发器(Load Balancer, Director): 整个集群对外的最前端机, 负责接收用户请求, 并且根据自己的调度算法, 将请求转发到后端真实服务器上的动作,而客户认为服务是来自一个IP地址(我们可称之为VIP虚拟IP地址)上的。
OfficeWord2007图片编辑功能使用教程(转) 1.起始操作 要开始插入一张新的图片,仍然在功能标签上选择“插入”-“Picture”(我们使用的还不是完全中文版,有些功能还未翻译为中文)。 520)this.width=520;" style="CURSOR: hand" οnclick=javascript:window.open(this.src); src="http://tool.chinaitlab.com/UploadFiles_9734/200606/20060620163059492.jpg" οnlοad="javascript:if(this.width>520)this.width=520;" align=absMiddle border=0> 插入-Picture
2.支持的图片文件格式 在弹出的窗口中我们可以看到,Word2007支持的图片文件空前的达到了23种格式: Emf/Wmf/Jpg/Jpeg/Jfif/Jpe/Png/Bmp/Dib/Rle /Bmz/Gif/Gfa/Wmz/Pcz/Tif/Tiff/cdr/cgm/eps/Pct/Pict/Upg 在插入图片之后,就会自动出现图片工具下的“格式”功能面板,如下图所示: 520)this.width=520;" style="CURSOR: hand" οnclick=javascript:window.open(this.src); src="http://tool.chinaitlab.com/UploadFiles_9734/200606/20060620163102501.jpg" οnlοad="javascript:if(this.width>520)this.width=520;" align=absMiddle border=0> 格式面板
可以看到有关于图片的工具都会集中呈现在面板上,分为“图片工具”、“图片格式”、“排列”、“大小”四个功能区。Word2007之中重点加强了前两个功能区的内容。 3.功能区详解 3.1图片工具 图片工具主要是剥离了旧版图片工具中的亮度、对比度等功能,增加了“重新着色”、“压缩图片”的工具,采用直接点击和下拉菜单选择相结合的操作。 520)this.width=520;" style="CURSOR: hand" οnclick=javascript:window.open(this.src); src="http://tool.chinaitlab.com/UploadFiles_9734/200606/20060620163102408.jpg" οnlοad="javascript:if(this.width>520)this.width=520;" align=absMiddle border=0> 图片工具
作为Word2007工具操作的特点,选中图片对象后,只要将鼠标移至相应的工具,在页面马上就可以看到效果。 (1)亮度、对比度 都预设了分级选项,操作起来一目了然,在“图像修正”中可以对这两项指标作更详细的设置。 (2)重新着色 预先设置了具有不同风格的颜色样式队图片进行格式化处理,满足不同要求,免去了对图片效果有特殊要求的朋友再次使用图片处理软件的麻烦,效果很不错。 (3)压缩图片也是新增的实用功能,是针对一些不了解对原始大容积图片进行预处理的朋友们设计的,分别设置了“打印”“屏幕”“电子邮件”三个压缩级别。 3.2图片样式 这是Word2007图片处理新增的最为出彩的功能,它使用了文字样式功能,对图片的样式预设了几十种风格,这个功能一定会使图片的表现力更加出色。 操作上与前述工具类似,选定图片后直接点击目的样式,鼠标移动就可以预览不同样式的效果。 520)this.width=520;" style="CURSOR: hand" οnclick=javascript:window.open(this.src); src="http://tool.chinaitlab.com/UploadFiles_9734/200606/20060620163102973.jpg" οnlοad="javascript:if(this.width>520)this.width=520;" align=absMiddle border=0> 图片样式
可以看到预设的20种图片样式和对图片的处理效果,这下您不用再花费太多工夫对图片预处理,也可以制作出具有专业级别的特殊效果。 右侧的“形状轮廓”则可以对图片框线作进一步处理,而在“Picture Effects(图片效果)”中更是有多达几十种图片样式。 520)this.width=520;" style="CURSOR: hand" οnclick=javascript:window.open(this.src); src="http://tool.chinaitlab.com/UploadFiles_9734/200606/20060620163649336.jpg" οnlοad="javascript:if(this.width>520)this.width=520;" align=absMiddle border=0>
轮廓
主要是学习语法
html代码:
1 <img id ="lunbo"src="img/1.jpg" width="1500px" height="700px"> jQ代码:
//主要学习语法,js的方法到了jq是不管用的,相同jq的方法到js里也是不管用的 var i=1; function lunboPlay(){ i++; $("#lunbo").attr("src","img/"+i+".jpg") if(i==3){ i=1; } } //定义页面加载事件 $(function(){ setInterval("lunboPlay()",3000); } ); 转载于:https://www.cnblogs.com/zhang188660586/p/11182583.html
1.首先是在用户的目录下面找到.jupyter的文件夹
这里是我的.jupyter文件目录
如果没有jupyter_notebook_config.py文件需要运行 jupyter notebook --generate-config命令来生成这个文件,需要注意的是有时候在cmd输入的时候并不起作用,此时需要运行Anaconda Prompt,在这里的命令行中输入相应的命令来生成这个文件。
接下来修改jupyter_notebook_config.py的内容
此时设置的工作目录应该是起作用了,如果还是不起作用可以进行如下的配置:
将你的Jupyter Notebook的快捷方式右键打开“属性”
注意到目标有一个“%USERPROFILE%”,这其实就是你系统环境变量里的用户目录,每次在用这个快捷方式进入Jupyter的时候,不管你怎么设置,都会将这个变量值传给目标,也就是Jupyter,然后再启动。将红圈标出的 %USERPROFILE% 从“目标里”删去,就能使用之前设置默认路径了。
更简单的方式请见:https://blog.csdn.net/afsdfq/article/details/80782611
报错消息:Cannot call sendRedirect() after the response has been committed
问题描述:在response已经重定向的情况下,在其后面不能再有其他respons重定向。
代码展示
if (adduser.getName() == "" || adduser.getName() == null) { response.sendRedirect(request.getContextPath() + "/add.jsp"); } int num = user.addUser(adduser); if (num > 0) { response.sendRedirect(request.getContextPath() + "/userListServlet"); } 解决方法:在response重定向语句后面加上return,执行完第一次response重定向后,后面的语句则不会执行即可,问题得到解决!
演示代码
if (adduser.getName() == "" || adduser.getName() == null) { response.sendRedirect(request.getContextPath() + "/add.jsp"); return; } int num = user.addUser(adduser); if (num > 0) { response.sendRedirect(request.getContextPath() + "/userListServlet"); return; }
前面的话 animate.css是一个使用CSS3的animation制作的动画效果的CSS集合,里面预设了很多种常用的动画,且使用非常简单。本文将详细介绍animate.css的使用
引入
animate.css的最新版本是3.5.2,引入animate.css很容易,有以下几种方法
1、从官网下载
https://raw.github.com/daneden/animate.css/master/animate.css
2、通过npm安装
$ npm install animate.css 3、使用在线cdn
https://unpkg.com/animate.css@3.5.2/animate.min.css
效果演示
animate.css的使用非常简单,因为它是把不同的动画绑定到了不同的类里,所以想要使用哪种动画,只需要把通用类animated和相应的类添加到元素上就行了
下面来详细介绍animate.css里面的类,主要包括Attention(晃动效果)、bounce(弹性缓冲效果)、fade(透明度变化效果)、flip(翻转效果)、rotate(旋转效果)、slide(滑动效果)、zoom(变焦效果)、special(特殊效果)这8类
【Attention(晃动效果)】
bounce flash pulse rubberBand shake headShake swing tada wobble jello 以在div上使用bounce为例
<div class="animated bounce"></div> 【bounce(弹性缓冲效果)】
bounceIn bounceInDown bounceInLeft bounceInRight bounceInUp bounceOut bounceOutDown bounceOutLeft bounceOutRight bounceOutUp 【fade(透明度变化效果)】
fadeIn fadeInDown fadeInDownBig fadeInLeft fadeInLeftBig fadeInRight fadeInRightBig fadeInUp fadeInUpBig fadeOut fadeOutDown fadeOutDownBig fadeOutLeft fadeOutLeftBig fadeOutRight fadeOutRightBig fadeOutUp fadeOutUpBig 【flip(翻转效果)】
flip flipInX flipInY flipOutX flipOutY 【rotate(旋转效果)】
rotateIn rotateInDownLeft rotateInDownRight rotateInUpLeft rotateInUpRight rotateOut rotateOutDownLeft rotateOutDownRight rotateOutUpLeft rotateOutUpRight 【slide(滑动效果)】
sqlsugar使用 sqlsugar是一款非常轻量级并且特别强大的ORM,支持常见的关系型数据库(Oracle , sqlserver , MySQL等等等等),本文示例的是SqlServer,更多一起玩耍的朋友可以关注鄙人的公众号,获取更多源码哦
## web MVC程序实现 思路和流程如下 新建web MVC程序 ,我就命名WebApplication1好了程序NuGet引入两个类库sqlsugar和Newtonsoft.Json,两种引入方法:第一种,程序包管理控制台依次输入Install-Package sqlsuga和Install-Package Newtonsoft.Json;第二种在管理解决方案NuGet程序包中依次搜索sqlsugar和Newtonsoft.Json然后安装。新建一个文件夹,里面新建一个模型一个类, 类dbContext和模型test,下面会讲解,当然,文件夹和类名可以自己命名,模型的话是对应数据库表的,所以命名得和数据库表名一致。类dbContext用来连接数据库用。调用dbContext类(第3点新建的),完成。 using SqlSugar; using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace WebApplication1.Helper { public class dbContext { private static SqlSugarClient _db = null; /// <summary> /// test是数据库名 /// </summary> public static string ConnectionString = "Data Source=localhost;Initial Catalog=test;User id=sa;Password=123456"; public static SqlSugarClient CretClient() { _db = new SqlSugarClient(new ConnectionConfig() { ConnectionString = ConnectionString, //数据库连接字符串 DbType = DbType.
LinkedBlockingQueue和LinkedBlockingDeque,两个都是队列,只不过前者只能一端出一端入,后者则可以两端同时出入,并且都是结构改变线程安全的队列。其实两个队列从实现思想上比较容易理解,有以下特点:
链表结构(动态数组)
通过ReentrantLock实现锁
利用Condition实现队列的阻塞等待,唤醒
LinkedBlockingQueue LinkedBlockingQueue 也是使用单向链表实现的,其也有两个 Node,分别用来存放首、尾节点, 并且还有一个初始值为0的原子变量count,用来记录 队列元素个数 。 另外还有两个 ReentrantLock 的实例,分别用来控制元素入队和出队的原 子性,其中 takeLock 用来控制同时只有 一个线程可以从队列头获取元素 ,其他线程必须 等待, putLock控制同时只能有一个线程可以获取锁,在队列尾部添加元素,其他线程必 须等待。另外, notEmpty 和 notFull 是条件变量 ,它们内部都有 一个条件队列用来存放进队和出队时被阻塞的线程,其实这是生产者一消费者模型。
类图: 常量代码:
/** * Linked list node class */ static class Node<E> { E item; /** * One of: * - the real successor Node * - this Node, meaning the successor is head.next * - null, meaning there is no successor (this is the last node) */ Node<E> next; Node(E x) { item = x; } } /** The capacity bound, or Integer.
今天碰到问题用xshell登陆ubuntu16.04虚拟机时,中文显示为问号
我在百度上查了很多方法,基本都是设置xshell编码为UTF-8,试过了没用,服务器也是UTF-8没问题,但就是一直乱码
最后找了一篇博客说的是LANG设置为C.UTF-8,最后成功了
命令:
vi /etc/profile
在最后一行添加:
export LANG=C.UTF-8
然后:source /etc/profile
最近由于工作需要开始接触爬虫,作为一个小白,真的是像个屋头苍蝇,下面主要是针对我自己遇到的问题以及解决办法做一下记录。。。
①登录网页:包含用户名、密码、验证码,获取cookie
网页源码格式:
<script type=text/javascript src=static/js/manifest.37a2ecbb1d1b7e6c9ada.js></script> 放在<script></script>之间的是文本类型(text)。
javascript是告诉浏览器里面的文本是属于javascript脚本
网上的教程 通过标签路径获取,显然这是不可行的。
from selenium import webdriver
import requests
driver = webdriver.Chrome()
driver.get("http://mydomain.com/login") name_label = driver.find_element_by_id("clientname1")
name_label.send_keys(" ") # 防止发送不成功
name_label.clear()
name_label.send_keys(my_name)
通过查看,发现登录连接为:http://mydomain.com/api/vue/login_login?KEYDATA=myname,mg,pwd,mg,veri KEYDATA后面是用户名、密码、验证码,显然用户名和密码是已知的,最不好得到的是验证码,
这里我用selenium模拟登录,当现实登录界面后,用
from selenium import webdriver import requests driver = webdriver.Chrome() driver.get("http://domain.com/GWC/#/login") check=input() print(check) url_dl = 'http://domain.com/api/vue/login_login?KEYDATA=name,mg,pwd,mg,' +check driver.get(url_dl) seleniumCookies = driver.get_cookies() cookie = [item["name"] + "=" + item["value"] for item in seleniumCookies] cookMap = ';'.join(item for item in cookie) #把获得的cookie:seleniumCookies,放到header中 self.
Beyond Compare4 分享给大家! 6TTCoWi2N0Pv+o2HGfqUpZfuaMhtf2zX0u1OuNeqTYkKKWh-CKwBWkPUG3+CiAQ2q4MNPbf0t8+gmPdo+Vyw64aU-zuQQt9d7Q6EcJ+T42by0E+kxf+q3QLs40H+RD3h5OLjFGpxClodRnTCNoAM39xsWm2aHZI0Z9KdXzLo1fo1OdNlaptoK17SsxNK-7JUtTztLwBM8BUwWA24ghoeLhFq39FMP+pcdU7RttFJoosVk3d-DRrDH0EARo6GXWEeeUgnyjdWKv5ElwrHWw2HMpfFq9VRfMqcJV00ePAUB4MT3zPE43Tu0BDt-WXYSpUqf7AjaWnBC7MpNfdkS0mWXk
运行的时候出现了这个,原因是我是直接找到文件的属性然后粘贴复制的路径
其实这个路径有问题,就是说这个路径的C:…的C前边还有个东西,如果按BackSpace会发现光标没有移动,但此时删掉了一个东西,删掉之后再用这个路径就没问题了。
// html <Select multiple @input="limitcount"> <Option v-for="item in list" :value="item.value">{{item.text}}</Option> </Select> // js limit(e) { if (e.length > 10) { this.$Message.warning('最大10'); e.pop(); } },
记录一下Quartz使用 Quartz是一款比较好用的定时任务执行工具类,这里就简单说一下用法,至于有何优势或者说需要更深层的挖掘,可能就需要您更多的摸索了。
winfrom程序实现 先说一下思路和流程 新建winfrom程序 ,我就命名WindowsFormsApplication1好了程序NuGet引入Quartz类库,两种引入方法:第一种,程序包管理控制台输入Install-Package Quartz;第二种在管理解决方案NuGet程序包中搜索Quartz然后安装。新建一个文件夹Helper,里面新建两个类Class用来配置Quartz, Quartz和IQuartz,下面会讲解,当然,这两个类名和路径都是没规定的,自己喜欢就好。调用Quartz类(第3点新建的Class),完成。开始实现…… 第1、2点很简单就不说了,第二点的两个类我就放在一个新建的Helper文件夹下,注意一点就是时间的设定,这个可以根据需求去设置,时间设置在Quartz类的WithCronSchedule中设定,代码实现如下:
using Quartz; using Quartz.Impl; using System; using System.Collections.Generic; using System.Collections.Specialized; using System.Linq; using System.Text; using System.Threading.Tasks; namespace WindowsFormsApplication1.Helper { public class Quartz { public static async Task Start() { try { // Grab the Scheduler instance from the Factory NameValueCollection props = new NameValueCollection { { "quartz.serializer.type", "binary" } }; StdSchedulerFactory factory = new StdSchedulerFactory(props); IScheduler scheduler = await factory.GetScheduler(); await scheduler.
该系列文章总纲链接:专题分纲目录 Android Framework 窗口子系统
本章关键点总结 & 说明: 导图是不断迭代的,这里主要关注➕ 左上角 Android 窗口动画系统部分(因为导图是在太大,因此这里做了分层处理)。子导图展开后如下所示:
在这张图⬆️上,我们主要关注下方的动画系统框架即可。一方面从WMS入口开始解读动画系统,了解Animator各种类型和作用,另一方面从解读WindowStateAnimator开始解读了动画关键流程:动画选择和设置、Transformation计算、动画渲染。
1 动画系统框架
这里以Animator为研究入口研究WMS动画子系统框架,即WMS的scheduleAnimationLocked为入口,用于启动动画,代码如下
/** Note that Locked in this case is on mLayoutToAnim */ void scheduleAnimationLocked() { if (!mAnimationScheduled) {//避免重复发送 mAnimationScheduled = true; mChoreographer.postCallback( //处理mAnimator.mAnimationRunnable,mAnimator是WMS所有动画的管理者 Choreographer.CALLBACK_ANIMATION, mAnimator.mAnimationRunnable, null); } } 这里专注分析Animator(属于WindowAnimator类)的mAnimationRunnable实现,代码如下:
WindowAnimator(final WindowManagerService service) { mService = service; mContext = service.mContext; mPolicy = service.mPolicy; mAnimationRunnable = new Runnable() { @Override public void run() { synchronized (mService.mWindowMap) { mService.
该系列文章总纲链接:专题分纲目录 Android Framework 窗口子系统
本章关键点总结 & 说明: 导图是不断迭代的,这里主要关注➕ 左上角 Android 窗口系统中Animation & Animator部分即可。主要说明Android的3种常见动画:View动画、帧动画、属性动画的基础概念以及使用方法。放大Android 窗口系统中Animation & Animator部分,效果如下:
1 Animation
在Android 3.0以前,android支持两种动画模式,tween(view) animation,frame(drawable) animation,在android3.0中又引入了一个新的动画系统:property animation,这3种动画模式被称为property animation,view animation,drawable animation。 注意:可以通过{NineOldAndroids}(github上开源项目)在3.0之前的系统中使用Property Animation
1.1 View Animation / Tween Animation
@1 Animation是以XML格式定义的,定义好的XML文件存放在res/anim中。 由于Tween Animation与Frame Animation的定义、使用都有很大的差异。按照XML文档的结构{父节点|子节点|属性}来介绍Tween Animation,其由4种类型:
Alpha:渐变透明度动画效果
Scale:渐变尺寸伸缩动画效果
Translate:画面转换位置移动动画效果
Rotate:画面转换位置移动动画效果
@@1.1 在介绍以上4种类型前,先介绍Tween Animation共同的节点属性
@@1.2 alpha专有属性说明
@@1.3 scale专有属性说明
@@1.4 translate专用属性说明
@@1.5 rotate专有属性说明
@2 Tween Animation如何使用(Android SDK提供了2种方法) @@2.1 直接从XML资源中读取Animation并使用。
用XML定义的动画放在/res/anim/文件夹内,XML文件的根元素可以为<alpha>,<scale>,<translate>,<rotate>, interpolator元素 或<set>(表示以上几个动画的集合,set可以嵌套)。默认情况下,所有动画是同时进行的,可以通过startOffset属性设置各个动画的开始偏移(开始时间)来达到动画顺序播放的效果。
定义好动画的XML文件后,可以通过类似下面的代码对指定View应用动画。使用实例如下所示:
ImageView spaceshipImage = (ImageView)findViewById(R.id.spaceshipImage); Animation hyperspaceJumpAnimation=AnimationUtils.
很简单,直接上代码
html:
1 <tr onmouseover="mover('userName1')" onmouseout="mout('userName1')" id="userName1"> 2 <td> 3 姓名 4 </td> 5 6 <td> 7 * 8 <input type="text" name="userName" id="userName" onfocus="of('userName')" onblur="ob()" required="required" /> 9 10 </td> 11 </tr> JS代码:
1 function mover(id){ 2 document.getElementById(id).style.backgroundColor="pink"; 3 4 } 5 function mout(id){ 6 document.getElementById(id).style.backgroundColor="white"; 7 } 转载于:https://www.cnblogs.com/zhang188660586/p/11172779.html
题目要求
生成大量随机信息1000条,(每条信息包括:姓名、性别、年龄、籍贯、电话号码、地址、电子邮件、数学成绩、英语成绩)统计分析数学成绩90分以上的人的性别、年龄、籍贯。尝试将上述随机生成信息写入到Excel文件中。
代码实现
from random import choice,randint import string import codecs import random from openpyxl import Workbook ##常用汉字编码表 StringBase = '\u7684\u4e00\u4e86\u662f\u6211\u4e0d\u5728\u4eba\u4eec\u6709\u6765\u4ed6\u8fd9\u4e0a\u7740\u4e2a\u5730\u5230\u5927\u91cc\u8bf4\u5c31\u53bb\u5b50\u5f97\u4e5f\u548c\u90a3\u8981\u4e0b\u770b\u5929\u65f6\u8fc7\u51fa\u5c0f\u4e48\u8d77\u4f60\u90fd\u628a\u597d\u8fd8\u591a\u6ca1\u4e3a\u53c8\u53ef\u5bb6\u5b66\u53ea\u4ee5\u4e3b\u4f1a\u6837\u5e74\u60f3\u751f\u540c\u8001\u4e2d\u5341\u4ece\u81ea\u9762\u524d\u5934\u9053\u5b83\u540e\u7136\u8d70\u5f88\u50cf\u89c1\u4e24\u7528\u5979\u56fd\u52a8\u8fdb\u6210\u56de\u4ec0\u8fb9\u4f5c\u5bf9\u5f00\u800c\u5df1\u4e9b\u73b0\u5c71\u6c11\u5019\u7ecf\u53d1\u5de5\u5411\u4e8b\u547d\u7ed9\u957f\u6c34\u51e0\u4e49\u4e09\u58f0\u4e8e\u9ad8\u624b\u77e5\u7406\u773c\u5fd7\u70b9\u5fc3\u6218\u4e8c\u95ee\u4f46\u8eab\u65b9\u5b9e\u5403\u505a\u53eb\u5f53\u4f4f\u542c\u9769\u6253\u5462\u771f\u5168\u624d\u56db\u5df2\u6240\u654c\u4e4b\u6700\u5149\u4ea7\u60c5\u8def\u5206\u603b\u6761\u767d\u8bdd\u4e1c\u5e2d\u6b21\u4eb2\u5982\u88ab\u82b1\u53e3\u653e\u513f\u5e38\u6c14\u4e94\u7b2c\u4f7f\u5199\u519b\u5427\u6587\u8fd0\u518d\u679c\u600e\u5b9a\u8bb8\u5feb\u660e\u884c\u56e0\u522b\u98de\u5916\u6811\u7269\u6d3b\u90e8\u95e8\u65e0\u5f80\u8239\u671b\u65b0\u5e26\u961f\u5148\u529b\u5b8c\u5374\u7ad9\u4ee3\u5458\u673a\u66f4\u4e5d\u60a8\u6bcf\u98ce\u7ea7\u8ddf\u7b11\u554a\u5b69\u4e07\u5c11\u76f4\u610f\u591c\u6bd4\u9636\u8fde\u8f66\u91cd\u4fbf\u6597\u9a6c\u54ea\u5316\u592a\u6307\u53d8\u793e\u4f3c\u58eb\u8005\u5e72\u77f3\u6ee1\u65e5\u51b3\u767e\u539f\u62ff\u7fa4\u7a76\u5404\u516d\u672c\u601d\u89e3\u7acb\u6cb3\u6751\u516b\u96be\u65e9\u8bba\u5417\u6839\u5171\u8ba9\u76f8\u7814\u4eca\u5176\u4e66\u5750\u63a5\u5e94\u5173\u4fe1\u89c9\u6b65\u53cd\u5904\u8bb0\u5c06\u5343\u627e\u4e89\u9886\u6216\u5e08\u7ed3\u5757\u8dd1\u8c01\u8349\u8d8a\u5b57\u52a0\u811a\u7d27\u7231\u7b49\u4e60\u9635\u6015\u6708\u9752\u534a\u706b\u6cd5\u9898\u5efa\u8d76\u4f4d\u5531\u6d77\u4e03\u5973\u4efb\u4ef6\u611f\u51c6\u5f20\u56e2\u5c4b\u79bb\u8272\u8138\u7247\u79d1\u5012\u775b\u5229\u4e16\u521a\u4e14\u7531\u9001\u5207\u661f\u5bfc\u665a\u8868\u591f\u6574\u8ba4\u54cd\u96ea\u6d41\u672a\u573a\u8be5\u5e76\u5e95\u6df1\u523b\u5e73\u4f1f\u5fd9\u63d0\u786e\u8fd1\u4eae\u8f7b\u8bb2\u519c\u53e4\u9ed1\u544a\u754c\u62c9\u540d\u5440\u571f\u6e05\u9633\u7167\u529e\u53f2\u6539\u5386\u8f6c\u753b\u9020\u5634\u6b64\u6cbb\u5317\u5fc5\u670d\u96e8\u7a7f\u5185\u8bc6\u9a8c\u4f20\u4e1a\u83dc\u722c\u7761\u5174\u5f62\u91cf\u54b1\u89c2\u82e6\u4f53\u4f17\u901a\u51b2\u5408\u7834\u53cb\u5ea6\u672f\u996d\u516c\u65c1\u623f\u6781\u5357\u67aa\u8bfb\u6c99\u5c81\u7ebf\u91ce\u575a\u7a7a\u6536\u7b97\u81f3\u653f\u57ce\u52b3\u843d\u94b1\u7279\u56f4\u5f1f\u80dc\u6559\u70ed\u5c55\u5305\u6b4c\u7c7b\u6e10\u5f3a\u6570\u4e61\u547c\u6027\u97f3\u7b54\u54e5\u9645\u65e7\u795e\u5ea7\u7ae0\u5e2e\u5566\u53d7\u7cfb\u4ee4\u8df3\u975e\u4f55\u725b\u53d6\u5165\u5cb8\u6562\u6389\u5ffd\u79cd\u88c5\u9876\u6025\u6797\u505c\u606f\u53e5\u533a\u8863\u822c\u62a5\u53f6\u538b\u6162\u53d4\u80cc\u7ec6' # StringBase = ''.join(StringBase.split('\\u')) #转换为汉字 def getEmail(): suffix=['.com','.org','.net','.cn'] ##常用邮箱后缀 characters=string.ascii_letters+string.digits+'_' ##字母数字集合 username=''.join((random.choice(characters) for i in range(random.randint(6,12)))) ###6-12的随机整数用户名 domain=''.join((random.choice(characters) for i in range(random.randint(3,6)))) return username+'@'+domain+random.choice(suffix) def getSex(): return random.choice(('男','女')) ##每条信息包括:姓名、性别、年龄、籍贯、 # 电话号码、地址、电子邮件、数学成绩、英语成绩) def getAge(): return str(random.randint(18,100)) def getNat(): return random.choice(('北京市','天津市','上海市','重庆市','河北省','山西省','辽宁省','吉林省','黑龙江省','江苏省','浙江省','安徽省','福建省','江西省','山东省','河南省','湖北省','湖南省','广东省','海南省','四川省','贵州省','云南省','陕西省','甘肃省','青海省','台湾省','内蒙古自治区','广西壮族自治区','西藏自治区','宁夏回族自治区','新疆维吾尔自治区','香港特别行政区','澳门特别行政区')) def getTelNo(): return ''.join((str(random.randint(0,9)) for i in range(11))) def getNameOrAddress(flag): '''flag=1表示返回随机姓名,flag=0表示返回随机地址''' result='' if flag==1: rangestart,rangeend=2,5 ##姓名 elif flag==0: rangestart,rangeend=10,31 else: print('flag must be 1 or 0') for i in range(random.
练习3-2 计算符号函数的值 (10 分)
对于任一整数n,符号函数sign(n)的定义如下:
请编写程序计算该函数对任一输入整数的值。
输入格式: 输入在一行中给出整数n。
输出格式: 在一行中按照格式“sign(n) = 函数值”输出该整数n对应的函数值。
输入样例1: 10 输出样例1: sign(10) = 1 输入样例2: 0 输出样例2: sign(0) = 0 输入样例3: -98 输出样例3: sign(-98) = -1 #include "stdio.h" main() { int n,sign; //printf("请输入正整数n:\n"); scanf("%d",&n); if(n==0) sign=0; else if(n<0) sign=-1; else sign=1; printf("sign(%d) = %d\n",n,sign); } 练习3-3 统计学生平均成绩与及格人数 (15 分)
本题要求编写程序,计算学生们的平均成绩,并统计及格(成绩不低于60分)的人数。题目保证输入与输出均在整型范围内。
输入格式: 输入在第一行中给出非负整数N,即学生人数。第二行给出N个非负整数,即这N位学生的成绩,其间以空格分隔。
输出格式: 按照以下格式输出:
average = 成绩均值 count = 及格人数 其中平均值精确到小数点后一位。
输入样例: 5 77 54 92 73 60 输出样例: average = 71.
感性是什么意思 2005-09-25 15:55 xinghuali | 分类:恋爱 有人说自己很感性?不知到底是什么意思 人在这方面分两种,一种是理性,一种就是感性,理性是很理智的那种,就是做事都依据道理,不会冲动.
而感性的就是凭着感觉来的那一种,凡是只要感觉对了就行,不管有没有事实根据,都会按照自己的想法去做的. 转载于:https://www.cnblogs.com/jeanschen/p/3503351.html
在机器视觉中,打光是一种技术。其重要性甚至可以影响处理精度和速度,甚至系统的成败。
需要根据被测物的特征改变打光方式,可以突出被测物。改变颜色可以得到对比更鲜明的图像。
理想光源应该是明亮的、均匀的、稳定的,视觉系统使用的光源主要有三种:高频荧光灯、光纤卤素灯、LED光源。
1.光源特性
高频荧光灯:使用寿命约1500-3000小时;优点:扩散性好、适合大面积均匀照射;缺点:亮度较暗,响应速度慢。
光纤卤素灯:使用寿命约1000小时;优点:亮度高;缺点:响应速度慢,几乎没有光亮度和色温的变化。
LED灯:使用寿命越10000-30000小时;优点:可以使用多个LED达到高亮度,同时可组合不同的形状,响应速度快,波长可以根据用途选择。
高频荧光灯卤素灯LED光源价格低高中亮度低高中稳定性低中高闪光装置无无有使用寿命中低高光线均匀度高中低多色光无无有复杂设计低中高温度影响中低高 对LED光源的补充说明:
用于机器视觉中的LED光源可以分为两大类:正面照明LED光源和背面照明LED光源。正面照明LED光源用于检测物体表面特征;背面照明LED光源用于检测物体轮廓或透明物体的纯净度。正面照明LED光源按照结构不同,又可分为环形光源、条形光源、同轴光源和方形光源。目前,环形光源用得最多,包括直接照射环形光源、漫反射环形光源、Dome光源等。
直接照射环形光源,适用于不反光物体的检测;漫反射环形光源,适用于反光物体的检测;
Dome光源也是漫反射光源的一种,但它是通过半球型的内壁多次反射,可以完全消除阴影。主要用于检测球型或曲面物体。
直接照射环形光源
按照照射角度的不同,直接照射环形光源可分为:垂直照射环形光源、带角度环形光源、低角度环形光源和水平照射环形光源等。可以简单理解为:每个LED的光轴和环形灯外壳之间的夹角,依次为0°、20°、60°和90°(具体型号可能会稍有变化)。
不同的照明角度适用于不同的检测要求。垂直照明和带角度照明为明视野照明,也就是被测物体表面大部分反光都能进入摄像头,故背景呈白色,比如物体表面突出特征的检测。低角度照明和水平照明为暗视野照明,也就是被测物体表面大部分反光都不进入摄像头,故背景呈黑色,只有物体高低不平之处的反光进入摄像头,比如金属表面划痕的检测,背景呈黑色,划痕呈白色。同时,垂直照明和带角度照明的区别在于,前面一种的照射距离较远,后者较近。低角度环形照明和水平照射环形照明的区别也是这样。同时,漫反射环形也有直射和低角度之分。
漫反射光源
低角度漫反射条形灯,有两个应用。一个是宽幅检测,2个或4个条形组合使用,另一个是线扫描的照明。
另外一个应用,就是线扫描照明。目前线扫描项目逐渐增多。线扫描相机每次都是采集一条线,且曝光时间短,对光源亮度要求很高。光源需要采用聚光型,集中照到一条线上,这样才能准确控制图象稳定。线扫描的照明,常用的有几种办法:超高亮LED+聚光镜、光纤+聚光镜、高频荧光灯+聚光镜。超高亮LED+聚光镜,寿命长不用说,但成本较高,照射距离可能会受一些限制;光纤亮度高,但成本贵;高频荧光灯,成本较低,但需要隔一定时间换灯管。
2.光的特性
(1)光沿着直线传播
(2)光的反射:入射角 = 反射角
(3)光的折射:受到材质的影响
(4)光的吸收:形成色差
(5)光的透射:<1>材料和厚度影响透射率;<2>波长越长,对物质的穿过能力越强
3.照射光种类
(1)直射光:主要来自同一个方向的光,可以在亮度和暗色阴影之间产生相对高的对比度高的图像。
(2)漫射光:各种角度混在一起的光。
(3)偏振光:在垂直于传播方向的平面内,光矢量只沿某一个方向振动的光。通常是利用偏光板来防止特定方向的反射。
(4)平行光:照射角度一致的光。太阳光就是平行光。发光角度越窄的LED直射光越接近平行光。
4.光源选择
(1)目的:<1>将感兴趣部分和其他部分的灰度值差异加大<2>尽量消影不感兴趣的部分<3>提高信噪比,利于图像处理<4>减少因材质、照射角度对成像的影响。
(2)种类应用:
<1>卤素灯是冷光源,适合对环境温度比较敏感的场合,比如测量仪器的照明。
<2>高频荧光灯要进口,注意消除图像闪烁,适合亮度高和大面积的照明。
<3>Demo灯主要适合于检测球形或者曲面物体
<4>直接照射漫反射适合于划痕检测
<5>条形灯主要用于宽幅检测和线扫描照明
<6>同轴灯主要用于检测反光程度很厉害的平面物体
5.照明技术特点
(1)直射光:明亮、有光点、射角窄
(2)漫射光:较暗、射角宽、、无光斑、均匀照射
(3)镜面反射:明亮、与照射距离无关、与角度有关、不反应照射物的颜色
(4)漫反射:较暗、与照射距离有关、与角度无关、反映照射物颜色
6.明视野与暗视野
明视野:用直射光来观察对象物(散乱光呈黑色)
暗视野:用散乱光来观察对象物(散乱光呈白色)
7.透射照明
光线透过观测物,观察其透射光。
8.颜色和补色
一、webpack webpack 是前端的一个项目构建工具,它是基于 Node.js 开发出来的一个前端工具;所以要想是用webpack的话,要先安装node.js,然后通过npm 命令行去安装,npm是随同NodeJS一起安装的包管理工具,npm有一个远程代码仓库(registry),在里面存放所有需要被共享的js代码,每个js文件都有自己唯一标识。只需命令行就可以安装使用所需的包,
webpack安装的两种方式 运行npm i webpack -g全局安装webpack,这样就能在全局使用webpack的命令在项目根目录中运行npm i webpack --save-dev安装到项目依赖中 二、git Git是目前世界上最先进的分布式版本控制系统。
下载地址:https://git-scm.com/downloads ,点击next安装即可
安装完成后在菜单找到git Bash,显示类似的窗口就表示安装成功
因为Git是分布式版本控制系统,所以,想使用github或者码云来下载代码和上传diamante时需要配置你的名字和Email地址。账号申请完成后,打开命令行或者Git Bash,输入
git config –global user.name “name”,之后回车,再输入
git config –global user.email email@example.com
注:其中name和email@example.com 是你在github或者码云上注册时的用户名和邮箱。
生成SSH公钥的方法:https://gitee.com/help/articles/4191#article-header0
统计字符数组中字符的个数 定义printCount方法,统计每个字符出现的次数并打印到控制台。这里采用了数组的方式来完成。 public class Demo5 { public static void main(String[] args) { char[] arr = {'a', 'l', 'f', 'm', 'f', 'o', 'b', 'b', 's', 'n','a', 'l','8','$','@'}; printCount(arr); } public static void printCount(char arr[]) { char max = arr[0]; for (int i = 0; i < arr.length; i++) { if (max < arr[i]) { max = arr[i];//找到字符数组中最大的字符 } } int [] arry1 = new int[max + 1]; for (int j = 0; j < arr.
hive和mysql用法相同。
字符串反转函数:reverse
语法: reverse(string A)。返回字符串A的反转结果
举例:select reverse(abcedfg’) from dual; ##返回值为gfdecba
实例:
select reverse(a),reverse(b),reverse(c) from tmp.csv_t1
window 1.导出整个数据库
mysqldump -u 用户名 -p 数据库名 > 导出的文件名 mysqldump -u dbuser -p dbname > dbname.sql 2.导出一个表
mysqldump -u 用户名 -p 数据库名 表名> 导出的文件名 mysqldump -u dbuser -p dbname users> dbname_users.sql 3.导出一个数据库结构
mysqldump -u dbuser -p -d --add-drop-table dbname >d:/dbname_db.sql -d 没有数据 --add-drop-table 在每个create语句之前增加一个drop table 4.导入数据库
常用source 命令 进入mysql数据库控制台,如 mysql -u root -p mysql>use 数据库 然后使用source命令,后面参数为脚本文件(如这里用到的.sql) mysql>source d:/dbname.sql 4.1 导入数据到数据库
mysql -uroot -D数据库名 4.2 导入数据到数据库中得某个表
mysql -uroot -D数据库名 表名 D:\APMServ5.
1.日期-节假日-星期
计算与节假日,以及工作日,周末属性相关的一些指标,代码如下
import pandas as pd import argparse from workalendar.asia import China # 节假日计算包 def date_to_week(start_time, end_time): # 把时间列标准化时间格式 df = pd.DataFrame() df['date'] = pd.date_range(start=start_time, end=end_time) df['dayofweek'] = df['date'].dt.dayofweek + 1 # 星期为 1-7 df['date'] = df['date'].map(lambda x: x.strftime('%Y%m%d')) return df def cal_festival(year): cal = China() lis = [] if type(year) != list: # eval函数就是实现list、dict、tuple与str之间的转化 year = eval(year) for ye in year: for x, v in cal.holidays(ye): lis.append([str(x).replace('-', ''), v]) lis.
目录
1、使用场景
2、实践操作
2.1、在Idea环境之中修改
2.2、最有效修改方式(直接修改windows凭据)
3、成果展现
4、总结
5、参考文章
1、使用场景 最近在使用腾讯的coding,搞个自己的演示demo,因为家事及各种原因;有一段时间未动代码了。结果在https://dev.tencent.com/ 重置了一下密码。最后打开idea更新代码无法拉取(pull)了。一看console,说是认证失败。于是需要修改以前的密码。
2、实践操作 2.1、在Idea环境之中修改 结果网上一堆文章说
可以在Idea环境之中file->settings->passwords 之中(验证不成功,好像说是需要 执行一次提交或更新,试验过不成功 )
2.2、最有效修改方式(直接修改windows凭据) 3、成果展现 更改过后就可以针对git进行pull和push啦。
4、总结 计算机这个东东,相关内容都得实践去体验一下;也许另外一种有效;但是目前没有试验成功。也说明了一个问题;有些成功经验不一定适合你;选择适合自己的路比较合适。
5、参考文章 修改idea中git账号和密码(试验成功) IDEA修改git账号及密码的方法(暂时未试验成功)
文章目录 Redis - 架构演变(主从、哨兵、集群)1.单节点模式2.主从架构2.1 主从搭建2.1.1 配置文件2.1.2 启动服务验证 2.2 主从如何实现数据同步的?2.2.1 SYNC2.2.2 PSYNC2.2.3 重同步流程 2.3 分布式系统高可用架构2.3.1 什么是高可用?2.3.2 高可用2.3.3 典型互联网系统分层架构 3.哨兵模式3.1 哨兵模式搭建3.2 哨兵模式三大工作任务3.3 哨兵模式工作模式3.4 SpringBoot整合哨兵模式 4.高可用集群4.1 集群搭建4.1.1 配置文件4.1.2 启动集群节点4.1.3 创建集群 4.2 集群特点4.2.1 集群数据分片4.2.2 集群主从复制模型4.2.3 集群一致性保证4.2.4 集群模拟故障转移 4.3 集群分片重哈希4.3.1 集群重新分片4.3.2 集群添加主节点4.3.3 集群添加从节点4.3.4 集群移除节点 4.4 SpringBoot整合集群 Redis - 架构演变(主从、哨兵、集群) 由于Redis是基于内存的高性能KV数据库,这些年随时Redis的快速发展,更多的技术开发者将Redis融入自己的实际项目中。为了应对各式各样的业务场景保证数据更加稳定安全,各种高可用架构以及优化方案不断改进,导致Redis的整个架构体系也有了一个演变过程。集群模式是近年来Redis架构不断改进中较好的高可用方案。我们这里会对Redis的整个演变过程中每一个环节都进行一个介绍。主要包括了单机单节点模式、主从架构(M/S主从读写分离)、哨兵模式高可用架构、redis集群高可用架构等方案。
1.单节点模式 最初Redis刚进入我们身边的时候,是因为传统关系型数据库在某些特定场景下处理起来并不是十分合适,所以最初单机单节点的模式就能够满足我们对业务场景的应对,这里我们不做过多介绍这种模式,其实就是我们部署单个节点的Redis仅仅支持使用即可,对高可用以及数据安全性要求并不高。
2.主从架构 随着我们Redis不断融入我们项目中各式各样业务场景,我们发现其实在大多数时候甚至超过90%的情况下,我们只Redis进行读操作,写操作只是为了支撑缓存数据内容,一次写操作之后伴随的是大量的读操作。所以Master-Slave主从架构出现了,我们通过部署额外的一些Redis服务让其与主服务器连接,主服务器会通过网络发送数据副本给从服务器进行准实时更新。我们在应用的过程中将写操作都集中在主服务器,而读操作集中在从服务器,这样就分散了主服务器的压力,使其性能更好并且更具备可用性,并且同时部署多台从服务器也能很大程度上解决读操作集中造成的性能瓶颈。
其实主从架构还有一个好处,那就是可以保证我们数据的安全性。我们知道Redis通过持久化的功能保证了服务器重启之后只会损失少量数据甚至不会损失数据的问题。由于持久化会将我们内存中的数据保存到磁盘上,重启之后会从磁盘上加载数据。但是由于数据仅会存储在一台服务器上,当这台服务器磁盘故障那么数据也会出现丢失。为了避免这种单点故障造成的数据丢失,所以通常会部署多个服务到不同服务器上,也就能够保证数据有多个备份,数据更加安全不易丢失。
2.1 主从搭建 我们之前讲过Redis环境的搭建Redis- Linux环境安装及使用,Redis发展迅速其实和它的强大息息相关,开发团队对这款产品的支持也是做得尽心尽责。随着整个发展趋势,Redis开发团队也对其进行了更多的功能支持。主从模式其实就是Redis现在本身就提供的,我们很简单几步就能够搭建出一个雏形并且投入使用。
2.1.1 配置文件 这里我们就以主从服务全部集中在一台服务器为例,我们模拟的是一主两从的一个架构,首先我们分别在Redis目录下建/6379、/6380、/6381三个目录,将redis.conf复制到三个文件目录下。
mkdir 6379 mkdir 6380 mkdir 6381 cp redis.conf ./6379 cp redis.conf ./6380 cp redis.
连接console进入设置
进入视图模式
system-view
设置交换机名称
system hostname
退出视图模式
quit
设置telnet登录
system-view
开启telnet
telnet server enable
进入VTY用户线类视图
line class vty
进入一个或多个vty用户线视图
line vty 1 50
设置登录用户的认证方式为密码登录
authentication-mode password
设置密码认证的密码明文密码“gjit123”
set authentication password simple gjit.123
配置从当前用户线登录设备的用户角色
user-role gjsy
[sw2] telnet server enable //开启telnet服务
[sw2]interface Vlan-interface 1
[sw2-Vlan-interface1]ip address 192.168.1.2 24 //配置管理IP地址
[sw2]user-interface vty 0 4 //进入虚拟接口
[sw2-line-vty0-4]authentication-mode scheme //设置认证方式
[sw2-line-vty0-4]quit
[sw2]local-user telnet //添加本地用户telnet
New local user added.
[sw2-luser-manage-telnet]password simple 123 //设置密码
[sw2-luser-manage-telnet]service-type telnet //设置用户用途
Redhat7.5 (纯净OS,未安装任何tools)
一、rpm 安装 MySQL下载地址: https://dev.mysql.com/downloads/mysql/8.0.html
[root@localhost tools]# mysql -V
mysql Ver 15.1 Distrib 5.5.56-MariaDB, for Linux (x86_64) using readline 5.1
[root@localhost tools]# rpm -qa|grep mysql
akonadi-mysql-1.9.2-4.el7.x86_64
qt-mysql-4.8.7-2.el7.x86_64
[root@localhost tools]# rpm -e akonadi-mysql
[root@localhost tools]# rpm -e qt-mysql
[root@localhost tools]# rpm -qa|grep mysql
[root@localhost tools]# mysql -V
mysql Ver 15.1 Distrib 5.5.56-MariaDB, for Linux (x86_64) using readline 5.1
[root@localhost tools]# whereis mysql
mysql: /usr/bin/mysql /usr/lib64/mysql /usr/share/mysql /usr/share/man/man1/mysql.1.gz
[root@localhost tools]# rm -rf mysql: /usr/bin/mysql /usr/lib64/mysql /usr/share/mysql /usr/share/man/man1/mysql.
参照:
iOS企业版证书到期 https://www.jianshu.com/p/44b0dc46ef37
如果不能十分确定每一个打出来的ipa的有效期(过期时间),而又需要关注它具体什么时候需要强制用户update,最好是在要发行的ipa生成之后,查看其中的provisioning profile。具体方法:
具体方法:
1,解压ipa:右键->打开压缩包; 2,进入解压后生成的Payload目录; 3,右键app->显示包内容 4,找到文件:embedded.mobileprovision 5,用查看文本文件的工具打开这个文件,并转换编码为UTF-8。 补充一点,如果在控制台,直接: # unzip xxx.ipa 得到Payload目录,然后 # cd Payload , 继续 # cd xxx.app,就可以看见包里的文件了,最后 # vi embedded.mobileprovision 就可以直接打开provision文件,不用再转换编码了 当然,更加方面的是在Finder里使用文件的预览功能啦,直接点embedded.mobileprovision ,预览里就能看到内容啦 转载于:https://www.cnblogs.com/kaerxifa/p/11157138.html
线性基:对一组数建立线性基得到:一组数a1,a2、、、an,其中ax:存最高位的1在第x位的元素值。
线性基作用:线性基的子集的抑或和的 值域与原数抑或和的值域相同。
性质1:线性基的任意子集的抑或和都不为0
构造线性基: 对原数组的每一个数p,从高位到低位扫描,找到第一位为1的,若该位上的线性基ai不存在,则ai=p,否则p=p^ai,继续扫描下一位。
像如果原数是2,3,则插入线性基中的是1,2 ll b[63], nb[63], tot=0,flag=false; //b为线性基 nb用来求第K小异或值,基线性基中数 tot为nb元素个数,flag为true表示线性基外有数 void insert(ll x) { //插入 for(int i = 62; i >= 0; i--) { if(x & (1ll << i)) { if(!b[i]) { b[i] = x; return; } x ^= b[i]; } } flag = true; } 查询xor最大、小值: ll Max(ll x) { //求最大值 ll res = x; for(int i = 62; i >= 0; i--) res = max(res, res ^ b[i]); return res; } ll Min(ll x) { //求最小值 ll res = x; for(int i = 0; i <= 62; i++) if(b[i]) res ^= b[i]; return res; } 验证一个数x能否被xor出 bool fin(ll x) { //验证存在性 if(x == 0 && b[0]) return 1; for(int i = 62; i >= 1; i--) { int j = i - 1; if(x & (1 << j)) { x ^= b[i]; if(!
在开发python webservice测试接口时遇到的问题
安装 suds 时提示 ModuleNotFoundError: No module named 'client' ,没有模块叫 client 的
需要先安装 client ,然后再安装 suds pip install client
pip install suds
在我们开发的工程中,有时候会报
[Err] 1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ------
这种异常 不用多想,肯定是我们的sql语句出现问题,下面我只说我经常犯的一种错误。当然还有很多种错误,我们遇到再说。
这时候 我们不难发现 错误的原因是我们这里多了一个 ,号
有时候也会出现这种错误 [Err] 1054 - Unknown column ‘----------’ in 'field list’
这时候是我们的字段写错了 我们会发现数据库中并没有这个字段 而是我们的字段写错了
下面为大家写上两个同级sql
select a.Attribute_Id as Attribute_Id, a.Attribute_Name as Attribute_Name, a.Attribute_Alias as Attribute_Alias, a.Attribute_Unit as Attribute_Unit, a.DeviceType_Id as DeviceType_Id, a.SortCode as SortCode, a.
转载自:https://segmentfault.com/a/1190000008293902?utm_source=tag-newest
博主:Rdou Typing
来源:segmentfault
什么是回调函数
我们先来看看百度百科是如何定义回调函数的:
回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。
这段话比较长,也比较绕口。下面我通过一幅图来说明什么是回调:
假设我们要使用一个排序函数来对数组进行排序,那么在主程序(Main program)中,我们先通过库,选择一个库排序函数(Library function)。但排序算法有很多,有冒泡排序,选择排序,快速排序,归并排序。同时,我们也可能需要对特殊的对象进行排序,比如特定的结构体等。库函数会根据我们的需要选择一种排序算法,然后调用实现该算法的函数来完成排序工作。这个被调用的排序函数就是回调函数(Callback function)。
结合这幅图和上面对回调函数的解释,我们可以发现,要实现回调函数,最关键的一点就是要将函数的指针传递给一个函数(上图中是库函数),然后这个函数就可以通过这个指针来调用回调函数了。注意,回调函数并不是C语言特有的,几乎任何语言都有回调函数。在C语言中,我们通过使用函数指针来实现回调函数。那函数指针是什么?不着急,下面我们就先来看看什么是函数指针。
什么是函数指针
函数指针也是一种指针,只是它指向的不是整型,字符型而是函数。在C中,每个函数在编译后都是存储在内存中,并且每个函数都有一个入口地址,根据这个地址,我们便可以访问并使用这个函数。函数指针就是通过指向这个函数的入口,从而调用这个函数。
函数指针的使用
函数指针的定义
函数指针虽然也是指针,但它的定义方式却和其他指针看上去很不一样,我们来看看它是如何定义的:
/* 方法1 */ void (*p_func)(int, int, float) = NULL; /* 方法2 */ typedef void (*tp_func)(int, int, float); tp_func p_func = NULL; 这两种方式都是定义了一个指向返回值为 void 类型,参数为 (int, int, float) 的函数指针。第二种方法是为了让函数指针更容易理解,尤其是在复杂的环境下;而对于一般的函数指针,直接用第一种方法就行了。
如果之前没见过函数指针,可能会觉得函数指针的定义比较怪,为什么不是 void ()(int, int, float) *p_func 而是 void (*p_func)(int, int, float) 这种形式?这个问题我也不知道,也没必要纠结,花点时间理解下它与普通指针的区别,实在不行就先记住它的形式。
函数指针的赋值
在定义完函数指针后,我们就需要给它赋值了我们有两种方式对函数指针进行赋值:
void (*p_func)(int, int, float) = NULL; p_func = &func1; p_func = func2; 上面两种方法都是合法的,对于第二种方法,编译器会隐式地将 func_2 由 void ()(int, int, float) 类型转换成 void (*)(int, int, float) 类型,因此,这两种方法都行。想要了解更详细的说明,可以看看下面这个stackoverflow的链接。
JAVA eclipse 左边的导航栏是这样的,打开后工作起来会方便很多。
那么是如何打开的呢:
点击 Window,出现很多选项,鼠标放在 show view 那个地方,找到 package explorer 点击就会出现入上图一样的~
另外,如果还想要的更多的话,你可以尝试project explorer ,就在package explorer的下面。
Golang浮点数比较和运算会出现误差,我们来看看下面的例子:
package main import "fmt" func main(){ var a float64=1.5 var b float64=1.3 var result float64=a-b if result==0.2 { fmt.Println("相等") }else{ fmt.Println("不相等") } fmt.Printf("%.20f\n ",result) //浮点数运算后,转换成int64位 var c float64 = 78.6 fmt.Println(int64(c *100)) } 执行结果是:
很明显,结果不是我们想要的, 运算的误差导致程序不按照我们的逻辑走,所以可以的话,尽量不要比较浮点数,
浮点数的运算和比较,可以使用第三方扩展包来实现:
go get github.com/shopspring/decimal 安装后,我们来看如何解决上面的问题:
package main import ( "fmt" "github.com/shopspring/decimal" "reflect" ) func main() { num1:=decimal.NewFromFloat(1.5) num2:=decimal.NewFromFloat(1.3) num3:=decimal.NewFromFloat(0.2) result:=num1.Sub(num2) //num1 - num2 fmt.Println(result,reflect.TypeOf(result)) //比较是否相等 if result.Cmp(num3)==0 { fmt.Println("相等!") }else{ fmt.Println("不相等!") } num4:=decimal.
逻辑&和&& 逻辑&和逻辑&&(短路与)的主要区别: package aa; public class Test1 { public static void main(String[] args) { String str=null; if(str!=null&str.equals("")){ //str=null,表示不存在str这个字符串,str.equals("")表示str与一个空串等价 System.out.println(0); }else{ System.out.println("输出了,表示程序不会有异常"); } } } 当用单&时,表示在判断if表达式时,&两边的表达式都会执行。
package aa; public class Test1 { public static void main(String[] args) { String str=null; if(str!=null&&!str.equals("")){ //str=null,表示不存在str这个字符串,str.equals("")表示str与一个空串等价 System.out.println(0); }else{ System.out.println("输出了,表示程序不会有异常"); } } } 当用双&时,程序在判断&&前面的表达式时,str!=null是false,由于是与运算,就肯定是false,就不判断后面的表达式了。
逻辑|和逻辑||(短路或) 其实这个和前面的基本上没什么区别,就是当写一个 | 时,程序在执行的时候会把 | 两边的表达式都进行判断,而当写两个 || 时,此时,如果第一个表达式判断为真,那么接下来的表达式就不会进行判断了,就是真的。
逻辑&&和逻辑||的优先级问题 逻辑&&和逻辑||是有优先级的,逻辑&&的优先级要高于逻辑||的优先级。
public class Test2 { public static void main(String[] args) { boolean a = true; boolean b = false; boolean c = true; System.
生成内存快照dump.rdb 安装 redis-rdb-tools 使用redis-rdb-tools生成内存报告 将报告导入mysql,进行分析,或者使用excel、脚本统计 1、生成dump.rdb,使用redis客户端,执行bgsave命令,生成dump.rdb快照
2、安装redis-rdb-tools
源码安装
git clone https://github.com/sripathikrishnan/redis-rdb-tools
cd redis-rdb-tools
python setup.py install
或者
pip install rdbtools
3、使用redis-rdb-tools生成内存报告
rdb -c memory d:\redis\dump.rdb > redis_memory_report.csv
4、使用python脚本统计
列头
database,type,key,size_in_bytes,encoding,num_elements,len_largest_element,expiry
取size_in_bytes
脚本如下:
脚本统计以数组内容开头的key
#!/usr/bin/python
# -*- coding:UTF-8 -*-
import csv;
def analysis_json_report(key_list):
report_all = csv.reader(open('E:\\redis\\redis_memory_report.csv'))
result_list = {}
result_list["other"] = (long) (0)
for report in report_all:
if report.__len__() <= 4:
continue
isexists = False for key in key_list:
if report[2].
前言:
在写这篇文章之前,大量的查找FPGA的开发流程资料。感觉网络上的开发流程书写都是复制粘贴,没有任何的实质性的实践流程,都是泛泛而谈,有思想却很空洞。现在我总结一下使用quartus软件进行FPGA开发流程的介绍,另外本人是高校在读生,只从在读生的角度看待问题。
我认为的开发流程:
首先是确定完成的思路框架,其中重点包括需要达到什么功能,选择什么芯片及工具,划分为几个模块进行。在这个工程开始时,首先应该对这方面有一定的材料积累。不能什么东西都从头开始写,这样工作量太大。想好了怎么划分模块之后就可以开始正式的开发。
然后就是设计输入,这里主要是使用HDL进行编程,在上面完成整体的框架构思之后,这个时候模块化思想就开始起作用了。首先是开始第一个子模块的编程,完成所有子模块之后在开始等顶层模块的编写。这时候的子模块编写的先后顺序应该是根据数据的传输过程的先后顺序来的,这样能够更好的确定思路。
在设计输入的同时,应该做好的的功能仿真。其实硬件逻辑编写与仿真不应该有先后顺序,应该是同时进行的,这样才能一边修改一边验证。只是说在具体说话上应该先完成程序的编写才有仿真的对象。
然后就是使用quartus软件进行编译,包括综合,映射、布局布线等等,这里软件本身就能自动完成,只需要看其最终的结果是否符合要求。然后继续修改,在仿真,在综合。直到符合要求。
然后进行时序约束,再综合。然后进行时序仿真。这个时候还是使用modelsim进行时序仿真,这个时候比之前的功能仿真还要添加更过的时序方面的文件,包括网表文件,延时文件以及元件库等。之后进行仿真,这个过程是比较复杂的(一般简单的开发是不太用的着的)。最后观察波形是否符合要求。
然后就是板级仿真,本实验室没有板级仿真仪器,所以没有仿真过。这个一般是高速电路需要的。没有具体了解过,所以这个就不提,一般是用不着的。
最后是板级在线调试。这个时候需要开发板进行实际的验证以及在线调试,使用的工具是quartus自带的signaltap 工具来实现的
**总结来说就是,
**想好怎么做,
设计输入加功能仿真(当然也可综合,这里是实现逻辑功能,达到目的,quartus加modelsim),
综合(包括编译,映射,布局布线等quartus),
时序约束加时序仿真(这里考虑时序的问题quartus加modelsim),
板级仿真(不做),
在线调试(signaltap)
最后说一句,编程与仿真是一个反复的过程,不是顺序的一二一。需要先编程,再仿真(发现问题),再编程,再仿真。。。。。知道达到目的。
最后总结一下网络上的FPGA开发流程
1、设计思路
这就是想好怎么做
2、设计输入
就是使用工具进行编程
3、综合编译
使用软件综合
4、功能仿真
使用Modelsim仿真,验证功能是否达到。
5、布局布线
quartus软件能自动布局布线,这里还需要时序约束。
6、时序仿真
时序约束仿真
7、板级仿真
没有工具,没有使用到这一步
8、芯片在线调试
signaltap在线调试
文章目录 概览1.计算机视觉简介:2.图像分类 一、LeNet-51.模型架构2.模型简介3.模型特点 二、AlexNet1.网络架构2.模型介绍3.模型特点 三、VGGNet1.模型架构2.模型简介3.模型特点 四、GoogLeNet1. 网络架构2、模型解析3、模型特点 五、ResNet(深度残差网络)1、模型解析2、模型特点 六、DenseNet1.模型架构2.模型特点 在上一篇详细讲解了卷积神经网络的基本模块之后,对卷积的神经网络应该有了一个清晰的认识。后边的卷积神经网络,都是基于这些模块不断优化、改进,但是并未真正跳出这个框架。那么,这一章内容就讲一下用于图像分类的卷积神经网络的发展历程。
概览 1.计算机视觉简介: 计算机视觉是当前最热门的研究之一,是一门多学科交叉的研究,涵盖计算机科学(图形学、算法、理论研究等)、数学(信息检索、机器学习)、工程(机器人、NLP等)、生物学(神经系统科学)和心理学(认知科学)。计算机视觉中主要有五大内容,分别为图像分类、目标检测、目标跟踪、语义分割以及物体分割。针对每项内容,都有自己的基本概念及相应的适用于自己的一套典型方法。
今天要讲的是基于图像分类的经典的卷积神经网络的发展历程。
2.图像分类 官方定义为:给定一组图像集,其中每张图像都被标记了对应的类别。之后为一组新的测试图像集预测其标签类别,并测量预测准确性。
完整的图像分类步骤一般形式如下:
1.首先,输入一组训练图像数据集;
2.然后,使用该训练集训练一个分类器,该分类器能够学习每个类别的特征;
3.最后,使用测试集来评估分类器的性能,即将预测出的结果与真实类别标记进行比较;
大多数图像分类算法都是在ImageNet数据集上训练的,该数据集由120万张的图像组成,涵盖1000个类别,该数据集也可以称作改变人工智能和世界的数据集。ImagNet 数据集让人们意识到,构建优良数据集的工作是 AI 研究的核心,数据和算法一样至关重要。为此,世界组织也举办了针对该数据集的挑战赛——ImageNet挑战赛。
而本文所讲解的适用于图像分类的经典的卷积神经网络,也是历年来的ImageNet的冠军。
本文将从经典的LeNet-5网络讲起,到了2012年,AlexNet一举夺得首届ImageNet的冠军。之后,有很多基于CNN的算法也在ImageNet上取得了特别好的成绩,比如ZFNet(2013)、GoogleNet(2014)、VGGNet(2014)、ResNet(2015)以及DenseNet(2016)等。
一、LeNet-5 这个是n多年前就有的一个CNN的经典结构,卷积神经网络的开山之作,主要是用于手写字体的识别,也是刚入门需要学习熟悉的一个网络。网络虽然简单,但是麻雀虽小五脏俱全,卷积层、池化层、全链接层一直沿用至今
1.模型架构 层数很浅,并且kernel大小单一,C1、C3、C5三个卷积层使用的kernel大小全部都是5×5。C5的feature map大小为1×1是因为,S4的feature map大小为5×5而kernel大小与其相同,所以卷积的结果大小是 1×1。
S2和S4两个池化层使用的window大小均为2×2,这里的池化有两种。
F6是一个有84个神经元的全连接层。
2.模型简介 用下图所示的模型,更加直观:
第一层:输入层,图片大小为 32×32×1,其中 1 表示为黑白图像,这些手写字体包含0~9数字,也就是相当于10个类别的图片。第二层:C1,卷积层,filter 大小 5×5,filter 深度(个数)为 6,padding 为 0, 卷积步长 s=1,输出矩阵大小为 28×28×6,其中 6 表示 filter 的个数。所以共有28×28×6个神经元(32-5+1=28),参数数量为156( 5 ∗ 5 ∗ 6 + 6 = 156 5*5*6+6=156 5∗5∗6+6=156,6为偏置项参数),每一个单元与输入层的25个单元连接。第三层:S2,池化下采样层,平均池化,filter 大小 2×2(即 f=2),步长 s=2,no padding,输出矩阵大小为 14×14×6。第四层::C3,卷积层,filter 大小 5×5,filter 个数为 16,padding 为 0, 卷积步长 s=1,输出矩阵大小为 10×10×16,其中 16 表示 filter 的个数。第五层:S4,池化下采样层,average pooling,filter 大小 2×2(即 f=2),步长 s=2,no padding,输出矩阵大小为 5×5×16。注意,在该层结束,需要将 5×5×16 的矩阵flatten 成一个 400 维的向量。第六层:C5,卷积层,有120个特征图,每个特征图有一个神经元,卷积核大小为5×5,步长 s=1,no padding。第七层:F6,全连接层,有84个神经元,与C5层构成全连接关系,使用sigmoid激活函数。第八层:输出层,十分类任务,有10个神经元。 3.
搞过CI/CD的同学一定吃过不少苦头,或者说遇到不少坑,但是对自动化的执着住挡不了前进的步伐,如果你缺少了运维这一块知识,那么你的流水线总是不那么完美,本文记录的是自己躺过的坑,希望对你有所帮助。
一、相关环境和版本 服务器:windows2008【历史遗留服务器,建议升级到2012以上,2016支持Windows的容器化技术】源代码管理:git.net core版本:net core 2.2 这里最应该注意的是操作系统版本和Jenkins的版本,不同的版本,特别是操作系统操作的shell可能千差万别,你会在网上看到各种命令,所以选择好自己的环境。
安装Jenkins比较简单,这里略过……
二、Jenkins相关配置 Step1.创建一个自由风格的Jenkins项目,这一步比较简单略过(pipeline项目是一项更加挑战,也许运维高手更需要熟悉,这里跳过)
Step2.在 配置git 源码路径的时候报错: 解决方法:
1.安装git client插件,并重启jenkins
2.确保安装jenkins的服务器同时也安装了git,并在jenkins上配置git的路径,如下图:
3.成功配置git源码路径
Step3.构建时候报错:
从中可以判断,我的邮件还没有配置,所以发送报错……
Step4.进行 邮件的配置 Jenkins内置邮箱功能: 1.首先配置Jenkins Location
所在路径:Manage Jenkins=》Configure System=>Jenkins Location
2.配置E-mail Notification如下图所示
3.测试发送成功
Email插件:Email Extension 插件安装后如下图所示:
step5.构建的坑[该坑最耗时间,最后发现却是最简单] 1.请指定项目或解决方案文件。当前工作目录中未包含项目或解决方案文件。
排查:切换到服务器cmd下进行restore后发现,原来是nuget作怪,因为服务器无法找到部署在本地服务器的nuget包
2.发布Nuget包到官网 试着解决:试着把nuget包发布到官网。具体如何发布请跳转
新版本的发布需要增加License.txt,否则无法通过,配置如下:其中Licese是从github上拷贝过来的。如果你发布后发现代码没有生效,请确认你是否在release下进行编译,并且build过?
解决方法:如下图所示,极其简单,折腾的半天,晕!你甚至dotnet restore和dotnet build都不用写,因为dotnet publish本身包含restore和build
Step6. 卡住在using GIT_ASKPASS to set credentials的坑 Unable to delete 'D:\Program Files (x86)\Jenkins\workspace\Stone.Base.API'. Tried 3 times (of a maximum of 3) waiting 0.1 秒 between attempts.
总结记录一下,C++实现各种排序算法,加深理解。参考《大话数据结构》
排序 冒泡排序选择排序插入排序希尔排序堆排序归并排序快速排序 冒泡排序 冒泡排序(Bubble Sort)是一种交换排序,它的基本思想是:两两比较相邻记录的关键字,如果反序则交换,直达没有反序的记录位置。
void BubbleSort(vector<int> &nums) { for (int i = 0; i<nums.size() - 1; i++) { for (int j = nums.size() -1; j>i; j--) { if (nums[j]<nums[j - 1]) { int t = nums[j]; nums[j] = nums[j - 1]; nums[j - 1] = t; } } } } 冒泡排序优化
当一轮比较中,没有任何数据交换,这就说明此序列已经有序,不需要再继续后面的循环判断工作了。为了实现这个想法,改进一下代码,增加标记变量flag.
void BubbleSort1(vector<int> &nums) { for (int i = 0, flag = 1; i < nums.size() - 1 && flag == 1; i++) { flag = 0; for (int j = nums.
1.Idea导出自己设置好的主题 1.1.File–>Export Setting … 2.导入主题 导入文件即可,这个时候,导入成功,需要重启一下idea;
我的自己设置的绿豆色(护眼)的主题背景链接地址如下,如果大家喜欢的话,可以参考:
在实际项目中,有时候一个项目有好几块电路板。为了便于管理项目。这样我们就可以在一个项目下可以做到多个原理图和多个PCB 一一去对应。
1、首先在一个项目下建好多个原理图(.SchDoc)和PCB(.PcbDoc)文件。
2、然后在Porjects中选择对应原理图,右键选择“显示差异”。
3、再选择勾选“高级模式”,然后在右边选择原理图1更新到哪个PCB文件中。最后点击“确定”。
4、在出现Defferences between Schematic Document窗口中,右击Updata All in这一栏。接着,点击“创建工程变更列表”。
5、接下来点击“执行更改”,在点击“更改生效”,看看有没有报错,如有报错应导出报错报表。
6、同理,如需将其他原理图(.SchDoc)导入一个PCB(.PcbDoc)文件中,则需执行好几次。大家可以自己动手去试试。
PS:如果直接是整个Project中的原理图更新到一个PCB文件中,直接选择菜单栏中的Design–>Updata Schematics in xxxxx.PrjPCB即可。
本人博客仅仅代表我个人见解。如有错误请各位大牛指出,谢谢!!
连接一个最基本的二阶RLC震荡电阻
元器件的位置如图:
RLC和电流表电压表在Simscape-Foundation Library-Electrical下可以找到,如图:
单纯利用这些基本电路元件连接运行会出错,还需要接地,并加入Solver Configuration(解决方案模块)
电压表连接示波器需要PS-Simulink Converter(物理模型信号->仿真模型信号转换)
他们两个的位置如图:
电路连接如图:
运行结果(感觉不太正常,比如仿真定步长就发散,不知道哪儿错了)
String类 String是系统完成的一个类,String 类代表字符串 构造方法 1. public String() :空构造 2. public String(byte[] bytes) 3. public String(byte[] bytes,int offset,int length) 4. public String(char[] value) 5. public String(char[] value,int offset,int count) 6. public String(String original) 方法 1. 判断功能 boolean equals() boolean equalsIgnoreCase() boolean isEmpty() boolean startsWith() boolean endsWith() boolean contains() String s1 = "Hello"; String s2 = "HELLO"; String s3 = "Hello"; String s4 = "world"; System.out.println(s1.equals(s2)); //false System.out.println(s1.equals(s3)); //true System.out.println(s1.equals(s4)); //false System.
展望5G对web前端发展的影响 5G浪潮的来临让全世界都为之关注,
各个国家都在争夺它的主导权。
它对软件行业影响是巨大的,深远的,
甚至会导致行业的重新洗牌,和很多技术工种的兴衰。
所以我们这些开发者不得不去关注它。
那么5G对web前端开发又有什么样的影响呢?
网上各大论坛都有关于5G的帖子,据说理论下载速度达到 1.25G每秒。
一个前端项目的本地文件往往不会超过100M,
里面最大的文件就是多媒体,图片视频,更多的动态文件会通过图片服务器传输。
我们正常使用现在的4G网络打开一个APP主页往往需要2-3秒的时间,
首次打开页面需要等待加载,如果有长图或者视频之类的展示耗时会更长,
还有一些后端的数据库查询,如果有大量的数据获取时间会更长。
且不说后端,我们今天只讨论前端,
所以我们到今天为止,还在讨论怎么做到更好的性能优化,
一个项目开始要做技术选型,要做缓存机制,项目文件要深度压缩等等…
项目的优化手段似乎到了瓶颈,
无论我们怎么去优化,如果有大量的文件和多媒体资源的加载,
仍然不可避免的会导致卡顿,不管是现在的互联网巨头BAT,
不管他们有多优秀的开发人员,和多先进的硬件支持,
他们做的软件也不能实现秒开。
5G即将到来,这些问题都将被迎刃而解,
如果还是保持传统的页面风格,以5G的速度,这些都将是浮云,
不管打开任何软件都不需要等待。
5G做任何事都是0延迟,
有了这个优势,才会推动物联网,人工智能的真正兴起,
将来会有更多的人机合一,
自动驾驶将不再只是一个概念,
大型工厂的产业链人工将会被机器人替代,
到时候可能会有超级物流公司,
不管是运输还是配货,都是机器人来代替,
快递小哥和外卖小哥也有可能失业由机器人代替(这条是我瞎猜的!)
说回前端,人类是永不知足的,
一旦实现单页面秒开,传统意义的单页面布局就会消失,
会有更多更炫酷的动画被加入进来,还有3D模型,
比如今天的二手车软件的3D看车,租房软件的3D看房,
AR增强现实、VR虚拟现实 技术都将会被加入。
到时候会有更多的AR游戏领域的崛起,
远程的虚拟现实呈现服务,眼前的例子比如APP口红试色号等等,
将来还会有更夸张的意想不到的服务体验。
作为web前端开发来说,这就带来一个问题
互联网公司,外包公司,IT产品服务类公司。
每个公司关心的东西是不一样的。
互联网公司一般是技术主导,由于充足资金的保障,
他们会用最前沿的技术,新的事物他们都不会放过,
页面会更炫酷,功能会儿更丰富,互动效果会更好。
但页面呈现的东西多了,靠一个人是不行的,将来的开发更多是嵌入,
需要动画有专门开发动画的团队,
需要VR,3D模型,canvas组件等等需要第三方的支持,
这些都是重应用是不能够一个人来完成的,
所以开发业务的程序员将来更多是架构的维护和模块的嵌入,
还会有专门开发动画的,专门开发模型的等等…
所有的东西都是封装好的抛出接口等着你去调用。
这些东西多了,会出现更多的浏览器兼容问题,到时候会有一场浏览器的技术变革。
外包公司和IT服务公司就不一样了,
他们往往是给客户开发产品,
客户买这些产品的时候讨价还价,服务商还要保证利润,
所以…重点来了
从上到下,他们毫不关心性能问题,
即使有对技术敬畏的程序员进了这种公司也是力不从心,
只要产品能将就用,不会动不动就闪退就行,反正客户也不懂技术。
总而言之,不管代码质量多差,只要成功交付就是万事大吉。
这种公司做项目往往都是时间紧任务重,人员少,不要提什么体验效果,
996都干不完常规业务哪来的优化?
有了5G之后,这些表面问题也会瞬间迎刃而解,小小的卡顿也没了影子。
程序员也不会为性能付出更多的时间成本。
这种公司会招更便宜的程序员,
这道题是数据结构、算法与应用c++的书籍的练习题25题,首先我先列出详细题目
题目 编写一个C++递归函数,输出n个元素的所有子集。例如,三元素集{a,b,c}的子集是{}(空集),{a},{b},{c},{a,b},{a,c},{b,c},{a,b,c}。这些子集用0/1组成的代码序列来表示分别是000,100,010,001,110,101,011,111(0表示相应的元素不在子集中,1表示相应的元素在子集中)。因此你的程序输出长度为n的0/1序列即可。
分析 题目已经告诉大概的方向了,用0/1代码序列表达,递归,从集合里0个元素到n个元素输出。
代码 #include <iostream> using namespace std; template<class T> void f(T* a, int* mark, int n, int i) {//a为集合元素,mark为标记数组,n为起点,i为元素个数 if (n == i) { cout << "{ "; for (int k = 0; k < i; k++) { if (mark[k] == 1) cout << a[k]; } cout << "}" << endl; return; } mark[n] = 0; f(a, mark, n + 1, i); mark[n] = 1; f(a, mark, n + 1, i); } int main() { int mark[3]; char a[3] = { 'a','b','c' }; f(a, mark, 0, 3); } 输出
题意: 有n(n<=200) 个恰好需要一天完成的任务,要求用最少的时间完成所有任务。任务可以并行完成,但必须满足一些约束,约束分为有向约束和无向约束两种,其中A->B表示A必须在B之前完成,A-B表示A和B不能在同一天晚上。输入保证约束图是将一颗树的一些边定向之后得到的。 分析: 参考紫书P297-298,写的很详细。算是一道比较复杂的树形dp了。 LRJ代码: #include<bits/stdc++.h> using namespace std; const int maxn = 200 + 5; const int INF = 1000000000; struct Edge { int u, v, d; // d=1 means u->v, d=2 means v->u, d=0 means u-v Edge(int u=0, int v=0, int d=0):u(u),v(v),d(d){} }; vector<Edge> edges[maxn]; int n, root, maxlen, f[maxn], g[maxn], have_father[maxn]; // maximal length of a DIRECTED path starting from u int dfs(int u) { int ans = 0; for(int i = 0; i < edges[u].
这周进行了课程实践,题目是老掉牙的图书管理系统,因为一些原因,原本打算做前端的我做了全栈,虽然最后交的不是我写的,就当练手了。
首先上部分运行截图:
前端部分:采用bootstrap与layui结合,导航栏,输入框,按钮用的layui,表格用的bootstrap,大部分样式在原有框架的基础上进行了重构。
后端部分:管理员对用户和图书的管理,用户对图书的各种操作均是对数据库的更改,为方便对数据库进行操作,将各种操作封装到dao层中。Jsp用于接收信息,在 servlet中对jsp传来的数据进行逻辑判断与操作。
Java部分 servlet包,dao层,数据类,数据库连接模板如下
Jsp界面部分如下 其中的static用来放一些css ,img ,js,字体资源等
一些注意事项:
一.在写的过程中会遇到各种需要共享数据的情况。 Jsp与Servlet之间的传值有两种,一种是Jsp传值给Sevlet,另一种是Servlet传值给Jsp;使用request、response对象完成传值,具体实现如下:
1.JSP传值给Servlet
JSP传值给Servlet有几种形式:Form表单传值,url传值,其他方式传值
a、form表单传值:
JSP页面有:<input type="text" name="user_name" />在servlet中接收数据需要这样写
String user_name=request.getParameter("user_name"); b、url传值
我没用过,了解之后再来更新。
c、java代码传值
java片段代码,servlet只能接到 session.setAttribute("testSession","Hello session")的内容,而接不到 request的内容。在 servlet里用 request.getSession().getAttribute("testSession")获取 session内容。
2.Servlet传值给Jsp
具体实现如下:
java代码:
String a= "abccdefg "; request.setAttribute( "ValueA ",a); request.getRequestDispatcher( "网址/jsp页面 ").forward(request,response); jsp页面:
<% String s =(String)request.getAttribute( "ValueA "); %> jsp页面就可以取出Servlet的值。
3.servlet与servlet之间共享数据
我是用的servletContext
servlet1中这么写
this.getServletContext().setAttribute("user",user); servlet2中这么接收
User user=(User)this.getServletContext().getAttribute("user"); user是一个Javabean 类对象,在接收的时候要进行强制类型转换
二、跳转问题 1…从servlet到jsp的方法
从 servlet转到 jsp不外乎两种方法,重定向 和 url转发
出于安全考虑,浏览器不能在地址栏中访问WEB-INF下的内容,否则会出现404无法找到指定页面
在springmvc中是这样处理的
首先在controller中
package com.taotao.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; @Controller public class PageController { @RequestMapping("/") //视图解析器,返回值用于拼接路径 public String showIndex() { return "index"; } } 然后在springmvc.xml文件中有
<!-- 视图解析器 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/jsp/" /> <property name="suffix" value=".jsp" /> </bean> 这样就能将路径完整拼接,当浏览器访问requestmapping的时候,就会执行下面的视图解析器,并与springmvc结合拼接路径,所以最后的访问路径为/WEB-INF/jsp/index.jsp
CPU主频就是CPU运算时的工作频率,在单核时间它是决定CPU性能的重要指标,一般以MHz和GHz位单位,如Phenom II X4 965主频是3.4GHz。说到CPU主频,就不得不提外频和倍频的概念,它们的关系是:主频=外频×倍频。
虽然提高频率能有效提高CPU性能,但受限于制作工艺等物理因素,早在2004年,提高频率便遇到了瓶颈,于是Intel/AMD只能另辟途径来提升CPU性能,双核、多核CPU应运而生。
其实增加核心数目就是为了增加线程数,因为操作系统是通过线程来执行任务的,一般情况下它们是1:1对应关系,也就是说四核CPU一般拥有四个线程。但Intel引入超线程技术后,使核心数与线程数形成1:2的关系,如四核Core i7支持八线程(或叫作八个逻辑核心),大幅提升了其多任务、多线程性能。
CPU的虚拟化技术(Virtualization Technolegy,简称VT)就是单CPU模拟多CPU,并允许一个平台同时运行多个操作系统,而应用程序都可以在互相独立的空间内运行而互不影响,从而显著提高工作效率。在Windows 7中安装XP模式就是一个很好的例子,当需要使用XP时直接调用,不需要重启切换系统,这点对于程序员来说是非常有用的。
虽然虚拟化可以通过软件实现,但是CPU硬件支持的话,执行效率会大大提升,也可以支持64位操作系统,其中Windows 7的XP模式则是必须要CPU的虚拟技术支持。目前Intel/AMD绝大部分CPU都支持虚拟化技术,但对于普通用户而言,虚拟化技术没有实质作用。如果要用到虚拟化技术,需要在BIOS开启技术。
随着CPU的性能越来越强大,也带来了更高的功耗,为减少CPU闲置使得能量浪费,Intel和AMD均不约而同地为CPU添加节能技术。Intel方面,采用节能技术叫“Enhance Intel SpeesStep Technology”,简称EIST,虽然经过多次增强优化,但名字始终没变。但名字始终没变。而AMD的节能技术则是“Cool ‘n’Quiet”,现在已经发展到3.0版。简单来说,它们均是在CPU空闲时自动降低CPU的主频,从而降低CPU功耗与发热量,达到节能目的。
无论是Intel还是AMD的节能技术,均需要在BIOS开启才有效,找到类似EIST(Intel CPU)或(AMD CPU)的选项进行行开启即可
cpu个数是指物理上安装了几个cpu,一般的个人电脑是安装了1个cpu
cpu内核数是指物理上,一个cpu芯片上集成了几个内核单元,现代cpu都是多核的。
cpu线程数是指逻辑上处理单元,这个技术是Intel的超线程技术,它让操作系统识别到有多个处理单元。
如下图所示:插槽指cpu个数,内核数量是4个,线程数是4个。我的I5 4590 cpu不支持超线程技术。所以,一个内核就是一个线程。
命令行查看cpu信息:
wmic cpu get name cpu get numberofcores cpu get numberoflogicalprocessors ------查看系统信息 systeminfo 相关分析:
问题描述 A机器通过ssh-copy-id root@IP(B)添加了链接到B机器的ssh秘钥。但是某天,B机器的密码修改或者机器重装,此时,在A机器上再次ssh IP(B)会报类似如下错误:
Please contact your system administrator. Add correct host key in /root/.ssh/known_hosts to get rid of this message. Offending ECDSA key in /root/.ssh/known_hosts:4 remove with: ssh-keygen -f "/root/.ssh/known_hosts" -R kube-001 ECDSA host key for kube-001 has changed and you have requested strict checking. Host key verification failed. 此时无法ssh到B,如果重新使用以下命令:
ssh-copy-id root@IP(B) 会报错如下:
ssh-copy-id root@IP(B) /usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed /usr/bin/ssh-copy-id: WARNING: All keys were skipped because they already exist on the remote system.
一、串口通信原理 串口通信(Serial Communications)的概念非常简单,串口按位(bit)发送和接收字节。
串口用于ASCII码字符的传输。通信使用3根线完成,分别是地线(GND)、发送(TX)、接收(RX)。由于串口通信是异步的,端口能够在一根线上发送数据同时在另一根线上接收数据。其他线用于握手,但不是必须的。串口通信最重要的参数是波特率、数据位、停止位和奇偶校验。对于两个进行通信的端口,这些参数必须和通讯协议保持一致;
二、串口通信实现 1.项目配置
SerialPort 包名必须一致
启动串口
public static SerialConnection getInstance() { return instance; } public void register(Handler mHander) { this.mHandler = mHander; } /** * 启动串口接受信息 */ public void startSerial(int rate) { lodg("[startSerial]......rate===>" + rate); try { //三个参数 1.哪个口 2.波特率 3.校验方式 mSerialPort = new SerialPort(new File("/dev/ttyS1"), rate, 'o'); } catch (Exception e) { lodg("[startSerial]......e===>" + e.toString()); } if (mSerialPort != null) { mInputStream = mSerialPort.getInputStream(); mOutputStream = mSerialPort.
1、两数求和 print('Please input two numbers:') num1 = float(input()) num2 = float(input()) print('the sum of the two numbers is : ', num1+num2) 输入数字可能是整数也可能是小数,此时统一转换成float来计算
posted on 2018-01-27 15:39 Hello _ world 阅读( ...) 评论( ...) 编辑 收藏 转载于:https://www.cnblogs.com/zwb8848happy/p/8366239.html
6、sorted()对分别按名字和成绩排序 假设我们用一组tuple表示学生名字和成绩:
L = [('Bob', 75), ('Adam', 92), ('Bart', 66), ('Lisa', 88)] 请用sorted()对上述列表分别按名字和成绩排序:
# -*- coding: utf-8 -*- L = [('Bob', 75), ('Adam', 92), ('Bart', 66), ('Lisa', 88)] #先按名字排序: def by_name(t): return t[0].lower() #t是tuple,t[0]是姓名(字符串)!!! L2 = sorted(L, key=by_name) print(L2) #再按成绩从高到低排序: def by_score(t): return t[1] L2 = sorted(L, key=by_score) print(L2) tuple类型本身没有lower()方法,t[0]是tuple的第一个元素,t[1]是tuple的第二个元素,以此类推!!!
posted on 2018-02-07 19:26 Hello _ world 阅读( ...) 评论( ...) 编辑 收藏 转载于:https://www.cnblogs.com/zwb8848happy/p/8428136.html
18、【转载】python中inspect模块 转载自:https://blog.csdn.net/weixin_35955795/article/details/53053762
前言 我在学习到实战Day5 - python教程 - 廖雪峰的官方网站时,遇到了inspect模块,之前对这个inspect模块一无所知啊,所以本着打破砂锅问到底的精神,决定对inspect模块做一些探究。
根据度娘搜到的,inspect模块主要提供了四种用处:
(1). 对是否是模块,框架,函数等进行类型检查。
(2). 获取源码
(3). 获取类或函数的参数的信息
(4). 解析堆栈
我在这次课程中,只用到了第三种用处,即获取类或函数的参数的信息,下面我来探究一下。
探究 结合我正在学习的课程,我自己也对inspect做了一些探究。根据在课程中用到的一些函数及方法,我做了一个python脚本。
# test import inspect def fn(a, b=0, *c, d, e=1, f='hello', **g): pass sig = inspect.signature(fn) print("inspect.signature(fn)的值是:%s" % sig) #(a, b=0, *c, d, e=1, f='hello', **g) print("inspect.signature(fn)的类型:%s" % (type(sig))) #<class 'inspect.Signature'> print("\n") params = sig.parameters print("signature.paramerters属性的值是:%s" % params) #OrderedDict([('a', <Parameter "a">), ('b', <Parameter "b=0">), ('c', <Parameter "*c">), ('d', <Parameter "
方法一:
eclipse打开当前文件所在文件夹的插件
Run-->External Tools-->External Tools Configurations...
new 一个 program
location 里面填 :C:/WINDOWS/explorer.exe
Arguments 里面填: ${container_loc} 方法二:
安装:
EasyExplorer 从 http://sourceforge.net/projects/easystruts 下载后就是一个jar压缩文件。最新版就是1.04,已经很久没有更新了,但是对最新的eclipse 3.*平台还是支持的。但是,该插件的安装方式好像通过eclipse 的自动更新管理不起作用。 他最简单的工作方式就是:直接将该jar文件放置在eclipse的 plugin 目录下 ,然后重启eclipse平台就可以在右键中看到East Explorer菜单项,就可以打开资源所在的目录了。
但是,缺点就是新下载的插件PlugIn放在了原始的Eclipse的PlugIn目录下,一大堆,乱死你:( 利用EasyExplorer插件可以在Eclipse用Explorer打开资源文件所在的文件夹。其它配置是在这里Windows => Preferences => Easy Explore => Target => explorer.exe {0} 可以看到在Windows平台上是用explorer.exe {0}来打开的,{0}是用来传递参数的。 技巧:我习惯以资源管理器的方式来打开文件夹,方便进行拖动操作,即左边带文件树,那么在这里你可以设置成为explorer.exe /e,{0} 即可,这样用EasyExplore打开文件夹时就是以这种方式来打开的,而且左边的文件树里,直接定位到文件夹上面,很是方便。 Explorer.exe的参数如下:大家可以根据自己的喜好进行设定:
命令格式Explorer [/n][/e][[,/root],[path]][[,/select],[path filename]] 参数说明 /n表示以“我的电脑”方式打开一个新的窗口,通常打开的是Windows安装分区的根目录。
/e表示以“资源管理器”方式打开一个新的窗口,通常打开的也是Windows安装分区的根目录。
/root,[path]表示打开指定的文件夹,/root表示只显示指定文件夹下面的文件(夹),不显示其它磁盘分区和文件夹;[path]表示指定的路径。
如果不加/root参数,而只用[path]参数,则可以显示其它磁盘分区和文件夹中的内容。另外,[path]还可以指定网络共享文件夹。
/select,[path filename]表示打开指定的文件夹并且选中指定的文件,[path filename]表示指定的路径和文件名。
如果不加/select参数,则系统会用相应的关联程序打开该文件。如果[path filename]不跟文件名就会打开该文件夹的上级目录并选中该文件夹。
通过对以上explorer.exe的参数分析,我们可能会有个希望就是实现既显示左边的文件树,又同时右边也定位到的选定的文件或文件夹上面。
那应当是设置为:explorer.exe /e,/select,{0} ,不过这件EasyExplore帮你打开的只是定位在文件夹上面,而不是相应的文件上面。
转载于:https://www.cnblogs.com/liuyy/p/3321399.html
第一章 音及音高
音是由于物体的振动而产生的
音有高低、强弱、长短、音色等四种性质。
音的高低是由于物体在一定时间内的振动次数(频率)而决定的。振动次数多,音则高;振动次数少,音则低。
音的长短是由于音的延续时间的不同而决定的。音的延续时间长,音则长;音的延续时间短,音则短。
音的强弱是由于振幅(音的振动范围的幅度)的大小而决定的。振幅大,音则强;振幅小,音则弱。
音色则由于发音体的性质、形状及其泛音的多少等而不同。
由于音的振动状态的规则与不规则,音被分为乐音与噪音两类。音乐中所使用的主要是乐音,但噪音也是音乐表现中不可缺少的组成部分。
第二节 乐音体系音列音级
在音乐中使用的、有固定音高的音的总和,叫做乐音体系。
乐音体系中的音,按照上行或下行次序排列起来,叫做音列。
乐音体系中的各音叫做音级。音级有基本音级和变化音级。
乐音体系中,七个具有独立名称的音级叫做基本音级。
基本音级的名称是用字母和唱名两种方式来标记的。
字母体系:C D E F G A B
唱名体系:1 2 3 4 5 6 7
钢琴上白键所发出的音是与基本音级相符合的。钢琴上五十二个白键循环重复地使用七个基本音级名称。
两个相邻的具有同样名称的音叫做八度。
例如:
简单一点讲,就是你唱1 2 3 4 5 6 7 1
第一个1就是最后一个1的低八度
最后一个1就是第一个1的高八度
升高或降低基本音级而得来的音,叫做变化音级。将基本音级升高半音用“升”或“#”来标明。降低半音用“降”或“b”来标明。升高全音用“重升”或“×”来标明。降低全音用“重降”或“bb”来标明。
如:升C或#C 降C或bC
第三节 音的分组
为了区分音名相同而音高不同的各音,我们将音列分成许多个“组”。
在音列中央的一组叫做小字一组。它的音级标记用小写字母并在右上方加数字1来表示。
比小字一组高的组顺次定名为:小字二组、小字三组、小字四组、小字五组。
小字二组的标记用小写字母并在右上方加数字2来表示。
比小字一组低的组,依次定名为小字组、大字组、大字一组及大字二组。
小字组各音的标记用不带数字的小写字母来表示。
大字组用不带数字的大写字母来标记。
大字一组用大写字母并在右下方加数字1来标明。
大字二组用大写字母并在右下方加数字2来标明。
第四节 音域及音区
总的音域是指音列的总范围,即从它的最低音(C2——c5)间的距离而言。
个别的人声或乐器的音域是指在整个音域中所能够达到的那一部分,如钢琴的音域是A2——c5。
音区是音域中的一部分,有高音区、低音区、中音区三种。
在整个音域中,小字组、小字一组和小字二组属于中音区。小字三组、小字四组和小字五组属高音区。大字组、大字一组和大字二组属低音区。
各音区的特性音色在音乐表现中,有着重大的意义。高音区一般具有清脆、嘹亮、尖锐的特性;而低音区则往往给人以浑厚、笨重之感。
第二章 音律
乐音体系中各音的绝对准确高度及其相互关系叫做音律。
将八度分成十二个均等的部分——半音——的音律叫做十二平均律。
半音是十二平均律组织中最小的音高距离。两音间的距离等于两个半音的叫做全音。八度内包括十二个半音,也就是六个全音。
原文地址:http://blog.csdn.net/wind19/article/details/6156339
从一个简单的使用TCP例子开始socket编程,其基本步骤如下:
server client
+++++++ ++++++++
创建socket 创建socket
+++++++ ++++++++
| |
| |
| |
+++++++ ++++++++
地址赋值( 地址赋值(
自己的地址) 服务器地址)
+++++++ ++++++++
| |
| |
| |
++++++++ |
用bind绑定 |
socket和地址 |
++++++++ |
| |
| |
| |
+++++++ |
listen |
+++++++ |
| ++++++++++
| <------------------------------ connect 服务器 | ++++++++++
+++++++ |
accept |
+++++++ |
| |
| +++++++++
| recv 和send
mount命令中除了常见的-t 也就是选择挂在文件系统的类型。还有一个重要的参数-o
这个参数里面可以携带很多参数,比如设定挂在的用户名,密码等等,但是这些参数怎么接受呢,也就是具体会传递到哪里呢?
首先注册文件系统的时候,有个数据结构file_system_type
如cfs的文件系统定义如下:
static struct file_system_type cfs_fs_type = {
.owner = THIS_MODULE,
.name = "cfs",
.get_sb = cfs_get_sb,
.kill_sb = kill_litter_super,
.fs_flags = 0,
};
这个参数是要传递给文件系统注册函数 register_filesystem(&cfs_file_system)的。
当我们调用mount的时候,一定会转到cfs_get_sb这个函数。
该函数调用cfs_fill_super(struct super_block *sb, void *data, int silent)
在这个函数中可以接收shell下传入的参数。
比如,在shell下有如下调用:
mount -t cfs -o mds=192.168.0.81 -o port=2123 -o user=$1 -o pwd=root -o semethod=$SEMETHOD seclient /mnt/cfs 那么在cfs_fill_super里面就有以下的命令解析:
while (ptr&&strlen(ptr)) {
if ((ptr2=strchr(ptr, ','))) {
strncpy(opt, ptr, ptr2-ptr);
opt[ptr2-ptr] = '\0';
ptr = ptr2+1;