基于shiro的权限设计
shiro介绍
Apache shiro是一个权限控制框架,它将安全认证抽取出来,实现用户身份认证,权限授权,加密,会话管理等功能,是一个通用的安全认证框架,而且还可以用于分布式集群。功能如下
1.验证用户
2.对用户执行访问控制,如:判断用户是否具有角色admin,判断用户是否拥有访问的资源权限。
3.无论c/s还是b/s都可以使用session api
4.可以使用多个用户数据源。例如一个是Oracle数据库,另外一个是MySQL数据库。
5.单点登录(SSO)功能
6."Remember Me"服务,类似于购物车的功能,shiro官方建议开启。
shiro核心部分

如图所示,shiro的4大组成部分:身份认证,授权,会话管理,加密
Authentication:身份认证,简称“登录”。
Authorization:授权,给用户分配角色或者权限资源
Session Manager:用户Session管理器,可以让c/s程序也可以使用Session控制权限。
Cryptography:将JDK中复杂的密码加密方式进行封装。
此外,shiro还提供一些扩展功能:
Web Support:针对web应用提供一些常用功能
Caching:缓存可以使得程序运行更有效率。
Concurrency:多线程相关功能。
Testing:帮助我们进行测试相关的功能。
"Run As":一个允许用户假设为另一个用户身份(如果允许)的功能,有时候在管理脚本时很有用。
"Remember Me":记住用户身份,提供类似购物车的功能。
shiro运行的大致流程:

Subject:主体,是与程序进行交互的对象,可以是人也可以是服务或者其他程序,通常理解为用户。所有的Subject实例都必须绑定到一个SecurityManager上。我们与Subject交互,运行时shiro会自动转化为与SecurityManager交互的特定的subject的交互。
SecurityManager:SecurityManager是shiro的核心,初始化时协调各个模块运行。然而,一旦SecurityManager协调完毕,SecurityManager会被单独留下,且我们只需要去操作Subject即可,无需操作SecurityManager。但是需要了解的是当我们与一个Subject进行交互时,实质上是SecurityManager在处理Subject的安全操作。
Realms:Realms在shiro中是程序和安全数据之间的“桥梁”或“连接器”。它用于获取安全数据来判断subject是否可以登陆,subject拥有什么权限。在配置realms时,需要至少一个realm。而且shiro还提供了一些常用的realms来连接数据源如LDAP数据源的JndiLdapRealm,JDBC数据源的JdbcRealm,ini文件数据源的iniRealm,Properties文件数据源的PropertiesRealm,等等,我们也可以插入自己的Realm实现来代表自定义的数据源。像其他组件一样,Realms也是由SecurityManager控制。
shiro架构

Subject:(org.apache.shiro.subject.Subject) 即主体,简称用户,主体既可以是用户也可以是程序,主体访问系统,系统需要对主体进行认证、授权。外部应用与subject进行交互,Subject记录了当前操作用户,将用户的概念理解为当前操作的主体,可能是一个通过浏览器请求的用户,也可能是一个运行的程序。Subject在shiro中是一个接口,接口中定义了很多认证授权相关的方法,外部程序通过subject进行认证授权,而Subject是通过SecurityManager安全管理器进行认证授权。
SecurityManager::(org.apache.shiro.mgt.SecurityManager)如上所述,SecurityManager是shiro的核心,协调shiro的各个组件。SecurityManager就是安全管理器,负责对全部的subject进行安全管理。通过SecurityManager可以完成Subject的认证、授权等,实质上SecurityManager是通过Authenticator对主体进行认证,通过Authorizer对主体进行授权,通过SessionManager进行会话管理等等。SecurityManager是一个接口,继承了Authenticator,Authorizer,SessionManager这三个接口。
Authenticator:(org.apache.shiro.authc.Authenticator) 即认证器,对用户身份进行认证,Authenticator是一个接口,shiro提供ModularRealmAuthenticator实现类,通过ModularRealmAuthenticator基本上可以满足大多数需求,也可以自定义认证器。
Authorizer:(org.apache.shiro.authz.Authorizer)即授权器,用户在通过认证器认证通过后,在访问时需要通过授权器判断用户是否有此功能的操作权限。最终是通过认证器对主体进行授权的。
Realm::(org.apache.shiro.realm.Realm)Realm即领域,相当于DataSource数据源,通过Realm存取认证、授权相关数据。SecurityManager通过认证器对主体进行安全认证需要通过Realm获取用户身份数据,比如:如果用户身份数据在数据库,那么Realm就需要从数据库获取用户的身份信息。授权也是如此,也需要通过Realm取出授权相关信息。注意:不要将Realm理解成只是从数据源获取数据,在Realm中还有认证授权校验的相关代码
SessionManager:(org.apache.shiro.session.SessionManager)会话管理。web应用中一般是web容器对Session进行管理,shiro框架定义了一套会话管理,它不依赖于web容器的Session,所以shiro可以使用在非web应用上,也可以将分布式应用的会话集中在一点进行管理,此特性可使它实现单点登录。
SessionDAO:SessionDAO即会话dao,是对Session会话操作的一套接口,比如要将Session存储到数据库,可以通过JDBC将会话存储到数据库。针对个性化的Session数据存储(存到数据库)需要使用SessionDAO。
CacheManager:(org.apahce.shiro.cache.CacheManager)缓存管理器,主要对Session和授权数据进行缓存,比如将授权数据通过cachemanager进行缓存管理,和ehcache整合对缓存数据进行管理,可以减少不必要的后台访问,提高应用效率,增加用户体验。
Cryptography:(org.apache.shiro.crypto.*)密码管理,提供了一套加密/解密组件,对JDK中的加密解密算法进行了封装,方便开发。比如提供常用的散列、加/解密等功能,比如MD5散列算法。
shiro相关jar
<dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-core</artifactId><version>1.2.3</version>
</dependency>
<dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-web</artifactId><version>1.2.3</version>
</dependency>
<dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-spring</artifactId><version>1.2.3</version>
</dependency>
<dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-ehcache</artifactId><version>1.2.3</version>
</dependency>
<dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-quartz</artifactId><version>1.2.3</version>
</dependency>
如果为了方便,可以使用所有
<dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-all</artifactId><version>1.2.3</version>
</dependency>
shiro认证(就是登录过程)
shiro认证过程

流程如下:
1.应用程序构建了一个终端用户认证信息AuthenticationToken实例后,调用Subject.login方法。
2.Subject的实例通常是DelegatingSubject类(或子类)的实例对象,在认证开始时,会委托应用程序设置的SecurityManager实例调用SecurityManager.login(token)方法。
3.SecurityManager接受到token(令牌)信息后会委托内置的Authenticator的实例(通常是ModularRealmAuthenticator类的实例)调用authenticator.authenticate(token)。ModularRealmAuthenticator在认证过程中会对设置的一个或者多个Realm实例进行适配,它实际上为shiro提供了一个可插拔的认证机制。
4.如果在应用程序中配置国歌Realm,ModularRealmAuthenticator会根据配置的AuthenticationStrategy(认证策略)来进行多Realm的认证过程。在Realm被调用后,AuthenticationStrategy将对没有给Realm的结果做出响应。注意:如果应用程序中仅配置了一个Realm,Realm将被直接调用而无需在配置认证策略。
5.判断每一个Realm是否支持提交的token,如果支持,Realm将调用getAuthenticationInfo(token);getAuthenticationInfo方法就是实际认证处理,我们通过覆盖Realm的doGetAuthenticationInfo方法来编写我们自定义的认证处理。
shiro认证的流程图如下:

shiro的入门程序(用户登陆和退出)
首先创建shiro-first.ini文件,并配置用户名密码
#对用户信息进行配置
[users]
#用户账号和密码
zhangsan=123456
lisi=654321
入门程序认证代码
// 用户登录和退出@Testpublic void testLoginAndLogout() {// 创建SecurityManager工厂。通过ini配置文件创建securityManagerFactory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro-first.ini");// 创建SecurityManagerSecurityManager securityManager = factory.getInstance();// 将securityManager设置到当前的运行环境中SecurityUtils.setSecurityManager(securityManager);// 从SecurityUtils中创建一个subjectSubject subject = SecurityUtils.getSubject();// 在认证提交前准备token(令牌)// 这里的账号和密码 将来是由用户输入进去的UsernamePasswordToken token = new UsernamePasswordToken("zhangsan", "123456");//执行认证提交try {//执行认证提交subject.login(token);} catch (AuthenticationException e) {e.printStackTrace();}// 是否认证通过boolean isAuthenticated = subject.isAuthenticated();System.out.println("是否认证通过:"+isAuthenticated);//退出操作subject.logout();// 是否认证通过isAuthenticated = subject.isAuthenticated();System.out.println("是否认证通过:"+isAuthenticated);}
常见的认证异常
UnknownAccountException
账号不存在异常如下:org.apache.shiro.authc.UnknownAccountException: No account found for user…
IncorrectCredentialsException
当输入密码错误会抛此异常,如下:org.apache.shiro.authc.IncorrectCredentialsException: Submitted credentials for token [org.apache.shiro.authc.UsernamePasswordToken - zhangsan, rememberMe=false] did not match the expected credentials.
更多如下:
DisabledAccountException(帐号被禁用)
LockedAccountException(帐号被锁定)
ExcessiveAttemptsException(登录失败次数过多)
ExpiredCredentialsException(凭证过期)等
自定义Realm
上边的程序中使用的是Shiro自带的iniRealm。iniRealm从配置文件中读取用户的信息,大部分情况下需要从系统的数据库中读取用户信息,所以需要自定义Realm。
shiro中提供的Realm接口的实现

实现自定义的Realm
public class CustomRealm extends AuthorizingRealm {// 设置Realm的名称@Overridepublic String getName() {return super.getName();}// 支持UsernamePasswordToken@Overridepublic boolean supports(AuthenticationToken token) {return token instanceof UsernamePasswordToken;}// 用于认证@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {// token是用户输入的// 第一步从token中取出身份信息String usercode = (String) token.getPrincipal();// 第二步:根据用户输入的usercode从数据库查询// ......// 如果查询不到返回null// 数据库中用户账号是zhangsanif (!usercode.equals("zhangsan")) {return null;}// 模拟从数据库中查询到密码String password = "123456";// 如果查询到返回认证信息AuthenticationInfoSimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(usercode, password,this.getName());return simpleAuthenticationInfo;}// 用于授权@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {return null;}
}
需要在shiro-realm.ini配置realm注入到securityManager
[main]
#自定义realm
customRealm=liuxun.test.shiro.realm.CustomRealm
#将realm设置到SecurityManager,相当于Spring中的注入
securityManager.realms=$customRealm
测试代码同入门程序,只需要将ini的地址改为shiro-realm.ini即可。
散列算法
用户登录一般都是加密的,所以需要用到散列算法。散列算法一般用于生成一段文本的摘要信息,散列算法不可逆,将内容可以生成摘要,无法将摘要转成原始内容。散列算法常用于对密码进行散列,常用的散列算法有MD5、SHA。
一般散列算法需要提供一个salt(盐)与原始内容生成摘要信息,这样做的目的是为了安全性,比如:111111的md5值是:96e79218965eb72c92a549dd5a330112,拿着“96e79218965eb72c92a549dd5a330112”去md5破解网站很容易进行破解,如果要是对111111和salt(盐,一个随机数)进行散列,这样虽然密码都是111111加不同的盐会生成不同的散列值。
下面是md5散列测试程序:
package liuxun.test.shiro.authentication;import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.crypto.hash.SimpleHash;public class MD5Test {public static void main(String[] args) {//原始密码String source = "123456";//盐String salt = "qwerty";//散列次数int hashIterations = 2;//上边散列1次:48474f975022f960bc2afbe49be581e8//上边散列2次:13f79dafcbbedc313273e2b891ac84d3//构造方法中://第一个参数:明文,原始密码//第二个参数:盐,通过使用随机字符串//第三个参数:散列的次数,比如散列两次,相当于md5(md5(''))Md5Hash md5Hash = new Md5Hash(source, salt, hashIterations);String password_md5 = md5Hash.toString();System.out.println(password_md5);//使用后SimpleHash//第一个参数:散列算法SimpleHash simpleHash = new SimpleHash("md5", source, salt, hashIterations);System.out.println(simpleHash.toString());}
}
建议对MD5进行散列时加salt(盐),相当于对原始密码+盐进行散列
正常使用时散列算法:
在程序中对"原始密码+盐"进行散列,将散列值存储到数据库中,并且还要将盐存储在数据库中,如果进行密码比对时,使用相同方法,将原始密码+盐进行散列,进行比对。
自定义的Realm加入散列算法
实际应用中是将盐和散列后的值存在数据库中,自动Realm从数据库中取出盐和加密后的值,由shiro完成密码校验。
代码如下:
// 用于认证@Overrideprotected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {// token保存了用户输入的身份信息userName和password// 第一步:从token中取出身份信息String userCode = (String) token.getPrincipal();// 第二步:根据用户输入的userCode从数据库查询// ....// 如果查询不到返回null 假设用户输入的账号是zhansgan// 模拟从数据库中查询账号是zhangsan的用户if (!userCode.equals("zhangsan")) {return null;}// 模拟从数据库中查询到密码(散列值)// 按照固定规则加密的结果,此密码是在数据库中存储的,原始密码是123456 盐是qwertyString password = "48474f975022f960bc2afbe49be581e8";// 盐,随机字符串,此随机字符串也是在数据库中存储的,模拟从数据库中获取String salt = "qwerty";// 如果查询到则返回认证信息AuthenticationInfoSimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(userCode, password,ByteSource.Util.bytes(salt), this.getName());return simpleAuthenticationInfo;}
在classpath下配置shiro-realm-md5.ini
[main]
#定义凭证匹配器
credentialsMatcher=org.apache.shiro.authc.credential.HashedCredentialsMatcher
#散列算法
credentialsMatcher.hashAlgorithmName=md5
#散列次数
credentialsMatcher.hashIterations=1#将凭证匹配器设置到Realm
customRealm=liuxun.test.shiro.realm.CustomRealmMd5
customRealm.credentialsMatcher=$credentialsMatcher
#将Realm设置到securityManager
securityManager.realms=$customRealm
测试代码同上,修改ini文件路径即可
shiro授权(查看用户有没有权限)
授权有三个核心元素:权限、角色和用户。
shiro权限声明通常是使用冒号分隔的表达式,权限表达式示例如下:
user:view 可查询用户数据
user:view, edit 可查询或编辑用户数据
user:*或user 可对用户数据进行所有操作
user:edit:123 可编辑id为123的用户数据。
Shiro支持两种角色模式:
1、传统角色:一个角色代表着一系列的操作,当需要对某一操作进行授权验证时,只需判断是否是该角色即可。这种角色权限相对简单、模糊,不利于扩展。
2、权限角色:一个角色拥有一个权限的集合。授权验证时,需要判断当前角色是否拥有该权限。这种角色权限可以对该角色进行详细的权限描述,适合更复杂的权限设计。
shiro授权的过程(可与认证过程比较来看)

1.在应用程序中调用授权验证方法(Subject的isPermitted或hasRole等)
2.Subject的实例通常是DelegatingSubject(或子类)的实例对象,在认证开始时,会委托应用程序设置的securityManager实例调用相应的isPermitted或hasRole方法。
3.接下来SecurityManager会委托内置的Authorizer的实例(默认是ModularRealmAuthorizer类的实例,类似于认证实例,它同样支持一个或多个Realm实例认证)调用相应的授权方法。
4.每一个Realm将检查是否实现了相同的Authorizer接口。然后,将调用Realm自己相应的授权验证方法。
注意:
当使用多个Realm时,不同于认证策略处理方式,在授权处理过程中:
(1) 当调用Realm出现异常时,将立即抛出异常,结束授权验证。
(2) 只要有一个Realm验证成功,那么将认为授权成功,立即返回,结束认证。
Shiro有3中认证策略的具体实现:
(1) AtLeastOneSuccessfulStrategy 只要有一个(或更多)的Realm验证成功,那么认证将被视为成功 (2) FirstSuccessfulStrategy 第一个Realm验证成功,整体认证将被视为成功,且后续Realm将被忽略 (3) AllSuccessfulStrategy 所有Realm成功,认证才视为成功
shiro的授权流程

shiro的授权方式
shiro支持三种方式的授权:编程式、注解式、标签式
方式一:编程式,通过写if/else授权代码块完成
Subject subject = SecurityUtils.getSubject();
if(subject.hasRole("admin")){
//有权限
}else{
// 无权限
}
方式二:注解式,通过在执行的Java方法上放置相应的注解完成。
@RequiresRoles("admin")
public void hello(){
//有权限
}
方式三:JSP/GSP标签,页面通过相应的标签完成
<shiro:hasRole name="admin">
</shiro:hasole>
创建存放权限的配置文件shiro-permission.ini 如下:
#用户
[users]
#用户zhang的密码是123,此用户具有role1和role2两个角色
zhang=123,role1,role2
wang=123,role2#权限
[roles]
#角色role1对资源user拥有create、update权限
role1=user:create,user:update
#角色role2对资源user拥有create、delete权限
role2=user:create,user:delete
#role3对资源user拥有create权限
role3=user:create
在ini文件中用户、角色、权限的配置规则是:
" 用户名=密码,角色1,角色2 .... "
“ 角色=权限1,权限2...... ”
首先根据用户名查找角色,再根据角色查找权限,角色是权限的集合
权限字符串规则
权限字符串的规则是:“资源标识符:操作:资源实例标识符”,意思是对哪个资源的哪个实例具有什么操作,“:”是资源/操作/实例的分割符,权限字符串也可以使用通配符。
例子:
用户创建权限:user:create,或user:create:
用户修改实例001的权限:user:update:001
用户实例001的所有权限:user:*:001
权限测试代码
测试代码同认证代码,注意ini地址改为shiro-permission.ini,主要掌握其授权方法
注意:在用户认证通过后才能执行下边的授权
// 角色授权、资源授权测试@Testpublic void testAuthorization() {// 创建SecurityManager工厂Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro-permission.ini");// 创建SecurityManagerSecurityManager securityManager = factory.getInstance();// 将SecurityManager设置到系统运行环境,和Spring整合后将SecurityManager配置在Spring容器中,一般单例管理SecurityUtils.setSecurityManager(securityManager);// 创建subjectSubject subject = SecurityUtils.getSubject();// 创建token令牌UsernamePasswordToken token = new UsernamePasswordToken("zhangsan", "123");// 执行认证try {subject.login(token);} catch (AuthenticationException e) {e.printStackTrace();}System.out.println("认证状态:" + subject.isAuthenticated());// 认证通过后执行授权// 基于角色的授权// hasRole传入角色标识boolean ishasRole = subject.hasRole("role1");System.out.println("单个角色判断 " + ishasRole);// hasAllRoles 是否拥有多个角色boolean hasAllRoles = subject.hasAllRoles(Arrays.asList("role1", "role2", "role3"));System.out.println("多个角色判断 " + hasAllRoles);//使用check方法进行授权,如果授权不通过会抛出异常,用于断言subject.checkRole("role2");//基于资源的权限//isPermitted传入权限标识符boolean isPermitted = subject.isPermitted("user:create:1");System.out.println("单个权限判断 "+isPermitted);boolean isPermittedAll = subject.isPermittedAll("user:create:1","user:delete");System.out.println("多个权限判断 "+isPermittedAll);//使用check方法进行授权测试,如果授权不通过会抛出异常subject.checkPermission("item:delete");}
使用check方法测试授权失败会抛出异常:org.apache.shiro.authz.UnauthorizedException
上边的程序通过shiro-permission.ini对权限信息进行静态配置,实际开发中从数据库中获取权限数据。就需要自定义Realm,由Realm从数据库查询权限数据。Realm根据用户身份信息查询权限数据,将权限数据返回给authorizer(授权器)。
在原来自定义的Realm类中完善doGetAuthorizationInfo方法,此方法需要完成以下功能:根据用户身份信息从数据库中查询权限字符串,由shiro进行授权。
// 用于授权@Overrideprotected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {//从principals获取身份信息//将getPrimaryPrincipal方法返回值转为真实类型//(在上边的doGetAuthenticationInfo认证通过后填充到SimpleAuthenticationInfo中身份类型)String userCode = (String) principals.getPrimaryPrincipal();//根据身份信息从数据库中获取权限信息//模拟从数据库中取到的数据List<String> permissions = new ArrayList<String>();permissions.add("user:create");//用户创建permissions.add("items:add");//商品添加权限//....//查询到权限数据,返回授权信息(要包括上边的permissions)SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();//将上边查询到的授权信息填充到simpleAuthorizationInfo对象中simpleAuthorizationInfo.addStringPermissions(permissions);return simpleAuthorizationInfo;}
ini配置文件还使用认证阶段用的,不用改变(即在shiro-realm.ini中配置自定义realm,将realm设置到securityManager)。注意:shiro-realm是配置自定义的Realm,是从数据库中获取权限数据,所以不需要再配置[roles]了。
[main]
#自定义realm
customRealm=liuxun.test.shiro.realm.CustomRealm
#将realm设置到SecurityManager,相当于Spring中的注入
securityManager.realms=$customRealm
授权流程总结
1.对subject进行授权,调用isPermitted("permission串")
2.SecurityManager执行授权,通过ModularRealmAuthorizer执行授权
3.ModularRealmAuthorizer执行realm(自定义的CustomRealm)从数据库查询权限数据(调用realm的授权方法doGetAuthorizationInfo)
4.realm从数据库查询权限数据,返回给ModularRealmAuthorizer
5.ModularRealmAuthorizer调用PermissionResolver进行权限串比对
6.如果比对后,isPermitted中"permission串" 在realm查询到的权限数据中,说明用户访问permission串有权限,否则没有权限,抛出异常。
相关文章:

C++ 中隐藏DOS调用的命令行窗口
转自:http://hi.baidu.com/jackyho2000/blog/item/b5c5fabdd3b4db0019d81fbb.html 我演示了一下在MFC程序中怎么应用DOS的dir的命令,可是我们遇到了需要解决的问题,首先就是文件dir.txt的残留问题,其实这个问题很简单,…

Citrix Avalon安装实验手册之一----Avalon概述及实验环境准备
“Avalon”(阿瓦隆)是思杰下一代桌面/应用交付产品的项目名称,其核心目标是把现有Windows应用和桌面转换成云服务。 其中你最熟悉的XenApp和XenDesktop就是Avalon项目的核心所在。Avalon这个全新解决方案将XenApp、XenDesktop、CloudGateway、…

图片像素、英寸、厘米之间的单位换算
转自:http://hi.baidu.com/cjg501/blog/item/f040fc0898d5379f0b7b8244.html 今天朋友用photoshop处理图片时要把图片保存指定的大小,但她只对厘米要形像感,可是在软件里保存的图片没有这个单位,只能保存的单位为像素;…

创客集结号_你知道单机片和Arduino之间的区别吗
Arduino 是一款便捷灵活、方便上手的开源电子原型平台,包含硬件和软件都是开源的。 开源硬件指与自由及开放原始码软件相同方式设计的计算机和电子硬件。开源硬件开始考虑对软件以外的领域开源,是开源文化的一部分。这个词主要是用来反映自由释放详细信息…

痛!“做C#半年,挣的不如做AI 1个月?”看到第二句泪目……
前两天在网上发现一个热门话题:“做开发一年,在北京月薪不到1万,有点迷茫。” 其中,这个回答我永远忘不了:来源:库库的派派知乎回答,已取得授权在这短短的一条信息里,小编佩服不仅…

刷新记录,算法开源!字节跳动获人体姿态估计竞赛双冠 | CVPR 2019
整理 | Jane出品 | AI科技大本营(id:rgznai100)【导读】6 月 16--20 日,计算机视觉与模式识别领域顶会 CVPR 2019 在美国长滩举行。每年的 CVPR 盛会除了精彩的论文分享、Workshop 与 Tutorial,还会举办多场涵盖计算机…

java 赋值,算术,一元操作符(翻译自Java Tutorials)
原文出自 http://www.cnblogs.com/ggjucheng/archive/2012/12/15/2819621.html 英文出自 http://docs.oracle.com/javase/tutorial/java/nutsandbolts/op1.html 简单赋值操作符 见到的最常用的操作符之一就是简单赋值操作符"".它把值从操作符的右边赋予到左边&#x…

初识Kubernetes(K8s):理论基础
Kubernetes是什么?Kubernetes,简称K8s,是用8代替8个字符“ubernete”而成的缩写。Kubernetes是Google开源的一个容器编排引擎,同时也是一个开源的容器集群管理系统,可以实现容器应用的自动化部署、自动扩缩容、监控和维…
Sobel算子及cvSobel
转自:http://blog.sina.com.cn/s/blog_4bdbec750100mufo.html 由于项目里要用到边缘检测,所以今天研究了一下最简单的梯度的方法。 首先,我们来开一下计算机是如何检测边缘的。以灰度图像为例,它的理论基础是这样的,如…

python全栈开发笔记---------函数
一 数学定义的函数与python中的函数 初中数学函数定义:一般的,在一个变化过程中,如果有两个变量x和y,并且对于x的每一个确定的值,y都有唯一确定的值与其对应,那么我们就把x称为自变量,把y称为因…

OpenCV中的内存泄露问题(cvLoadImage,cvCloneImage)
转自:http://apps.hi.baidu.com/share/detail/30893646 在做项目的过程中,使用OpenCV经常会出现一些内存泄露问题,自己编写的程序出现问题还情有可原,但若是库函数调用和使用时出现,却很令我恼火。花了好长时间和实践的…

41款实用工具,数据获取、清洗、建模、可视化都有了
诸如结构式访谈、非结构式访谈、开放式问卷调查、封闭式问卷调查、记录评论和观察等技术统称为事实调查方法。这种事实调查方法和其他数据获取方法可以采取自动化,而不必使用人工方法。使用具有专用软件的物理设备(如终端、传感器和扫描仪等)…

OpenCV中的内存泄漏检测
转自:http://chaishushan.blog.163.com/blog/static/130192897200911685559809/ 内存泄漏时程序开发中经常遇到的问题. 而且出现内存泄漏很难检测,但是其导致的结果却是灾难性的. 这里讲一下opencv中内存泄漏检测的一些技巧.OpenCV中关于内存管理主要涉及到以下3个函…

一文全面了解基于内容的推荐算法
作者丨gongyouliu来源 | 转载自大数据与人工智能(ID:ai-big-data)这篇文章我们主要关注的是基于内容的推荐算法,它也是非常通用的一类推荐算法,在工业界有大量的应用案例。本文会从什么是基于内容的推荐算法、算法基本原理、应用场…

[Nginx优化]分享nginx配置文件及优化说明
1、系统及内核方面 根据服务器用途,建议系统最小化安装或针对web服务器进行系统内核重新编译;在内核参数的一些优化,如下: # Add net.ipv4.tcp_max_syn_backlog 65536 #表示SYN队列的长度 net.core.netdev_max_backlog 3…

laravel项目composer安装
1.下载 Composer (https://pkg.phpcomposer.com/#how-to-install-composer) 安装前请务必确保已经正确安装了 PHP。打开命令行窗口并执行 php -v 查看是否正确输出版本号。 打开命令行并依次执行下列命令安装最新版本的 Composer: 复制php -r…

淘宝装修:第一日 —— 图片轮播
先添加一个自定义内容区,进入源码编辑,如下图所示: 添加源码如下: <TABLE border0 cellSpacing0 cellPadding0 width773 height220> <TBODY> <TR> <TD width773> <P> <MARQUEE height220 behavi…

强化学习大规模应用还远吗?Youtube推荐已强势上线
来源 | 转载自深度传送门导读:本文将介绍在深度学习的强力驱动下,给推荐系统工业界所带来的最前沿的变化。本文主要根据几大顶会2019的最新论文,总结一下深度强化学习给推荐系统以及CTR预估工业界带来的最新进展。 凡是Google出品,…

layui select 与 vue 的结合使用
2019独角兽企业重金招聘Python工程师标准>>> 1. 创建一个select元素 <form class"layui-form layui-form-pane all-account-filter-form"><div class"layui-form-item"><div class"layui-inline"><label class&…

OpenCV 2.2.0 CvvImage的使用
转自:http://blog.csdn.net/raocong2010/archive/2011/01/17/6146158.aspx# 前几日,OpenCV 2.2.0版本出现了...但是...以前版本的CvvImage类不见了...为了能够继续使用这个类,下面把这个类的源代码贴出来,使用的时候将该代码加入到…

c/c++标准预定义宏
转自:http://www.eefocus.com/andysun001/blog/10-06/192018_008b3.html 一、标准预定义宏The standard predefined macros are specified by the relevant language standards, so they are available with all compilers that implement those standards. Older c…

阿里AI攻克心血管识别技术,冠脉中心线提取论文入选国际医学影像会议
阿里在医疗AI领域取得新进展,继创下肺结节检测、肝结节诊断技术的重大突破后,又攻克了难度系数更高的心血管识别技术。 近日,阿里达摩院机器智能实验室有关冠状动脉中心线提取的论文已被国际顶级医学影像会议MICCAI 2019提前接收。 阿里AI论…

自由程序员在国外
可靠的做法是,在一些像oDesk这样的网站上找一些临时开发任务,在Linked In网站上提交一份个人简历。这样将有助于你在出行后尽早的找到可干的项目,而不必到时大减价来抢其他程序员的活儿(或消减自己的预算)。 从来不缺乏你可以捐赠代码的开源项…

关于spring aop Advisor排序问题
关于spring aop Advisor排序问题 当我们使用多个Advisor的时候有时候需要排序,这时候可以用注解org.springframework.core.annotation.Order或者实现org.springframework.core.Ordered接口。 示例代码: import org.aspectj.lang.ProceedingJoinPoint; im…

NLP重大突破?一文读懂XLNet“屠榜”背后的原理
作者 | 李理 原文链接:https://fancyerii.github.io/2019/06/30/xlnet-theory/ 本文介绍XLNet的基本原理,读者阅读前需要了解BERT等相关模型,不熟悉的读者建议学习BERT课程。 语言模型和BERT各自的优缺点 在论文里作者使用了一些术语&#…

CSS3支持IE6, 7, and 8的边框属性
我们都知道,IE 6,7不支持新增加的CSS3属性,甚至与IE8是CSS3还没有完全准备好。你知道吗,今天给大家分享一个脚本工具,可以帮助您启用CSS3的支持IE浏览器(IE6)与新的CSS3属性,包括:bo…

解决:VS 2005/2008 中 fstream 不能处理带有中文路径的问题
转自:http://blog.csdn.net/code_robot/archive/2010/06/23/5688867.aspx 有时候用ifstream或ofstream打开带有中文路径的文件会失败。 解决办法:1、使用C语言的函数设置为中文运行环境setlocale(LC_ALL,"Chinese-simplified"); 2、使用STL函…

NLP文本标注工具与平台(数据标注公司)
最近在做NLP相关项目,包括句法分析、情感分析等,有大量数据需要标注。我评估了几个文本标注工具,也接触了几家数据标注公司和平台,总结如下,供各位参考。 文本标注平台(标注外包公司) 数据标注公…

一文读懂基于神经网络的图片风格转移
作者 | moliam转载自 CSDN 博客前言将A图片的风格转移到B图片上,指的是将A图片的抽象艺术风格(如线条、色彩等等)和B图片的内容框架合成为一幅图。自然地,A图片称为风格图,而B图片就称为内容图。就像这样:左…
【物联网中间件平台-01】真正面向物联网的组态软件 YFIOs和YFHMI的前生今世
1前言 从2001年进入工控领域以来,前后7年多的时间开发了诸如二型计量监控系统、焦炉四大机车自动化系统、烧结配水监控系统、隧道广告影像系统、通用组态软件、嵌入式系统组态软件(基于WINCE系统)、LED视频影像系统和ICU病室输液管理等系统。…