首页 文章 精选 留言 我的

精选列表

搜索[x265编码],共10012篇文章
优秀的个人博客,低调大师

java安全编码指南之:lock和同步的正确使用

简介 在java多线程环境中,lock和同步是我们一定会使用到的功能。那么在java中编写lock和同步相关的代码之后,需要注意哪些问题呢?一起来看看吧。 使用private final object来作为lock对象 一般来说我们在做多线程共享对象的时候就需要进行同步。java中有两种同步方式,第一种就是方法同步,第二种是同步块。 如果我们在实例方法中使用的是synchronized关键字,或者在同步块中使用的是synchronized(this),那么会以该该对象的实例作为monitor,我们称之为intrinsic lock。 如果有恶意代码恶意获取该对象的锁并且释放,那么我们的系统将不能及时响应正常的服务,将会遭受到DOS攻击。 解决这种问题的方法就是使用private final object来作为lock的对象。因为是private的,所以恶意对象无法获取到该对象的锁,从而避免了问题的产生。 如果是在类方法(static)中使用了synchronized关键字,那么将会以这个class对象作为monitor。这种情况下,恶意对象可以通过该class的子类或者直接获取到该class,然后通过调用getClass()获取到class对象,从而进行加锁操作,让正常服务无法获取到锁。 所以,我们推荐使用private final object来作为lock对象。 下面举几个例子来说明: public class SynObject { public synchronized void doSomething(){ //do something } public static void main(String[] args) throws InterruptedException { SynObject synObject= new SynObject(); synchronized (synObject){ while (true){ //loop forever Thread.sleep(10000); } } } } 上面代码可能使我们最常使用的代码,我们在对象中定义了一个synchronized的doSomething方法。 如果有恶意代码直接拿到了我们要调用的SynObject对象,并且直接对其进行同步,如上例所示,那么这个对象的锁将永远无法释放。最终导致DOS。 我们看第二种写法: public Object lock = new Object(); public void doSomething2(){ synchronized (lock){ //do something } } 上面的例子中,我们同步了一个public对象,但是因为该对象是public的,所以恶意程序完全可以访问该public字段,并且永久获得这个对象的monitor,从而产生DOS。 再看下面的一个例子: private volatile Object lock2 = new Object(); public void doSomething3() { synchronized (lock2) { // do something } } public void setLock2(Object lockValue) { lock2 = lockValue; } 上面的例子中,我们定义了一个private的lock对象,并且使用它来为doSomething3方法加锁。 虽然是private的,但是我们提供了一个public的方法来对该对象进行修改。所以也是有安全问题的。 正确的做法是使用private final Object: private final Object lock4= new Object(); public void doSomething4() { synchronized (lock4) { // do something } } 我们再考虑一下静态方法的情况: public static synchronized void doSomething5() { // do something } synchronized (SynObject.class) { while (true) { Thread.sleep(10000); } } 上面定义了一个public static的方法,从而锁定的是class对象,恶意代码可以恶意占有该对象的锁,从而导致DOS。 不要synchronize可被重用的对象 之前我们在讲表达式规则的时候,提到了封装类对象的构建原则: 对于Boolean和Byte来说,如果直接从基础类值构建的话,也是同一个对象。 而对于Character来说,如果值的范围在\u0000 to \u007f,则属于同一个对象,如果超出了这个范围,则是不同的对象。 对于Integer和Short来说,如果值的范围在-128 and 127,则属于同一个对象,如果超出了这个范围,则是不同的对象。 举个例子: Boolean boolA=true; Boolean boolB=true; System.out.println(boolA==boolB); 上面从基础类型构建的Boolean对象其实是同一个对象。 如果我们在代码中使用下面的Boolean对象来进行同步,则可能会触发安全问题: private final Boolean booleanLock = Boolean.FALSE; public void doSomething() { synchronized (booleanLock) { // ... } } 上面的例子中,我们从Boolean.FALSE构建了一个Boolean对象,虽然这个对象是private的,但是恶意代码可以通过Boolean.FALSE来构建一个相同的对象,从而让private规则失效。 同样的问题也可能出现在String中: private final String lock = "lock"; public void doSomething() { synchronized (lock) { // ... } } 因为String对象有字符串常量池,直接通过字符串来创建的String对象其实是同一个对象。所以上面的代码是有安全问题的。 解决办法就是使用new来新创建一个对象。 private final String lock = new String("LOCK"); 不要sync Object.getClass() 有时候我们想要同步class类,Object提供了一个方便的getClass方法来返回当前的类。但是如果在父类和子类的情况下,子类的getClass会返回子类的class类而不是父类的class类,从而产生不一致对象同步的情况。 看下面的一个例子: public class SycClass { public void doSomething(){ synchronized (getClass()){ //do something } } } 在SycClass中,我们定义了一个doSomething方法,在该方法中,我们sync的是getClass()返回的对象。 如果SycClass有子类的情况下: public class SycClassSub extends SycClass{ public void doSomethingElse(){ synchronized (SycClass.class){ doSomething(); } } } doSomethingElse方法实际上获得了两个锁,一个是SycClass,一个是SycClassSub,从而产生了安全隐患。 在sync的时候,我们需要明确指定要同步的对象,有两种方法指定要同步的class: synchronized (SycClass.class) synchronized (Class.forName("com.flydean.SycClass")) 我们可以直接调用SycClass.class也可以使用Class.forName来获取。 不要sync高级并发对象 我们把实现了java.util.concurrent.locks包中的Lock和Condition接口的对象称作高级并发对象。比如:ReentrantLock。 这些高级并发对象看起来也是一个个的Lock,那么我们可不可以直接sync这些高级并发对象呢?看下面的例子: public class SyncLock { private final Lock lock = new ReentrantLock(); public void doSomething(){ synchronized (lock){ //do something } } } 看起来好像没问题,但是我们要注意的是,我们自定义的synchronized (lock)和高级并发对象中的Lock实现是不一样的,如果我们同时使用了synchronized (lock)和Lock自带的lock.lock(),那么就有可能产生安全隐患。 所以,对于这些高级并发对象,最好的做法就是不要直接sync,而是使用他们自带的lock机制,如下: public void doSomething2(){ lock.lock(); try{ //do something }finally { lock.unlock(); } } 不要使用Instance lock来保护static数据 一个class中可以有static类变量,也可以有实例变量。类变量是和class相关的,而实例变量是和class的实例对象相关的。 那么我们在保护类变量的时候,一定要注意sync的也必须是类变量,如果sync的是实例变量,就无法达到保护的目的。 看下面的一个例子: public class SyncStatic { private static volatile int age; public synchronized void doSomething(){ age++; } } 我们定义了一个static变量age,然后在一个方法中希望对其累加。之前的文章我们也讲过了,++是一个复合操作,我们需要对其进行数据同步。 但是上面的例子中,我们使用了synchronized关键字,同步的实际上是SyncStatic的实例对象,如果有多个线程创建多个实例对象同时调用doSomething方法,完全是可以并行进行的。从而导致++操作出现问题。 同样的,下面的代码也是一样的问题: private final Object lock = new Object(); public void doSomething2(){ synchronized (lock) { age++; } } 解决办法就是定义一个类变量: private static final Object lock3 = new Object(); public void doSomething3(){ synchronized (lock3) { age++; } } 在持有lock期间,不要做耗时操作 如果在持有lock期间,我们进行了比较耗时的操作,像I/O操作,那么持有lock的时间就会过长,如果是在高并发的情况下,就有可能出现线程饿死的情况,或者DOS。 所以这种情况我们一定要避免。 正确释放锁 在持有锁之后,一定要注意正确的释放锁,即使遇到了异常也不应该打断锁的释放。 一般来说锁放在finally{}中释放最好。 public void doSomething(){ lock.lock(); try{ //do something }finally { lock.unlock(); } } 本文的代码: learn-java-base-9-to-20/tree/master/security 本文已收录于 http://www.flydean.com/java-security-code-line-lock/ 最通俗的解读,最深刻的干货,最简洁的教程,众多你不知道的小技巧等你来发现! 欢迎关注我的公众号:「程序那些事」,懂技术,更懂你!

优秀的个人博客,低调大师

IDEA中这么玩MyBatis,让编码速度飞起!

云栖号资讯:【点击查看更多行业资讯】在这里您可以找到不同行业的第一手的上云资讯,还在等什么,快来! IDEA 逆向 MyBatis 工程时,不像支持 Hibernate 那样有自带插件,需要集成第三方的 MyBatis Generator。MyBatis Generator的详细介绍 http://mybatis.github.io/generator/index.html 本篇博客图解 MyBatis Generator 的使用过程,并结合实战说明逆向工程的使用方式。 搭建 MyBatis Generator 插件环境 添加插件依赖 pom.xml <!--mybatis 逆向生成插件--> <plugin> <groupId>org.mybatis.generator</groupId> <artifactId>mybatis-generator-maven-plugin</artifactId> <version>1.3.2</version> <configuration> <configurationFile>src/main/resources/generatorConfig.xml</configurationFile> <verbose>true</verbose> <overwrite>true</overwrite> </configuration> <executions> <execution> <id>Generate MyBatis Artifacts</id> </execution> </executions> <dependencies> <dependency> <groupId>org.mybatis.generator</groupId> <artifactId>mybatis-generator-core</artifactId> <version>1.3.2</version> </dependency> </dependencies> </plugin> b.配置文件 generatorConfig.xml <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN" "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd"> <generatorConfiguration> <properties resource="jdbc.properties"/> <classPathEntry location="${jdbc_driverLocation}"/> <!--指定特定数据库的jdbc驱动jar包的位置--> <context id="default" targetRuntime="MyBatis3"> <!-- optional,旨在创建class时,对注释进行控制 --> <commentGenerator> <property name="suppressDate" value="true"/> <property name="suppressAllComments" value="true"/> </commentGenerator> <!--jdbc的数据库连接 --> <jdbcConnection driverClass="${jdbc_driverClass}" connectionURL="${jdbc_url}" userId="${jdbc_user}" password="${jdbc_pwd}"> </jdbcConnection> <!-- 非必需,类型处理器,在数据库类型和java类型之间的转换控制--> <javaTypeResolver><property name="forceBigDecimals" value="false"/></javaTypeResolver> <!-- Model模型生成器,用来生成含有主键key的类,记录类 以及查询Example类 targetPackage 指定生成的model生成所在的包名 targetProject 指定在该项目下所在的路径 --> <javaModelGenerator targetPackage="com.rambo.sdm.dao.pojo" targetProject="src/main/java"> <!-- 是否允许子包,即targetPackage.schemaName.tableName --> <property name="enableSubPackages" value="false"/> <!-- 是否对model添加 构造函数 --> <property name="constructorBased" value="true"/> <!-- 是否对类CHAR类型的列的数据进行trim操作 --> <property name="trimStrings" value="true"/> <!-- 建立的Model对象是否 不可改变 即生成的Model对象不会有 setter方法,只有构造方法 --> <property name="immutable" value="false"/> </javaModelGenerator> <!--Mapper映射文件生成所在的目录 为每一个数据库的表生成对应的SqlMap文件 --> <sqlMapGenerator targetPackage="com.rambo.sdm.dao.mapper" targetProject="src/main/java"> <property name="enableSubPackages" value="false"/> </sqlMapGenerator> <!-- 客户端代码,生成易于使用的针对Model对象和XML配置文件 的代码 type="ANNOTATEDMAPPER",生成Java Model 和基于注解的Mapper对象 type="MIXEDMAPPER",生成基于注解的Java Model 和相应的Mapper对象 type="XMLMAPPER",生成SQLMap XML文件和独立的Mapper接口 --> <javaClientGenerator targetPackage="com.rambo.sdm.dao.inter" targetProject="src/main/java" type="XMLMAPPER"> <property name="enableSubPackages" value="true"/> </javaClientGenerator> <table tableName="user" domainObjectName="UserPO"> <generatedKey column="uuid" sqlStatement="SELECT REPLACE(UUID(),'-','') UUID FROM DUAL"/> </table> </context> </generatorConfiguration> c.数据库配置文件 jdbc.properties jdbc_driverLocation=D:\\Program Files\\Repository\\mysql\\mysql-connector-java\\5.1.38\\mysql-connector-java-5.1.38.jar jdbc_driverClass=com.mysql.jdbc.Driver jdbc_url=jdbc:mysql://localhost:3306/db_test?useUnicode=true&amp;characterEncoding=utf-8 jdbc_user=root jdbc_pwd=123456 validationQuery = select 1 配置插件启动项 项目实战 User类就是普通的实体类,定义了数据库对应的字段,以及set/get方法。Mybatis 引入了 Example 类,用来封装数据库查询条件。关注公众号互联网架构师,回复关键字2T,获取最新架构视频 a.比如在一个项目 我们要删除某个小组下某个用户的信息 public int deleteUserApplyInfo(long user_id,long team_id){ StudyTeamUserApplyInfoExample ue = new StudyTeamUserApplyInfoExample(); ue.createCriteria().andUserIdEqualTo(new BigDecimal(user_id)).andTeamIdEqualTo(new BigDecimal(team_id)); return studyTeamUserApplyInfoDAO.deleteByExample(ue); } b.根据小组ID(非主键 更新小组信息) public int updateStudyTeamInfo(StudyTeamInfo st){ StudyTeamInfoExample ste = new StudyTeamInfoExample(); ste.createCriteria().andTeamIdEqualTo(st.getTeamId()); return studyTeamInfoDAO.updateByExampleSelective(st,ste); } c.其它 (1)模糊查询并且排序 public List<StudyTeamInfo> getStudyTeamInfoByName(String team_name){ StudyTeamInfoExample se = new StudyTeamInfoExample(); se.createCriteria().andTeamNameLike("%"+team_name+"%").andEnableEqualTo((short)1); se.setOrderByClause("team_score desc"); List<StudyTeamInfo> ls = studyTeamInfoDAO.selectByExample(se); if(ls!=null&&ls.size()>0){ return ls; } return null; } (2)大于等于某个分数 并且小于某个分数的查询 public StudyTeamLevel getStudyTeamLevel(long score){ StudyTeamLevelExample le = new StudyTeamLevelExample(); le.createCriteria().andNeedScoreLessThanOrEqualTo(score).andUpScoreGreaterThan(score); List<StudyTeamLevel> ls = studyTeamLevelDAO.selectByExample(le); if(ls!=null&&ls.size()>0){ return ls.get(0); } return null; } 【云栖号在线课堂】每天都有产品技术专家分享!课程地址:https://yqh.aliyun.com/zhibo 立即加入社群,与专家面对面,及时了解课程最新动态!【云栖号在线课堂 社群】https://c.tb.cn/F3.Z8gvnK 原文发布时间:2020-07-12本文作者:Orson本文来自:“互联网架构师”,了解相关信息可以关注“互联网架构师”

优秀的个人博客,低调大师

常见Serialize技术探秘(ObjectXXStream、XML、JSON、JDBC byte编码、Protobuf)

目前业界有各种各样的网络输出传输时的序列化和反序列化方案,它们在技术上的实现的初衷和背景有较大的区别,因此在设计的架构也会有很大的区别,最终在落地后的:解析速度、对系统的影响、传输数据的大小、可维护性及可阅读性等方面有着较大的区别,本文分享一些我在一些常见序列化技术的分析和理解: 文章分成3个部分: 1、列举常见的序列化和反序列化方案(ObjectXXStream、XML、JSON) 2、MySQL JDBC结果集的处理方案 3、Google Protocol Buffer处理方案 【一、常见的在API及消息通信调的用中Serialize方案】: 方案1、基于Java原生的ObjectOutputStream.write()和ObjectInputStream.read()来进行对象序列化和反序列化。 方案2、基于JSON进行序列化和反序列化

优秀的个人博客,低调大师

10 个 Python 初学者必知编码小技巧

技巧 #1 字符串翻转 >>> a = "codementor">>> print "Reverse is",a[::-1]翻转后的结果为 rotnemedoc 技巧 #2 矩阵转置 >>> mat = [[1, 2, 3], [4, 5, 6]]>>> zip(*mat)[(1, 4), (2, 5), (3, 6)] 技巧 #3 a = [1,2,3] 将列表中的三个元素分拆成三个变量 >>> a = [1, 2, 3]>>> x, y, z = a>>> x1>>> y2>>> z3 技巧 #4 a = ["Code", "mentor", "Python", "Developer"] 将字符串列表拼接成一个字符串 >>> print " ".join(a)Code mentor Python Developer 技巧 #5 List 1 = ['a', 'b', 'c', 'd'] List 2 = ['p', 'q', 'r', 's'] 编写 Python 代码,实现下面的输出 ap bq cr ds >>> for x, y in zip(list1,list2):... print x, y...a pb qc rd s 技巧 #6 仅用一行代码实现两个变量的交换 >>> a=7>>> b=5>>> b, a =a, b>>> a5>>> b7 技巧 #7 不使用循环,输出 "codecodecodecode mentormentormentormentormentor" >>> print "code"*4+' '+"mentor"*5codecodecodecode mentormentormentormentormentor 技巧 #8 a = [[1, 2], [3, 4], [5, 6]] 不使用循环,将其转变成单个列表 输出:- [1, 2, 3, 4, 5, 6] >>> import itertools>>> list(itertools.chain.from_iterable(a))[1, 2, 3, 4, 5, 6] 技巧 #9 检查一个单词和另一个单词是否只是字母顺序不同 def is_anagram(word1, word2): """检查一个单词和另一个单词是否只是字母顺序不同 word1: string word2: string returns: boolean """ 将上面的函数补充完毕,以检查一个单词和另一个单词是否只是字母顺序不同 from collections import Counterdef is_anagram(str1, str2): return Counter(str1) == Counter(str2)>>> is_anagram('abcd','dbca')True>>> is_anagram('abcd','dbaa')False 技巧 #10. 从字符串输入中获取值 对于输入数据 1 2 3 4 我们希望得到列表 [1, 2, 3, 4] 。 请注意,列表中的元素都是 int 类型,且只能使用一行代码。 >>> result = map(lambda x:int(x) ,raw_input().split())1 2 3 4>>> result[1, 2, 3, 4]

优秀的个人博客,低调大师

Python多进程抓取全国邮政编码和长途区号

由于Python设计的限制(就是咱们常用的CPython)最多只能用满1个CPU核心。Python提供了非常好用的多进程包multiprocessing,你只需要定义一个函数,Python会替你完成其他所有事情。借助这个包,可以轻松完成从单进程到并发执行的转换。使用进程池可以让你跑满多核CPU,而且使用方法非常简单。 Show You The Code: import multiprocessing import time def func(msg): for i in xrange(3): print msg time.sleep(1) return "done " + msg if __name__ == "__main__": pool = multiprocessing.Pool(processes=4) resu

优秀的个人博客,低调大师

编码24小时,赢硅谷游学,你敢来一试?

2017年7月17日,由阿里巴巴集团主办,阿里中间件(Aliware)与阿里云天池平台联合承办,第三届阿里中间件性能挑战赛总决赛在阿里巴巴杭州西溪园区圆满落幕。在总决赛前夕的一场持续24小时的极客挑战赛,将总决赛答辩前的气氛推向了高潮。最终南京理工大学张震宇、Splunk上海研发中心傅宇和中科院计算所岑武斌等四位同学,脱颖而出赢得西行游学大奖,将由阿里巴巴全程资助于10月赴美参加国际顶会,拜访硅谷知名IT企业。极客挑战赛选手赛前集体合影 赛事规模和影响力迅速攀升,极客挑战赛造就全新挑战 作为阿里中间件(Aliware)团队举办的历史最悠久的工程视角赛事,阿里中间件性能挑战赛已连续举办三届,受到业界工程师和高校技术爱好者的一贯支持和好评。据悉本次挑战赛规模再创新高,共吸引近2300支队伍报名参赛,选手来源分布广泛,既有国内外顶级理工科院

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册