正点原子STM32103 战舰V3 开发板的ST LINK(SWD)接线如下图,5V供电旁边有个自锁开关,需要按下去(右下角有个POWER蓝色灯会点亮)才是上电的,另外另外根据实验测试使用ST LINK(SWD)下载方式下载后需要复位下,就是屏幕右下角有个红色的按钮(有写着RESET),这样才可以使程序正常工作。
首先这是均衡化之前 imhist(f) 执行的结果
执行g = histeq(f,256) %均衡操作
可以看到原本很窄的分布,却变得很宽。
这里在附上几张图,更好的理解
操作之前的矩阵
操作之后的矩阵
也就是说,比如原本非常窄分布的图像(灰度比较集中分布在一个范围内),但是每个灰度的占比确是不同的
我们有变换公式 新灰度值 = 老灰度的概率*255(这里设定灰度级数是255)
如原本灰度值为50的 变换为 0.25*255 = 63.75
又因为概率是连续的,但概率的连续程度并不会如之前图像里的灰度那般密集,比如像图中就有4个阶段,而且之间
的差值还比较大,故可以达到离散化(灰度之间的级数差变大)的目的
本文没有严格的数学推导,均在指简化理解过程,如有错误,还请指正。
数据定义:
2048游戏界面如下,界面为一个4乘4的方格,在游戏设计中定义一个16个元素的数组即可,因为每个格子有多个游戏属性,比如数值,颜色,方格坐标中心位置等,方格行列编号,这里定义了以下的数据结构:
class CGameNumBlock { public: int m_iBlockID; int m_iGameNumShow; CRect m_RectBlock; int m_iFlashCount; }; 游戏方块颜色值的映射表,每种数字对应一个颜色:
map<int,COLORREF> g_mapColor; g_mapColor[0] = RGB(205,194,181); g_mapColor[2] = RGB(238,226,213); g_mapColor[4] = RGB(238,222,197); g_mapColor[8] = RGB(238,178,115); g_mapColor[16] = RGB(246,149,98); g_mapColor[32] = RGB(246,125,90); g_mapColor[64] = RGB(246,93,49); g_mapColor[128] = RGB(238,206,106); 游戏启动时方块坐标及数值的初始化:
CRect rectCore; m_wndCore.GetClientRect(rectCore); m_BlockGapX = 10; m_BlockGapY = 8; m_BlockWidth = (rectCore.Width() - m_BlockGapX*5)/4; m_BlockHeight = (rectCore.Height() -m_BlockGapY*5)/4; int iLeftX(0),iLeftY(0); for (int i=0;i<4;i++) // 行 { iLeftY = ((1+i)*m_BlockGapY + i*m_BlockHeight); iLeftX = 0; for (int j=0;j<4;j++) // 列 { iLeftX = ((j+1)*m_BlockGapX + j*m_BlockWidth); m_RectBlocks[i*4+j].
opencv-python 中文显示在图像上 opencv只能在图像上输出英文字符,不支持汉字。可以和PIL一起使用实现在图像上输出中文。结合使用时注意一下几点:
1)opencv读取图像后图像颜色通道是BGR排列的,而PIL读取的图像是RGB排列的。要注意图像颜色通道排列的转化cv2.cvtColor(img, cv2.COLOR_BGR2RGB)。
2)opencv读取完图像存储格式是numpy。PIL是自己定义的格式。要调用PIL的方法需要先将numpy转为自己的格式。pilimg = Image.fromarray(cv2img)。相反,PIL处理完后,调用opencv方法要将格式转回numpy。
cv2charimg = cv2.cvtColor(np.array(pilimg), cv2.COLOR_RGB2BGR)。
不转的话会报错。TypeError: Expected cv::UMat for argument 'src'
3)字体simhei.ttf需要下载,然后在font = ImageFont.truetype("./simhei.ttf", 20, encoding="utf-8")指定simhei.ttf的路径即可
4)中文编码为utf-8。否则中文会显示为矩形。str1 = str1.decode('utf-8')
源码和结果如下:
# -*- coding: utf-8 -*- import cv2 import numpy as np from PIL import Image, ImageDraw, ImageFont # cv2读取图片 img = cv2.imread('timg.jpg') cv2img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # cv2和PIL中颜色的hex码的储存顺序不同 pilimg = Image.fromarray(cv2img) str1 = '中文,hi.我来自远方' if not isinstance(str1,unicode): str1 = str1.decode('utf-8') # PIL图片上打印汉字 draw = ImageDraw.
code snippet用于方便代码编写人员快速输入常用代码片段或者模板,vscode在2019年的版本更新中加强了这一特性。
Vscode的Code snippet是根据不同语言配置的,每一个语言有一个 l a n g u a g e . j s o n language.json language.json文件用于配置该语言所关联的文件类型编写时可用的代码片段,如下图所示:
这个json文件的配置方式网上已经有很多解释,具体请参考Creating your own snippets
除了根据文件类型配置代码片段之外,还可以配置全局的代码片段,或者为工作空间配置特定的代码片段,需要新建一个文件,如果是为工作空间新建代码片段,一般放在工作空间下的.vscode文件夹下,文件名为 ∗ ∗ ∗ . c o d e − s n i p p e t s ***.code-snippets ∗∗∗.code−snippets,语法和上面是一样的。
但是据笔者实验,只是上面的设置并不能实现Markdown文件编写时代码片段的快捷使用,我们还需要针对markdown类型文件进行具体的设置,打开 s e t t i n g s . j s o n settings.json settings.json文件,添加如下配置:
"[markdown]": { "editor.formatOnSave": true, "editor.renderWhitespace": "all", "editor.quickSuggestions": { "other": true, "
作者:Davie
链接:https://www.zhihu.com/question/40980436/answer/655067839
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
作为一门静态语言,支持调试是必须的。
1、godebug godebug是一个跨平台的Go程序调试工具,传统的编译型语言调试器使用底层系统调用并读取二进制文件用于调试各类符号。使用起来很麻烦而且很难移植。godebug使用不同的方法,直接把源码作为目标程序,在每一行插入调试代码,然后编译并运行。 但是目前GDB做的并不好,使用起来有这样那样的问题。
2、dlv 专业调试Go语言的一款工具。
安装:go get -u http://github.com/derekparker/delve/cmd/dlv配置:
export GOROOT=/usr/lib/golang
export GOPATH=$HOME/go
export PATH=$PATH:$GOPATH/bin使用:
1、dlv debug xxx.go 指定需要debug的文件
2、进入dlv交互式窗口后,b <filename>:<line> 指定断点
3、r arg 指定运行参数
4、n 执行一行
5、c 运行至断点或程序结束 3、日志输出 如果使用GoWeb框架进行开发,可以使用日志输出来进行程序调试。
``` Logger.Info() Logger.Warn() Logger.Error() Logger.Debug() .... ``` 4、开发IDE调试工具 Golang开发工具如Goland,本身自带debug调试功能。
问题:当我们在项目需要 复制一个对象到另一个对象并且 被复制的对象不能受复制后的对象的影响
我先总结下 我们哪些方法可以复制对象:
// 直接赋值 var obj1 = { a: 1 }; var obj2 = obj1; console.log(obj2); // { a: 1 } // 通过 Object.assign() 这个属性来进行复制 var obj = { a: 1 }; var obj2 = Object.assign({}, obj); console.log(obj2); // { a: 1 } // 通过 for in 循环赋值 var obj1={ a: 1, b: { c: 2 }, c: 0 } var obj2={} for( var key in obj1 ){ obj2[key]=obj[key] } console.
简单的登录事件 现在网上的软件一般都需要登录才能使用,对于登录大家也都习以为常,下面我来为大家介绍一下简单的登录事件。 1. 登录页面; 一般软件登录都需要几个条件,不同的软件可能所需要的登录条件不一样,但用户名和密码是必须要输入的信息。 下图是一个简单的登录页面,这个登录页面的登录条件只有用户名和密码两个信息。
这样的页面的基本代码如下。
(下图来自网络,并不是下面代码的效果图。下面的代码只是Html布局的基本代码,不包括css样式。)
<form id="form" method="post" "enter()" > <div class="user"> <label>用户名:</label> <input type="text" name="Username" id="input" placeholder="用户名"> </div> <div class="Mi"> <label>密码:</label> <input type="password" name="password" id="password" placeholder="密码"> </div> <input type="checkbox" name="remember" id="remember"/><label>记住密码</label> <button type="button" id="btnDeng">登录</button> </form> 2. 验证登录:
(1)下面是一段点击登录的代码,其Id对应1上面的代码。
<script> $("#btnDeng").click(function(){ var form = $("#form").serializeArray(); $.post("这里填写在控制器封装的对应方法的链接", form, function (data) { if (data == "success") { //登录成功,跳转到登陆页面 window.location.replace(“这里填写登录页面的链接”); } else { //引用第三方对话框。 layer.alert(data, { title: '提示' }); } }) }); </script> 先获取登录按钮的id,然后click触发登录按钮的单击事件;然后,上面的Html代码【method=“post”】这里点明了使用的是Post的异步提交。
「1」
当我演示一个功能,
但它没有按预期进行时。
「2」
Bug 变 Feature,
这招简直太帅了!
「3」
CPU新用途:烤肉
隔着屏幕都闻到一阵香气
「4」
当我修复一个隐藏Bug时
然后,陷入了死循环中....
「5」
当两个实习生结对编程的时候
「6」
一张图诠释了二分查找和顺序查找
「7」
资深工程师:
左脚程序继续运行,右脚程序调试
「8」
从项目的开始到结束,
开发人员的变化。
「9」
我以为的工作量 VS 实际上的工作量
还是好好写代码吧
「10」
产品经理:要时时刻刻为客户着想,他们买车干嘛,最终的归宿就是回家啊,让客户直接到家不更好吗?好好想想……
「11」
当最棒的程序员遇见了Bug,
就是遇上最配合的Bug。
但其实一般角色是反过来的......
「12」
一句话让程序员“脱单”
原来祖师爷早已看破一切
「13」
经常地,你和Bug的关系就像这样
看得见却解决不了
「14」
当我的代码运作正常的时候
我没看到那堆警告~
「15」
最真实的现代互联网商业模式
「16」
上线前加了一个小特性,结果......
玛德!一堆bug啊,快跑
「17」
一直认为写代码的自己有点小帅
不,是非常帅!!
「18」
C++ 中的递归
「19」
据说这是很多公司的办事流程
每个人都在积极努力啊
「20」
前程序员离职后没人想接的代码
半路接的什么都看不懂
「21」
Java VS C# 「22」
当项目经理突然看到我的屏幕时
写bug呢?
「23」
追加(最简单的一种办法): 不重写系统的Appbar 可以用下面方式 但最终还是用preferredSize
Scaffold( appBar: PreferredSize( child: AppBar( ), preferredSize: Size.fromHeight(screenSize.height * 0.07)) ); 效果:
修改后:
因为嵌套 TabBar的时候 不需要appBar有高度 但Appbar的调试控制 也没有提供对应的方法
于是查看AppBar的源码:
可以看以到解释:这里可以设置 appBar的高度 但它是一个final修饰的 我们是无法再次给这个值
赋值的
那么就只有重写了 或者直接把 preferredSize直接写死 修改如下: 这个类在Scaffold里直接使用就行了
重点修改了这里: 把kToolBarHeight去掉了
// Copyright 2015 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. import 'dart:math' as math; import 'package:flutter/foundation.
我不是大佬,只是还算喜欢帮助别人的普通人,最近对网上向我求助的新手逐渐丧失耐心。
这个世界对新手并不友好,尤其是在技术领域。老手可以接受新手问简单问题,但是如果一个简单问题被问3次以上,而我自己因为性格原因会强迫自己回答别人问题,最后感觉时间被消磨和浪费。
我最近几年一直在反复思考一个问题:如何组建一个闭环?使老手愿意帮助新手,新手也能回馈老手。
这个问题很难,很有深度,对人的影响也很深远。我总结了以下几点思考:
大多数学习的新手并没有资源,而老手更愿意帮助有资源的人,容易造成知识流动的停滞。老手白天需要上班和工作,如果要帮助新手,则需要晚上8点以后。新手需要在解决简单问题后,总结困难问题寻求老手帮助解决。很多实践性的基础教程工作需要人做,但是大多数新手都只是寄希望于输入,而从来不输出。一般技术领域的人,帮助别人解决技术问题还是挺热心的。但1对1指导,1个人顶多指导3个人,自己的时间就不剩多少了。每个普通人,也就是没有资源的新手菜鸟,都应该学会自己拼杀出一条血路。有了拼搏的心态,如何培养能力?
请阅读这篇文章《研究生培养的六大科研能力》,链接:http://www.sohu.com/a/218004103_367246
在这篇文章里面,通俗地可以概括为6步:发现问题、查阅文献、整理资料、分析问题并设计试验、解决问题、总结问题,请读者以后请求本文作者帮忙时,对比一下自己完成了这6步中的哪些步骤?csdn网站的积分制度,简书的简书钻制度,都一定程度上形成了闭环,制度并没有明显的缺陷。对于新手,要么付费,要么接受csdn的广告,要么接受简书为了提高市场占有率推送的娱乐文章。对于老手,在工作和生活之余,能够单独帮助到朋友,就算圆满了。律人先律己,这是一种美好的德行。能做到这一步的人,是值得尊敬的人。建议读者在解决自己的问题后,能够总结问题形成结果,比如博客。既可以帮助别人,又可以升华自己学习的知识成果。
需要时不时膜拜一下大神,激发一下原动力!!!
前言:以前读论文,都是靠脑子硬记,哪个实验室,谁,哪一年在什么会议上发了一篇关于什么的论文。当需要回溯的时候,每篇论文能给出个大概,不具体,找起来也麻烦,以后就在这个 List 里分类整理已经读过的论文。之前读的,以及后续的一些新的有意义的论文都会慢慢补充进来 (汗, 感觉会是一个非常长的 list)。
基础知识材料
2018年, joan sola 大神, A micro Lie theory for state estimation in robotics. 系统讲述李代数,非常棒。点击可以进他的主页,他写过非常多的笔记材料以及代码,ekf slam 工具箱啥的,各类笔记材料值得入门者反复读。科研也有非常棒的论文,TRO, IROS, ICRA 不胜枚举,我辈楷模。
2017年, joan sola 大神, Quaternion kinematics for the error-state Kalman filter. 四元数和 error state ekf 系统百科全书,当初学 vio 就靠他入门。
2000年,book, 矩阵分析,Matrix Analysis and Applied Linear Algebra. 越到 SLAM 后期,数学基础知识越需要。这本书是研一那会老师上矩阵分析课的教材,非常非常棒,跟 MIT 那个有得一拼。再次看到这个书名,是在预积分的参考文献里,SVO 那个预积分用到矩阵零空间的基等一些性质就是引用的这本书。
VIO 系统
VIO 初始化和外参数标定
该部分主要是 VIO系统中初始参数的确定,如相机尺度,系统初始速度,重力方向,imu bias,甚至相机和 imu 之间的外参数等等。
首先是闭式求解的方法,三篇论文一脉相承,Martinelli 作为二作和一作。
文章目录 摘要介绍互补先验一个带约束权的无限有向模型 限制玻尔兹曼机和对比散度学习一种转换表示的贪婪学习算法Some Ideas Based on DBNNonlinear Dimensionality Reduction Learning Semantic Address Space (SAS) for Fast Document RetrievalLearning Nonlinear Embeddings参考文献 摘要 explaining away现象的存在使得稠密连接、拥有多个隐藏层的深度信念网络的训练变的困难,我们提出了使用互补先验来解决这一问题。使用互补先验,我们推导出一种快速、贪婪的算法,可以每次学习深层的有向信念网络中的一层,该网络的最上面两层形成了一个无向联想记忆。该算法用于初始化一个比较慢的学习算法,使用Wake-Sleep算法进行调整网络参数。一个经过调整的三层神经网络可以对手写数字识别数据进行很好的建模。
介绍 在稠密连接的多层有向信念网络中很难根据给定的输入向量推断隐藏单元的条件分布,因此其学习是十分困难的。变分学习方法可以对其真实的分布进行简单的近似,但是这种近似效果可能很差。而且,变分学习需要同时学习所有的参数,所以当网络参数规模增长的时候,这种学习方法的扩展性很差。
我们描述了一个网络模型,它的最上面两层形成了一个无向联想记忆模块,剩下的隐藏层形成了有向无环图,用于把抽象表达转化成可观察到的变量,比如图片像素。这个混合模型有以下特点:
存在一个快速、贪婪的算法可以快速的找到一组合适的参数,即使网络拥有上百万的参数并且含有多个隐藏层;虽然学习算法是无监督的,但是可以通过学习一个同时生成数据和标签的模型来给数据打标签;存在一个微调算法可以学习得到一个生成模型,使其在MINST数据集上的表现优于判别模型;这个生成模型可以很容易的解释隐藏层中的分布表示;学习算法是局部的; 第二部分介绍了互补先验的概念,以及它如何去除了explaining away的影响,并举了一个例子。第三部分解释了为什么限制玻尔兹曼机和有约束权的无限有向网络是等价的。
第四部分介绍了一个快速的、贪婪的学习算法,一层一层的构造多层有向网络。使用变分约束展示了每当加入一个新的层,整个生成模型的效果都会提升。
第五部分展示了这个算法是如何调整权重的,这是Wake-Sleep算法的对比版本,并且不受模式平均问题的影响,使得该算法能够学习到更好的重构权重。
第六部分展示了使用该算法训练的一个三层模型在Minst数据及上的表现。
第七部分展示了当使用该模型生成数据的时候,内部神经元到底是怎么变化的。
互补先验 explaining away现象的存在是的有向信念网络的推断边的困难,在稠密连接的网络中,隐变量的后验分布是难以处理的,只有少数特殊情况例外,如混合模型或线性模型加上高斯噪声。MCMC系列的采样方法可以从这种后验分布中采样,但是非常耗时。变分方法(Neal & Hinton, 1998)用更易于处理的分布近似真实后验,可以提高训练数据对数概率的下限。
complementary prior就是在第一层hidden unit上再加一层或多层Sigmoid,并且拥有和visible到hidden相反作用的weight。目的是为了抵消explaining away现象,该现象使得p(h|v)对于不同的hi不可分解。具体的原理请参照Learning Deep Architecture for AI里的数学式。写出p(h|v)之后你会发现它依赖于likelihood而这个的式子无法分解,于是这里我们假设式子里有一个先验分布,使得其乘上似然之后得到的p(h|v)能够被分解为p(hi|v)的乘积。这个先验就是complementary prior。对于一个单层SBN,其补完先验就是无数多层的SBN,且相互之间互绑weight,至于为什么是这个请看数学式。这个模型也等同于一层的RBM。
Sigmoid信念网络是一种简单的由随机二值神经元组成的网络,当其被用于生成数据时,单元i的条件概率分布如下:
p ( s i = 1 ) = 1 1 + e x p ( − b i − ∑ j s j w i j ) p(s_i=1)=\frac{1}{1+exp(-b_i- \sum_js_jw_{ij})} p(si=1)=1+exp(−bi−∑jsjwij)1
用for循环,计算前50项。
方法:应用for循环
#include<stdio.h>
void main()
{
int i,n;
double sum =1,t=1;
printf("输入n:\n");
scanf("%d",&n);
for(i=1;i<=n;i++)
{
t=t*i;
sum= sum+1/t;
}
printf("e=%lf",sum);
}
方法1: (1 +5+9+13+17 +.... +101)-(3+7 +11 +15 +....+99)程序源代码:
#include<stdio.h>
void main()
{
int i,j,sum1=0,sum2=0,sum;
for(i=1;i<=101;i+=4)
sum1 += i;
for(j=3;j<=99;j+=4)
sum2 +=j;
sum=sum1-sum2;
printf("1-3+5-7+....-99+101=%d\n",sum);
}
方法2:符号交替变换程序源代码:
#include<stdio.h>
void main()
{
int i,sum=0,s=1;
for(i=1;i<=101;i+=2)
{
sum =sum+i*s; /*控制符号交替变换*/
s=-s;
}
printf("1-3+5-7+....-99+101=%d\n",sum);
}
运行结果:
1-3+5-7+....-99+101=51
写的比较杂乱,类似随笔,随时可能往里面添加修改
给lable文本赋值:
this.ScoreNumber.getComponent(cc.Label).string = GAME_DATE.MMscore; 查找游戏组件或者脚本
this.MMGameAccount = this.GameAccount.getComponent('MMGameAccount'); 播放音乐(不需要添加组件)
cc.audioEngine.playEffect(GAME_DATE.overAudio,false); 播放背景音乐(直接添加组件)
查找具体节点
var fangge = cc.find('Canvas/Game/GameView'); 查找子节点的拥有组件名字为 MMShuiDi 的子节点集合
var fanggeArray = fangge.getComponentsInChildren("MMShuiDi"); 定时器写法1
//定时器 this.schedule(function(){ //结束后执行内容 },1,0,0); 修改按钮的图片
this.node.getComponent(cc.Button).normalSprite = this.MMGameSprite; cc.log("name= "+this.node.getComponent(cc.Button).normalSprite.name); 修改当前组名
this.node.group = "kongbai"; 碰撞检测方法函数(可以利用组来进行筛选碰撞)
//碰撞检测 onCollisionEnter (other, self) { if(other.node.group == 'shuidi') //检测碰撞组 { //事件 } }, 设置组名和碰撞的关系
微信判断收藏路径进入游戏
var a = wx.getLaunchOptionsSync(); a.scene == 1104 //显示 礼包 就可以了 //1089 扫码 //1104 收藏 creator平台判断
信息检索评价是对信息检索系统性能(主要满足用户信息需求的能力)进行评估的活动。通过评估可以评价不同技术的优劣,不同因素对系统的影响,从而促进本领域研究水平的不断提高。信息检索系统的目标是较少消耗情况下尽快、全面返回准确的结果。
IR的评价指标,通常分为三个方面:
(1)效率(Efficiency)—可以采用通常的评价方法:时间开销、空间开销、响应速度。
(2)效果(Effectiveness):返回的文档中有多少相关文档、所有相关文档中返回了多少、返回得靠不靠前。
(3)其他指标:覆盖率(Coverage)、访问量、数据更新速度。
如何评价不同检索系统的效果呢?一般是针对相同的文档集合,相同的查询主题集合,相同的评价指标,不同的检索系统进行比较。相关的评测系统有:
(1)The Cranfield Experiments, Cyril W. Cleverdon, 1957 –1968
(上百篇文档集合)
(2)SMART System,Gerald Salton, 1964-1988 (数千篇文档集合)
(3)TREC(Text Retrieval Conference), Donna Harman, 美国标准技术研究所, 1992
-(上百万篇文档),信息检索的“奥运会”
信息检索的评价指标可以分为两类:
(1)对单个查询进行评估的指标:对单个查询得到一个结果
(2)对多个查询进行评估的指标(通常用于对系统的评价):求平均
一、单个查询的评价指标
P&R
召回率(Recall)=检出的相关文档数/相关文档数,也称为查全率,R∈[0,1]
准确率(Precision)=检出的相关文档数/检出文档数,也称为查准率,P∈[0,1]
假设:文本集中所有文献已进行了检查
关于召回率的计算
(1)对于大规模语料集合,列举每个查询的所有相关文档是不可能的事情,因此,不可能准确地计算召回率
(2)缓冲池(Pooling)方法:对多个检索系统的Top N个结果组成的集合进行标注,标注出的相关文档集合作为整个相关文档集合。这种做法被验证是可行的,在TREC会议中被广泛采用。
虽然Precision和Recall都很重要,但是不同的应用、不用的用户可能会对两者的要求不一样。因此,实际应用中应该考虑这点。
(1)垃圾邮件过滤:宁愿漏掉一些垃圾邮件,但是尽量少将正常邮件判定成垃圾邮件。
(2)有些用户希望返回的结果全一点,他有时间挑选;有些用户希望返回结果准一点,他不需要结果很全就能完成任务。
F值和E值
(1)F值:召回率R和正确率P的调和平均值,if P=0 or R=0, then F=0, else 采用下式计算:
或者公式:
F值也被称为F1值(F1 measure),因为recall和precision的权重一样。
更通用的公式如下:
其中F2值(更重视召回率)和F0.5值(更重视准确率)也是非常常用的指标值。
(2)E值:召回率R和正确率P的加权平均值,b>1表示更重视P
或者公式:
F和E的关系如下:
引入序的作用
R-Precision:计算序列中前R个位置文献的准确率。R指与当前查询相关的文献总数。
P-R曲线
P-R曲线是正确率-召回率曲线(precision versus recall curve)。检索结果以排序方式排列,用户不可能马上看到全部文档,因此,在用户观察的过程中,正确率和召回率在不断变化(vary)。可以求出在召回率分别为:0%,10%,20%,30%,…, 90%,100%上对应的正确率,然后描出图像。
某个查询q的标准答案集合为:Rq={d3,d5,d9,d25,d39,d44,d56,d71,d89,d123}
查看源码:
控制:
floatingActionButton: FloatingActionButton(onPressed: (){ if(videoPlayerController.value.isPlaying) { playerWidget.controller.pause(); }else { playerWidget.controller.play(); } },child: Icon(Icons.arrow_drop_down_circle),),
/** * @author ghm * @date 2019/4/15. * 买卖股票的最佳时机 II * 给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。 * <p> * 设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易(多次买卖一支股票)。 * <p> * 注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。 * <p> * 示例 1: * <p> * 输入: [7,1,5,3,6,4] * 输出: 7 * 解释: 在第 2 天(股票价格 = 1)的时候买入,在第 3 天(股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。 * 随后,在第 4 天(股票价格 = 3)的时候买入,在第 5 天(股票价格 = 6)的时候卖出, 这笔交易所能获得利润 = 6-3 = 3 。 */ public class MaxProfit { public static void main(String[] args) { int[] nums = {7, 1, 5, 3, 6, 4}; maxProfit(nums); } public static int maxProfit(int[] prices) { int total = 0; for (int i = 0; i < prices.
keras faster rcnn中train.py解读 学习笔记,以备注形式,将持续更新。
from __future__ import division import random import pprint import sys import time import numpy as np from optparse import OptionParser #optparse是专门用来在命令行添加选项的一个模块。 import pickle from keras import backend as K from keras.optimizers import Adam, SGD, RMSprop from keras.layers import Input from keras.models import Model from keras_frcnn import config, data_generators from keras_frcnn import losses as losses import keras_frcnn.roi_helpers as roi_helpers from keras.utils import generic_utils sys.setrecursionlimit(40000) #设置最大深度为4000,作用是防止无限递归导致堆栈溢出崩溃 parser = OptionParser() #optparse是专门用来在命令行添加选项的一个模块。实例化对象parser #下面的代码通过parser.
/** * 从排序数组中删除重复项 * 给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。 * <p> * 不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。 * <p> * 示例 1: * <p> * 给定数组 nums = [1,1,2], * <p> * 函数应该返回新的长度 2, 并且原数组 nums 的前两个元素被修改为 1, 2。 * <p> * 你不需要考虑数组中超出新长度后面的元素。 */ public class RemoveDuplicates { public static void main(String[] args) { int[] nums = {0, 0, 1, 1, 1, 2, 2, 3, 3, 4}; removeDuplicates(nums); } public static int removeDuplicates(int[] nums) { int index=0; for (int i=0;i<nums.
适定问题(well-posed problem)和不适定问题(ill-posed problem)都是数学领域的术语。
前者需满足三个条件,若有一个不满足则称为"ill-posed problem":
1. a solution exists 解必须存在
2. the solution is unique 解必须唯一
3. the solution's behavior changes continuously with the initial conditions. 解能根据初始条件连续变化,不会发生跳变,即解必须稳定
上述来自wiki。
在计算机视觉中,有很多任务不满足“适定”条件,通常不满足第二条和第三条。
比如用GAN“伪造”图像的时候,这个任务就不满足“解的唯一性”。
做图像超分辨率,或者对图像去雨去雾去模糊等等任务时,这些都没有一个标准答案,解有无数种。更重要的是,这些解都是不稳定的。
Jaeyoung在CVPR的论文中这样描述CV中的不适定问题:
In most cases, there are several possible output images corresponding to a given input image and the problem can be seen as a task of selecting the most proper one from all the possible outputs.
这种不适定问题就是:一个输入图像会对应多个合理输出图像,而这个问题可以看作是从多个输出中选出最合适的那一个。
pointer-events的风格更像JavaScript,它能够: 阻止用户的点击动作产生任何效果阻止缺省鼠标指针的显示阻止CSS里的hover和active状态的变化触发事件阻止JavaScript点击动作触发的事件 //可以定义一个css样式 任何进行封装 .disabled { pointer-events: none; } // 禁用启用封装 function $id(domid){ var obj = document.getElementById(domid); //新增div禁用点击和启用点击的封装 obj.disable = function () { this.style["pointer-events"] = "none"; } obj.enable = function () { this.style["pointer-events"] = "auto"; } return obj; } //调用示例 $id("div中的id").disable(); //禁止点击 $id("div中的id").disable(); //启用点击 彩蛋 //利用上面的封装模式 我们可以封装一个获取id的方法甚至其他class也行 function $id(id) { return typeof id === "string" ? document.getElementById(id) : id; }
MongoDB通过Shell 实现集合的日常归档
1.MongoDB数据归档的意义
和其他类型的数据库一样,归档对MongoDB同样重要。通过归档,可以保持集合中合适的数据量,对数据库的性能是一种保障,也就是大家常说的数据冷热分离。
同时,归档对数据库的管理也带来了很大方便性,例如日常的备份、灾难恢复等。
在此,不再展开叙述了。
2.集合数据归档流程图
3.归档实现代码
复制代码
The file is used by cron to Archive the data of NeedArchiveColName_Archive collection,the collection is part of NeedArchiveDBColName DB. The file is writed by DBA Carson Xu.If you find any error, please connect with me,thanks. The version is defined V.001 Version ModifyTime ModifyBy Desc Ver001 2019-02-22 14:20 Carson Xu Create the Scripts File !/bin/bash mongodb可执行文件所在文档路径,此例为4.04 ,同时支持3.4.4 command_linebin="/QQMSG/mongo_db/mongobin404/bin/mongo"
command_linebinT="/QQMSG/mongo_db/mongobin404/bin/mongo"
存放导出过渡文件的文档路径和文件名字,ColA可用你的集合名字替代 targetpath='/data/mongodb_back/ArchiveDB_端口号'
当写一个小的python项目时,打开一个IDE需要很长时间,所以迫切需要找到一个可以编辑加执行并且非常小巧的软件。偶然机会,我发现了notepad++。
首先,编写python第一步就是下载python,这里不再详细的叙述。
安装notepad++,大概几十mb左右,根据安装向导提示来安装,全部按默任来走。
安装完之后,打开notepad++,编写时在工具栏中选择语言,在找到python并点击,这样软件就知道你在编写python,它可以为你提供辅助功能,如代码补全,语法高亮等。
编写完之后,将此文件保存,注意是.py的后缀。然后点击工具栏中的运行,它会弹出一个小方框名为输入运行程序名,你需要在栏中输入:cmd /k C:\Python30\python.exe “$(FULL_CURRENT_PATH)”& PAUSE & EXIT
其中C:\Python30\python.exe是我计算机中python应用程序的路径,应注意你的路径。其他不变。
命令解释:1,md /k 的含义是执行后面的命令,并且执行完毕后保留窗口。& 是连接多条命令。PAUSE表示运行结束后暂停,等待一个任意按键。EXIT 表示关闭命令行窗口。如果使用 cmd /c 就可以省掉 EXIT 了。
2,C:\Python30\python.exe找到此程序,接着后面的命令是用python 来运行此文件。
原文:https://blog.csdn.net/qq_40963664/article/details/80062130 利用keep-alive 缓存需要缓存的页面
在app.vue中改写router-view
<keep-alive> <router-view> <!-- 这里是会被缓存的视图组件,比如 page1,page2 --> </router-view> </keep-alive> 在router/index.js中添加路由元信息,设置需要缓存的页面
routes: [{ path: '/', name: 'index', component: index, meta: { keepAlive: true, //此组件需要被缓存 } }, { path: '/page1', name: 'page1', component: page1, meta: { keepAlive: true, //此组件需要被缓存 } }, { path: '/page2', name: 'page2', component: page2, meta: { keepAlive: true, // 此组件需要被缓存 } }, { path: '/page3', name: 'page3', component: page3, meta: { keepAlive: true, // 此组件需要被缓存 } } ] 钩子函数的执行顺序
vmware15,输入许可证时报“您无权输入许可证密钥,请请使用系统管理员账户重试”,切换到Administrator以后,并没有什么作用。
网上的各种进入cmd的方法也无效。
后来发现,只要是已经存在过安装的痕迹,再覆盖安装,就会出这个提示。新装的不会。
所以,删除之前的目录,重新安装,再次输入许可证即可。
转载于:https://www.cnblogs.com/Sabre/p/10695034.html
目录
Kubernetes之(十三)ConfigMap和Secret ConfigMap ConfigMap创建方式存储卷方式挂载configmap:使用nginx-www配置nginxSecret 创建 Secret Kubernetes之(十三)ConfigMap和Secret 简介
ConfigMap和Secret是kubernetes系统上两种特殊类型的存储卷,ConfigMao对象用于为容器中的应用提供配置数据以定制程序行为,不过年敏感的配置信息,例如密钥,证书等通常由Secret对象来进行配置,它们将相应的配置信息保存于对象中,而后在Pod资源上以存储卷的形式将其挂载并获取相关配置,以实现配置与镜像文件的解耦。
传统的实践过程中们需要对一个应用进行配置,只需要修改其配置文件通常有以下几种方式:
启动容器时,通过命令传递参数 command args自定义参数把配置文件写入镜像内通过环境变量的方式传递配置数据 cloud native的程序,一般通过环境变量加载配置通过enteypoint脚本预处理变量为配置文件中的配置信息挂载Docker卷传送配置文件 而在Kubernetes系统之中也存在这样的组件,就是特殊的存储卷类型。其并不是提供pod存储空间,而是给管理员或用户提供从集群外部向Pod内部的应用注入配置信息的方式。这两种特殊类型的存储卷:configMap和secret
ConfigMap:主要用于向Pod注入非敏感数据,使用时,用户将数据直接存储在ConfigMap对象当中,然后Pod通过使用ConfigMap卷进行引用,实现容器的配置文件集中定义和管理。
Secret:用于向Pod传递敏感信息,比如密码,私钥,证书文件等,这些信息如果在容器中定义容易泄露,Secret资源可以让用户将这些信息存储在急群众,然后通过Pod进行挂载,实现敏感数据和系统解耦的效果。
ConfigMap configmap是让配置文件从镜像中解耦,让镜像的可移植性和可复制性。许多应用程序会从配置文件、命令行参数或环境变量中读取配置信息。这些配置信息需要与docker image解耦,ConfigMap API给我们提供了向容器中注入配置信息的机制,ConfigMap可以被用来保存单个属性,也可以用来保存整个配置文件或者JSON二进制对象。
ConfigMap API资源用来保存key-value pair配置数据,这个数据可以在pods里使用,或者被用来为像controller一样的系统组件存储配置数据。虽然ConfigMap跟Secrets类似,但是ConfigMap更方便的处理不含敏感信息的字符串。 注意:ConfigMaps不是属性配置文件的替代品。ConfigMaps只是作为多个properties文件的引用。可以把它理解为Linux系统中的/etc目录,专门用来存储配置文件的目录。下面举个例子,使用ConfigMap配置来创建Kuberntes Volumes,ConfigMap中的每个data项都会成为一个新文件。
[root@master ~]# kubectl explain cm. KIND: ConfigMap VERSION: v1 FIELDS: apiVersion <string> data <map[string]string> kind <string> metadata <Object> ConfigMap创建方式 1、 通过 --from-literal: [root@master configmap]# kubectl create configmap nginx-config --from-literal=nginx_port=8080 --from-literal=server_name=myapp.white.com configmap/nginx-config created [root@master configmap]# kubectl get cm NAME DATA AGE nginx-config 2 4s [root@master configmap]# kubectl describe cm nginx-config Name: nginx-config Namespace: default Labels: <none> Annotations: <none> Data ==== nginx_port: ---- 8080 server_name: ---- myapp.
SpringCloud系列一之微服务 微服务架构微服务的优劣为什么是SpringCloud?SpringCloud的简介组件实际用处 微服务架构 微服务架构是一种架构模式,它提倡将单一应用程序划分成一组小的服务,服务之间相互协调、互相配合,为用户提供最终价值。每个服务运行在其独立的进程中,服务和服务之间采用轻量级的通信机制相互沟通(通常是基于HTTP的Restful API).每个服务都围绕着具体的业务进行构建,并且能够被独立的部署到生产环境、类生产环境等。另外,应尽量避免统一的、集中的服务管理机制,对具体的一个服务而言,应根据业务上下文,选择合适的语言、工具对其进行构。----Martin Fowler(马丁·福勒)
微服务的优劣 优点:
每个服务足够内聚,足够小,可以聚焦指定业务功能。开发简单,开发效率提高。松耦合,无论在开发和部署时都是独立的。可以使用不同语言开发微服务。微服务可以灵活的集成自动化测试和自动化部署工具。 缺点:
开发人员要处理分布式系统的复杂性,比如网络延迟,分布式事务,异步消息等。多服务造成运维的压力增加。接口的规范要更加完善,因为从单体系统中的代码依赖变为服务间的通信依赖。服务间的通信成本,数据一致性等问题 为什么是SpringCloud? 比较著名的微服务架构:阿里的dubbo,当当的dubbox,netflix的Eureka等,那么我们为什么选择SpringCloud呢?
刚刚列举的框架只是针对微服务的某一类问题进行解决,而SpringCloud则是解决微服务架构综合性解决框架,比如服务治理,容错,负载均衡,网关,时间总线等
SpringCloud的简介 简述:
SpringCloud是基于SpringBoot实现的微服务架构开发工具,它为微服务架构中设计的配置管理,服务治理,断路器,智能路由,控制总线,分布式会话,集群管理,提供了一种简单的开发方式。
组件:
独挑大梁类(独自启动不需要依赖其它组件)
Eureka,服务注册中心,特性有失效剔除、服务保护。Dashboard,Hystrix仪表盘,监控集群模式和单点模式,其中集群模式需要收集器Turbine配合。Zuul,API服务网关,功能有路由分发和过滤。Config,分布式配置中心,支持本地仓库、SVN、Git、Jar包内配置等模式。 润物无声类(融合在每个微服务中、依赖其它组件并为其提供服务)
Ribbon,客户端负载均衡,特性有区域亲和、重试机制。Hystrix,客户端容错保护,特性有服务降级、服务熔断、请求缓存、请求合并、依赖隔离。Feign,声明式服务调用,本质上就是Ribbon+Hystrix。Stream,消息驱动,有Sink、Source、Processor三种通道,特性有订阅发布、消费组、消息分区。Bus,消息总线,配合Config仓库修改的一种Stream实现。Sleuth,分布式服务追踪,需要搞清楚TraceID和SpanID以及抽样,如何与ELK整合。 组件实际用处 每个组件都不是平白无故的产生的,是为了解决某一特定的问题而存在。
Eureka和Ribbon,是最基础的组件,一个注册服务,一个消费服务。Hystrix为了优化Ribbon、防止整个微服务架构因为某个服务节点的问题导致崩溃,是个保险丝的作用。Dashboard给Hystrix统计和展示用的,而且监控服务节点的整体压力和健康情况。Turbine是集群收集器,服务于Dashboard的。Feign是方便我们程序员写更优美的代码的。Zuul是加在整个微服务最前沿的防火墙和代理器,隐藏微服务结点IP端口信息,加强安全保护的。Config是为了解决所有微服务各自维护各自的配置,设置一个统一的配置中心,方便修改配置的。Bus是因为config修改完配置后各个结点都要refresh才能生效实在太麻烦,所以交给bus来通知服务节点刷新配置的。Stream是为了简化研发人员对MQ使用的复杂度,弱化MQ的差异性,达到程序和MQ松耦合。Sleuth是因为单次请求在微服务节点中跳转无法追溯,解决任务链日志追踪问题的。
错误信息 Error parsing column 11 (IsConvent=1 - SByte)
“指定类型转换无效”
数据库:MySQL
ORM:Dapper
框架: .NET
外在显示:
排查及验证结果 MySQL:
数据类型为tinyint(1)
且 数据中有null、和正常值
C#:
且 定义为bool、int、byte等值类型或可为空的值类型去接收
时使用dapper就会出现这种错误。
解决方案: 类型不变,修改长度大于1,如tinyint(2)等 --已验证修改为2可用长度不变,修改字段类型为 samllint 或 bit等 --已验证修改为samllint(1)可用修改视图,将该列cast转换null值 --已验证将null转换为实际值可用C#中修改接收类型为引用类型,object、string类型等,但是null、0、1需要程序内或交给前端自己去转换 --已验证object、string正常接收 猜测原因:
dapper以SByte类型去识别接收导致转换异常。可能是dapper本身的一个坑。
SByte类型和Byte类型的差别只是有无正负值的区别。与sql中tinyint类型也很像,都是-128~127。
2019-04-11 Aurora 框架开发--租房信息管理系统踩坑
ORA-01722:无效数字ORA-06512:在“HEC3DEV.TRAIN_HRMS_CHECK_IN_PKG”,line196 ORA-06512:在 line3 问题所在:数据库存的字段类型为date类型,但是自己存储过程声明的变量为varchar2类型
数据类型不匹配。(第七行代码)变量声明改为date之后又报错为,本为number类型参数,但是接收到的数
据类型为date(第四十一行代码),应为在计算时间天数的时候使用了to_char()函数,将字段变量转为了
char类型
代码示例:
错误代码
--退房过程记录 procedure update_check_out(p_check_in_id number, p_contract_info_id number, p_check_in_date number, p_person_info_id number, p_house_info_id number, p_check_out_time varchar2,--错误变量类型 p_check_out_by number, p_last_updated_by number, --最后更新人 p_last_update_date date --最后更新时间 ) is v_residue_bed varchar2(30); v_check_in_time_from date; begin --更新人员状态 update train_hrms_person_info set person_status = 'ALREADY_CHECKOUT', last_updated_by = p_last_updated_by, last_update_date = sysdate where person_info_id = p_house_info_id; --更新房屋床位 select residue_bed into v_residue_bed from train_hrms_house_info where house_info_id = p_house_info_id; update train_hrms_house_info set residue_bed = v_residue_bed + 1, last_updated_by = p_last_updated_by, last_update_date = sysdate where house_info_id = p_house_info_id; --更新入住过程 更新入住天数,和退房日期 select check_in_time_from into v_check_in_time_from from train_hrms_check_in_process where check_in_id = p_check_in_id; update train_hrms_check_in_process set check_in_date = (p_check_out_time - to_char(v_check_in_time_from)),--错误变量类型 check_out_time = p_check_out_time, check_out_by = p_check_out_by, last_updated_by = p_last_updated_by, last_update_date = sysdate where check_in_id = p_check_in_id; 正确代码
LLVM语言参考手册 1. 摘要(Abstract)2. 简介(Introduction)2.1 结构良好性(Well-Formedness) 3. 标识符(Identifiers)4. 高级结构(High Level Structure)4.1 模块结构(Module Structure)4.2 链接类型(Linkage Types)4.3 调用约定(Calling Conventions)4.4 可见性风格(Visibility Styles)4.5 DLL存储类(DLL Storage Classes)4.6 线程本地存储模型(Thread Local Storage Models)4.7 运行时抢占说明符(Runtime Preemption Specifiers)4.8 结构类型(Structure Types)4.9 非整型指针类型(Non-Integral Pointer Type)4.10 全局变量(Global Variables)4.11 函数(Functions)4.12 别名(Aliases)4.13 IFuncs4.14 Comdats(此选项允许编译器以封装函数)4.15 命名元数据(Named Metadata)4.16 参数属性(Parameter Attributes)4.17 垃圾回收策略名称(Garbage Collector Strategy Names)4.18 前缀数据(Prefix Data)4.19 序言数据(Prologue Data)4.20 Personality函数(Personality Function)4.21 属性组(Attribute Groups)4.22 函数属性(Function Attributes)4.23 全局属性(Global Attributes)4.24 操作数包(Operand Bundles)4.24.1 逆优化操作数包(Deoptimization Operand Bundles)4.24.2 Funclet操作数包(Funclet Operand Bundles)4.24.3 GC转换操作数包(GC Transition Operand Bundles) 4.
-----2019-7-22 更新
mmdetection 维护人员看来很用心啊,已经适配到了最新的pytorch 1.1 并且修改了编译的方式,看来是要官方支持Windows了,但是目前win下有两个bug 。
sigmoid_focal_loss 和 mask 那个层的编译有问题。官方作者在github 上已经给予了回复。貌似是torch的bug
目前如果想用的话,只能先注释掉相关的代码。
商汤科技(2018 COCO 目标检测挑战赛冠军)和香港中文大学最近开源了一个基于Pytorch实现的深度学习目标检测工具箱mmdetection,支持Faster-RCNN,Mask-RCNN,Fast-RCNN等主流的目标检测框架,后续会加入Cascade-RCNN以及其他一系列目标检测框架。
相比于Facebook开源的Detectron框架,作者声称mmdetection有三点优势:performance稍高、训练速度稍快、所需显存稍小。
我很早就听说了这个工具箱,但是一直没有开源。现在总算是开源了,发现官方没有对Windows系统进行适配,于是就迫不及待地对win10 进行了适配。下面将记录一下
首先官方给出的编译的方法是./compile.sh 我们发现这里面其实是执行了4 个python脚本,但是这4个setup.py 在win下执行会报错,我修改了一个版本。
首先dcn 目录下的setup.py 修改为两个文件,否则链接时候会出现错误。分别为setup_conv.py setup_pool.py
import os
from setuptools import setup
from torch.utils.cpp_extension import BuildExtension, CUDAExtension,CppExtension,CUDA_HOME
import torch
def get_extensions():
this_dir = os.path.dirname(os.path.abspath(__file__))
extension = CppExtension
extra_compile_args = {"cxx": []}
define_macros = []
sources=[
'src/deform_conv_cuda.cpp',
'src/deform_conv_cuda_kernel.cu']
if torch.cuda.is_available() and CUDA_HOME is not None:
extension = CUDAExtension
extra_compile_args["nvcc"] = [
Dota开源目标检测数据集
DOTA-v1.5包含16个类别中的40万个带注释的对象实例,这是DOTA-v1.0的更新版本,它们都使用相同的航拍图像,但是DOTA-v1.5修改并更新了对象的注释,其中许多在DOTA-v1.0中丢失的10像素以下的小对象实例已被另外注释,DOTA-v1.5的类别也得到了扩展。
具体地说,增加了集装箱起重机的类别。与DOTA-v.1.0一致,DOTA-v1.5中的图像主要来自中国资源卫星数据和应用中心、Google Earth,卫星JL-1和卫星GF-2。使用来自Google Earth的图片必须遵守相应的使用条款:“Google Earth”使用条款。 DOTA-v1.5中的所有图像及其相关注释仅可用于学术目的,但禁止任何商业用途。
目标类别:
DOTA-v1.5中的对象类别包括:飞机,船舶,储罐,棒球场,网球场,篮球场,地面场地,港口,桥梁,小型车辆,大型车辆,直升机,环形交叉路口,足球场,篮球 法院和集装箱起重机。
标注格式:
在数据集中,每个实例的位置由四边形边界框注释,可以表示为“x 1,y 1,x 2,y 2,x 3,y 3,x 4,y 4”,其中(xi,yi)表示图像中定向边界框顶点的位置。顶点按顺时针顺序排列。 以下是采用的注释方法的可视化。黄点代表起点。 它指的是:(a)飞机的左上角,(b)大型车辆钻石的左上角,(c)扇形棒球的中心。
除了位置的注释之外,为每个实例分配类别标签,其来自上述15个所选类别中的一个,同时提供难以识别的标签,其指示实例是否难以被检测(1表示难,0表示不难)
图像的注释保存在具有相同文件名的文本文件中。 在第一行,给出了’imagesource’(来自GoogleEarth,GF-2或JL-1)。 在第二行,给出’gsd’(地面采样距离,一个图像像素的物理尺寸,以米为单位)。 请注意,如果缺少’gsd’,则注释为’null’。 从注释文本文件的第三行到最后一行,给出了每个实例的注释。 注释格式为:
Dota的数据集标签转Voc2007数据集的格式:
Dota的数据集的标签是txt的格式,而Voc2007数据集的格式是xml的格式,要实现转换,就得先搞清楚Dota的数据集的标签的数据组织结构,这个文章上面介绍了。如果想要代码,可以联系我。QQ:3239516597
将转换后的xml和图片放在一个文件夹下,用labelImg打开检验一下转换的是对是错。如下图所示。
主要参考最后两个方法
<?php namespace App\Http\Controllers; use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Log; use ZipArchive; class TestController extends Controller { /** * 忽略 * PS: * 1.mb_convert_encoding,iconv 可能会导致内存溢出 * 2.使用fputcsv() */ public function indexTwo() { set_time_limit(0); Log::info("IndexTwo起始时间:" . date('Y-m-d H:i:s', time())); header('Content-Type: application/vnd.ms-excel'); header('Content-Disposition: attachment;filename=2.csv'); header('Cache-Control: max-age=0'); $myfile = fopen('php://output', 'a'); $headlist = [ '编号1', '编号2', '编号3' ]; //输出Excel列名信息 foreach ($headlist as $key => $value) { //CSV的Excel支持GBK编码,一定要转换,否则乱码 $headlist[$key] = iconv('UTF-8', 'GBK', $value); } //将数据通过fputcsv写到文件句柄 fputcsv($myfile, $headlist); $select = [ "
js 监听 radio 的变化
var attach = document.getElementById('attach'); $('.selling_cards').click(function () { attach.value = $("input[name='remarks']:checked").val(); }) html 代码:
// 引入了 bootstrap form 表单样式,并且在基于 PHP 后台基础上 <div class="form-group zwd_attach_form"> <label for="attach" hidden="true">请输入订单备注信息(选填)</label> <input type="text" placeholder="订单备注信息(选填)" class="form-control" id="attach" value=""> </div> {if condition='$remarks neq []'} <div class="form-group zwd_attach_form remarks" id="remarks"> <label>快速备注</label> {volist name='remarks' id='remark'} <input type="radio" name="remarks" value="{$remark.remark}" class="selling_cards">{$remark.remark} {/volist} </div> {/if} css
.remarks { text-align: left; } .remarks label { margin-right: 20px; } .
img中的title属性和alt属性的异同:
(1)含义不同:使用alt属性是为了给那些不能看到你文档图像的浏览者提供的文字说明,也就是图片显示不了的时候显示文字;title属性指的是图片正常显示时鼠标悬停在图片上方显示的提示文字。
(2)在浏览器中的表现不同:在火狐浏览器和IE8浏览器中,当鼠标经过图片时title值会显示,而alt的值不会显示;只有在IE6浏览器中,当鼠标经过图片时title和alt的值都会显示。
https加载http不安全脚本提示解决方案 点关注不迷路,欢迎再来! 精简博客内容,尽量已专业术语来分享。
努力做到对每一位认可自己的读者负责。
帮助别人的同时更是丰富自己的良机。
目录 https加载http不安全脚本提示解决方案浏览器拦截示例1.chrome2.firefox3.IE 出现不安全脚本加载提示原因解决方案笔记心得 最近在工作中遇到https加载http页面时浏览器会有不安全脚本提示,为了提升客户体验,需要绕过这个不安全脚本加载提示。
https是当下的网站的主流趋势,有些大公司则完全要求用户必须使用https地址。然而对于以前http链接来说,我们往往就存在一个兼容性问题,不可能达到一次性的切换,应该在很长一段时间内https与http将共存。改https初看起来,其实就是一个域名指向的问题,也许我们只要将http的请求,直接跳转到https地址去,那么也就完成了https的切换。实际并不是这么简单的。
浏览器拦截示例 1.chrome 2.firefox 3.IE ie浏览器需要启用安全设置中的显示混合内容。
出现不安全脚本加载提示原因 因为https地址中,如果加载了http资源,浏览器将认为这是不安全的资源,将会默认阻止,这就会给你带来资源不全的问题了,比如:图片显示不了,样式加载不了,JS加载不了。因为样式类,基本上都是写在本地的,所以一般还可以,但是一些公共的js文件,往往就是存在于cdn或者其他服务器上,这时候,如果访问不了,可能就导致了业务就完全操作不了。比如:jquery效法加载失败,可能所有的操作、请求都将无效了。(举例:https的项目A页面加载http的服务器B时,浏览器就会进行拦截,出现加载不安全脚本提示)
解决方案 将http请求直接跳转至https请求,是一种解决办法,而且很多公司都是这么干的,比如百度什么的,但是前提是,你所有的服务都已切换https完成。
1. 最笨的方法,直接复制原有代码,写成两套代码,一套为http使用,一套为https使用,http和https各自指向各自服务。(本人开始就采用此方法,丢脸,但是后期会出现冲突问题,果断放弃)
2. 推荐方法,不指定具体协议,使用资源协议自适配,比如,当前为https页面,那么就是https资源,如果是http页面,那么就是http资源。
3.在request请求头部加标签(简单粗暴)
// meta tag <meta http-equiv="Content-Security-Policy" content="upgrade-insecure-requests"> 参考:https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/upgrade-insecure-requests
笔记心得 解决此问题前,建议先了解下https协议有助于理解和区分https与http区别与联系。
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sqlSessionFactory' defined in class path resource [applicationContext.xml]: Invocation of init method failed; nested exception is org.springframework.core.NestedIOException: Failed to parse config resource: class path resource [SqlMapConfig.xml]; nested exception is org.apache.ibatis.builder.BuilderException: Error parsing SQL Mapper Configuration. Cause: org.apache.ibatis.builder.BuilderException: Error parsing Mapper XML. Cause: org.apache.ibatis.builder.BuilderException: Error resolving class. Cause: org.apache.ibatis.type.TypeException: Could not resolve type alias 'pojo.User'. Cause: java.lang.ClassNotFoundException: Cannot find class: pojo.User
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1578)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:545)
先科补一下原理
1.我们是利用Redis与Spring Data 来做
虽然定时任务quartz框架也可以做
主要嫌弃定时任务做太多刷数据
服务器压力过大
2.Redis中自带发布/订阅者模式(publish/subscribe)
主要是使用Redis中key的过期时间来做
也就是环境配置好后
3. 用Java保存Redis 顺便设置key的时间
用Java代码订阅Redis中的__keyevent@dbindex__:expired
__keyevent@dbindex__:expired的主要作用是Redis中检测key到期时间的事件 大家都知道Redis中默认有16个库
如果用的是0号库
就检测__keyevent@0__:expired
dbindex表示Redis库的下标
Java代码检测到指定的key过期
然后再把数据库中key指定的数据刷新状态
4. 未写完,先贴出思路,后续会补全实际操作与代码
实际操作(mac) 1.安装homebrew(mac的安装神器,其他操作系统不需要安装)
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
2.开始下载redis(Windows系统直接去官网下载)
brew install redis 3.下载好后,启动redis
redis-server 4.在Redis目录中找到redis.conf修改配置文件
vim /usr/local/etc/redis.conf 修改 daemonize no 为 daemonize yes 默认启动就后台运行
修改 requirepass foobared 为 requirepass 123456 修改默认密码
修改 notify-keyspace-events "" 为 notify-keyspace-events Ex 打开此配置,其中Ex表示键事件通知里面的key过期事件,每当有过期键被删除时,会发送通知
修改配置完,记得重启Redis
5. 测试redis
ping
set key1 123456
get key1
前提条件 我之前的服务器网站是可以正常访问的,网页文件也是可以正常访问,但是今天的一个不经意操作(没有分析出来是哪个步骤导致的。。。),导致网页文件无法正常访问,但是服务器环境是正常的。
起因 安装好lamp环境后,之前一直正常,今天不知道什么操作,竟然出现这个问题(我只记得自己添加了一个数据库。。。)
问题:
寻找解决方法 网上百度,谷歌,尝试的方法都没有解决。但是提供了思路。
进入apache的安装目录。找到httpd.conf文件。
既然apahe是安装好的,也能够正常运行,就说明是配置的问题。
进入目录,找到文件
找到问题 值得庆幸的是,之前保存了备份文件,打开备份文件,一一对比,查找不同。
进行更改,找到出错位置
出错位置
备份文件是进行了注释的,而现在不知道什么操作,导致去掉了注释
解决问题 加上注释,重启apache,重启mysql。
网站正常了。。。
网站正常
Virtual hosts …
https://www.cnblogs.com/bkylee/p/7190886.html
1、最常用的disabled。
被禁用的 input 元素,不可编辑,不可复制,不可选择,不能接收焦点,后台也不会接收到传值。设置后文字的颜色会变成灰色。
EP:<input type="text" disabled="disabled" />
*disabled 属性无法与 <input type="hidden"> 一起使用。
2、readonly unselectable='on'。
该属性跟disable类似,input 元素,不可编辑,不可复制,不可选择,不能接收焦点,设置后文字的颜色也会变成灰色,但是后台可以接收到传值。
EP:<input type="text" readonly unselectable="on" >
3、readonly。
只读可复制。用户可以使用Tab键切换到该字段,可选择,可以接收焦点,还可以选中或拷贝其文本。后台会接收到传值。该属性可以防止用户对值进行修改。
EP:<input type="text" readonly="readonly">
*readonly 属性可与 <input type="text"> 或 <input type="password"> 配合使用。
ElasticSearch基本查询(Query查询) 1、数据准备
2、term查询和terms查询
3、控制查询返回的数量
4、返回版本号
5、match查询
6、指定返回的字段、显示字段
7、显示要的字段、去除不需要的字段
8、排序
9、 范围查询
10、wildcard查询
11、fuzzy实现模糊查询
12、高亮搜索结果
对人工智能感兴趣的同学,可以点击以下链接:
现在人工智能非常火爆,很多朋友都想学,但是一般的教程都是为博硕生准备的,太难看懂了。最近发现了一个非常适合小白入门的教程,不仅通俗易懂而且还很风趣幽默。所以忍不住分享一下给大家。点这里可以跳转到教程。
https://www.cbedai.net/u014646662
1、数据准备
put lib3 { "settings":{ "number_of_shards":3, "number_of_replicas":0 }, "mappings":{ "user":{ "properties":{ "name":{"type":"text"}, "address":{"type":"text"}, "age":{"type":"integer"}, "interests":{"type":"text"}, "birthday":{"type":"date"} } } } } post /lib3/user { "name":"lisi", "address":"shandong", "age":18, "interests":"youyong shufa changge tiaowu", "birthday":"2001-01-19" } post /lib3/user { "name":"wangwu", "address":"zhejiang", "age":22, "interests":"youyong shufa", "birthday":"1997-01-19" } post /lib3/user { "name":"zhangsan", "address":"zhejiang", "age":20, "interests":"youyong shufa changge changpao", "
今天帮同学做笔试题,在scanner的使用中遇到一个小坑,都怪自己学艺不精,赶紧来记录一下 问题来源 在线笔试题中,有时会给定多行输入,但是行数是未知的,这时该如何解决这一问题呢
容易想到但错误的解决方案 import java.util.Scanner; public class test { public static void main(String[] args) { Scanner sc = new Scanner(System.in); String s; while (sc.hasNext()){ System.out.println("loop"); if ((s = sc.nextLine()).equals("")) break; } } } 以上代码试图通过hasNext()方法解决这一问题,问题似乎是解决了,当没有输入的时候自动退出while不是很好吗?我们来看一下运行结果
注意看命令行中光标的位置,这是我点击了多次回车后的效果,可以看出,程序丝毫没有要退出while循环的迹象。
问题追踪 我们来看一下hasNext()方法的源码,注释中写的很清楚,这一方法很可能造成线程阻塞,也就是说如果方法发现缓冲区中没有数据,它就会一直等下去。观察源码,方法中第三行有一个while,聪明的同学可能会想,我们把sourceClosed改了,把数据源关闭是不是就可以了,答案也是否定的,因为线程在这个方法中已经阻塞了,没有多余的精力去分析现状并关闭数据源。
那到底该怎么解决这一问题呢?
往下看
解决方案 先放代码
import java.util.Scanner; public class test { public static void main(String[] args) { Scanner sc = new Scanner(System.in); String s; while (true){ System.out.println("loop"); if ((s = sc.nextLine()).equals("")) break; } } } 这一次就可以了,因为当线程不会在hasNext方法中阻塞了,一旦出现空行,我们可以自行读取,并退出循环。
发布的栅格图层一直显示不出来,但矢量图层可以正常显示,试了半天,发现原来是之前发布的图层未定义空间参考和投影,修改重新发布就可以正常调用啦。
随着国家的科技转型,经济的结构也发生了很多的变化,由以前的实体经济,还有一些重工业经济,在以前出去打工还可以通过干一些体力活,或者繁琐的工作来赚钱,但现在就大有不同,现在提倡的都是互联网+“”,所以我们程序员这一个职业在以后就会变得吃香,但是话虽如此你能不能进入一个好的企业又是另一方面。 现在从事IT的人员与有很多,学IT的方法也有很多,当然相应的有IT方面的学校也有很多,当然本科的大学在以后的就业方面比专科的要方便,那就是说专科生就业难吗?其实不让,只要你的面试做的好,一样可以进一些好企业。 注意事项: 第一,在面试前最好恶补一下相关的专业知识,不要在一些基本概念上闹笑话。有的应聘者认为,在面试时主考官肯定会出难题,但没有想到的是,主考官可能挑了一个相当简单的概念题,而应聘者则在阴沟里翻了船,支支吾吾说不清这个概念。所以,java面试技巧的第一项,就是要保证自己在知识上不犯错误。 第二,在面试时保持谦虚谨慎的态度,不要让自己成为无所不能的“超人”。有的应聘者在面对主考官的询问时,习惯于大吹特吹。明明自己没有很多的工作经验,却把自己包装成为一个java老手。其实,这是很容易露馅的。只要主考官出几道实战方面的题目,你就有可能暴露出自己的不足。为了能得到这份工作,还是保持谦虚谨慎的态度更好,更能让主考官认识到你的价值。
第三,要向主考官展示自己的个性,不要让他认为你只是一个普通的程序员。尽管应聘单位要招的是java程序员,但主考官也会注重你在团队合作、与人交往方面的能力。也就是说,他们需要的是有血有肉的java程序员,而不是一个只知道钻研技术的书呆子。所以,在应聘时,最好把自己多面手的功能显露出来。一般情况下,一个阳光、充满正能量的应聘者,更容易得到这份工作。
希望这些总结的三点可以帮助你
有以下场景:
你用了别人的UI框架,然后你发现,你给css动态赋的值,被UI框架的优先级更高的css覆盖了。你可以写js来改变它,但是如果有很多层循环+操作,你需要写一大段的js,此时js并不是最优的选择,你真正需要的是 'unset'属性
unset优先级
给某个关键字设置了unset,例如 color: unset; 它首选会选择继承父级的属性,然后才去选择继承本身属性值, 即: inherit > initial
例如:
本身属性值p和span设置了color值,如果设置了unset,就会去选择继承h_bg的color值。
HTML: <header class="h_bg"> <p class="reset">title title title</p> <span class='reset'>text text text</span> </header> 复制代码 CSS: p{ color:red; } span{ color:blue; } .h_bg{ color:#FFF; background:#DEDEDE; padding:20px; text-align:center; width:200px; height:200px; } .reset{ color:unset; //去掉这个属性,文字会优先使用span和P的color值 } 复制代码
课程概要 1、什么是自然语言处理
2、什么是深度学习(DL)
3、课程简介
4、为什么自然语言处理很难?
5、Deep NLP=Deep learning(深度学习)+NLP
一、什么是自然语言处理 自然语言处理是计算机科学,人工智能与语言学的交叉领域。目的:使得计算机能够处理/理解自然语言,以完成任务,比如购物,问答(siri,cortana等)充分理解并表征语言的含义是一个非常困难的任务自然语言处理层次
自然语言处理(NLP)的一些应用
– 拼写检查,关键词搜索,寻找同义词
– 从网站进行信息抽取,比如产品价格、日期、地点、人或者公司名字
– 分类:比如情感分类等
– 机器翻译(Machine translation)
– 人机对话在工业上,目前已经实现的自然语言处理(NLP)
– 搜索
– 在线广告匹配
– 自动/辅助翻译
– 市场或者金融的情感分析
– 语音识别
– 聊天机器人(Chatbots/Dialog agents):自动客户辅助,控制设备,产品排序等等人类的语言有什么特点? 人类语言是能够传递说话者/写作者想要表达的含义的系统:它不仅仅是一个环境信号,也是一种慎重准确的交流;有趣的是这样一种编码,即使是很小的孩子也能马上学习。人类语言是分离的/象征性的/分类象征系统我们用语言表示概念,比如rocket表示火箭,violin表示小提琴,并基于这些概念建立起我们的交流语言的分类象征性在交流中可以被编码为不同形式的信号(声音,手势,文字等),虽然形式不同,但是象征是一致的。大脑在进行编码的时候是连续的模式,然后通过连续的声音或者信号进行象征的表现。这种词汇巨大的象征编码会导致机器学习的一个问题:稀疏性(sparsity) 二、什么是深度学习(DL) 深度学习是机器学习的一个子领域。 在深度学习出现之前,大部分的机器学习方法奏效的原因是人类设计的表征和输入的特征,而机器学习主要的任务就是为了获得更好的预测而进行权重优化。而深度学习则相反,它将会从原始输入中尝试学习多层的表征与输出。 研究深度学习的原因 人工特征往往会有过度设定,不完整,需要花很长的时间设计和验证,而深度学习的特征很容易学习到。深度学习提供了一个灵活的,几乎是普遍性的,可以学习的框架来对世界、语言、图像进行表征。深度学习可以进行无监督学习也可以进行有监督学习从2010开始深度学习技术的表现开始远远超过于其他机器学习的技术,最早是在语音识别上将效果大大提升,接下来在计算机视觉领域有了大大的提升(ImageNet)。(大数据,算力提升以及新的模型算法以及想法) 三、课程简介 前置需求 熟练使用python多元微积分、线性代数基础概率和统计机器学习基础(损失函数,求导,梯度下降优化) 教学内容 理解并且能够使用有效的深度学习模型(会涉及到所有的基础模型,但是会对重要的有所侧重)理解人类语言以及理解和生产他们的困难理解并且能够建立系统来解决NLP的主要问题(单词相似,语法分析,机器学习,实体识别,问答系统,句子理解) 四、为什么自然语言处理很难? 表征、学习和使用语言知识、生活知识、情景知识以及图像知识是很困难的。人类的语言是很模糊的(不像程序语言)人类语言的解释依赖于现实世界、常识以及上下文知识 五、 Deep NLP=Deep learning(深度学习)+NLP 用表征学习和深度学习的方法去解决NLP的问题一些在NLP领域的重大提升 层次:语音,单词,句法,语义工具:词性、实体、句法分析应用:机器翻译,情感分析,自动问答 将单词含义表征为高维向量,将这些高维向量降维以后转化为2维进行可视化,可以看到相似的单词距离会比较近。
从计算余弦相似度,两个向量之间相似度越高,代表的单词越相似。
NLP层次的表征:语素,传统认为单词是由语素组成的,在深度学习中每个语素就是一个向量,神经网络会将两个向量合并成为一个向量
NLP工具:句法分析,神经网络可以确定句子的结构,以辅助解释。
NLP表征:语义
NLP应用:情感分析,传统的方法是使用词袋表征(忽视单词顺序)或者是人工设定否定特征(并不能捕捉到全部);基本的深度学习模型RNN就可以解决这个问题。
对话机器人/回答生成:一个简单的应用实例就是Google Inbox app。这是神经语言模型(Neural Language Model)的一个应用,是RNN(循环神经网络)的一个实例。
机器翻译:使用神经机器翻译(Neural Machine Translation)将源语言投射成向量然后输出生成的句子。
结论:所有层次进行向量表征,在下一节课将会介绍怎样进行单词表征。 相关笔记: (本文)斯坦福大学-自然语言处理与深度学习(CS224n) 笔记 第一课 介绍
JS如何将变量作为一个对象的Key var lastWord = 'last word'; var a = { 'first word': 'hello', [lastWord]: 'world' }; a['first word'] // "hello" a[lastWord] // "world" a['last word'] // "world" posted @ 2019-04-02 16:25 王维璋 阅读( ...) 评论( ...) 编辑 收藏
来自百度百科 先学习一下MOSFET 图1是典型平面N沟道增强型NMOSFET的剖面图。它用一块P型硅半导体材料作衬底,在其面上扩散了两个N型区,再在上面覆盖一层二氧化硅(SiO2)绝缘层,最后在N区上方用腐蚀的方法做成两个孔,用金属化的方法分别在绝缘层上及两个孔内做成三个电极:G(栅极)、S(源极)及D(漏极),如图所示。
图 1 从图1中可以看出栅极G与漏极D及源极S是绝缘的,D与S之间有两个PN结。一般情况下,衬底与源极在内部连接在一起,这样,相当于D与S之间有一个PN结。
原文链接:http://www.elecfans.com/d/708877.html 一文看懂MOSFET基础知识 什么是MOSFETMOSFET的原意是:MOS(Metal Oxide Semiconductor金属氧化物半导体),FET(Field Effect Transistor场效应晶体管),即以金属层(M)的栅极隔着氧化层(O)利用电场的效应来控制半导体(S)的场效应晶体管。
功率MOSFET的内部结构和电气符号如图所示,它可分为 NPN型和PNP型。NPN型通常称为N沟道型,PNP型通常称P沟道型。由图1可看出,对于N沟道型的场效应管其源极和漏极接在N型半导体上,同样对于P 沟道的场效应管其源极和漏极则接在P型半导体上。我们知道一般三极管是由输入的电流控制输出的电流。但对于场效应管,其输出电流是由输入的电压(或称场电压)控制,可以认为输入电流极小或没有输入电流,这使得该器件有很高的输入阻抗,同时这也是我们称之为场效应管的原因。
个人理解:
P代表positive表示里面有大量的正电荷,N代表negative表示里面有大量的负电荷 所以PN结,在P极接正电压,N极接负电压。此时正电荷受到两个力:正电压的排斥与负电压的吸引。负电荷同理,如此这般PN结就导通了。反之就不导通。
图 1 功率MOSFET的工作原理 截止:漏源极间加正电源,栅源极间电压为零。P基区与N漂移区之间形成的PN结J1反偏,漏源极之间无电流流过。导电:在栅源极间加正电压UGS,栅极是绝缘的,所以不会有栅极电流流过。但栅极的正电压会将其下面P区中的空穴推开,而将P区中的少子—电子吸引到栅极下面的P区表面当UGS大于UT(开启电压或阈值电压)时,栅极下P区表面的电子浓度将超过空穴浓度,使P型半导体反型成N型而成为反型层,该反型层形成N沟道而使PN结J1消失,漏极和源极导电。 个人理解:
NPN型的MOSFET是怎么导通的呢?
首先,在栅极加正电压,这样就会排斥衬[chèn]底——P型硅中的正电荷,同时吸引负电荷,这样在漏极与源极之间形成一层负电荷区域,这时再火上浇油在漏极加上正电压,源极加上负电压。 在双层诱惑下哪个受得了。所以源极的负电荷就会在栅极的掩护下,源源不断的往漏极去了。
电子是先从源极出发的,所以叫源极;而到漏极的电子,漏极没有留住,都漏掉了,所以叫漏极。
至于怎么分辨MOSFET的电路符号是N沟道还是P沟道。沟道的正负,就是衬底中通道的正负。电路符号中的箭头表示的是电子的流向。可以看到N沟道的电路符号中的箭头是指向栅极的,衬底下堆积的就是一层负电子,而这层负电子从漏极和源极的角度看,就是一条电子从源极通往漏极的沟,所以这个沟就叫做negative沟道,简称N沟道。 在所有半导体元件中, 箭头的意义表示p-n结的方向. MOS管符号箭头指向问题? - 呆涛的回答 - 知乎 https://www.zhihu.com/question/27955221/answer/38939126
衬底中的负电荷虽然很想投入栅极的怀抱,但是栅极之下是一层由二氧化硅(SiO2)形成的绝缘层,所以电子只能聚集在绝缘层的另一边,可望而不可即。也就不难理解为什么MOSFET是压控型的,以及为什么说MOSFET有很高的输入阻抗。
至于高输入阻抗有什么用?可以想象一个由电池V与电阻R1、电阻R2串联的电路,此时在电阻R2两边再并联一个电阻R3,那么电阻2两端的电压会因为R3的并联而下降,但是如果R3很大很大甚至趋向于无穷呢!此时R2的电压就不会受并联的影响,也更容易分析就是原来的V/(R1+R2)
功率MOSFET的基本特性静态特性: 其转移特性和输出特性如图2所示。
漏极电流ID和栅源间电压UGS的关系称为MOSFET的转移特性,ID较大时,ID与UGS的关系近似线性,曲线的斜率定义为跨导Gfs。
MOSFET的漏极伏安特性(输出特性):截止区(对应于GTR的截止区);饱和区(对应于GTR的放大区);非饱和区(对应于GTR的饱和区)。电力 MOSFET工作在开关状态,即在截止区和非饱和区之间来回转换。电力MOSFET漏源极之间有寄生二极管,漏源极间加反向电压时器件导通。电力 MOSFET的通态电阻具有正温度系数,对器件并联时的均流有利。动态特性:
其测试电路和开关过程波形如图3所示。
td(on)导通延时时间——导通延时时间是从当栅源电压上升到10%栅驱动电压时到漏电流升到规定电流的10%时所经历的时间。
tr上升时间——上升时间是漏极电流从10%上升到90%所经历的时间。 iD稳态值由漏极电源电压UE和漏极负载电阻决定。UGSP的大小和iD的稳态值有关,UGS达到UGSP后,在up作用下继续升高直至达到稳态,但iD已不变。
开通时间ton——开通延迟时间与上升时间之和。
td(off)关断延时时间——关断延时时间是从当栅源电压下降到90%栅驱动电压时到漏电流降至规定电流的90%时所经历的时间。这显示电流传输到负载之前所经历的延迟。tf下降时间——下降时间是漏极电流从90%下降到10%所经历的时间。关断时间toff——关断延迟时间和下降时间之和。
理解MOSFET的几个常用参数VDS,即漏源电压,这是MOSFET的一个极限参数,表示MOSFET漏极与源极之间能够承受的最大电压值。需要注意的是,这个参数是跟结温相关的,通常结温越高,该值最大。 RDS(on),漏源导通电阻,它表示MOSFET在某一条件下导通时,漏源极之间的导通电阻。这个参数与MOSFET结温,驱动电压Vgs相关。在一定范围内,结温越高,Rds越大;驱动电压越高,Rds越小。 Qg,栅极电荷,是在驱动信号作用下,栅极电压从0V上升至终止电压(如15V)所需的充电电荷。
也就是MOSFET从截止状态到完全导通状态,驱动电路所需提供的电荷,是一个用于评估MOSFET的驱动电路驱动能力的主要参数。 Id,漏极电流,漏极电流通常有几种不同的描述方式。根据工作电流的形式有,连续漏级电流及一定脉宽的脉冲漏极电流(Pulsed drain current)。这个参数同样是MOSFET的一个极限参数,但此最大电流值并不代表在运行过程中漏极电流能够达到这个值。它表示当壳温在某一值时,如果MOSFET工作电流为上述最大漏极电流,则结温会达到最大值。所以这个参数还跟器件封装,环境温度有关。
Eoss,输出容能量,表示输出电容Coss在MOSFET存储的能量大小。由于MOSFET的输出电容Coss有非常明显的非线性特性,随Vds电压的变化而变化。所以如果datasheet提供了这个参数,对于评估MOSFET的开关损耗很有帮助。并非所有的MOSFET手册中都会提供这个参数,事实上大部分datasheet并不提供。 Body Diode di/dt 体二极管的电流变化率,它反应了MOSFET体二极管的反向恢复特性。因为二极管是双极型器件,它受到电荷存储的影响,当二极管反向偏置时,PN结储存的电荷必须清除,上述参数正是反应这一特性的。
Vgs,栅源极最大驱动电压,这也是MOSFET的一个极限参数,表示MOSFET所能承受的最大驱动电压,一旦驱动电压超过这个极限值,即使在极短的时间内也会对栅极氧化层产生永久性伤害。一般来说,只要驱动电压不超过极限,就不会有问题。但是,某些特殊场合,因为寄生参数的存在,会对Vgs电压产生不可预料的影响,需要格外注意。 SOA,安全工作区,每种MOSFET都会给出其安全工作区域,不同双极型晶体管,功率MOSFET不会表现出二次击穿,因此安全运行区域只简单从导致结温达到最大允许值时的耗散功率定义。功率MOSFET的选型原则了解了MOSFET的参数意义,如何根据厂商的产品手册表选择满足自己需要的产品呢?可以通过以下四步来选择正确的MOSFET。
1) 沟道的选择 为设计选择正确器件的第一步是决定采用N沟道还是P沟道 MOSFET.在典型的功率应用中,当一个MOSFET接地,而负载连接到干线电压上时,该MOSFET就构成了低压侧开关。在低压侧开关中,应采用N沟 道MOSFET,这是出于对关闭或导通器件所需电压的考虑。当MOSFET连接到总线及负载接地时,就要用高压侧开关。通常会在这个拓扑中采用P沟道 MOSFET,这也是出于对电压驱动的考虑。 2) 电压和电流的选择 额定电压越大,器件的成本就越高。根据实践经验,额定电压应当大于干线电压或 总线电压。这样才能提供足够的保护,使MOSFET不会失效。就选择MOSFET而言,必须确定漏极至源极间可能承受的最大电压,即最大VDS.