Apache Shiro

Apache Shiro Apache Shiro (发音为"shee-roh",日语"堡垒 (Castle) “的意思) 是一个强大易用的Java安全框架,提供了认证、授权、加密和会话管理功能,可为任何应用提供安全保障 - 从命令行应用、移动应用到大型网络及企业应用。 Shiro为解决下列问题 (我喜欢称它们为应用安全的四要素) 提供了保护应用的API: 认证 - 用户身份识别,常被称为用户"登录”; 授权 - 访问控制; 密码加密 - 保护或隐藏数据防止被偷窥; 会话管理 - 每用户相关的时间敏感的状态。 Shiro还支持一些辅助特性,如Web应用安全、单元测试和多线程,它们的存在强化了上面提到的四个要素。 Subject 在考虑应用安全时,你最常问的问题可能是"当前用户是谁?“或"当前用户允许做X吗?"。当我们写代码或设计用户界面时,问自己这些问题很平常: 应用通常都是基于用户故事构建的,并且你希望功能描述 (和安全) 是基于每个用户的。所以,对于我们而言,考虑应用安全的最自然方式就是基于当前用户。Shiro的API用它的Subject概念从根本上体现了这种思考方式。 Subject一词是一个安全术语,其基本意思是"当前的操作用户”。称之为"用户"并不准确,因为"用户"一词通常跟人相关。在安全领域,术语"Subject"可以是人,也可以是第三方进程、后台帐户 (Daemon Account) 或其他类似事物。它仅仅意味着"当前跟软件交互的东西"。但考虑到大多数目的和用途,你可以把它认为是Shiro的"用户"概念。在代码的任何地方,你都能轻易的获得Shiro Subject, http://www.infoq.com/cn/articles/apache-shiro http://kdboy.iteye.com/blog/1154644

2012-12-12 · 1 min · 38 words · -

Quartz

Quartz Quartz 是个开源的作业调度框架 Quartz是OpenSymphony开源组织在Job scheduling领域又一个开源项目,它可以与J2EE与J2SE应用程序相结合也可以单独使用。Quartz可以用来创建简单或为运行十个,百个,甚至是好几万个Jobs这样复杂的日程序表。Jobs可以做成标准的Java组件或 EJBs。 Quartz 是个开源的作业调度框架,为在 Java 应用程序中进行作业调度提供了简单却强大的机制。Quartz 允许开发人员根据时间间隔 (或天) 来调度作业。它实现了作业和触发器的多对多关系,还能把多个作业与不同的触发器关联。整合了 Quartz 的应用程序可以重用来自不同事件的作业,还可以为一个事件组合多个作业。虽然可以通过属性文件 (在属性文件中可以指定 JDBC 事务的数据源、全局作业和/或触发器侦听器、插件、线程池,以及更多) 配置 Quartz,但它根本没有与应用程序服务器的上下文或引用集成在一起。结果就是作业不能访问 Web 服务器的内部函数;例如,在使用 WebSphere 应用服务器时,由 Quartz 调度的作业并不能影响服务器的动态缓存和数据源。 Quartz任务调度CronTrigger配置格式详细说明 CronTrigger配置完整格式为: [秒] [分] [小时] [日] [月] [周] [年] 序号 说明 是否必填 允许填写的值 允许的通配符 1 秒 是 0-59 , - * / 2 分 是 0-59 , - * / 3 小时 是 0-23 , - * / 4 日 是 1-31 , - * ? / L W ...

2012-12-11 · 2 min · 287 words · -

PropertyPlaceholderConfigurer

PropertyPlaceholderConfigurer http://callan.iteye.com/blog/161540 关于PropertyPlaceholderConfigurer与PropertyOverrideConfigurer PropertyPlaceholderConfigurer,允许在spring的配置文件中加入properties文件,可以将一些动态参数移到properties中. <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="location" value="classpath:config/jdoserver.properties"/> </bean> 但是好像在属性文件定义中却不支持多个属性文件的定义,比如不能这样用config/*.properties。 经过查看源码,发现可以使用locations属性定义多个配置文件: Java代码 <property name="locations"> <value>classpath:config/maxid.properties</value> <value>classpath:config/jdoserver.properties</value> </list> </property> 使用外部属性后如下: Java代码 <img src="http://callan.iteye.com/images/icon_star.png" alt="收藏代码" /> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="${jdbc.agent.driver}"/> <property name="url" value="${jdbc.agent.main.url}"/> </bean> PropertyOverrideConfigurer: 在spring所有的bean初使化以后,将bean的值强行改变 Xml代码 <img src="http://callan.iteye.com/images/icon_star.png" alt="收藏代码" /> <bean id="configBean" class="org.springframework.beans.factory.config.PropertyOverrideConfigurer"> <property name="location"> <value>hello.properties</value> </property> </bean> <bean id="helloBean" class="com.HelloBean"> <property name="word"> <value>Hello!</value> </property> </bean> 定义HelloBean,注入word的值为hello. 在hello.properties中 helloBean.word=Welcome! word初使为hello后,当bean全加载完,PropertyOverrideConfigurer将helloBean.word的值改成为welcome.

2012-12-08 · 1 min · 63 words · -

jdbc driver

jdbc driver jdbc driver: com.MySQL.jdbc.Driver oracle.jdbc.driver.OracleDriver jdbc url: jdbc:MySQL://localhost:3306/xxxxxx jdbc:oracle:thin:@xxx.xxx.xxx.xxx:1521:xxxxxx

2012-12-08 · 1 min · 10 words · -

SIteMesh

SIteMesh 转自:http://javauu.com/thread-27-1-1.html 一、SIteMesh介绍 一、SiteMesh简介 SiteMesh是由一个基于Web页面布局、装饰以及与现存Web应用整合的框架。它能帮助我们在由大量页面构成的项目中创建一致的页面布局和外观,如一致的导航条,一致的banner,一致的版权,等等。 它不仅仅能处理动态的内容,如jsp,php,asp等产生的内容,它也能处理静态的内容,如htm的内容,使得它的内容也符合你的页面结构的要求。甚至于它能将HTML文件象include那样将该文件作为一个面板的形式嵌入到别的文件中去。所有的这些,都是GOF的Decorator模式的最生动的实现。尽管它是由java语言来实现的,但它能与其他Web应用很好地集成。与传统区别如下图: SIteMesh官方地址: http://www.opensymphony.com/sitemesh/index.html SIteMesh官方下载: http://www.opensymphony.com/sitemesh/download.html SIteMesh 2.3下载: http://www.javauu.com/downloads/resource/sitemesh-2.3.zip 二、SiteMesh原理 SiteMesh框架是OpenSymphony团队开发的一个非常优秀的页面装饰器框架,它通过对用户请求进行过滤,并对服务器向客户端响应也进行过滤,然后给原始页面加入一定的装饰(header,footer等),然后把结果返回给客户端。通过SiteMesh的页面装饰,可以提供更好的代码复用,所有的页面装饰效果耦合在目标页面中,无需再使用include指令来包含装饰效果,目标页与装饰页完全分离,如果所有页面使用相同的装饰器,可以是整个Web应用具有统一的风格。

2012-12-07 · 1 min · 15 words · -

FreeMarker

FreeMarker http://www.oecp.cn/hi/hailang/blog/146 一、 FreeMarker简介 FreeMarker是一个用Java语言编写的模板引擎,它基于模板来生成文本输出。 所谓模板,就是一份已经写好了基本内容,有着固定格式的文档,其中空出或者用占位符标识的内容,由使用者来填充,不同的使用者给出的数据是不同的。在模板中的占位符,在模板运行时,由模板引擎来解析模板,并采用动态数据替换占位符部分的内容。 FreeMarker与Web容器无关,即在Web运行时,它并不知道Servlet或HTTP。它不仅可以用作表现层的实现技术,而且还可以用于生成XML,JSP或Java 文等。 二、 FreeMarker的优点和缺点 (一) FreeMarker的优点 1.使用FreeMarker的优点之一,可以彻底的分离表现层和业务逻辑。 使用JSP 开发过程中在页面中大量的存在业务逻辑的代码,使得页面内容凌乱,在后期大量的修改维护过程中就变得非常困难。 FreeMarker根本不支持Java脚本代码。 FreeMarker的原理就是: 模板+数据模型=输出 ,模板只负责数据在页面中的表现,不涉及任何的逻辑代码,而所有的逻辑都是由数据模型来处理的。用户最终看到的输出是模板和数据模型合并后创建的。 2.使用FreeMarker的优点之二,可以提高开发效率。 在我们以往的开发中,使用的都是JSP 页面来展示数据的,即所谓的表现层。我们都知道,JSP在第一次执行的时候需要转换成Servlet类,开发阶段进行功能调适时,需要频繁的修改JSP,每次修改都要编译和转换,那么试想一天中我们浪费在程序编译的时间有多少。相对于JSP来说,FreeMarker模板技术不存在编译和转换的问题,所以就不会存在上述问题。而且开发过程中,我们在不必在等待界面设计开发人员完成页面原形后,我们再来开发程序。 3.使用FreeMarker的优点之三,使得开发过程中的人员分工更加明确。 以往用JSP展现数据时,作为程序员的我们,并不熟悉界面设计技术,反之界面开发人员,也并不熟悉程序语言。对两者而言,交替性的工作本身就有难度。有时候稍有不慎,可能会将某个页面元素删除或去掉了某个程序符号,使得页面走样或程序错误,这样就需要双方相互沟通协作,解决出现的问题。有时候因为项目中的时间,任务量等因素的存在,可能这个工作就由一个人来完成,这样就可能加大某一方开发人员的工作量。 使用FreeMarker后,作为界面开发人员,只专心创建HTML文件、图像以及Web页面的其他可视化方面,不用理会数据;而程序开发人员则专注于系统实现,负责为页面准备要显示的数据。 (二)FreeMarker的缺点 1.使用FreeMarker的缺点之一,应用FreeMarker模板技术,在修改模板后,可能会看到已经过期的数据。如: 生成静态的HTML页面后,如果一旦模板改变,而没有及时更新模板生成的HTML页面的话,用户看到的就是过期的数据。 2.使用FreeMarker的缺点之二,FreeMarker模板技术在应用过程中,FreeMarker中的变量必须要赋值,如果不赋值,那么就会抛出异常。想避免错误就要应用if/elseif/else 指令进行判段,如果对每一个变量都判断的话,那么则反而增加了编程的麻烦。 3.使用FreeMarker的缺点之三,FreeMarker的map限定key必须是string,其他数据类型无法操作 4.使用FreeMarker的缺点之四,FreeMarker不支持集群应用。为了编成的方便性,把序列化的东西都放到了Session中,如Session,request等,在开发的过程中确实方便,但如果将应用放到集群中,就会出现错误。 通过以上的阐述,希望可以令您清晰FreeMarker的优点和缺点,旨在抛砖引玉。有什么问题可以留下您的宝贵留言,我非常愿意与大家讨论。

2012-12-07 · 1 min · 33 words · -

serialVersionUID

serialVersionUID serialVersionUID作用: 序列化时为了保持版本的兼容性,即在版本升级时反序列化仍保持对象的唯一性。 有两种生成方式: 一个是默认的1L,比如: private static final long serialVersionUID = 1L; 一个是根据类名、接口名、成员方法及属性等来生成一个64位的哈希字段,比如: private static final long serialVersionUID = xxxxL; 当你一个类实现了Serializable接口,如果没有定义serialVersionUID,Eclipse会提供这个 提示功能告诉你去定义 。在Eclipse中点击类中warning的图标一下,Eclipse就会 自动给定两种生成的方式。如果不想定义它,在Eclipse的设置中也 可以把它关掉的,设置如下: Window ==> Preferences ==> Java ==> Compiler ==> Error/Warnings ==> Potential programming problems 将Serializable class without serialVersionUID的warning改成ignore即可。 如果你没有考虑到兼容性问题时,就把它关掉,不过有这个功能是好的,只要任何类别实现了Serializable这个接口的话,如果没有加入serialVersionUID,Eclipse都会给你warning提示,这个serialVersionUID为了让该类别Serializable向后兼容。 如果你的类Serialized存到硬盘上面后,可是后来你却更改了类别的field(增加或减少或改名),当你Deserialize时,就会出现Exception的,这样就会造成不兼容性的问题。 但当serialVersionUID相同时,它就会将不一样的field以type的预设值Deserialize,可避开不兼容性问题。

2012-12-07 · 1 min · 45 words · -

Intellij IDEA CE 自动生成 serialVersionUID

Intellij IDEA CE 自动生成 serialVersionUID IDEA的Inspector对serialVersionUID检测默认是关闭的,因此如果你的class是Serialization,那么需要重新设置一下(IDEA 9.0): Setting->Inspections->Serialization issues->Serializable class without ‘serialVersionUID’ 选上以后,在你的class中: Alt+Enter就会提示自动创建serialVersionUID了。 http://blog.sina.com.cn/s/blog_728c25590100y33w.html

2012-12-07 · 1 min · 15 words · -

SpringMVC

SpringMVC http://www.iteye.com/blogs/subjects/springmvc-explore 《Struts2技术内幕» 本文是专栏文章 (SpringMVC深度探险) 系列的文章之一,博客地址为: http://downpour.iteye.com/blog/1330537 在我们熟知的建立在三层结构 (表示层、业务逻辑层、持久层) 基础之上的J2EE应用程序开发之中,表示层的解决方案最多。因为在表示层自身的知识触角很多,需要解决的问题也不少,这也就难免造成与之对应的解决方案层出不穷。 笔者在很多讨论中经常可以看到类似"某某框架已死",或者"某某框架已经足以打败所有其他的框架"的言论。**事实上,每一种解决方案都有着自身独有的存在价值和历史背景。**如果单单从某一个方面或者某几个方面去看一个框架,那么评论难免有失偏颇。 所以,整个系列的第一篇文章,我们脱开SpringMVC框架本身,把SpringMVC放到一个更大的知识体系范围之中,讲一讲整个Web开发领域、尤其是MVC框架的发展历程。正如"认识历史才能看清未来",当我们能够正确审视整个MVC框架的发展历程,也就能够分析它的发展趋势,并且站在一个更高的高度来对所有的解决方案进行评价。 两种模型 从整个B/S程序的运行结构来看,J2EE的表示层解决方案实际上是对"请求-响应"模式的一种实现。既然谓之"请求-响应"也就势必存在着两大沟通角色: 由于这两大角色的承载载体和编程语言实现基础都不同,因而也就产生了两种截然不同的针对表示层的解决方案的设计思路: 以服务器端应用程序为主导来进行框架设计 以浏览器页面组件 (及其自身的事件触发模型) 为主导来进行框架设计 业界对于上述这两种不同的设计模型也赋予了不同的名词定义: 前一种被称之为MVC模型;后一种则被称之为组件模型,也有称之为事件模型。 **注: **笔者个人对于这两种模型的概念定义并不是非常认同。因为在笔者个人的观点认为,MVC模型的定义角度所针对的是编程元素的划分;而组件模型 (事件模型) 的定义角度是动态交互方式的表述。所以我们在这里强调的是解决方案自身所设立的基准和侧重点的不同。 从使用者的社区力量上来看,无疑MVC模型获得了更多程序员的青睐。这里面的原因很多,我们在这里也不想过多展开对两种不同编程模型之间的讨论。不过在这里,我们将针对同一个业务场景 (用户注册) 分别给出基于这两个编程模型的代码示例,帮助读者了解这两种编程模型在设计思想上的不同之处。 【MVC模型】 在MVC模型中,我们选取当前比较热门的两大框架Struts2和SpringMVC作为代码示例。 首先,我们将用户注册场景中最为核心的"用户类"定义出来: Java代码 <img src="http://downpour.iteye.com/images/icon_star.png" alt="收藏代码" /> public class User { private String email; private String password; // 省略了setter和getter方法 } 紧接着是一个简单的JSP表单: Html代码 <img src="http://downpour.iteye.com/images/icon_star.png" alt="收藏代码" /> <form method="post" action="/register"> <label>Email:</label><input type="text" name="email" /> <label>Password:</label><input type="password" name="password" /> <input type="submit" value="submit" /> </form> 上述这两段代码无论是SpringMVC还是Struts2,都可以共用。而在请求响应处理类 (也就是Controller) 上的设计差异是两个框架最大的不同。 ...

2012-11-30 · 2 min · 420 words · -

用 dbunit-maven-plugin 来管理你的测试数据

用 dbunit-maven-plugin 来管理你的测试数据 http://newwhx2011.iteye.com/blog/1089559 单元测试有人写过,也有人没做过,数据库的 dbunit 的用的人应该更少了,它可以用来给你做测试准备数据。一般我们做测试会在一个测试数据库中不停的测,自然会累积许多垃圾数据,给单元测试会造成不便,功能测试倒无太紧要。如果我们想在单元测试的时候有一份干净的数据,有个做法是搞个备用的数据库,测试前导到测试库的,或用某些数据库的导入导出功能。 这里我们来看 dbunit 怎么实现准备测试数据的,它可以用来导出数据库数据到数据文件中,从数据文件中导入干净的数据到数据库中,比较数据库与数据文件、或增量的插入记录等等。 dbunit 最初为 ant 提供了 antask,当然可以编程使用,如今 maven 大行其道,所以也就有了 maven 的 dbunit 插件,相似功能的插件有两个: dbunit-maven-plugin maven-dbunit-plugin 就是 maven 和 dbunit 倒了一下,别晕了,第二个似乎提供了更多的 goal,但运行 mvn dbunit:xxxx,指向的是第一个 dbunit-maven-plugin,看来第一个要正统些。本文也就介绍下dbunit-maven-plugin 的用法,测试数据库是 MySQL。

2012-11-30 · 1 min · 34 words · -

Filter FilterChain

Filter FilterChain http://blog.csdn.net/zhaozheng7758/article/details/6105749 一、Filter的介绍及使用**** 什么是过滤器? 与Servlet相似,过滤器是一些web应用程序组件,可以绑定到一个web应用程序中。但是与其他web应用程序组件不同的是,过滤器是"链"在容器的处理过程中的。这就意味着它们会在servlet处理器之前访问一个进入的请求,并且在外发响应信息返回到客户前访问这些响应信息。这种访问使得过滤器可以检查并修改请求和响应的内容。 过滤器适用于那些地方? l 为一个web应用程序的新功能建立模型(可被添加到web应用程序中或者从web应用程序中删除而不需要重写基层应用程序代码); l 向过去的代码添加新功能。 过滤器放在容器结构的什么位置? 过滤器放在web资源之前,可以在请求抵达它所应用的web资源(可以是一个Servlet、一个Jsp页面,甚至是一个HTML页面)之前截获进入的请求,并且在它返回到客户之前截获输出请求。Filter: 用来拦截请求,处于客户端与被请求资源之间,目的是重用代码。Filter链,在web.xml中哪个先配置,哪个就先调用。在filter中也可以配置一些初始化参数。 Java中的Filter 并不是一个标准的Servlet ,它不能处理用户请求,也不能对客户端生成响应。 主要用于对HttpServletRequest 进行预处理,也可以对HttpServletResponse 进行后处理,是个典型的处理链。 Filter 有如下几个用处: l 在HttpServletRequest 到达Servlet 之前,拦截客户的HttpServletRequest 。 l 根据需要检查HttpServletRequest ,也可以修改HttpServletRequest 头和数据。 l 在HttpServletResponse 到达客户端之前,拦截HttpServletResponse 。 l 根据需要检查HttpServletResponse ,可以修改HttpServletResponse 头和数据。 Filter 有如下几个种类: l 用户授权的Filter: Filter 负责检查用户请求,根据请求过滤用户非法请求。 l 日志Filter: 详细记录某些特殊的用户请求。 l 负责解码的Filter: 包括对非标准编码的请求解码。 l 能改变XML 内容的XSLTFilter 等。 一个Filter 可负责拦截多个请求或响应:一个请求或响应也可被多个请求拦截。 创建一个Filter 只需两个步骤: (1)创建Filter 处理类: (2)在web.xml 文件中配置Filter 。 创建Filter 必须实现javax.servlet.Filter 接口,在该接口中定义了三个方法。 • void init(FilterConfig config): 用于完成Filter 的初始化。 ...

2012-11-18 · 3 min · 558 words · -

java JVM 内存问题 调查,调优

java JVM 内存问题 调查,调优 https://my.oschina.net/u/3345762/blog/1784199 https://my.oschina.net/u/3345762/blog/1644973 http://www.infoq.com/cn/articles/Troubleshooting-Java-Memory-Issues?utm_campaign=infoq_content&utm_source=infoq&utm_medium=feed&utm_term=global http://www.importnew.com/14933.html http://lovestblog.cn/blog/2015/08/21/rssxmx/ # set jdk path export PATH=/usr/java/default/bin/:$PATH # list java process jcmd -l # show jcmd command jcmd PID help #heap dump jcmd PID GC.heap_dump /root/dump.hprof Eclipse Memory Analyzer Eclipse Memory Analyzer NMT, pmap Max memory = [-Xmx] + [-XX:MaxPermSize] + number_of_threads * [-Xss] init: represents the initial amount of memory (in bytes) that the Java virtual machine requests from the operating system for memory management during startup. The Java virtual machine may request additional memory from the operating system and may also release memory to the system over time. The value of init may be undefined. ...

2012-11-06 · 4 min · 807 words · lcf

sk_buff

sk_buff sk_buff (internal networking structure used by linux kernel) sk_buff的意思是socket buffer,这是Linux网络子系统中的核心数据结构 https://liu-jianhao.github.io/2019/05/linux%E5%86%85%E6%A0%B8%E7%BD%91%E7%BB%9C%E6%BA%90%E7%A0%81%E8%A7%A3%E6%9E%901sk_buff%E7%BB%93%E6%9E%84/ tcp连接的资源占用 size of sk_buff (internal networking structure used by linux kernel) the read and write buffer for a connection the size of buffers can be tweaked as required root@x:~# sysctl -A | grep net | grep mem check for these variables these specify the maximum default memory buffer usage for all network connections in kernel net.core.wmem_max = 131071 ...

2012-10-31 · 1 min · 197 words · -

Java中的instanceof关键字

Java中的instanceof关键字 instanceof是Java的一个二元操作符,和==,>,<是同一类东西。由于它是由字母组成的,所以也是Java的保留关键字。它的作用是测试它左边的对象是否是它右边的类的实例,返回boolean类型的数据。举个例子: String s = “I AM an Object!”; boolean isObject = s instanceof Object; 我们声明了一个String对象引用,指向一个String对象,然后用instancof来测试它所指向的对象是否是Object类的一个实例,显然,这是真的,所以返回true,也就是isObject的值为True。 instanceof有一些用处。比如我们写了一个处理账单的系统,其中有这样三个类: public class Bill {//省略细节} public class PhoneBill extends Bill {//省略细节} public class GasBill extends Bill {//省略细节} 在处理程序里有一个方法,接受一个Bill类型的对象,计算金额。假设两种账单计算方法不同,而传入的Bill对象可能是两种中的任何一种,所以要用instanceof来判断: public double calculate(Bill bill) { if (bill instanceof PhoneBill) { //计算电话账单 } if (bill instanceof GasBill) { //计算燃气账单 } … } 这样就可以用一个方法处理两种子类。 然而,这种做法通常被认为是没有好好利用面向对象中的多态性。其实上面的功能要求用方法重载完全可以实现,这是面向对象变成应有的做法,避免回到结构化编程模式。只要提供两个名字和返回值都相同,接受参数类型不同的方法就可以了: public double calculate(PhoneBill bill) { //计算电话账单 } public double calculate(GasBill bill) { //计算燃气账单 } ...

2012-10-31 · 1 min · 72 words · -

tomcat启动jvm内存设置

tomcat启动jvm内存设置 配置tomcat调用的虚拟机内存大小 (1) 直接设置tomcat Linux 修改TOMCAT_HOME/bin/catalina.sh 位置cygwin=false前。 JAVA_OPTS="-server -Xms256m -Xmx512m -XX:PermSize=64M -XX:MaxPermSize=128m" (仅做参考,具体数值根据自己的电脑内存配置) windows 修改TOMCAT_HOME/bin/catalina.bat 第一行加上 JAVA_OPTS="-server -Xms256m -Xmx512m -XX:PermSize=64M -XX:MaxPermSize=128m" (2) 配置环境变量 环境变量中设 变量名: JAVA_OPTS 变量值: -Xms512m -Xmx512m https://www.cnblogs.com/oskyhg/p/6549877.html

2012-10-25 · 1 min · 30 words · -

Arrays.binarySearch()

Arrays.binarySearch() Arrays.binarySearch();的用法。 public static int binarySearch(Object[] a,Object key) 使用二分搜索法来搜索指定数组,以获得指定对象。在进行此调用之前, 必须根据元素的自然顺序对数组进行升序排序 (通过 sort(Object[]) 方 法 ) 。如果没有对数组进行排序,则结果是不确定的。 (如果数组包 含不可相互比较的元素 (例如,字符串和整数) ,则无法 根据其元素的自 然顺序对数组进行排序,因此结果是不确定的。) 如果数组包含多个等于 指定对象的元素,则无法保证找到的是哪一个。 参数: a - 要搜索的数组 key - 要搜索的值 返回: 如果它包含在数组中,则返回搜索键的索引;否则返回 (-(插入点) - 1) 。插入点 被定义为将键插入数组的那一点: 即第一 个大于此键的 元素索引,如果数组中的所有元素都小于指定的键,则为 a.length。注意 ,这保证了当且仅当此键被找到时,返回的值将 >= 0。 否则返回 (-(插入点) - 1)这句话要注意: 要是查询的的值小于数组里面 的最小值那么结果(-(0)-1结果就是-1),如果查询的 值大于数组里面的 最大值。那么结果就是(-(它的索引值)-1结果就是-(1+索引值)) 抛出: ClassCastException - 如果搜索的键不能与数组的元素进行比较。

2012-10-16 · 1 min · 57 words · -

synchronized

synchronized 多线程 在现代计算机中往往存在多个CPU核心,而1个CPU能同时运行一个线程,为了充分利用CPU多核心,提高CPU的效率,多线程就应时而生了。 那么多线程就一定比单线程快吗? 答案是不一定,因为多线程存在单线程没有的问题 上下文切换 线程执行过程中发生系统调用或者线程调度时都会发生上下文切换 线程从运行状态切换到阻塞状态或者等待状态的时候需要将线程的运行状态保存,线程从阻塞状态或者等待状态切换到运行状态的时候需要加载线程上次运行的状态。线程的运行状态从保存到再加载就是一次上下文切换,而上下文切换的开销是非常大的,而我们知道CPU给每个线程分配的时间片很短,通常是几十毫秒(ms),那么线程的切换就会很频繁。 死锁 死锁的一般场景是,线程A和线程B都在互相等待对方释放锁,死锁会造成系统不可用。 资源限制的挑战 资源限制指计算机硬件资源或软件资源限制了多线程的运行速度,例如某个资源的下载速度是1Mb/s,资源的服务器带宽只有2Mb/s,那么开10个线程下载资源并不会将下载速度提升到10Mb/s。 既然多线程存在这些问题,那么我们在开发的过程中有必要使用多线程吗?我们知道任何技术都有它存在的理由,总而言之就是多线程利大于弊,只要我们合理使用多线程就能达到事半功倍的效果。 多线程的意思就是多个线程同时工作,那么多线程之间如何协同合作,这也就是我们需要解决的线程通信、线程同步问题 线程通信 线程通信指线程之间以何种机制来交换消息,线程之间的通信机制有两种: 共享内存和消息传递。共享内存即线程通过对共享变量的读写而达到隐式通信,消息传递即线程通过发送消息给对方显示的进行通信。 线程同步 线程同步指不同线程对同一个资源进行操作时候线程应该以什么顺序去操作,线程同步依赖于线程通信,以共享内存方式进行线程通信的线程同步是显式的,以消息传递方式进行线程通信的线程同步是隐式的。 synchronized synchronized 的锁机制的主要优势是Java语言内置的锁机制,因此,JVM可以自由的优化而不影响已存在的代码。 synchronized 是 Java 的关键字,可用于同步实例方法、类方法(静态方法)和代码块 同步实例方法: 当 synchronized 修饰实例方法 (函数修饰符)的时候,同步的范围是当前实例的实例方法。 同步类方法(静态方法): 当 synchronized 修饰类方法的时候,同步的范围是当前类的方法。用synchronized修饰方法名时,编译后会在方法名上生成一个ACC_SYNCHRONIZED标识来实现同步 同步代码块: 当 synchronized 修饰代码块的时候,同步的范围是()中的对象。当使用synchronized修饰代码块时,编译后会在代码块的前后生成monitorenter和monitorexit字节码来实现同步。 synchronized 是非公平锁 synchronized 关键字经过编译之后,会在同步块的前后分别形成 monitorenter 和 monitorexit 这两个字节码指令,这两个字节码需要关联到一个监视对象,当线程执行 monitorenter 指令时,需要首先获得获得监视对象的锁,这里监视对象锁就是进入同步块的凭证,只有获得了凭证才可以进入同步块,当线程离开同步块时,会执行 monitorexit 指令,释放对象锁。 synchronized 关键字,代表这个方法加锁,相当于不管哪一个线程 (例如线程A) ,运行到这个方法时, 都要检查有没有其它线程B (或者C、 D等) 正在用这个方法,有的话要等正在使用 synchronized 方法的线程B (或者C 、D) 运行完这个方法后再运行此线程 A,没有的话,直接运行。 markword markword 数据的长度在32位和64位的虚拟机 (未开启压缩指针) 中分别为32bit和64bit,它的最后2bit是锁状态标志位,用来标记当前对象的状态,对象的所处的状态,决定了markword存储的内容 ...

2012-10-16 · 5 min · 910 words · -

单例 Singleton

单例 Singleton 静态内部类 static nested class 这种方法也是《Effective Java》上所推荐的。 这种写法仍然使用JVM本身机制保证了线程安全问题;由于 SingletonHolder 是私有的,除了 getInstance() 之外没有办法访问它,因此它是懒汉式的;同时读取实例的时候不会进行同步,没有性能缺陷;也不依赖 JDK 版本。 这是利用了JVM的特性:静态内部类时在类加载时实现的,因此不会受到多线程的影响,自然也就不会出现多个实例。 public class Singleton { private static class SingletonHolder { private static final Singleton INSTANCE = new Singleton(); } private Singleton() { } public static final Singleton getInstance() { return SingletonHolder.INSTANCE; } } 单例模式 (Singleton) 介绍: 也叫单子模式,是一种常用的软件设计模式。在应用这个模式时,单例对象的类必须保证只有一个实例存在。许多时候整个系统只需要拥有一个的全局对象,这样有利于我们协调系统整体的行为。比如在某个服务器程序中,该服务器的配置信息存放在一个文件中,这些配置数据由一个单例对象统一读取,然后服务进程中的其他对象再通过这个单例对象获取这些配置信息。这种方式简化了在复杂环境下的配置管理。 实现单例模式的思路是: 一个类能返回对象一个引用(永远是同一个)和一个获得该实例的方法 (必须是静态方法,通常使用getInstance这个名称); 当我们调用这个方法时,如果类持有的引用不为空就返回这个引用,如果类保持的引用为空就创建该类的实例并将实例的引用赋予该类保持的引用;同时我们还将该类的构造函数定义为私有方法,这样其他处的代码就无法通过调用该类的构造函数来实例化该类的对象,只有通过该类提供的静态方法来得到该类的唯一实例。 注意事项: 单例模式在多线程的应用场合下必须小心使用。如果当唯一实例尚未创建时,有两个线程同时调用创建方法,那么它们同时没有检测到唯一实例的存在,从而同时各自创建了一个实例,这样就有两个实例被构造出来,从而违反了单例模式中实例唯一的原则。 解决这个问题的办法是为指示类是否已经实例化的变量提供一个互斥锁(虽然这样会降低效率)。 实现方式: 通常单例模式在Java语言中,有两种构建方式: 饿汉方式:指全局的单例实例在类装载时构建。(一般认为这种方式要更加安全些) ...

2012-10-16 · 2 min · 278 words · -

Builder, Factory

Builder, Factory http://www.cnblogs.com/shenfx318/archive/2007/01/28/632724.html 在设计模式的学习过程中,Builder与Factory是创建模式中两个经典的教程,给与了我们很多值得汲取的宝贵设计思想,然而Builder与Factory模式也是初学者容易混淆的两个模式,经常看到有人问及两者的区别与适用的场景,我在近一段设计模式的学习过程中同样碰到了这个问题,在两种模式的区别与联系间我看到的更多是后者,在这里愿意与大家分享一些我对Builder与Factory模式的感悟,有说的不对的地方,还请各位多加提点、指教。 写在前面 本文旨在两种模式间的对比与探讨,因此还希望各位看官首先对两个模式有一定的了解为好,因为常常看到有人提问说,Builder模式与抽象工厂 (Abstract Factory) 之间的区别,其实在我看来这两者间并无太多联系,因此也就谈不上区别,至于原因在此不做细述,有兴趣的朋友可以看看我写的有关 http://www.cnblogs.com/shenfx318/archive/2007/01/16/621237.html 抽象工厂的文章。故本文中所提的Factory模式皆指的是工厂方法 (Factory Method) 。 从Builder到Factory的演化 先来看看Builder模式,Builder模式的一般设计及实现 ```java public interface IBuilder { void BuildPart1(); void BuildPart2(); Product GetResult(); } //ConcreteBuilderA public class BuilderA : IBuilder { private Product product; public void BuildPart1() { product = new Product(); product.Add(“Part1 build by builderA”); } public void BuildPart2() { product.Add(“Part2 build by builderA”); } public Product GetResult() { return product; } } } //ConcreteBuilderB public class BuilderB : IBuilder //Director public class Director { public void Construct(IBuilder builder) { builder.BuildPart1(); builder.BuildPart2(); } } ...

2012-10-12 · 2 min · 378 words · -

持续改进,抽象工厂也反射

持续改进,抽象工厂也反射 http://www.cnblogs.com/shenfx318/archive/2007/01/16/621237.html 在我的上一篇文章(疑惑?改良?从简单工厂到工厂方法)中,详细论述了创建模式中简单工厂到工厂方法的演变过程,并试图结合工厂方法的设计以及.net中的反射机制之所长,改良出一种新型的工厂—反射工厂,这当然不是我的首创,经典的PetShop 中便有此工厂的身影。本文尝试按照前篇文章的思路,借着工厂方法到抽象工厂的演变过程而继续对抽象工厂进行改良,文章中的思想仅代表了作者当时的观点,有欠妥的地方,还请各位不吝赐教。 工厂模式 前面的文章提到了简单工厂和工厂方法其实是一码事,他们完成了将客户对产品功能的使用与创建具体产品职责的分割,不同的只不过是他们实现方式上的差异,工厂方法利用更加优雅的多态性取代了相对ugly的switch case…语句,从而很好的体现了设计原则中的OCP原则,此文章将不再强调这种实现上的差异性,而更多的强调两者之间设计思路上的共性,并将这种共性统称成为工厂模式,从而进一步与抽象工厂进行对比。 工厂的使用,选择的过程 工厂模式的使用,实际上是客户 (产品的消费者) 对于产品选择的过程,对于实现了相同功能的产品来讲,客户更加关心的是产品间的差异性,而工厂的作用则是将产品的生产过程封装,根据客户的要求直接返回客户需要的产品。注意,工厂只是隐藏了产品的生产过程,但是并没有剥夺客户选择的权利,那么客户的这个选择过程又是如何体现的呢?在简单工厂中,客户通过参数的形式告诉工厂需要什么样的产品,而在工厂方法中,客户通过对工厂的选择代替了直接对产品的选择,注意到工厂方法中一个工厂只有一个Create方法,也就是说一个工厂只负责生产一种产品,那么你选择了相应的工厂也就等同于你选择了对应的产品。就连改良后的反射工厂也没有消去对产品的选择,只不过是将这种选择外化 (外化到配置文件中,从而使得对代码的改动最小) 。可以说,正是由于产品间的差异性带给了客户选择的权利,这种权利是不应当被工厂取代的,那么工厂模式的价值又在哪里呢?答案是抽象与封装,工厂模式将由于客户的不同选择而可能导致的对已知事物的影响降到最低,途径是通过抽象产品取代具体产品,使得客户依赖于抽象 (越抽象的东西越稳定) ,同时将客户的选择封装到一处,隔离与具体产品间的依赖。 工厂模式与抽象工厂 前面说了这么多无关的,为得是做好铺垫,更加有益于对下文的理解,OK,终于该说说从工厂模式到抽象工厂的转变了,先来对比两张类图: 工厂方法(Factory Method) <img src="http://images.cnblogs.com/cnblogs_com/shenfx318/FactoryMethod3.jpg" alt="" width="506" height="186" border="0" /> 抽象工厂(Abstract Factory) 从图中我们能够看到哪些差异? 最明显的一点就是在工厂方法的类关系图中只有一类产品,他们实现了一个统一的接口,而抽象工厂有多个类别的产品,他们分别实现了不同的功能 (多个接口) 。其次的一点差别就是工厂本身所具有的方法数量不同,这点差异其实也是由第一点所导致的,工厂需要有生产不同类别产品的功能,如果抽象工厂中的产品的功能简化到一个,也便成为了工厂方法。 引出类别的概念,类别是指具有相同功能的一类产品的总称。 再来看选择的过程,在工厂方法中,客户关心的只不过是实现同一样功能的不同产品间的差异,这是一个一维选择的过程。 1 IFactory factory = new FactoryA(); //选择了工厂即选择了产品 2 IProduct productA = factory.Create(); //工厂只有一个Create方法,只能生产一种产品 而在抽象工厂中,客户首先要考虑的是需要哪一样功能,其次要考虑才是产品间的差异。也就是说这是一个二维选择的过程。 1 IFactory factory = new FactoryA(); //选择了某个具体工厂 2 IProduct productA = factory.CreateProductA(); //工厂具有多个Create方法,这里选择了其中的一个 ...

2012-10-12 · 1 min · 202 words · -