论文阅读:Instance-aware semantic segmentation via Multi-task Network Cascades
论文信息:CVPR2016, PASCAL VOC in VGG 63.5% mAP. COCO2015 in resnet101 won first prize
整体框架:对于传统的多任务方法,都是在共享特征的基础上,每个任务同时进行各不干扰,互相独立。这篇文章是在共享特征的基础上,上一个任务依赖于下一个任务,如此形成级联式的多任务结构(Multi-task Network Cascade,MNC)。 三个任务:(1)Differentiating instances;(2)Estimating masks;(3)Categorizing objects;
使用VGG16的第13层卷积层特征作为共享特征。每个阶段包含一个loss,下一阶段的loss依赖于前一阶段loss,故三个阶段的loss都不是独立的。
任务一:differentiating instance-->regressing box-level instances ,该阶段的主要任务找出所有可能的物体框,即使用Faster RCNN中的RPN网络,使用NMS得到 top-ranked 300个box;
这一阶段的主要实现就是在共享特征的基础上附加一个3*3的卷积层用于降维以及1*1的卷积用于目标框定位和目标分类。因此在这一阶段的loss,作者直接使用的是RPN的loss,即:
任务二:estimating masks-->regressing mask-level instances,该阶段的主要任务是以共享特征和上一阶段的得到的bounding box作为输入,输出基于box的pixel-level 的mask,不过此时的mask是class-agnostic,即无法对mask进行类别区分。
这一阶段的主要实现是在task1 输出的不同大小的box上使用ROI warping Pooling产生固定大小的特征:14*14大小的feature map,在此基础上为每个box附加两个fc层:fc1(256)+fc2(m*m,28*28),这里的28*28是预先设定的mask的分辨率。因此这一阶段的task不仅是依赖于mask还依赖于box,所以这一阶段的loss,即:
任务三:categorizing objects-->categorizing instances,该阶段的主要任务是以共享特征,task1的box,task2的mask作为输入,输出每个instance的categories scores。
这一阶段的主要实现是,一方面,在ROI warping pooling 的基础上连接两个fc层:fc1(4096)+fc2(4096);另一方面对task2得到的mask 也连接两个fc层:fc1(4096)+fc2(4096);然后再对这两个通道进行concat,最后得到每个instance的得分。因此这一阶段的计算量比较大,也是导致整个MNC模型巨大的原因。这一阶段的loss,如下:
End-to-end training
整个MNC网络结构的loss function如下:
MNC主要的技术挑战就是对上面的loss function 如何可以应用链式法则进行反向传播,实现end-to-end training。在fast R-CNN论文中使用的RoI pooling 的预测框是经过预训练的,是固定的,它的反向传播只考虑F(Θ) ,但我们现在必须同时考虑Bi(Θ),而在这里得到的预测框确实在不断变化。但是,实际上task2中的框是由task1给出的,那么task2的loss就不只是依赖mask,还依赖框。这导致了无法对这部分以end to end的方式来训练,因为无法同时对这两部分求导。
概括 一句话概括,就是根据显示屏幕宽度的大小,自动的选用对应的类的样式。
关键字 1、col是column简写:列;
2、xs是maxsmall简写:超小, sm是small简写:小, md是medium简写:中等, lg是large简写:大;
3、-* 表示占列数,即占每行row分12列栅格系统比;
4、.col-xs-* 超小屏幕如手机 (<768px)时使用;
.col-sm-* 小屏幕如平板 (768px ≤ 宽度 <992px)时使用;
.col-md-* 中等屏幕如普通显示器 (992px ≤ 宽度 < 1200px)时使用;
.col-lg-* 大屏幕如大显示器 (≥1200px)时使用。
解释 1、栅格系统都会自动的把每行row分为12列, col-xs-*、col-sm-* 、col-md-*和.col-lg-* 后面跟的参数表示在当前的屏幕中的占列数。例如 <div class="col-xs-6 col-md-3"></div> 这个div在屏幕中占的位置是: .col-xs-6 在超小屏幕中占6列,也就是屏幕的一半(12/6列=2个div), .col-md-3 在中等屏幕中占3列也就是1/4(12/3列=4个div)。
2、反推,如果我们要在移动端并排显示3个div(12/3个=每个占4 列 ),则col-xs-4;在PC端上显示6个div(12/6个=每个占2列 ) ,则 col-md-2。
实例 例一:单独使用
<div class="container"> <div class="row"> <div class="col-md-4">col-md-4</div> <div class="col-md-4">col-md-4</div> <div class="col-md-4">col-md-4</div> <!-- 说明:每row行共12列,分个3div,每个div平占4列,即3个*4列=12列 --> </div> <div class="row"> <div class="col-md-4">col-md-4</div> <div class="
在启动类上使用@EnableFeignClients注解来开启Feign的功能。EnableFeignClients有个basePackages属性,配置上{"包名"}启动后测试,成功了。
前段时间就开始学习Tensorflow了。虽然大致看了两本书,也没怎么上手实践过,但是学习期间就觉得Tensorflow有点乱,这两天试着写了个网络,主要目的就是给自己弄个初级的模板出来,以后有什么新的想法或者任务,就在这个模板的基础上添添改改就行,不必要每次都重新写很多东西。
为了以后的方便我目前主要想实现以下三个功能: 1. 使用tf.slim来构建网络的结构,因为看书上还有很多老一点的代码都还是一步步地做的,定义一个卷积层至少需要四五行代码,用slim的话一行就行,并且我看到一些新的网络的实现都是使用的slim。 2. 加上tensorboard 的功能,能够可视化的话,对理解网络有很大帮助,并且也很方便训练(不得不说tensorboard可是让我吃了个大亏) 3. 加上保存的功能,也就是持久化,持久化的部分我看书的时候就没怎么看懂,后来么,,,就不管原理了,能用就行
最后经过一番调试,算是完成了上述几个“简单”的目标,但是还是在参考别人代码的情况下完成的,,,我只想说Tensorflow确实对新手不太友好,也可能是我学习路径不太对。
tf.slim模块 slim模块是对tensorflow底层代码的一个高级封装,可以大大简化构造网络的代码量,比如实现一个卷积层,传统的tensorflow层可能需要
input = ... with tf.name_scope('conv1_1') as scope: kernel = tf.Variable(tf.truncated_normal([3, 3, 64, 128], dtype=tf.float32, stddev=1e-1), name='weights') conv = tf.nn.conv2d(input, kernel, [1, 1, 1, 1], padding='SAME') biases = tf.Variable(tf.constant(0.0, shape=[128], dtype=tf.float32), trainable=True, name='biases') bias = tf.nn.bias_add(conv, biases) conv1 = tf.nn.relu(bias, name=scope) 但是用slim的话
input = ... net = slim.conv2d(input, 128, [3, 3], scope='conv1_1') conv2d的变量作用分别是 input:代表输入的张量 128:代表生成的张量的depth,其实就是在该层使用多少卷积核,也就是能够生成多少feature map scope: 用于命名
我本机是ubuntu16.0.4 远程主机是centos6 ,最近服务器主机重装系统,需要重新配置java环境,不太会linux命令,只能慢慢来,记录一下
1、本地准备好需要的工具包 安装包下载地址jdk8http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.htmltomcathttps://archive.apache.org/dist/tomcat/tomcat-7/v7.0.30/src/mysql(参考菜鸟教程)http://www.runoob.com/mysql/mysql-install.html 2、把文件上传到服务器 创建文件夹
mkdir [文件夹名称] mkdir /home/scpfile 上传文件,即把本地文件远程复制到服务器文件夹
scp -P(大写) [指定端口] [本地文件路径] root@[ip地址]:[复制到服务器文件地址] scp -P 123 /home/download/jdk-8u161-linux-i586.tar.gz root@123.123.123.123:/home/scpfile 3、ssh连接 ssh -p [端口号] root@[ip地址] ssh -p 123 root@123.123.123.123 如果之前连接的主机重装系统了,ssh会报错 Add correct host key in /home/thinkjoy/.ssh/known_hosts to get rid of this message.
把.ssh文件夹下的known_hosts文件删除重新连接即可
4、安装jdk 进入刚刚上传文件的文件夹
cd [文件夹路径] cd /home/scpfile 查看文件
ls 解压jdk包jdk-8u161-linux-i586.tar.gz
tar -zxvf [压缩文件名称] tar -zxvf jdk-8u161-linux-i586.tar.gz 修改环境变量之前先备份/etc/profile 复制profile文件到备份文件夹
mkdir /home/bak cp [原文件路径] [复制到的路径] cp /etc/profile /home/bak 修改环境变量
crontab定时执行表达式写法与crontab在线测试工具推荐
熟悉Unix和Linux的朋友都知道Crontab表达式,通过crontab指令可以周期性调用或执行某个程序。
但是大家写完crontab表达式后,心里总是担心表达式写的不对,可以又没法去验证。比如你的周期定的比较长,一天一周一月或者更久,那么等到那个时候通过去看程序是否运行来判断表达式的正确性是不实际的。这里为大家推荐两个可以在线测试crontab表达式的工具:
在线crontab表达式执行时间计算 在线Crontab表达式执行时间验证
这里你只需要输入你要执行的crontab表达式、开始时间和执行次数,就可以帮你计算出未来n次的时间。如下图所示:
crontab 表格式语法格式如下:
0 2 * * 6 * * * * * * - - - - - - | | | | | | | | | | | + year [optional] | | | | +----- day of week (0 - 7) (Sunday=0 or 7) | | | +---------- month (1 - 12) | | +--------------- day of month (1 - 31) | +-------------------- hour (0 - 23) +------------------------- min (0 - 59) Crontab介绍 | Introduce Crontab crontab命令常见于Unix和类Unix的操作系统之中,用于设置周期性被执行的指令。该命令从标准输入设备读取指令,并将其存放于“crontab”文件中,以供之后读取和执行。crontab储存的指令被守护进程激活,crond常常在后台运行,每一分钟检查是否有预定的作业需要执行。crontab文件的每一行均遵守特定的格式,由空格或tab分隔为数个领域,每个领域可以放置单一或多个数值。时程表的格式:f1 f2 f3 f4 f5 program,其中 f1 是表示分钟,f2 表示小时,f3 表示一个月份中的第几日,f4 表示月份,f5 表示一个星期中的第几天。program 表示要执行的程式。 Crontab使用 | Crontab Using cron是一个linux下的定时执行工具,可以在无需人工干预的情况下运行作业。由于Cron是Linux的内置服务,但它不自动起来,可以用以下的方法启动、关闭这个服务。cron服务提供crontab命令来设定cron服务的,以下是这个命令的一些参数与说明: crontab -u //设定某个用户的cron服务,一般root用户在执行这个命令的时候需要此参数;crontab -l //列出某个用户cron服务的详细内容;crontab -r //删除某个用户的cron服务;crontab -e //编辑某个用户的cron服务。 Crontab例子 | Crontab Example 30 21 * * * /usr/local/etc/rc.
概念区分 分支(branch):是指向某个commit对象的引用跟踪分支(tracking branch):本地的分支,比如master分支,用户可写远程跟踪分支(remote tracking branch):远程的分支origin/master, 用户只读 通过git clone操作来了解仓库同步的过程 克隆前【远程仓库】的状态:远程仓库master分支指向c2的commit 将数据克隆到本地之后:
首先会生成一个origin/master的引用指向最新的提交c2,这个orgin/master 就是远程跟踪分支,用户只读。 然后根据origin/master 生成一个master分支指向同一个提交c2, 如下: 通过git push操作来了解仓库同步的过程 项目克隆之后,修改本地文件并提交,此时master分支的head处于c3的位置【git push前的一个状态】 通过git push 命令会对远程和本地都作出修改
修改远程的master指向至c3,如下图所示: 修改本地的origin/master分支指向c3,如下图所示 关于checkout 的操作 通过 git checkout master 会把分支切换到master分支上而当 git checkout origin/master 时,这个操作会处于‘detached Head’ 状态,在这种状态下不会修改origin/master上的数据,可以修改并提交做一些实验性的操作,但是切换回master分支后,再次从master切换回origin/master时,之前的改变不会同步,因为origin/master 是用户只读的 通过git fetch origin获取数据 在fetch之前,远程处于c4,本地处于c3 fetch之后,本地的origin/master分支指向了最新的c4 对比修改的地方:git diff master origin/master
通过git merge origin/master合并本地分支 备注:可以merge的前提是在无冲突的状态下,有冲突要手动解决merge之后,master分支指向c4, 如下图: 通过git pull获取同步最新数据 备注:前提是没有冲突,有冲突手动解决git pull 之前的状态:远程在c4, 本地在c3 git pull 之后的状态:本地仓库更新了origin/master,将其指向c4; 然后更新master分支, 将其指向c4 git pull = git fetch + git mergegit pull –rebase = git fetch + git rebase 更新版本建议的操作 git fetch + git mergegit fetch + git rebasegit pull –rebase
孪生素数 相差为2的两个素数称为孪生素数。例如,3与5,41与43等都是孪生素数。设计程序求出指定区间上的所有孪生素数对。区间上限和下限由键盘获取。 程序运行示例如下: please input c,d(c>2): 10,200↙ (11,13) (17,19) (29,31) (41,43) (59,61) (71,73) (101,103) (107,109) (137,139) (149,151) (179,181) (191,193) (197,199) total=13 输入格式: 区间上限和下限的输入格式: "%ld,%ld" 输出格式: 区间上限和下限的输入提示信息:"please input c,d(c>2):\n" 孪生素数的输出格式:"(%ld,%ld)\n" 所有孪生素数对的总数输出格式: "total=%d\n"
#include<stdio.h>#include<math.h>int isPrime(int num){ int i; for(i=2; i<=sqrt(num); i++) { if(num%i==0) { return 0; } } return 1;}int main(){ int i,temp,a,b,total=0; temp=2; printf("please input c,d(c>2):\n"); scanf("%ld,%ld",&a,&b); for(i=a; i<=b; i++) { if(isPrime(i)) { if(i-temp==2) { printf("(%ld,%ld)\n",temp,i); total++; } temp=i; } } printf("
2019独角兽企业重金招聘Python工程师标准>>> #依赖:
redispostgresqlpython sentry是python开发的一个应用,使用python uWSG框架运行,所有安装完sentry要记得在nginx的代理上禁用掉/admin路径,不然uwsg的后台管理入口就泄漏了 具体的安装资料地址为:
https://docs.sentry.io/server/installation/ #redis的启动 su - redis redis-server /etc/redis.conf #postgresql因为是项目迁移,用的9.6版本,所以需要yum自己安装一下
systemctl restart postgresql-9.6 #使用的材料地址 https://download.postgresql.org/pub/repos/yum/9.6/redhat/rhel-7.2-x86_64/repodata/repomd.xml https://www.postgresql.org/download/linux/redhat/ db准备好之后要先初始化
postgresql-setup initdb /usr/pgsql-9.6/bin下也会有一个专用的命令 /usr/pgsql-9.6/bin/initdb -D /data/www/db 可以这样去指定一个目录来进行初始化 redis和pgsql都要要各自对用的用户来进行操作,pgsql的默认用户是postgres
初始化完成之后要注意两个文件: postgresql.conf #相当于mysql的my.cnf配置文件 pg_hba.conf #用户远程访问控制配置文件,这个文件弄不好,pgsql无法远程连接
pgsql的用户创建
CREATE USER dbuser WITH PASSWORD 'password'; #创建用户dbuser并设置密码 CREATE DATABASE sentry OWNER dbuser; #创建库sentry并指定拥有者给dbuser GRANT ALL PRIVILEGES ON DATABASE sentry TO dbuser; #授权dbuser可以对sentry库进行任何操作 修改密码的语句 alter user dbuser with password 'password'; pgsql登录好坑爹的,要先切到postgers用户,然后再运行pgsql(我的不知道为什么叫psql) 送一个pgsql的数据导入和导出操作语句
导出DB数据到file文件 pg_dump -h $host -p $port sentry -W > file 从file导入数据到DB psql -U dbuser -h $yourhost -p $port -W -d sentry -f file #redis和DB做好之后下来安装sentry 最直接的办法是用pip进行安装 可以指定版本
Vue-history模式的SpringBoot配置以及对错误状态的处理 使用history模式 vue-router 默认是hash模式的,但是连中文官网都承认hash 模式的url很丑,的确像我这种小渣渣都能一眼看出这是个单页面无疑了。比如这样http://xxx.com/#/home/index 官网提出了一种能让url能像http://xxx.com/home/index这样显示的办法,就是利用HTML5的history属性
vue-router配置 配置方法很简单: history模式:在实例Router的地方加入mode: 'history' 根路由:加入base: 'base'(这么做是因为服务器只需要对base相关的url进行转发操作就可以了,同时也能对404画面进行处理)
那么我们刚才的路由正确访问方法应当时这样的:http://xxx.com/base/home/index
但是这个模式的缺点就是需要后台对这种连接做一些处理,否则get不到对应的资源只会返回404。
后台配置 我用SpringBoot框架随便定义了一个controller:
@RequestMapping(value={ "/base", "/base/**" }) public String fowardRouter(){ return "forward://index.html"; } (@RequestMapping的value值可以是多个,以上是对根路由相关的url进行相应处理) 如果访问根路由下不存在的路由:http://xxx.com/base/notExists,会调用fowardRouter(),将会出现空白页; 如果连根路由都没写:http://xxx.com/randomstr/notExists,那么会由服务器返回404
以下是对vue-router单页面和springboot前后分离框架的异常状态处理
错误状态处理 在上面这种配置的情况下,找不到页面有可能有两种情况,一种是找不到的路由,一种就是服务器返回的404,找不到路由的情况我们还是得靠前台处理,但服务器其返回的所有异常状态,SpringBoot都会返回默认的error页面
针对不存在的路由的处理 使用vue-router是有可能发生用户随意修改路由地址,造成访问了不存在的路由出现空白页面的情况。结合官网对HTML5 history模式给出的警告,我们可以在配置路由时增加一个路由地址,覆盖所有的路由情况。
routes: [ { path: '*', component: ERROR404 }, ...其他路由... ] ERROR404是我们应该要自定义的组件,渲染不存在的路由的画面
由服务器返回的异常状态的处理 上面说过SpringBoot会根据错误状态码返回指定的页面,网上也有很多资源关于如何在发生错误时指定到自定义模板上。不过我想处理的方式是所有的错误页面全都由单页面组件来完成,这样可能就需要不管是不是ajax请求我们都不能用服务器渲染的方式,只能用返回JSON数据的方式来统一处理。 下面是SpringBoot服务器对此状况的处理:
拦截错误状态请求,主动抛异常 首先第一步重写了SpringBoot对错误页面的默认处理,我们需要实现ErrorController:
@Controller public class MainErrorController implements ErrorController { private static final String ERROR_PATH = "/error"; @Override public String getErrorPath() { return ERROR_PATH; } @RequestMapping(ERROR_PATH) public Object handleError(HttpServletRequest request) { Integer statusCode = (Integer) request.
一个前序遍历序列和一个中序遍历序列可以确定一颗唯一的二叉树。
根据前序遍历的特点, 知前序序列(PreSequence)的首个元素(PreSequence[0])为二叉树的根(root), 然后在中序序列(InSequence)中查找此根(root), 根据中序遍历特点, 知在查找到的根(root) 前边的序列为根的左子树的中序遍历序列, 后边的序列为根的右子树的中序遍历序列。 设在中序遍历序列(InSequence)根前边有left个元素. 则在前序序列(PreSequence)中, 紧跟着根(root)的left个元素序列(即PreSequence[1...left]) 为根的左子树的前序遍历序列, 在后边的为根的右子树的前序遍历序列.而构造左子树问题其实跟构造整个二叉树问题一样,只是此时前序序列为PreSequence[1...left]), 中序序列为InSequence[0...left-1], 分别为原序列的子串, 构造右子树同样, 显然可以用递归方法解决。
二叉树的定义于下:
[cpp] view plain copy //二叉链表表示二叉树 typedef struct BiNode { char data;//节点数据 struct BiNode * lchild;//左孩子 struct BiNode * rchild;//右孩子 }BiNode, * BiTree; 由前序遍历序列和中序遍历序列确定一颗唯一的二叉树的算法余下:
[cpp] view plain copy //由前序序列和中序序列建立二叉树的过程 void CreateBiTree(BiTree & t,string presequence,string insequence)//t为要建立的二叉树,presequence和insequence分别为前序和中序序列 { if(presequence.length()==0) { t=NULL; return ; } char rootNode=presequence[0];//根 int index=insequence.find(rootNode);//根在中序序列中的位置 string lchild_insequence=insequence.substr(0,index);//左孩子的中序序列 string rchild_insequence=insequence.substr(index+1);//右孩子的中序序列 int lchild_length=lchild_insequence.length();//左孩子的长度 int rchild_length=rchild_insequence.
方法一
# 有一个字符串text = "aAsmr3idd4bgs7Dlsf9eAF" # 请将text字符串中的数字取出,并输出成一个新的字符串 import re text = "aAsmr3idd4bgs7Dlsf9eAF" text = re.sub("\D", "", 'aAsmr3idd4bgs7Dlsf9eAF') print(text) 方法二
# 有一个字符串text = "aAsmr3idd4bgs7Dlsf9eAF" # 请将text字符串中的数字取出,并输出成一个新的字符串 import re text = "aAsmr3idd4bgs7Dlsf9eAF" text = ''.join(re.findall("\d+",text)) print(text) 转载于:https://www.cnblogs.com/kehaimin/p/8619603.html
一、STL是什么 STL是一个标准模板库,是一个高效的C++程序库qsort():C标准库的快速排序 二、string char str[12] = "Hello"; char *p = str; *p = 'h'; //可以赋值,因为创建了数组 ,在内存中又开辟了一块空间,然后把字符串赋值给该数组,是可以改变的量 char *ptr = "Hello"; *ptr = 'h'; //不能赋值。ptr指向内存中的一个临时常量。常量不能赋值 //更标准的用法 const char *cptr = "Hello"; string是一个字符串的类string.h和cstring都不是string类的头文件。都是定义的C风格字符串的一些操作方法,如strcpy()、strlen()等。只是string.h是c语言的头文件,cstring是C++对应的头文件,是为了和c语言进行兼容。 1.string类的实现 string类的底层是一个字符串指针,即char *m_data; 1)普通构造函数 P68 //构造函数见P68 传入的是一个char *类型的字符串; 如果传入是一个空字符串,那么string就也是一个空字符串"\0"; 如果str是非空,那么私有成员m_data就要预留length+1的长度,+1用来存放'\0'; //指针赋值只是把两个指针指向了同一个位置而已 //创建一个char *类型的变量,m_data需要首先分配内存,然后再拷贝 2)sting的析构函数 string::~string() { if(m_data){ //判断m_data是否为空 delete[] m_data; m_data = nullptr; //删除之后需要赋空指针 } } 3)拷贝构造函数 string::string(const string &s) // 传入的参数是一个常引用。一是保证传入参数不变,二是不进行拷贝,减少栈空间的消耗。(如果不使用引用将造成无限循环) { if(!s.m_data) //m_data的null判断 { m_data = nullptr; } else{ m_data = new char[strlen(s.
参考网址: http://blog.sina.com.cn/s/blog_79d599dc01012m7l.html
解决方法复制于此:
一、问题 std::sort()在排序的时候,如果对排序中的仿函数对相等的值返回true,会导致程序core掉。 二、解决办法 让比较函数对相等的值返回false
先看图理解:
类属性就相当与全局变量,实例对象共有的属性,实例对象的属性为实例对象自己私有。
类属性就是类对象(Tool)所拥有的属性,它被所有类对象的实例对象(实例方法)所共有,在内存中只存在一个副本,这个和C++中类的静态成员变量有点类似。对于公有的类属性,在类外可以通过类对象和实例对象访问
类属性 class People(object): name = 'Tom' #公有的类属性 __age = 12 #私有的类属性 p = People() print(p.name) #正确 print(People.name) #正确 print(p.__age) #错误,不能在类外通过实例对象访问私有的类属性 print(People.__age) #错误,不能在类外通过类对象访问私有的类属性 实例属性(对象属性) class People(object): address = '山东' #类属性 def __init__(self): self.name = 'xiaowang' #实例属性 self.age = 20 #实例属性 p = People() p.age =12 #实例属性 print(p.address) #正确 print(p.name) #正确 print(p.age) #正确 print(People.address) #正确 print(People.name) #错误 print(People.age) #错误 通过实例(对象)去修改类属性 class People(object): country = 'china' #类属性 print(People.country) p = People() print(p.
转载:https://blog.csdn.net/happen23/article/details/78763530
想做看图工具的,必然要支持jpg、png等常见格式,但tkinter是个纯粹的GUI库,不像GTK、QT那样大而全,所以只支持gif和ppm两种格式,局限很大,必须搭配图像处理库,才能实现基本的看图功能
###在python生态系统里,最常用的图像处理库是PIL
Python3下库的安装
这两个库在python3下跟python2有一定差异:
tkinter首字母变成小写
**PIL官方还不支持Python3,但有个fork叫Pillow,**可以替代官方并且接口保持不变,需要pip install Pillow安装
技术原理
那么怎么让PIL读取jpg文件生成的内存对象被tkinter处理呢?PIL的开发人员很贴心的提供了一个PhotoImage类,跟tkinter包里的同名类接口兼容,所以可以直接将PIL生成的PhotoImage对象赋给tkinter中能接收PhotoImage入参的所有控件(比如Label、Canvas等)
代码示例
#encoding=utf-8 import tkinter as tk from PIL import Image, ImageTk class App(tk.Frame): def __init__(self, master=None): super().__init__(master, width=400, height=300) self.pack() self.pilImage = Image.open("CSDN.png") self.tkImage = ImageTk.PhotoImage(image=self.pilImage) self.label = tk.Label(self, image=self.tkImage) self.label.pack() def processEvent(self, event): pass if __name__ == '__main__': root = tk.Tk() app = App(root) root.mainloop()
对于新产品而言:用户研究的主要目的是了解用户的需求点,帮助设计师选定产品设计方向;
对于已经发布的产品而言:用户研究的主要用于发现产品问题,帮助产品设计师实现产品优化体验
什么是用户体验?
产品如何与外界发生关系并发挥作用,也就是人们如何“接触”和“使用”产品
为什么用户体验如此重要?
用户体验就是生活。生活中处处涉及到你的体验,闹钟、卫生巾、公交、打卡机、红绿灯、手机、电脑、键盘、鼠标...每天都在和产品打交道,我们都在使用和体验产品。有的产品在使用过程中会出现糟糕的状况。
用户体验就是商机。和ROI关系密切,直接的就是销售量提高、网站用户粘性高,比如:色情网站的目的是盈利,重点是他抓住了人的心理,甚至生理上的需求
用户体验要素
1、战略层
产品目标以及目标用户(做什么,为谁而做?)经营者和用户分别想从产品得到什么
来自企业外部的用户需求是网站的目标--尤其是那些将要使用我们网站的用户。与用户需求相对应的,是我们自己对网站的期望目标,能够促进用户体验的确立和制定。
如何寻找产品战略:产品首先切入的必须是用户迫切需要的。比如陌陌的成功抓住了人们的心理,加上营销炒作获得了突破;另外陌陌改变了妓女拉客的方式,使得用户享受服务的时候风险降低了;陌陌想逐渐摆脱用户对产品约炮的概念,但是在功能上却越来越能促进约炮的成功率。比如微信的成功在于庞大的用户基数正好遇上了那时候即时语音刚开始在国内发展
2、范围层
功能及其内容需求结合(需要做哪些?)
需求的三个类别:人们讲述的、他们想要的;用户实际想要的;潜在需求
战略决定范围,功能承载产品价值,范围层是为了实现战略意图
3、结构层
交互设计以及信息架构(怎么做?)
在功能产品中,结构层将从范围转变成系统如何响应用户的请求。在信息产品方面,结构层则是信息空间元素中的内容元素分布
交互设计:作为软件界面设计,为用户设计结构化体验
信息架构:作为超文本网页,内容建设通过信息架构构建用户体验;产品关心的是理解用户、用户的工作方式和思考方式
4、框架层
界面设计、导航设计和内容(信息)设计(要做成什么样子?)
成功的界面设计是那些能让用户一眼看到“最重要的东西”的设计
导航设计的三个目标:第一,必须提供给用户一种在网站间跳转的方法;第二,必须传达出这些元素和它们包含的内容之间的关系;第三,必须传达出它的内容和用户当前浏览页面之间的关系
5、表现层
功能及内容的视觉呈现(做成了什么样子?)
内容、功能和美学汇集到一起产生一个最终设计,从而满足其他层面的目标
pip离线安装Python包
1.准备whl文件。
可以从网上下载,也可以在有互联网的机器上
pip install --download D:\test\xlwt xlwt 2.pip离线安装命令:
pip install --no-index --find-links=D:\test\xlwt xlwt
前言 模态框居中这个问题很常用,网上代码也很多,但是往往不是自己最想要的效果。
正文 首先设置宽高
#myModal{ left: 50%; top: 50%; transform: translate(-50%,-50%); } 这时候发现,宽度太小
设置宽度
#myModal{ left: 50%; top: 50%; transform: translate(-50%,-50%); min-width:80%;/*这个比例可以自己按需调节*/ } 浏览器高度较小的时候会发现上边被覆盖。不过不用担心,将上述写法完善一下就行了,完善后的写法如下:
#myModal{ left: 50%; top: 50%; transform: translate(-50%,-50%); min-width:80%;/*这个比例可以自己按需调节*/ overflow: visible; bottom: inherit; right: inherit; } 完美实现
一、基本概念 1、页和页框的区别 划重点::逻辑地址空间分为若干页;物理内存空间分为若干页框(也叫作块) 页 分页存储管理是将作业的逻辑地址划分为一系列同等大小的部分,称为页。 并为各页加以编号,每个作业的页的编号都是从0开始的。
页框 与之类似,把可用的物理内存也划分为同样大小的连续的部分,称为块或页框。同样为块也进行标号,从0#开始。 在为进程分配内存空间时,以页为单位,每个内存中的块存放一页用户作业。只要内存中有足够多的块,这些块可以相邻也可以不相邻,就可以存放整个作业了。
页面的大小对于内存利用和系统开销来说非常重要,页面太大,在作业的最后一页必然会剩余较大不能利用的空间–内碎片。页面太小,虽然可以减小内碎片的大小,但是一个作业的页太多,会使得作业页表太长而占用内存,同时系统频繁地进行页面转化,加重系统开销。 因此,页面的大小应该适中,通常为512B - 8KB,windows系统的页面大小为4KB。
2、地址结构 分页系统中的地址结构由两部分组成,页号和页内偏移量。 可以解释为一个二元组(p,w),其中p是页号,w是页面p中的偏移量或者相对于p页开始的位置。 下图(a) 中的地址长度为32位,其中0 - 9位为页内偏移量,每页的大小为2的10次方 = 1k;10 - 31位为页号,共计2的22次方 = 4M页。在图(b)中,地址长度同样为32位,其中0 - 11位页内偏移量,每页的大小为2的12次方 = 4k;12 - 31位为页号,共计2的20次方 = 1M页,由此可知不同的系统页的大小是不一样的。 图(a)页面大小为1KB(2的10次方) 图(b)页面大小为4KB(2的12次方)
对于特定的机器来说,其地址结构是一定的。 若给定逻辑地址A,页面大小为L,则页号p和页内偏移量w分别为 p = INT [A/L] w = [A]MODL 例如:系统的页面大小事1K,设A = 3096,则由上式得出 p =3,w =24
3、页表(在MMU中) 在分页存储管理中,页的存放可以是连续的,也可以是不连续的,这就增加了逻辑地址到物理地址转换的难度。如何在内存中找到页所对应的物理块是地址转换的关键。 为此,系统为每个进程创建了一个页表。在进程逻辑地址空间中的每一页,依次在页表中有一个表项,记录了该页对应的物理块号。如下图所示 在配置了页表之后,通过查找页表就可以很容易地找到该页在内存中的位置。页表具有逻辑地址到物理地址映射的作用。 对于页的保护通常设置一个存取控制字段。当这个字段占一位时,用于规定该页中的内容允许写还是读;如果存取控制字段占两位,那么它可以表示存取控制为读写、只读和只运行三种。当进程写一个只读页时,系统就会通过中断来报错。
二、 地址变换结构 为了实现分页管理逻辑地址到物理地址的转换,系统中必须设置地址变换机构,用来实现地址映射。由于页的大小和块的大小是一样的,当把进程的某一页放入内存时,该页内地址的页偏移量和块内偏移量是一致的,因此地址转换时就不必考虑偏移量,只考虑逻辑页号和实际物理号的对应即可。页表中存放的就是页号和其对应的物理块号(即物理页框号),所以地址变换就要借助页表来完成。
1、 基本地址变换 地址变换的第一步就是检索页表。 为了实现快速的检索页表,最好把页表放在寄存器中,每一个表项都用一个寄存器。但是有一个问题,通常计算机中的寄存器都不多,而页表可能非常大,现代计算机的虚拟地址至少是32位的,比如,页的大小为4KB,那么32位的地址空间将有1M个页面,64位的地址空间则更多。虚拟空间中的1M个页面需要1M个表项。并且,每个进程都有自己的页表。 因此,页表通常存放在内存中。在系统中只设置一个页表寄存器,其中存放页表的开始地址和页表长度。平时进程未执行时,页表的开始地址和页表的长度放在PCB中,当进程运行时,把这两个数据装入页表寄存器中。
当进程要访问某个地址中的数据时,地址变换机构首先自动地将地址转换成页号和页内偏移量,然后根据页号来检索页表。在检索之前要判断页号是否大于等于页表长度,如果页号大于等于页表长度,说明超出了有效地址范围,于是产生一个错误中断。否则,把页号和页表项长度相乘得到的结果与页表开始地址相加,就得到了该页表项在页表中的地址,从而找到对应的物理块号,把物理块号装入物理地址寄存器中,同时把页内偏移量送入物理地址寄存器对应的块内偏移量中,由此得到真正的物理地址。
由于页表是放在内存中的,那么一次数据访问需要两次访问内存,第一次访问页表,找到对应的物理号,然后与偏移量拼接形成物理地址;第二次从第一次得到的物理地址结构中访问数据。
页表遇到的问题:系统的运行速度一般都受到CPU从内存中取得指令和数据的速率的限制,一次数据两次访问内存会使计算机的处理速度降低50%。如何有效的解决这个问题? 采取的解决方法是:
快表:TLB 快表解决了两次访问内存的问题,降低系统的开销 在地址变换结构中增加一个具有并行查找能力的特殊的高速缓冲寄存器,这种设备称为转换检测缓冲区,又称为快表,用于存放当前访问过的页表项。此时,当给出一个有效地址时,地址变换机构首先通过将该页号p同TLB中的所有表项同时进行比较,判断该表是否在其中,如果发现可匹配的页面,则直接取出其页表项得到物理块号,而不必通过页表。如果地址变换机构没有可匹配的项,就进行正常的页表查询。首先从TLB中淘汰一个表项,然后用新找到的页表项替换它。这样,如果这一页很快再次被访问,那么第二次自然将会命中。 因为寄存器的价格原因,快表的结构不可能很大,通常能存放16 - 512个页表项,这对中小型作业来说,有可能把全部页表放入快表中,对于大型作业,可以将常用的页表项放入其中。由于程序的局部性原则,快表的引入极大改善了系统的效率,数据显示,从快表中查找到页表项的概率可以达到90%。这样因为访问快表而访问内存的次数就会大大减少,从而降低系统的开销。 2、 多级页表 现代的计算机都有非常大的逻辑地址空间,以32位计算机为例,假设页的大小为4KB,那么一个作业的页最多可以达到2的20次方个,这意味着该作业的页表现为2的20次方。假设一个页表现占用一个字节,那么该页表的大小为2的20次方B,即需要1MB的内存空间。并且要求者1MB的内存空间是连续的。这显然是不现实的,
看了姜晔老师的反病毒视频,其中提到了这些流程,就记录下来,方便自己查阅。
注入的流程如下:
1、OpenProcess获得要注入进程的句柄
2、VirtualAllocEx在远程进程中开辟出一段内存,长度为strlen(dllname)+1
3、WriteProcessMemory将Dll的名字写入第二步开辟出的内存中
4、CreateRemoteThread将LoadLibraryA作为线程函数,参数为Dll的名称,创建新线程
5、CloseHandle关闭线程句柄
卸载的流程如下:
1、CreateRemoteThread将GetModuleHandle注入到远程线程中,参数为被注入的Dll名
2、GetExitCodeThread将线程退出的退出码作为Dll模块的句柄值
3、CreateRemoteThread将FreeLibraryA注入到远程进程中,参数为第二步获得的句柄值
4、WaitForSingleObject等待对象句柄返回
5、CloseHandle关闭线程及进程句柄
跳跃表:是一种支持平均O(log(n)),最坏O(N)复杂度的节点查找,可以通过顺序性操作来处理节点的有序数据结构。 举例来理解一下跳跃表的情况: 跳跃表的效率可以和平衡二叉树相比较,但是实现起来却比平衡二叉树简单不少(不用旋转来,旋转去,哈哈) 跳跃表本身呢是有序链表的一种形式,但是在有序链表中选取了一些关键节点,举个例子序列为 1 2 3 4 5 6的有序链表 选取 2 4 6 作为上层的关键节点,这样是不是用空间换时间,然后就使得查找的效率提高了原来的2倍。 根据这样的思想,当链表很长有N个节点的时候我们可以从第一层提取大约N/2个节点,然后再从第二层提取大约N/4个节点。。。。。最终最上层只有2个节点这个时候查找效率变成了最高,当然这只是理想情况,redis中的实现跟着有些不同。 添加节点: 当要添加进一个节点的时候节点按照查找的顺序到最底层加入链表中,然后对于新加入的节点我们要判断是否将其提拔为关键节点(也就是是否让其上升),这个时候应用的策略是抛硬币,也就是每次节点都有百分之50的几率上升到上一层。 删除节点: 逐层查找到第一次出现节点的索引,然后逐层找到每一层的对应的节点 删除每一层查找到的节点,如果该层只剩下一个节点就删除整个一层。O(log(N))
跳跃表的用途 1. 实现有序集合键 2. 集群节点用作内部的数据结构
上面就是关于跳跃表的简单介绍,下面我们来看一看在redis中跳跃表的实现 首先介绍两个结构:zskiplist和zskiplistNode,zskiplist是用来保存跳跃表节点的相关信息的,比如节点的数量,以及指向表头节点和表尾节点的指针。
这里看图就能理解大体的zskiplist和zskiplistNode的样子了。 下面就是关于跳跃表如何实现关键节点也就是索引的选取,
typedef struct zskiplistNode{ //后退指针 struct zskiplistNode *backward; //分值 节点的顺序按score来排列,当score的值相同的时候就按照指向的SDS的字典顺序排列 double score; //成员对象 指向一个字符串(SDS)对象, robj * obj; //层 注意正是这个数据结构代表了这个节点最高可以作为第几层的索引 也正是redis中实现索引选取/的方法---->1-32中选择一个随机数作为该节点的高度 竟然是随机设置高度! struct zskiplistLevel{ //前进指针 struct zskiplistNode *forward; //跨度 unsigned int span; }level[]; }zskiplistNode 层这个结构体中存储的是指向一个跳跃表节点的指针和跨度 就是相距多少个节点的距离。一个跳跃表节点中层数组的大小就是这个跳跃表节点的高度了,而Redis是通过这样的方式来选取每一层的索引,是不是很有趣。同时呢,数组的大小是一个1-32的随机数,也就是说redis中的跳跃表层数最大为32,所以最高层的索引就是32层的索引了。
本文说说系统优化的常用手段吧,其中可能有一些内容在系列前面的文章里已经总结过了,这里还是再系统地整理出来,方便将知识汇总,有个整体上的认识。本文只讲方法论,没有具体实现。限于水平总结得可能不全,后面还会补充。
本文将系统主要分为前端优化和架构优化两个层面来说。
前端优化
1.页面优化
延迟加载
对一些还没有访问到的元素实行延迟加载,尤其是首页上的内容。
预加载
对用户即将访问到的元素进行预加载,提升用户体验。
减少DOM元素数量
可提升页面渲染速度。
iframe数量尽量少
众所周知iframe用于在页面中嵌入页面,如果数量过多也会降低页面加载速度。
压缩html文件大小
减少网络请求字节数,提升加载速度。
减少http请求数
分为三个方面:一是合并js或css文件;二是对图标类文件,使用css的sprites和background-image、background-position属性进行切图使用;三是使用浏览器缓存。
减少DNS查找次数
我们知道,我们是通过DNS服务器将网址解析成对应的服务器地址的,如果每次请求都去询问DNS服务器访问速度会很慢,因此我们第一次获取到对应的IP地址后将其缓存本地,不要每次去取。
避免跳转
页面的跳转都是通过301或302实现的,每次跳转也增加了网络消耗。
使用Ajax的GET请求
使用Ajax和服务器交互时,GET是交互一次,而POST是交互两次,分别发送文件头和请求数据。因此当我们只是为了加载数据时,通过GET方式即可,需要注意的是此方式限制数据量大小为2KB。
控制cookie大小
每次请求都会带上cookie,如果cookie过大爷会造成响应缓慢。建议不要将不常用的信息写入cookie。
2.CSS优化
将CSS置于页面顶端
因为页面是顺序加载的,预先加载css样式,可以保证后面的元素以我们设计的方式占线,用户体验更好。
避免使用CSS表达式
因为页面每加载到这个元素,就会重新计算一次,频率太高影响加载速度。
使用外部CSS
可减少HTML文件大小
3.JS优化
脚本放于页面底部
因为脚本的加载不影响页面内容的展示。
剔除重复的脚本
有效减少脚本大小,加速加载速度。
减少不必要的DOM访问
对已访问过的元素进行保存,因为DOM访问速度并不高。
判断条件多时用switch
尽量将概率大的case放在上面。
类型相同判断使用"==="
"==="判断类型相同的元素,而"=="会做类型转换。
4.图片
不在HTML中缩放图片
页面每次加载该图片,都是一个重新计算的过程。建议直接将图片切好尺寸载入。
架构优化
1.负载层
CDN加速
关于CDN的介绍可以系列这篇文章。使用CDN技术可以保证来自不同运营商网络的请求获取相差不多的访问速度。
动静分离
网站包括动态数据和静态数据。动态数据只能每次回到我们服务器上去取,而一些静态数据则可以部署在CDN服务器上,不要每次回源,加快加载速度。
负载均衡
通过随机、轮询、加权或哈希取模等方式,将请求尽量均衡地散布到我们的服务器上。详见系列这篇文章。
2.应用层
串行改并行、同步改异步
对热门数据或大的资源的加载,可考虑将其储存在多台服务器节点上,访问时启用多个线程去获取,加快访问速度。对于一个流程上对多个服务的调用,可考虑采用异步的方式(放入消息队列),快速响应用户请求。
连接复用、请求合并
不要每次连接都重新申请,可引入资源池的概念进行管理(线程池)。对高频次访问的请求,可考虑合并为一个请求处理,节约连接资源。
熔断、隔离、限流、降级
对服务调用的一系列治理措施。详见此文。
3.数据层
缓存
对经常访问的数据储存在缓存中,不要每次访问数据库。详见此文。
读写分离
针对数据库而言,使读和写操作互不影响。
分库分表
当数据库数据达到一定量级,可考虑分库分表。详见此文。
上篇文章:分布式系统漫谈【拾叁】_缓存带来的问题和解决方案 分布式系统漫谈【贰】_分布式系统带来的问题
安装NodeJs 在创建实际的“Hello,World!”应用之前,我们应该先安装NodeJS,安装NodeJS可以访问NodeJS官网,下载相应系统的NodeJS的安装包,进行安装。
程序组件 关于Hello World 这个应用主要包括三部分组成
导入所需的模块 -在程序中我们使用require指令来加载NodeJS模块
创建服务器 -一个将监听类似于Apache HTTP Server的客户端请求的服务器。
请求和响应 -在先前步骤中创建的服务器将读取由客户端(可以是浏览器或控制台)发出的HTTP请求并返回响应 创建NodeJS应用程序 第1步 - 导入所需模块 我们使用require指令加载http模块并将返回的HTTP实例存储到http变量中,如下所示
var http = require("http"); 第2步 - 创建服务器 我们使用创建的http实例并调用http.createServer()方法创建服务器实例,然后使用与服务器实例关联的listen方法将其绑定到端口3000 。通过参数请求和响应传递一个函数。编写样本实现以始终返回“Hello World”。
var http = require("http"); http.createServer(function (request, response) { // Send the HTTP header // HTTP Status: 200 : OK // Content Type: text/plain response.writeHead(200, {'Content-Type': 'text/plain'}); // Send the response body as "Hello World" response.end('Hello World\n'); }).listen(3000); // Console will print the message console.
leetcode 787. Cheapest Flights Within K Stops leetcode 787 Cheapest Flights Within K Stops 题目描述解答思路代码 题目描述 There are n cities connected by m flights. Each fight starts from city u and arrives at v with a price w.
Now given all the cities and fights, together with starting city src and the destination dst, your task is to find the cheapest price from src to dst with up to k stops.
任务一 安装与配置初始CentOS系统 安装完成。
任务二 认识linux的文件系统 【子任务一】 熟悉linux系统中的目录结构 文件结构是文件存放在磁盘等存储设备上的的组织方法,目录提供了一个方便而有效的途径。
第一步 理解linux系统的目录结构树 第二步 对比理解linux的文档结构 在一块硬盘,分成了四个分区,分别是/、boot、/usr和windows下的FAT,对于/和/boot或者/和/usr,它们是从属关系,对于 /boot和/usr,他们是并列关系。
如果把Windows下的FAT分区挂载到/mnt/winc下,那么对于/mnt/winc 和/usr或 /mnt/winc和 /boot来说,它们是从属于目录树上没有任何关系的分支。
因为Linux是一个多用户系统,所以要制订一个固定的目录规划,这样有助于对系统文件和不同的用户文件进行统一管理。但就是这一点让很多从Windows转到Linux的初学者感到头疼。
第三步 列出linux下一些常用目录的功能 / 根目录。
/bin 存放必要的命令。
/boot 存放内核以及启动所需的文件。 /dev 存放设备文件。 /etc 存放系统配置文件(最好占一个分区) /home 普通用户的宿主目录,用户数据存放在其主目录中(推荐占一个分区)。 /lib 存放必要的运行库。 /mnt 存放临时的映射文件系统,通常用来挂载。 /proc 存放储存进程和系统信息。 /root 超级用户的主目录 (推荐占一个分区)。 /sbin 存放系统管理程序。 /tmp 存放临时文件。 /usr 存放应用程序,命令程序文件,程序库,手册和其他文档(推荐占一个分区)。 /var 在正常操作中被改变的文件。 【子任务二】 了解linux系统的路径规则 linux系统中,路径就是一个文件存在的地方,如果告诉系统的这个路径,那么系统就可以找到这个文件,在linux中,存在着绝对路径和相对路径。
第一步 理解绝对路径 绝对路径:路径的写法一定是由根目录“/”写起,例如/usr/local/mysql就是绝对路径。 第二步 理解相对路径
相对路径:路径的写法不是由根目录“/”写起,例如,用户进入到/然后在进入到home,命令为【cd /home】,然后再使用【cd/test】命令,此时用户所在的路径为/home/test。第一个cd命令后/home,第二个cd命令后跟test,并没有/,这个test是相对/home目录而言的,所以叫相对路径。
【子任务三】掌握Linux系统中的基本命令
第一步:使用【pwd】命令在打印出当前所在目录
在linux系统中,只显示当前的目录,没有显示完整的路径,使用【pwd】命令打印当前完整的工作路径。
第二步:使用【cd】命令进入文件的目录
【cd /usr/local】 进入到/usr/local目录;
【pwd】打印当前工作目录。
【cd./】还是当前目录。
在PhotoshopCC2018的安装目录中,找到CRWindowsClientService.exe文件,删除即可。
在PhotoshopCC2018的安装目录中,找到CRWindowsClientService.exe文件,删除即可。
转载于:https://www.cnblogs.com/zhouwenwu/p/8594525.html
函数进阶 目标 函数参数和返回值的作用函数的返回值 进阶函数的参数 进阶递归函数 01. 函数参数和返回值的作用 函数根据 有没有参数 以及 有没有返回值,可以 相互组合,一共有 4 种 组合形式
无参数,无返回值无参数,有返回值有参数,无返回值有参数,有返回值 
定义函数时,是否接收参数,或者是否返回结果,是根据 实际的功能需求 来决定的!
如果函数 内部处理的数据不确定,就可以将外界的数据以参数传递到函数内部如果希望一个函数 执行完成后,向外界汇报执行结果,就可以增加函数的返回值 1.1 无参数,无返回值 此类函数,不接收参数,也没有返回值,应用场景如下:
只是单纯地做一件事情,例如 显示菜单在函数内部 针对全局变量进行操作,例如:新建名片,最终结果 记录在全局变量 中 注意:
如果全局变量的数据类型是一个 可变类型,在函数内部可以使用 方法 修改全局变量的内容 —— 变量的引用不会改变在函数内部,使用赋值语句 才会 修改变量的引用 1.2 无参数,有返回值 此类函数,不接收参数,但是有返回值,应用场景如下:
采集数据,例如 温度计,返回结果就是当前的温度,而不需要传递任何的参数 1.3 有参数,无返回值 此类函数,接收参数,没有返回值,应用场景如下:
函数内部的代码保持不变,针对 不同的参数 处理 不同的数据例如 名片管理系统 针对 找到的名片 做 修改、删除 操作 1.4 有参数,有返回值 此类函数,接收参数,同时有返回值,应用场景如下:
函数内部的代码保持不变,针对 不同的参数 处理 不同的数据,并且 返回期望的处理结果例如 名片管理系统 使用 字典默认值 和 提示信息 提示用户输入内容 如果输入,返回输入内容如果没有输入,返回字典默认值 02.
前言 在这里和大家分享一下,我对Android的ImageView图像视图组件的学习以及一些属性的使用。
ImageView ImageView,图像视图,直接继承自View类,它的主要功能是用于显示图片。实际上它不仅仅可以用来显示图片,任何Drawable对象都可以使用ImageView来显示。ImageView可以适用于任何布局中,并且Android为其提供了缩放和着色的一些体操作。
ImageView常用属性和方法 ImageView的一些常用属性和方法,这些属性和方法可以帮助我们更好的开发:
“android:adjustViewBounds”:设置ImageView是否调整自己的边界来保持所显示图片的长宽比例;“android:maxHeight”:设置ImageView的最大高度,可选;“android:maxWidth” :设置ImageView的最大宽度,可选;“android:scaleType”:设置所显示的图片如何缩放或移动以适应ImageView的大小;“android:src”:设置ImageView所显示的Drawable对象的ID;“android:alpha”:设置ImageView的透明度;“setAlpha(int alpha)”:设置ImageView的透明度;“setImageBitmap(Bitmap bm)”:设置ImageView所显示的内容为指定的Bitmap对象;“setImageDrawable(Drawable drawable)”:设置ImageView所显示的内容为指定的Drawable对象;“setImageResource(int resId)”:设置ImageView所显示的内容为指定id的资源;“setImageURI(Uri uri)”:设置ImageView所显示的内容为指定Uri;“setSelected(boolean selected)”:设置ImageView的选中状态; 对于android:scaleType属性,因为关于图像在ImageView中的显示效果,所以有如下属性值可以选择:
“matrix”:使用matrix方式进行缩放。“fitXY”:横向、纵向独立缩放,以适应该ImageView。“fitStart”:保持纵横比缩放图片,并且将图片放在ImageView的左上角。“ fitCenter”:保持纵横比缩放图片,缩放完成后将图片放在ImageView的中央。“fitEnd”:保持纵横比缩放图片,缩放完成后将图片放在ImageView的右下角。“center”:把图片放在ImageView的中央,但是不进行任何缩放。“centerCrop”:保持纵横比缩放图片,以使图片能完全覆盖ImageView。“centerInside” :保持纵横比缩放图片,以使得ImageView能完全显示该图片。 src属性和background属性的区别 在API文档中我们发现ImageView有两个可以设置图片的属性,分别是:src和background
常识:
①background通常指的都是背景,而src指的是内容;
②当使用src填入图片时,是按照图片大小直接填充,并不会进行拉伸而使用background填入图片,则是会根据ImageView给定的宽度来进行拉伸。
缘由 收到系统告警如下:
告警一次,Seconds_Behind_Master的值到了11083795,很快就恢复。
原因 网上查找相似问题发下如下文章:
https://www.jianshu.com/p/d01190078cf5
看后觉得不错。但是本人并未测试出相同的结果。可能是数据量的问题。
于是我开始查找官方文档,与Seconds_Behind_Master相关内容如下:
Seconds_Behind_Master: The number of seconds that the slave SQL thread is behind processing the master binary log. A high number (or an increasing one) can indicate that the slave is unable to handle events from the master in a timely fashion.
A value of 0 for Seconds_Behind_Master can usually be interpreted as meaning that the slave has caught up with the master, but there are some cases where this is not strictly true.
1. 安装版本控制Mercurial 直接下载使用Mercurial安装包进行傻瓜式安装,无需解释一用就灵 *改版本控制工具的命令都是以hg开头 2. 检查是否安装好。 a. 使用命令 hg version 如果安装成功会显示类似下面的版本信息 Mercurial Distributed SCM (version 0.7) Copyright (C) 2005 Matt Mackall <mpm@selenic.com> This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. b. 直接输入命令 hg,可显示基本常用hg命令列表 3. 需要了解hg有那些命令 a. 直接输入命令 hg 显示基本列表。 b. 输入 hg help -v 显示全部命令 (包括名字的参数) 4. 克隆代码仓库 a. 克隆远程仓库到本地并创建my-hello的文件夹在存放 hg clone http://www.selenic.com/repo/hello my-hello (注意,my-hello文件夹会创建在当前文件夹下面,克隆时应注意当前文件路径是否正确) 如果所有都没问题,clone 命令输出: requesting all changes adding changesets adding manifests adding file changes added 2 changesets with 2 changes to 2 files b.
android NSD服务详解 一.NSD的基础知识: NSD全称为: Network Service Discovery.翻译过来的意思就是发现服务器网络的意思。理解的说就是:发现服务器对应的网络信息。 作用为: The addition of Network Service Discovery (NSD) takes this further by allowing an application to seek out a nearby device running services with which it can communicate. (也就是说使用这个服务就可以搜索附近哪个网络设备设备可以进行通信,一般指的是局域网内连接同一个wifi的信号源).
NSD的作用和意义 NSD只是发现网络,并非直接连接网络,发现网络就是发现某个局域网内可连网络,并且获取到对应设备的IP地址和端口号。
NSD的作用就是为下一步连接网络做准备,比如使用Socket网络连接同一局域网两个手机,并且进行数据通信,这就要知道服务器的ip地址和端口号。
Socket不限于蓝牙交互,通过IP和端口号也是可以进行网络交互的,并且效率也比较快,就是会麻烦一些。
二.关于NSD的开发的过程. NSD(NsdManager)是Android SDK中自带的类库,可以直接调用编程。
这里我吐槽一下,网上很多示例代码都是比较坑爹的,基本步骤都是说什么注册、监听、处理、注销。。。 他们最大的失误是没有区分服务端和客户端。。。而是将代码混合在一起,刚开始接触的开发者就不知道怎么搞了!
其实NSD和Socket有点类似,都是有Server服务器端和Client客户端
对于Socket: SocketServer服务器端需要定义端口号,然后进行监听连接 SocketClient客户端需要知道服务器端定义的端口号和服务器的ip地址,然后请求连接 然后在客户端进行发送请求连接,服务器端同意连接,这时Socket连接就建立起来的,就可以相互通信了。 对于NSD: NSD Server服务器端定义主机名字、端口号,然后进行NSD注册 NSD Client客户端进行扫描,但是只能扫描到包含NSD Server服务器定义的主机名字的NsdServiceInfo对象 然后NSD Client客户端能根据这个NsdServiceInfo对象解析到服务器端的IP地址和它的端口号 到这里我们就应该知道了:NSD是为Socket连接做准备的其中一种手段! 1.NSD Server 服务器端的开发 服务器端很简单的,就一个注册就可以了 具体的步骤有:
(1)进行注册监听 private NsdManager.RegistrationListener mRegistrationListener; //实例化注册监听器 private void initializeRegistrationListener() { mRegistrationListener = new NsdManager.
1、用户细分:目标用户群。以用户为中心,正在为谁创建价值?谁是我们最重要的客户?
2、价值主张:向客户传达怎么样的价值?正在帮助用户解决哪类难题?正在满足哪些用户需求?正在提供给客户细分群体哪些系列的产品和服务
3、渠道通路:哪些渠道可以接触我们的客户细分群体?如何接触他们?如何整合渠道?哪些渠道最有效?哪些渠道成本效益最好?如何把我们的渠道与例行程序整合
4、用户关系:我们每个用户细分群体希望我们与建立和保持何种关系?那些关系我们已经建立了?这些关系成本如何?如何把它们与商业模式的其余部分进行整合?
5、收入来源:什么样的价值能让用户愿意付费?他们现在付费买什么?他们是如何支付费用的?每个收入来源占总收入的比例是多少?
6、核心资源:我们的价值主张需要什么样的核心资源?我们的渠道通路需要什么样的核心资源?我们的用户关系呢?收入来源呢
7、关键业务:产品哪些功能,让用户感受到产品形态
8、重要合作:重要伙伴儿、重要供应商,从伙伴儿那里获得了哪些关键业务
9、成本结构 :什么是我们商业模式中最重要的固有成本?哪些核心资源花费最多?哪些关键业务花费最多?
实例分析:
以下是百度文库的商业模式画布(只画出了部分)
一、什么是localStorage?
在HTML5中,新加入了一个localStorage特性,这个特性主要是用来作为本地存储来使用的,解决了cookie存储空间不足的问题(cookie中每条cookie的存储空间为4k),localStorage中一般浏览器支持的是5M大小,这个在不同的浏览器中localStorage会有所不同。
二、localStorage的优势与局限
localStorage的优势
1、localStorage拓展了cookie的4K限制
2、localStorage会可以将第一次请求的数据直接存储到本地,这个相当于一个5M大小的针对于前端页面的数据库,相比于cookie可以节约带宽,但是这个却是只有在高版本的浏览器中才支持的
localStorage的局限
1、浏览器的大小不统一,并且在IE8以上的IE版本才支持localStorage这个属性
2、目前所有的浏览器中都会把localStorage的值类型限定为string类型,这个在对我们日常比较常见的JSON对象类型需要一些转换
3、localStorage在浏览器的隐私模式下面是不可读取的
4、localStorage本质上是对字符串的读取,如果存储内容多的话会消耗内存空间,会导致页面变卡
5、localStorage不能被爬虫抓取到
localStorage与sessionStorage的唯一一点区别就是localStorage属于永久性存储,而sessionStorage属于当会话结束的时候,sessionStorage中的键值对会被清空。
三、localStorage的使用
清空localStorage
localStorage.clear() // undefined localStorage //Storage {length: 0} 存储数据 存储数据
localStorage.setItem("name","caibin") //存储名字为name值为caibin的变量 localStorage.name = "caibin"; // 等价于上面的命令 localStorage // Storage{name: "caibin", length: 1} 读取数据 读取数据
localStorage.getItem("name") //caibin,读取保存在localStorage对象里名为name的变量的值 localStorage.name // "caibin" localStorage.valueOf() //读取存储在localStorage上的所有数据 localStorage.key(0) // 读取第一条数据的变量名(键值) //遍历并输出localStorage里存储的名字和值 for(var i=0; i<localStorage.length;i++){ console.log('localStorage里存储的第'+i+'条数据的名字为:'+localStorage.key(i)+',值为:'+localStorage.getItem(localStorage.key(i))); } 删除某个变量
localStorage.removeItem("name"); //undefined localStorage // Storage {length: 0} 可以看到之前保存的name变量已经从localStorage里删除了 检查localStorage里是否保存某个变量
// 这些数据都是测试的,是在我当下环境里的,只是demo哦~ localStorage.hasOwnProperty('name') // true localStorage.
from: http://blog.csdn.net/tellh/article/details/50782653
前言 想必大家也发现,时下的很多App都应用了这个Google出品的SwipeRefreshLayout下拉刷新控件,它以Material Design风格、适用场景广泛,简单易用等特性而独步江湖。但在我们使用的过程中,不可避免地会发现一些bug,或者需要添加某些特性来满足需求。出现这些问题,最好的方法就是解读源码,理解它实现的原理,并且在理解源码的基础上修改源码,达成需求。然而不知为何,至今还没有一篇关于SwipeRefreshLayout源码解析的文章,所以萌发了要写一篇这样的文章。鉴于阅读技术博文的枯燥,加之还是篇源码解析的文章,我不打算一下子扔出来一大段代码让读者去啃,而是一步一步往下走,揭开SwipeRefreshLayout的神秘面纱。
阅读源码的小技巧 为什么源码普遍都很难读,有人甚至谈之色变?其实代码(出自大神之手)生来是易读的,但代码多了就变得难读了。所以阅读源码时,要把握住主干,细枝末节可以暂时忽略,一路下来理解了程序工作流程后再回过头来会有一种豁然开朗的感觉。 阅读源码我还是选择Android Studio。这个强大的工具提供了很多快捷键,大大地方便了源码的阅读。
Ctrl+F :在当页查找关键字Alt+F7: 查看方法或变量在哪里被使用过Ctrl+Q:查看java doc,如果该方法或变量有的话javadoc的话就可以更快知道该它的相关信息Ctrl+左击:这个不用说了吧,进入方法体或者查看定义或者查看被使用的地方Ctrl+Shift+i:可以不离开当前阅读的位置,查看指定方法的方法体Ctrl+F11:加BookMark,简直是非常有用的功能,不过需要去设置添加一下跳转下一个书签或上一个书签的快捷键才能发挥出该功能真正强大。Ctrl+F12 : 输入关键字快速定位指定的变量或方法,支持模糊搜索。Ctrl +Alt+左箭头或右箭头:返回前一个或下一个光标的位置,在想回溯阅读位置的时候非常有用关于阅读源码的快捷键就这些吧,以后想到了再补充… 你应该知道: 在看往下看之前,我希望你了解:
事件分发机制ViewGroup的测量绘制过程 准备工作 所幸该控件没有跟系统api耦合,所以可以直接copy一份代码到自己的demo工程中,尽情地改。但是hint会理解报出一些错误。首先包名要改一下,类名最好也改吧,以免混淆~其次把CircleImageView和MaterialProgressDrawable这两个类都copy过来,放在同一个包里。如图: 如果嫌麻烦可以直接fork我的项目。
探究之旅 我们朝着未知的黑暗出发。打开SwipeRefreshTestLayout的类文件,看到左边这么小的滑块,其实我一开始是拒绝的~ 感觉无从下手啊有没有… 沉下心来,想想看看它是继承于ViewGroup的,所以想想它一定有两个很关键的方法:onMeasure和onLayout,分别解决了它和它的子View占多大地和搁到哪。因为它是一个下拉刷新控件,它必定要涉及到事件分发的处理,同样是两个关键方法:onInterceptTouchEvent和onTouchEvent,分别用于决定是否拦截点击事件和进行点击事件的处理。天空瞬间亮了许多…
onMeasure @Override public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); if (mTarget == null) { ensureTarget(); } if (mTarget == null) { return; } //mTarget的尺寸为match_parent,除去内边距 mTarget.measure(MeasureSpec.makeMeasureSpec( getMeasuredWidth() - getPaddingLeft() - getPaddingRight(), MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec( getMeasuredHeight() - getPaddingTop() - getPaddingBottom(), MeasureSpec.EXACTLY)); //设置mCircleView的尺寸 mCircleView.measure(MeasureSpec.makeMeasureSpec(mCircleWidth, MeasureSpec.EXACTLY), MeasureSpec.
Windows小技巧5--如何通过vb脚本实现Chrome浏览器页面自动切换和刷新的功能 需求 近期由于某些需求,需要定时自动刷新Chrome浏览器页面,并在不同页面之间切换,经过查阅资料,发现可以用vb脚本轻松解决该问题。以下是该问题的脚本源码和使用说明,贴在此处以便于学习!
源码 '脚本代码实现(注释) Set objShell = CreateObject("Wscript.Shell") do WScript.Sleep 5000 objShell.SendKeys "^1" WScript.Sleep 10 objShell.SendKeys "^{F5}" WScript.Sleep 20000 objShell.SendKeys "^2" WScript.Sleep 10 objShell.SendKeys "^{F5}" loop 说明: SendKeys 1 、2 对应第一个和第二个页面
其对应进程为wscript.exe
单引号为注释,若要实现切换该窗口,需要将该窗口放在最外层,即鼠标可直接点击该窗口 缺点:该脚本只能在Chrome上起作用;打开该窗口后,若再打开其他软件或者浏览器会导致功能失效
关闭程序方法: 打开任务管理器,进入详细信息栏目,找到名称为wscript.exe的文件,结束任务即可,如下图:
/ <summary> /// 1.Clear CircleReference /// 2.Set Page to Fit Wide /// 3.Set Column Text fit /// </summary> /// <param name="app"></param> /// <param name="ws"></param> private void WorkSheetPageSet(Microsoft.Office.Interop.Excel.Application app, Worksheet ws) { ClearCircleReference(ws); SetPagetoFitWide(ws); SetColumnFit(ws); } / <summary> /// Set Column Text fit /// </summary> /// <param name="sheet"></param> private static void SetColumnFit(Worksheet sheet) { char column = 'B'; for (int i = 0; i < 25; i++) { Range range = sheet.
在项目中遇到了:10.0.0.0/8 的网络地址,只知道8是网络掩码,但具体表示什么地址,都还给老师了:),赶紧翻书复习一下:
子网掩码是一个长32位的值,让IP分组的接收方能够将IP地址的网络ID部分与主机ID部分区分开来。 32位的子网掩码由1和0组成,其中的1表示IP地址的相应部分为网络地址或子网地址,0的部分为主机地址。 在上述问题中的IP地址10.0.0.0/8中,这种斜杠表示法(/)指出了子网掩码中有多少位为1,则/8表示IP地址的前8位是网络地址或者子网地址,后24位为主机地址。 也就可以算出上述IP地址的可用主机范围为为10.0.0.1 ~ 10.255.255.254,广播地址为10.255.255.255
在一个项目中用到了八九个服务,服务的执行时间也是五花八门,有的年末执行一次,有的月中执行一次,有的月末最后一天执行一次,有的月初连续执行5天,
有的每天晚上执行,。。。还好各个服务并没有严格的关联关系,大体按照排班表达式执行就行,为此选定了开源框架Quartz.Net作为集中调度服务,
本文不讲解Quartz.Net的原理和细节,只是描述安装Windows服务时遇到的一点坑。
首先这个项目已经成功运行,然后又来了第二个项目,基本还是复制第一个项目。
在第二个项目服务器上部署基于Quartz.Net、TopSelf编写的Windows服务时,提示报错。。。根据提示大约能看出是注册表权限的问题,
后根据大神的提示,用ProcessMonitor监视了一下,果然是写注册表值的时候,提示Access Denied,然后各种操作赋权限后,还是不好使,
期间尝试在把另一台服务器的注册表值导出,在这个项目的服务器上导入,不好使(安装的时候修改注册表值还是失败,会回退!!)
无奈,抱着试一试的态度,重启服务器,关闭360软件,重新执行 **.exe install。。。竟然安装成功了,偶滴神。。
转载于:https://www.cnblogs.com/niuge/p/8556591.html
本文通过源码分析,探究zabbix web应用的整体架构,所有分析基于zabbix 3.0.10进行。
总体而言,zabbix web应用使用PHP开发,大量应用OOP方法,主要采用mvc架构,同时包含一套遵循JSON-RPC 2.0协议的web API。
由于web应用结构复杂,仅类文件就有300多个,本文仅选择重要的部分,介绍mvc架构和api结构的大体框架。
1.论文相关 Bertinetto, Luca, et al. "Fully-convolutional siamese networks for object tracking." European conference on computer vision. Springer, Cham, 2016.
之前写的论文总结更多的偏向于论文翻译,以后写的论文总结要更偏向于总结
2.论文内容 2.1摘要 任意目标的跟踪问题,传统方法实施起来基本上是使用单独的视频本身作为训练集,然后学习一个目标的表观模型。尽管这种方法很成功,但是这种在线学习方式限制了可以学到模型的丰富性。近来,很多人尝试探索深度卷积网络强大的表达能力。然而,由于目标跟踪中目标事先是不知道的,所以每次都需要在线执行一次随机梯度下降算法来调整网络权重,这严重影响了跟踪系统的速度。在这篇论文里,我们使用了一种新颖的全卷积孪生网络来做为基本的跟踪算法,网络以端到端的形式在用来进行目标检测的视频数据集ILSVRC15上训练而成。我们的跟踪器远远超过了实时性的要求,操作起来还很简单,并且在多个benchmark上都达到了当前最优的性能。
2.2引入 跟踪问题是在视频的第一帧确定一个单独的目标来进行跟踪,目标是任意给定的,所以这就无法收集数据来训练一个特定的检测器来进行跟踪。
今年来,很多成功的范例基本都是使用视频里提取出来的例子,以在线的形式学习一个目标的表观模型出来。这种方法的盛行很大程度上归功于一些已有算法的成功,比如TLD,Struck,KCF。然而,很明显的一个效率不高的地方在于,使用当前视频派生出来的数据仅仅能学习到相对简单的模型。尽管计算机视觉中深度卷积网络的应用无处不在,但是由于缺乏监督数据以及跟踪的实时性要求,通过深度学习在每一个视频学到一个简单的检测器这种方法都难以应用。
最近很多工作志在通过使用预训练模型来解决上述问题。这些方法中,要么是使用网络内部某一层作为特征,然后再使用浅显的方法来跟踪,比如相关滤波;要么是使用SGD方法来微调多层网络。浅显的方法不能充分利用端到端学习的益处,而使用SGD微调虽然能到达时下最优效果,但是却难以达到实时性的要求。
我们提倡另一种替代性的方法。这个方法在初始离线阶段把训练网络更多地看成一个通用的相似性学习问题。这篇论文的关键贡献就在于证明这个方法在benchmark上可以达到非常有竞争性的性能,并且运行时的帧率远超实时性的要求。具体点讲,我们训练了一个孪生网络在一个较大的搜索区域搜索样本图片。本文另一个贡献在于,孪生网络是一个关于搜索区域的全卷积网络,而最后目标位置的估计我们通过计算两个输入的交叉相关,然后再进行插值得到,密集而且高效。
这种相似度学习方法之前是被忽略的,因为跟踪领域难以获得大量的标记数据集。事实上,直到最近,我们能获得的数据集也仅仅包含几百个标注视频。然而,我们相信ILSVRC视频目标检测数据集的出现让训练这么一个模型成为可能。为了公平起见,VOT委员会禁止既使用视频来训练网络,又用这个视频来验证网络。而我们证明了我们模型从ImageNet视频到ALOV/OTB/VOT视频的泛化能力,我们保留跟踪的benchmarkmark视频单独用来测试我们的性能。
3.跟踪中的深度相似性学习 跟踪一个任意目标可以被当做一种相似性学习。我们要学习到一个函数,函数比较样本z和搜索区域x,然后返回一个得分图。得分图和搜索区域x尺寸相同。得分高,说明这个区域和z相似,反之说明不相似。要找到z在新一帧中的位置,我们只需要把所有的可能位置都计算一下相似度即可。在实验中,我们使用目标初始的表观作为z就足够了。
******************上面还是像翻译,下面我要多总结**********************
那么用什么来模拟这么一个函数f呢?当然是最近很火的深度卷积网络了,因为他早已经在计算机视觉领域取得了广泛成功。而使用深度卷积的相似性度量函数可以作为一个很典型的孪生结构。孪生网络如同一个特征提取器,同时提取z和x图片的特征,然后将提取到的特征送入另一个函数g,那么我们这个相似性度量函数其实就是。函数g可以是一个很简单的距离度量或者相似度度量。这种深度孪生网络早已被广泛应用与人脸确认,关键描述点学习,one-shot字符识别。
3.1网络的总体结构 网络总体结构如上图所示,孪生网络其实就是一个特征提取器,它提取z和x特征之后,送到相似度函数里计算一下相似度。本文的相似度函数是使用交叉相关,公式如下,
其实就是将作为一个卷积核,在上进行卷积,相似度大的地方,那么自然响应值就大,那自然也就可以当做是目标z在x中的位置了。
那岂不是随便找一个特征提取器,提取一个特征一做,然后再一卷积都可以了?也许可以,但是由于本文的孪生网络是以端到端的形式学习出来的,那么可以认为,它训练出来的这个特征提取器,提取的特征更适合做卷积来获得最后的相似度得分图。而其他的特征提取器提取到的特征可能就不太适合用卷积来获得相似度响应图。
跟踪的方法就很好想到了,把上一帧目标的位置作为中心,在下一帧附近计算响应图。响应值最大的位置相对于中心的偏移再乘以步长,那就是目标在下一帧的真实位置了。为了应对尺度变化,作者在进行跟踪的时候也同时使用了多种尺寸来进行搜索。
3.2使用图片来训练 作者的训练方式是非常有创意的。网络最后的输出,其实相当于一个判别式方法,用正负样本对来训练网络。搜索图片x中的每一个候选子窗口,其实相当于一个样本,而它的得分,输出的就是它是正/负样本的概率。使用逻辑回归来表示的话,这就是一个应用逻辑回归的典型二分类问题,那么逻辑损失就可以表示为下式:
其中,v是候选位置的得分,而y是它的真实类别,y属于{1,-1}。这个推导其实很简单,分别表示出来逻辑回归分类时正负样本对应的概率和,那么损失函数就是和,结合y属于{1,-1}稍微整理一下就可以把这两个式子统一为作者给出的形式。
而训练的时候网络的最终损失函数如下,
简单来说就是搜索区域x的所有候选位置的平均损失。
训练样本对(z,x)从标注视频数据集中获得,如下图
只要x和z在视频里相隔不超过T帧,那么都可以作为一个训练对。图片要进行归一化,但是不能破坏长宽比,而是用背景补充。至于y怎么确定呢,也就是说什么叫做正样本什么叫做负样本呢?定义如下
R是我们定义的半径,c是目标的中心,k是网络最终总步长。上面的意思就是说在255*255这张图片上,只要和目标的距离不超过R,那就算正样本,否则就是负样本。
3.3孪生网络部分的结构 pooling是最大值pooling,每个线性层之后都batch normalization,除了conv5每个卷积层之后都有relu,等等,具体设置可以查看论文。
4.总结 网络的总体思路如上,但是在训练的时候数据集还有些其他处理,比如填充背景的大小,等等。总之网络速度快,性能好。有什么缺点呢?
近几年来,随着社会经济的发展和生活水平的提升,人们对居住环境的安全度和舒适度也有了更高的要求,不少城市社区为提高民众生活质量,安装了云脉人脸识别门禁系统,方便民众生活,推进智慧社区建设。
“刷脸”出入 健康安全
据了解。目前我国国内的门禁系统仍然以门禁磁卡、指纹、密码锁设置为主。这些门禁设置多需要居民近距离手动接触才能打开,频繁接触容易引发皮肤传染性疾病,尤其是抵抗力较弱儿童和老年人。此次普及安装的人脸识别门禁系统,主张用“人脸”代替“门禁卡”,尽量减少不必要的接触。
人脸识别门禁系统主要通过摄像头采集人脸信息,与后台庞大的人脸模板对比,确认是社区或楼层住户就可以自由通行。如此一来,即便是出门忘带磁卡、指纹变形、忘记密码,也不会被拦在小区大门处,“刷脸”出入,安全卫生。
人脸识别 强化安防体系
社区人口集中,人员出入情况复杂,既有亲朋好友、快递外卖,也有不知名的陌生人。由于人流量大,管理人员精力问题,出入口管理工作一直不大理想,再加上磁卡丢失、密码泄露、指纹被盗等问题得不到有效解决,不少非法分子趁机潜入,导致社区内安全事件频发。
人脸识别门禁系统,结合人脸识别、人脸对比、物联网等技术实现身份交叉验证,协助社区管理人员精确用户身份。据了解,由于人脸的直观性和不易被复制的特性,人脸识别门禁系统可以有效阻拦陌生人随意进出社区,尽可能降低社区安全事故发生的频率,强化社区安防体系。
智能登记 降低管理成本 随着人脸识别技术的飞速发展,人脸识别门禁的优化更进一步。目前云脉人脸识别技术的识别率已不受化妆技术、人像照片、面具模型、白天黑夜等外在因素影响。陌生人想要凭借伪装进入社区大门难如登天。
与传统的指纹、磁卡等门禁系统管理相比,人脸识别门禁系统在管理应用上更加智能便捷。以往社区人员发生变动,需要及时更换指纹、磁卡和钥匙。人脸识别门禁投入应用之后,新入住的用户只需要在社区管理处等级人脸信息,即可自由进出,大大节省社区人员变动管理成本。
门禁作为居住环境安防第一关,其重要性不言而喻,门禁系统的设计工作渐成安防市场关注的重点。在人工智能技术百花齐放的当下,人脸识别异军突起,借助东风,推动人脸识别门禁进一步走向市场。目前,人脸识别门禁系统已被应用于金融、安防、教育、办公、大楼管理等领域。
字符串在Python内部的表示是unicode编码,因此,在做编码转换时,通常需要以unicode作为中间编码,即先将其他编码的字符串解码(decode)成unicode,再从unicode编码(encode)成另一种编码。 Decode的作用是将其他编码的字符串转换成unicode编码,如str1.decode('gb2312'),表示将gb2312编码的字符串str1转换成unicode编码。 Encode的作用是将unicode编码转换成其他编码的字符串,如str2.encode('gb2312'),表示将unicode编码的字符串str2转换成gb2312编码。 因此,转码的时候一定要先搞明白,字符串str是什么编码,然后decode成unicode,然后再encode成其他编码 代码中字符串的默认编码与代码文件本身的编码一致。 python在安装时,默认的编码是ascii,当程序中出现非ascii编码时,python的处理常常会报这样的错UnicodeDecodeError: 'ascii' codec can't decode byte 0x?? in position 1: ordinal not in range(128),python没办法处理非ascii编码的,此时需要自己设置将python的默认编码,一般设置为utf8的编码格式。 解决方法有三中: 1.在命令行修改,仅本会话有效: 1)通过>>>sys.getdefaultencoding()查看当前编码(若报错,先执行>>>import sys >>>reload(sys)); 2)通过>>>sys.setdefaultencoding('utf8')设置编码 2.较繁琐,最有效 1)在程序文件中以下三句 import sys reload(sys) sys.setdefaultencoding('utf8') 3.修改Python本环境(推荐) 在Python的Lib\site-packages文件夹下新建一个sitecustomize.py文件,内容为: #coding=utf8 import sys reload(sys) sys.setdefaultencoding('utf8') 重启Python解释器,发现编码已被设置为utf8,与方案二同效;这是因为系统在Python启动的时候,自行调用该文件,设置系统的默认编码,而不需要每次都手动加上解决代码,属于一劳永逸的解决方法。 ----以上内容均摘自网络,如有侵权,告知修改。 引用地址: 1.UnicodeEncodeError: ‘ascii’ codec can’t encode characters in position xxx ordinal - bjkandy http://www.tuicool.com/articles/qiqi2i 2.UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-1: ordinal not in range(128) http://www.cnblogs.com/bluescorpio/p/3594359.html
前几天,软通动力来我们学校面试,软通的面试还是比较简单的。下面说一下面试流程。
软通的面试总共分为三轮,一面是资格面,主要是问一些比较基本的问题看你的基本素质怎么样,基本条件能不能达到他们的要求,反正就是随便吹吹就可以了。第二面是技术面,面试官会问你一些技术方面的问题,我是面C++的主要就问了算法、c和c++的区别、有没有做过什么项目等等。也还是很简单,我就面了几分钟面试官就让我过来。第三面是终面,好像是由部门主管直接来面吧,我也不是很清楚,反正他说我去就在他手下工作。他跟第二面一样也会问一些技术方面的问题,问了我什么是虚函数什么是纯虚函数,C++和java的区别(我说我java和C++都会),你用过多线程嘛等等。问得也比较简单。之后他主要会跟你介绍他们部门的情况,你有什么问题也可以问一下他。最后,他就告诉我过了。
因为软通动力主要是做外包的,还有他们在C++方面业务不很多,只有20%左右。所以我就没去,直接拒绝了。但总的来说这一次面试给我的启发还是很大的,放弃了就意味着,又要从新开始了,加油。
点击关注 异步图书,置顶公众号
每天与你分享 IT好书 技术干货 职场知识
本文大概 10624 字
读完共需 30 分钟
Tips 参与文末话题讨论,即有机会获得异步图书一本。 数据建模是对现实世界各类数据进行抽象组织、界定数据库需管辖的范围、确定数据的组织形式等直至转化成现实数据库的过程。而数据模型是构建应用系统的核心,是尽可能精准地表示业务运转的概念性框架。
数据建模的过程是界定、分析、发现数据需求,再用可视化的形式(“模型”)表示这种数据需求的过程。数据模型是用于精确表示信息领域沟通的一套符号和文字。任何景观的模型都会包含某些内容(例如地图就是地理景观的模型),同时为了方便理解又排除某些内容。
“发现”是确定业务过程或应用中业务需要什么信息,例如了解到客户和账号是个重要的概念。“分析”是明确需求的过程,例如对客户和账户逐步有了清楚的定义,理解了客户与他们的账户之间的关系。“界定范围”涉及与业务合作来决定什么对于特定的业务阶段是最重要的。例如,第一阶段是否同时需要“保存”和“检查账号”,还是只要“检查账号”就行了。“表示”是指要用清晰明确的语言展现出信息景观看上去是什么样的,例如可以用以下数据模型表示:
一个客户可以有一个或多个账号。
一个账号必须由一个或多个客户拥有。
一旦我们将这些需求写成了数据模型文档,就可以跟应用开发所涉及的业务和信息技术(Information Technology,IT)人员进行沟通了,如业务用户、业务分析师、数据建模人员、数据架构师、数据库管理员、开发者、测试人员以及管理人员。
数据模型是用于从业务到IT,IT内部从系统分析员、建模人员、架构师到数据库设计人员和开发人员之间沟通的主要媒介。无论要用的数据库技术是关系数据库管理系统(Relational Database Management System,RDBMS)(如ORACLE、Teradata),还是像MongoDB或Hadoop这样的非关系型数据库(Not Only SQL,NoSQL),都需要有种方式能用来沟通数据需求。因此,我们需要数据模型。
数据模型应该是高质量的,要能支持目前的需求同时又要能满足未来的需要。数据模型记分卡是一个可以用来改进数据模型质量的工具。
许多我正在为他们提供咨询服务的客户都决定将数据记分卡应用到客户的数据模型中,他们也推荐用数据模型记分卡来改进设计。
大数据就业挑战月薪30K,本文将简要介绍数据模型的组成,并教你如何看懂数据模型。
1.1 实体 实体表示与业务有关的重要且有价值的事务的信息集合。每个实体由一个名词或名词词组来表示,一般适用于以下6种问题之一:谁、什么、何时、哪里、为什么、如何。表1-1是这些实体类的定义并举例说明。
表1-1 实体类的定义
分类
定义
举例
谁
(Who)
能为企业带来好处的个人或组织。“谁对业务很重要?”常常与角色有关,例如客户或供应商
员工、病人、演员、嫌疑人、客户、供应商、学生、旅客、参赛者、作者
什么(What)
对企业有利的产品或服务。常常指能使组织保持业务运转的产出物。“什么是对业务至关重要的?”
产品、服务、原材料、货物清单、课程、歌曲、照片、图书
何时(When)
企业所关心的日历或时间周期。“何时业务在运作?”
时间、日期、月份、季度、年、学期、会计期间、分钟
哪里(Where)
企业关心的位置。位置可以指实际的地理位置,也可以指虚拟的位置。“业务在哪里开展?”
邮件地址、分布地点、网站的URL及IP地址
为什么(Why)
企业所关心的事件或事务。事件会让业务具有不确定性。“业务为什么可以运转?”
订单、盈利、投诉、取钱、存钱、褒扬、问询、交易、索赔
如何
(How)
将企业关心的事件记录下来。可以用文档记录事件,如采购订单用于记录一个订单事件。这就是”业务是如何跟踪事件的?”
发票、合同、协议、购买订单、收据、发票、装箱清单、交易确认单
实体的实例是指特定实体的发生或实体的值。例如,表单就是一个实体,它的表头的每个字段表示每个实体要记录的信息。每个有实际值的表单行表示一个实体实例。“客户”实体可能会有多个有不同名字的客户实例,如Bob、Joe、Jane等。“账号”实体有Bob的支票账户实例、Bob的存款账户实例、Joe的佣金账户实例等。
实体可以从概念层、逻辑层、物理层进行描述。概念层是对一个业务过程或应用系统定义其范围和重要术语。逻辑层是对一个业务过程或应用系统的业务解决方案进行详细描述,物理层则是对一个应用系统的技术解决方案进行详细描述。
一个与概念层相关的实体一定是对业务基本且关键的。至于什么是“基本且关键的”主要因范围不同而不同。在通用层面,某些概念是大多数公司都共有的,例如,客户、产品和员工。稍微收窄这个范围,特定的行业可能会有某个特定的概念。例如,广告役,这在广告行业是有个有效的概念,但在其他行业中却不适用。在出版行业,作者(Author)、书(Title)和订单(Order)是概念实体,如图1-1矩形框中的名字。
图1-1 用矩形框中的名字表示概念实体
逻辑层的实体比概念层更加详细地表示了业务。经常会用一个概念实体表示多个逻辑实体。逻辑实体包含一些特性,我们叫作“属性”,下一节会讨论。前面的概念实体可以由3个逻辑实体表示,如图1-2所示。
图1-2 逻辑实体
在物理层,实体与技术特定的对象有关,例如关系数据库管理系统(Relational Database Management System,RDBMS)中的数据库表或者非关系型数据库(Not Only SQL,Nosgl)MongoDB中的集合。物理层与逻辑层相似,但可以包括弥补技术缺陷所需要的折中方案,一般是与性能或存储有关的。
解题思路:写一个转换的函数,用a b c d依次代替每一位的值,求得值之后再进行加5除以10的转换,最后再计算这个数本身的时候再把 ad bc 位置互换
代码:public class Main9 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner input = new Scanner(System.in);
int n = input.nextInt();
int sum=transform(n);
System.out.println("转换后的数字是:"+sum);
}
public static int transform(int n){
int sum=0;
int a,b,c,d;
a=n/1000;
b=(n/100)%10;
c=(n/10)%10;
d=n%10;
a=(a+5)/10;
b=(b+5)/10;
c=(c+5)/10;
d=(d+5)/10;
sum=d*1000+a+b*10+c*100;
return sum;
}
}
Uncaught Error: Bootstrap's JavaScript requires jQuery 浏览器console报了上面的错误, 发现是bootstrap文件头的检测,
if("undefined"==typeof jQuery)throw new Error("Bootstrap's JavaScript requires jQuery"); 开始以为是jquery.js文件名的原因,最后改成jQuery发现问题依旧
经查找在stackoverflow上面找到了解决问题的办法:原地址:https://stackoverflow.com/questions/22658015/bootstrap-wont-detect-jquery-1-11-0-uncaught-error-bootstraps-javascript-re
解决办法是: 在导入bootstrap之前先导入jquery,
posted on 2018-03-10 17:54 Andy_963 阅读( ...) 评论( ...) 编辑 收藏 转载于:https://www.cnblogs.com/Andy963/p/8541128.html
在我们部署项目的时候,需要将本地的项目部署于远程服务器上,(腾讯云,公司内网云,等等),那么经常使用的方法就是通过ssh来进行文件传输
什么是ssh协议: SSH 为 Secure Shell 的缩写,即安全外壳协议,SSH 为建立在应用层基础上的安全协议。SSH 是目前较可靠,专为远程登录会话和其他网络服务提供安全性的协议。使用SSH,还有一个额外的好处就是传输的数据是经过压缩的,所以可以加快传输的速度。
如何配置ssh: 这里我们使用的工具是openssh-server,OpenSSH 是 SSH (Secure SHell) 协议的免费开源实现,我使用的主机是ubuntu,所以以下的命令均是在ubuntu下进行。
首先安装openssh-server:
root@ubuntu:~# apt-get install openssh-server 若出现关于openssh-client依赖包问题,请看我另外一篇文章:
安装openssh-server提示依赖包问题
若安装成功则提示:
root@ubuntu:~# Setting up ssh-import-id (5.5-0ubuntu1) ... root@ubuntu:~# Processing triggers for systemd (229-4ubuntu7) ... root@ubuntu:~# Processing triggers for ureadahead (0.100.0-19) ... root@ubuntu:~# Processing triggers for ufw (0.35-0ubuntu2) ... 检查ssh服务是否启动:
root@ubuntu:~# ps -e | grep ssh root@ubuntu:~# 9050 ? 00:00:00 sshd ssh服务此时已经启动,接着修改配置文件:
root@ubuntu:~# gedit /etc/ssh/sshd_config 将该文件中: PermitRootLogin prohibit-password 注释掉,变为 #PermitRootLogin prohibit-password 然后添加:
我们在进行远程文件传输的时候,经常会使用ssh传输,那么我们需要安装openssh-server,可是在安装的时候会遇到依赖包问题,如下: 下列软件包有未满足的依赖关系: openssh-server : 依赖: openssh-client (= 1:6.6p1-2ubuntu) E: 无法修正错误,因为您要求某些软件包保持现状,就是它们破坏了软件包间的依赖关系。 这是因为,openssh-server是依赖于openssh-clien的,原由是自带的openssh-clien与所要安装的openssh-server所依赖的版本不同,这里所依赖的版本是
= 1:6.6p1-2ubuntu1 所以要安装对应版本的openssh-clien,来覆盖掉ubuntu自带的
apt-get install openssh-client=1:6.6p1-2ubuntu1 然后安装openssh-server
apt-get install openssh-server 最后显示
Setting up ssh-import-id (5.5-0ubuntu1) ... Processing triggers for systemd (229-4ubuntu7) ... Processing triggers for ureadahead (0.100.0-19) ... Processing triggers for ufw (0.35-0ubuntu2) ... openssh-server安装成功