chart library

chart library web chart library chartjs Simple yet flexible JavaScript charting https://www.chartjs.org/ Apache ECharts An Open Source JavaScript Visualization Library https://echarts.apache.org/en/index.html

2011-09-22 · 1 min · 21 words · -

Jena

Jena Jena is a Java framework for building Semantic Web applications. It provides a programmatic environment for RDF, RDFS and OWL, SPARQL and includes a rule-based inference engine. Jena is open source and grown out of work with the HP Labs Semantic Web Programme. The Jena Framework includes: A RDF API Reading and writing RDF in RDF/XML, N3 and N-Triples An OWL API In-memory and persistent storage SPARQL query engine

2011-09-22 · 1 min · 70 words · -

OWL

OWL OWL Web本体语言指南 W3C推荐标准 2004年02月10日 摘要 目前这种结构的万维网,很像一本地图做得很差的地理书,我们对于Web中可以使用的文档和服务的了解,都是基于关键字搜索的, 同时还需要灵活地使用文档的链接和使用模式。如果没有强有力的工具的支持,这么大规模的数据是很难管理的,为了能够给Web绘制出更为详实的地图,计算代理需要对于网络上可用资源的内容和能力做一个机器能够读得懂的描述。这些描述是人类能够读得懂的信息的扩展。 OWL,这种本体描述语言,可以用来描述Web文档和应用中内在的类和关系。 这篇文章解释了OWL语言的使用: 通过定义类以及类的属性来形式化某个领域; 定义个体并说明它们之间的属性; 在OWL语言的形式化语义允许的层次上,对类和个体进行推理。 本文的各章节间是按照类、属性、个体的集合的定义给出来的,从最简单的概念开始,逐渐过渡到更为复杂的概念。 本文档的状态 本文档已被W3C成员及其他相关方面审阅,并已被W3C总监 (W3C Director) 批准为W3C推荐标准 (W3C Recommendation) 。W3C制定推荐标准的任务是使之受到关注,并促使其被广泛应用。这将增强Web的功能性与互操作性。 本文档是W3C关于Web本体语言OWL的推荐标准的六个部分之一。 它已经被Web 本体工作小组(小组章程) 作为W3C语义Web行动 (行动声明) 的一部分于2004年2月10日发布。 本文档的早期版本中所描述的关于OWL的设计已被广泛评阅,并已满足工作小组的技术需求。工作小组充分考虑所有收到的意见,并做了必要的修改。本文档自从候选推荐标准版本以来的所有修改都在文后的变更日志中。 欢迎通过public-webont-comments@w3.org (历史存档)提出您的意见,也可以通过www-rdf-logic@w3.org (mailto:www-rdf-logic@w3.org)(历史存档) 参与相关技术的讨论。 可以访问到有关实现的一个列表。 W3C维护着一个与这些工作相关的专利声明的目录。 这节描述了本文档在发布时的状态。其他文档可能替代这文档。一份当前W3C的最新出版物的目录和这个技术报告的最新版本可以在 W3C技术报告索引http://www.w3.org/TR/ 上找到。 目录 引言 1.1. OWL的种类 1.2. 本文档的结构 本体的结构 2.1. 命名空间 2.2. 本体头部 2.3. 数据集成与隐私 基本元素 (Basic Elements) 3.1. 简单的类和个体 3.1.1. 简单的具名类 3.1.2. 个体 3.1.3. 使用方面的考虑 3.2. 简单属性 3.2.1. 定义属性 (Defining Properties) 3.2.2. 属性和数据类型 ...

2011-09-22 · 8 min · 1625 words · -

RDF OWL

RDF OWL http://blogger.org.cn/blog/more.asp?name=babyblue&id=21546 Ontology来源于哲学词汇: 存在论 (也有翻译成本体论) 。RDF是一种不错的本体描述方式,我们可以定义根据对现实世界的理解针对某个领域定义词汇来描述这个领域的知识。但RDF与RDF不能定义同义词、反义词以及描述词与词间的关系 (类与类之间的关系) ,比如说等价性、互补排斥性、限制个数、属性的对称性等。OWL弥补了RDF的不足,运用AI中的逻辑论 (逻辑论中,把人们的思维用式子来表述,并且证明这些式子的正确性) 来赋予网给以语义,形成SW。在SW的定义中,吸收了很多知识的优点,如OO,逻辑论、树结构等。 从HTML到XML HTML是我们最常用的文档标记语言,并且已广泛应用于WEB上。HTML可用来描述资源,但其的特点限制了其生成的文档只有人可以看得懂。HTML有两大不足限制其发展: 一是其结构不明显,很难被应用程序解析;二是描述的局限性,如无法描述某些科学符号。 为了让应用程序能够理解文档,就需要良好的结构,于是最简单但功能强大的树状结构就被采用了。用树状结构来描述数据就生成了XML。XML为在各种应用程序间以及meta数据的交换提供了一致的体系和解析器。但XML本身没有进行任何语义的定义 (或说弱语义定义) ,即其描述的数据的语义机器无法理解。 理解数据的首要条件是更准备地记录数据结构与类型。预定义的最基本的数据类型不能很好地满足大多数现实生活中数据要求。我们需要更清楚地描述数据类型,即更给出数据更严格的限制。XML Schema提供了在预定义的类型上自定义数据类型,而且这种数据类型可以被解析器解析。 XML Schema XML Schema (XML的定义机制) 提供了在XML中可以利用的基本的数据类型 (如date,string等,DTD中只提供了string) ,通过对已有的类型进行扩张或者进行制约,从而定义新的类型。和DTD文档类型不同,XML Schema不需要另外的解析器和编辑器。 但XML Schema只是对文档的结构进行了定义,仍然不能让应用程序理解数据的语义。为了实现让应用程序理解数据,就出现了RDF。 从XML到RDF RDF(Resource Description Framework)并不是一种语言,只是一种书写规范。RDF的基本构造为陈述(或声明,Statement),表述了一个 (资源,资源所具有的属性,属性值) (即主体—属性—客体) 的三元组。RDF表现的是一个数据模型,简言之就是一个陈述就是一个什么事物 (资源) ,这个事物具有什么属性,这些属性应该有什么样的属性值。XML用来做为描述这种抽象的数据模型的具体书写方式 (不用XML,也可以用其他的构成来表现RDF) 。同样因为现实世界的超级复杂性,预定义的词汇根本不够用,我们就使用RDF Schema来自定义词汇。 RDF描述资源的特性是: 以属性为中心的思考方法。不是重在定义属性的值,而是通过定义拥有这个属性的主体 (资源) 的范围 (定义域) ,以及这个属性的取值范围 (值域) 。这样我们就可以比较精确地定义词汇,不是精确是因为我们不可能也没必要精确定义词汇,我们更关心的是词汇者的相互关系,即我们不能想让机器理解某个词汇,还是要让其理解词汇之间的相互关系,从而能为我们提供智能的服务。 RDF Schema RDFS翻译为资源描述框架的定义机制。其与RDF的关系不同于XML与XMLS间的关系。XMLS是用来对XML的结构 (构造) 进行定义,而RDFS是用来对RDF数据模型用到的词汇进行定义。 RDF+RDFS不能为我们提供描述词汇间的关系,导致OWL的出现。 OWL 是由DAML(DARPA Agent Markup Language)+OIL(Ontology Inference Layer)演变而来。 OWL是RDF的扩张,为我们提供了更广泛的定义RDFS词汇的功能,更广泛意指可以定义词汇之间的关系,类与类间的关系,属性与属性之间的关系等。 RDF是semantic web中MetaData层的资源表述框架,而 OWL应该是Ontology层的概念。 RDF着重于对数据的描述,而OWL则侧重于逻辑推理的准备。

2011-09-22 · 1 min · 68 words · -

XML RDF OWL

XML RDF OWL XML, RDF, OWL 请先理解RDF和RDF Schema的知识再看这篇文章。不理解的话请参照RDF和RDF Schema在线手册的第一篇相关概念的文章。理解概念很重要,因为对大多数人来说都有编程的基础,可以直接看别的语言的代码。但语义网相关概念是比较新 的概念。所以建议把概念一定到搞懂。通过RDF Schema,我们可以自定义词汇了。但在我们的实际生活当中,我们用的词汇之间都是有联系的。最简单的反义词,同义词。又比如"足球队"这个词,我们每个人脑子都有一个概念,上场比赛需要11个队员。这都是我们在生活中积累的经验。我们想让机器也理解数据的话,最起码要和人一样,也可以定义反义词,同义词,或者词和词之间的一些关系。这些仅仅靠RDF和RDF Schema是不够的。为了达到这个要求,就有了OWL(Web Ontology Language)的出现,Ontolory本是哲学词汇-存在论的意思。大多数中文翻译为本论。其实用原本哲学的意思就很好理解。我们就是在定义词汇,或者词汇之间的关系,或者类之间的关系等等。我们定义了它们,它们就存在于我们的网络里了。我们看看有了它对我们到底有什么好处。比如说它可以定义类和类之间的关系,等价性,互补排斥性,限制个数,属性的对称性等等。似乎还比较模糊,那就举一个具体的例子,比如我们描述这样一个资源: 从北京到上海的距离是400公里。人们听到了这句话后就知道了,上海到北京也是400公里。因为我们知道起点北京到终点上海的距离,和起点上海到终点北京的距离是一样的,也就是我们懂距离,起点,终点这3个词的概念而且知道它们之间的关系,所以我们得出上面的结论。现在我们可以用RDF和RDF Schema来定义这3个词汇,然后我们需要定义的是一个关系,起点-终点的距离等于终点-起点的距离,这里运用到了等价性。这个关系不能用RDF和 RDF Schema来定义,但是可以通过OWL来定义。当然解决这个问题方法可以有许多定义,我只是在这里举个例子。大家应该大概知道OWL是做什么的吧。那么为什么它有这个功能呢?其实它运用了人工智能中的逻辑论,逻辑论把人们的思维用式子来表达,并且可以证明这个式子的正确。其实在语义网的定义中,吸收了很多知识的优点,面向对象,逻辑轮,树结构等等。所以大家学起来,有时会有似曾相识的感觉。下面把大家容易混淆的几个概念XML,XML Schema,RDF,RDF Schema,OWL直接的关系拿出来讲一下。 主要的理解思想就是在语义网的定义中遇到问题了,就会有新的事物被定义或者说是出现. 从HTML到XML HTML的记述是我们最常用的,本来它是用来描述资源的,但是它记录的只有人可以看懂。还有它第一结构不明显,很难被应用程序解析,第二,记述的 局限性,比如某些科学符号无法表达等等。为了让应用程序好理解,就需要有良好的结构。最简单但也是功能很强大的树状结构就被采用了。我们以树状结构来记录数据,这就是XML。XML: 是一种国际通用标记语言。它为在各种应用程序间的数据和meta数据的交换,提供了一致的体系和解析器 (parser) 。但是对于数据的意义没有进行定义,比如说对于某个标签<课程>,也就是本身没有意义,除了结构的不同,它和HTML一样,数据也只有人可以看懂。想让机器理解数据,首先本身的数据类型很重要,不然自己都不知道自己是谁,或者自己是干什么的,怎么可能让机器理解。为了更好的描述资源,也就是说为了更准确的纪录数据的类型。需要我们可以自定义类型,因为预定义的类型只有最基本的类型,不能定义大多数现实生活中的数据类型。对于数据发布人,需要他描述清楚数据类型,也就是说数据的限制等等。所以我们需要一个可以在预定义类型上可以自定义类型,而且它也必须能被解析器解析。所以,就出现了XML Schema。 XML Schema XML Schema: XML的定义机制。和DTD文档类型定义不同,不需要另外的解析器和编辑器。定义的是XML的构造,对已有的类型进行扩张或者进行制约,从而定义了新的类型。XML Schema提供了在XML可以利用的基本的数据类型 (日期,数值等,DTD中只提供了文字列) 。但是即便是这样,它只是对XML文档的构造进行了定义,还是不能让应用程序理解数据。所以为了实现应用程序理解数据,就出现了RDF。 从XML到RDF RDF有时我们会称它为语言,其实这是不对的,RDF是一种书写规范,正确的翻译为资源描述框架。RDF的基本构造为陈述 (或者叫做声明, statement) 了一个资源-资源具有的属性-属性值 (主体-属性-客体) 的三元组。它表现的是一个数据模型,通俗的说一个陈述就是一个什么事物 (资源) 具有什么属性 (属性) ,这个属性是怎样的属性 (属性值) 。我们为了描述抽象的数据模型,需要具体的书写,这就用到了XML,这样RDF就继承了XML的优点。但是不用XML的构成,利用其他的构成也可以表现RDF。所以对RDF而言,XML不是必要的(一般我们的文档格式为RDF/XML就是这个原 因,用XML表示的RDF)。我们终于可以定义一个让机器理解的词汇了,但是它也遇到了一个问题,就是预定义的词汇根本不够用。我们需要自定义一些词汇。为了可以自定义词汇,就出现了RDF Schema。 RDF Schema RDF Schema (RDFS) 翻译为资源描述框架的定义机制,大家也许会比较容易联想到XML和XML Schema的关系,认为它们是同样的。这个想法也是不对的,XML Schema是用来对XML的构造进行定义,而RDFS是用来对RDF数据模型用到的词汇进行定义。我们需要了解一个RDF的特征,它是以属性为中心的思考方法。不是具体定义属性的值,而是定义了拥有这个属性的主体(资源)的范围(定义域),和这个属性可以取到的值的范围(值域)。这样就我们可以比较精确地定义词汇。为什么说比较精确,而不说精确,因为一个单独存在的词汇对我们毫无意义,即便机器可以理解它。我们语言中的词汇都是互相有关联的,正因为我们 只有知道了词汇的相互关系,我们才可以在生活中正常交流。同样我们一直说让应用程序理解词汇,其实是为了让应用程序理解词汇以及词汇之间的关系,从而自动地,智能地提供给我们服务。为了达到这个目的,描述词汇的关系至关重要。但是RDF和RDF Schema却不能提供给我们这样一个功能,所以也就出现了OWL。 OWL OWL是RDF的扩张,提供我们更广泛的由定义RDF Schema词汇。所谓更广泛就是指可以定义词汇之间的关系,类与类的关系,属性与属性之间的关系等等。具体请参照在线使用手册。 后记 其实每个概念都不难理解,理解的关键在于它们为了什么而出现。OWL的出现也没有能实现最终的目的。所以语义网结构上还有几层,这几层还没有推出规范,所以暂时不做它们的使用手册。

2011-09-22 · 1 min · 66 words · -

emacs format, 格式化

emacs format, 格式化 http://www.blogjava.net/killme2008/archive/2011/07/26/355041.html 格式化源码是很常见的需求,emacs有个indent-region函数用于格式化选定的代码,前提是你处在某个非text mode下,如c-mode或者java-mode之类。如果要格式化整个文件,你需要先选定整个文件(C-x-h),然后调用indent-region (或者 C-M-\ )。两个命令总是麻烦,我们可以定义个函数搞定这一切,并绑定在一个特定键上,实现一键格式化: ;;格式化整个文件函数 (defun indent-whole () (interactive) (indent-region (point-min) (point-max)) (message "format successfully")) ;;绑定到F7键 (global-set-key [f7] 'indent-whole) 将这段代码添加到你的emacs配置文件 (~/.emacs),重启emacs,以后格式化源码都可以用F7一键搞定。 整理整个文件 M-x mark-whole-buffer 或者 C-x h //选中整个文件 M-x indent-region 或者 C-M- //格式化选中 整理某个函数 M-x mark-defun 或者 C-M-h //选中函数 M-x indent-region 或者 C-M- //格式化

2011-09-21 · 1 min · 49 words · -

衬线字体

衬线字体 西方国家字母体系分为两类: serif以及sans serif。 serif是有衬线字体,意思是在字的笔画开始、结束的地方有额外的装饰,而且笔画的粗细会有所不同。相反的,sans serif就没有这些额外的装饰,而且笔画的粗细差不多。 serif字体容易识别,它强调了每个字母笔画的开始和结束,因此易读性比较高,sans serif则比较醒目。在走文阅读的情况下,适合适用serif字体进行排版,易于换行阅读的识别性,避免发生行间的阅读错误。 sans serif强调每一个字母,serif更强调于一个单词。 中文字体中的宋体就是一种最标准的serif字体,衬线的特征非常明显。字形结构也和手写的楷书一致。因此宋体一直被做为最适合的正文字体之一。不过由于强调横竖笔画的对比,在远处观看的时候横线就被弱化,导致识别性的下降 常用的serif (衬线字体) 字体为Time New Roman、Georgia、宋体 常用的sans serif (无衬线字体) 字体为Verdana、Arial、雅黑。 在传统的正文印刷中,普遍认为衬线体能带来更佳的可读性 (相比无衬线体) ,尤其是在大段落的文章中,衬线增加了阅读时对字母的视觉参照。而无衬线体往往被用在标题、较短的文字段落或者一些通俗读物中。相比严肃正经的衬线体,无衬线体给人一种休闲轻松的感觉。随着现代生活和流行趋势的变化,如今的人们越来越喜欢用无衬线体,因为他们看上去"更干净"。有调查显示,欧洲人对于无衬线体的接受度略高于北美,在书籍、报纸和杂志中大段落文字的排版,衬线体始终占据着压倒性的优势。 在文字足够大的情况下,无衬线字体也是同样可读的。而且因为无衬线字体通常有艺术性,因此在显示器上显示通常比较赏心悦目;而且无衬线字体种类比衬线字体多得多,因此选择余地也很大,在这里非衬线字体分类不做赘述。但是必须保证以下原则: 凡是使用无衬线字体的,必须保证其在正文内容中的可读性。否则,使用衬线字体。所以衬线字体在设计中占据很重要的位置;以下是衬线字体的具体分类。 线字体的分类有: 旧式衬线体 (Old style) : Adobe Jenson、Janson、Garamond、Bembo、Goudy Old Style 和 Palatino 过渡衬线体 (Transitional) 又称巴洛克体: Times Roman、Baskerville 现代衬线体 (Modern) : Didot、Bodoni 、Century、Computer Modern 粗衬线 (Slab Serif) 又称埃及体: Rockwell 、Courier、Clarendon

2011-09-19 · 1 min · 53 words · -

keyboard character english, 键盘上特殊符号的英文读法

keyboard character english, 键盘上特殊符号的英文读法 ! 叹号 exclamation mark/bang ? 问号 question mark , 逗号 comma . 点号 dot/period/point : 冒号 colon ; 分号 semicolon " 双引号 quotation marks/double quote/double quotation marks ’ 单引号/撇号 apostrophe/single quote, single quotation mark ` 反引号,重音号 backquote/grave accent * 星号 asterisk/star + 加号 plus sign - 减号/横线 hyphen/dash/minus sign = 等号 equal sign / 斜杠/斜线 slash, forward slash \ 反斜杠/反斜线 backslash/escape | 竖线 bar/pipe/vertical bar _ 下划线 underline/underscore $ 美元符号 dollar sign @ at, at sign # 井号 crosshatch/sharp/hash mark, hash tag % 百分号 percent sign/mod & and/和/兼 and/ampersand ^ 折音号 caret/circumflex ~ 波浪号 tilde {} (左/右) 花括号/大括号 (left/right|open/close) braces [] (左/右) 方括号/中括号 (left/right|open/close) brackets () (左/右) 圆括号/小括号 (left/right|open/close) parentheses <> 尖括号 angle brackets < 大于号 less than > 小于号 greater than … ellipsis https://www.douban.com/group/topic/12410327/

2011-09-17 · 1 min · 129 words · -

通过java反射机制获取该类的所有属性类型、值、

通过java反射机制获取该类的所有属性类型、值 http://blog.csdn.net/sd4000784/article/details/7448221 方法使用了这俩个包下的 field 和method import Java.lang.reflect.Field; import java.lang.reflect.Method; public static void getObjectValue(Object object) throws Exception { //我们项目的所有实体类都继承BaseDomain (所有实体基类: 该类只是串行化一下) //不需要的自己去掉即可 if (object != null && object instanceof BaseDomain) {//if (object!=null ) --begin // 拿到该类 Class<?> clz = object.getClass(); // 获取实体类的所有属性,返回Field数组 Field[] fields = clz.getDeclaredFields(); for (Field field : fields) {// -for() begin System.out.println(field.getGenericType());//打印该类的所有属性类型 // 如果类型是String if (field.getGenericType().toString().equals( "class java.lang.String")) { // 如果type是类类型,则前面包含"class ",后面跟类名 // 拿到该属性的gettet方法 /** * 这里需要说明一下: 他是根据拼凑的字符来找你写的getter方法的 * 在Boolean值的时候是isXXX (默认使用ide生成getter的都是isXXX) * 如果出现NoSuchMethod异常 就说明它找不到那个gettet方法 需要做个规范 */ Method m = (Method) object.getClass().getMethod( "get" + getMethodName(field.getName())); String val = (String) m.invoke(object);// 调用getter方法获取属性值 if (val != null) { System.out.println("String type:" + val); } } // 如果类型是Integer if (field.getGenericType().toString().equals( "class java.lang.Integer")) { Method m = (Method) object.getClass().getMethod( "get" + getMethodName(field.getName())); Integer val = (Integer) m.invoke(object); if (val != null) { System.out.println("Integer type:" + val); } } // 如果类型是Double if (field.getGenericType().toString().equals( "class java.lang.Double")) { Method m = (Method) object.getClass().getMethod( "get" + getMethodName(field.getName())); Double val = (Double) m.invoke(object); if (val != null) { System.out.println("Double type:" + val); } } // 如果类型是Boolean 是封装类 if (field.getGenericType().toString().equals( "class java.lang.Boolean")) { Method m = (Method) object.getClass().getMethod( field.getName()); Boolean val = (Boolean) m.invoke(object); if (val != null) { System.out.println("Boolean type:" + val); } } // 如果类型是boolean 基本数据类型不一样 这里有点说名如果定义名是 isXXX的 那就全都是isXXX的 // 反射找不到getter的具体名 if (field.getGenericType().toString().equals("boolean")) { Method m = (Method) object.getClass().getMethod( field.getName()); Boolean val = (Boolean) m.invoke(object); if (val != null) { System.out.println("boolean type:" + val); } } // 如果类型是Date if (field.getGenericType().toString().equals( "class java.util.Date")) { Method m = (Method) object.getClass().getMethod( "get" + getMethodName(field.getName())); Date val = (Date) m.invoke(object); if (val != null) { System.out.println("Date type:" + val); } } // 如果类型是Short if (field.getGenericType().toString().equals( "class java.lang.Short")) { Method m = (Method) object.getClass().getMethod( "get" + getMethodName(field.getName())); Short val = (Short) m.invoke(object); if (val != null) { System.out.println("Short type:" + val); } } // 如果还需要其他的类型请自己做扩展 }//for() -end }//if (object!=null ) --end } // 把一个字符串的第一个字母大写、效率是最高的、 private static String getMethodName(String fildeName) throws Exception{ byte[] items = fildeName.getBytes(); items[0] = (byte) ((char) items[0] - 'a' + 'A'); return new String(items); }

2011-09-17 · 2 min · 325 words · -

Connection reset

Connection reset 在使用HttpClient调用后台resetful服务时,“Connection reset”是一个比较常见的问题,有同学跟我私信说被这个问题困扰很久了,今天就来分析下,希望能帮到大家。例如我们线上的网关日志就会抛该错误: 从日志中可以看到是Socket socket 在read数据时抛出了该错误。 导致“Connection reset”的原因是服务器端因为某种原因关闭了Connection,而客户端依然在读写数据,此时服务器会返回复位标志“RST”,然后此时客户端就会提示“java.net.SocketException: Connection reset”。 可能有同学对复位标志“RST”还不太了解,这里简单解释一下: TCP建立连接时需要三次握手,在释放连接需要四次挥手;例如三次握手的过程如下: 第一次握手:客户端发送syn包 (syn=j)到服务器,并进入SYN_SENT状态,等待服务器确认; 第二次握手:服务器收到syn包,并会确认客户的SYN (ack=j+1),同时自己也发送一个SYN包 (syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态; 第三次握手:客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED (TCP连接成功)状态,完成三次握手。 可以看到握手时会在客户端和服务器之间传递一些TCP头信息,比如ACK标志、SYN标志以及挥手时的FIN标志等。 除了以上这些常见的标志头信息,还有另外一些标志头信息,比如推标志PSH、复位标志RST等。其中复位标志RST的作用就是“复位相应的TCP连接”。 TCP连接和释放时还有许多细节,比如半连接状态、半关闭状态等。详情请参考这方面的巨著《TCP/IP详解》和《UNIX网络编程》。 前面说到出现“Connection reset”的原因是服务器关闭了Connection[调用了Socket.close()方法]。大家可能有疑问了:服务器关闭了Connection为什么会返回“RST”而不是返回“FIN”标志。原因在于Socket.close()方法的语义和TCP的“FIN”标志语义不一样:发送TCP的“FIN”标志表示我不再发送数据了,而Socket.close()表示我不在发送也不接受数据了。问题就出在“我不接受数据” 上,如果此时客户端还往服务器发送数据,服务器内核接收到数据,但是发现此时Socket已经close了,则会返回“RST”标志给客户端。当然,此时客户端就会提示:“Connection reset”。详细说明可以参考oracle的有关文档:http://docs.oracle.com/javase/1.5.0/docs/guide/net/articles/connection_release.html。 另一个可能导致的“Connection reset”的原因是服务器设置了Socket.setLinger (true, 0)。但我检查过线上的tomcat配置,是没有使用该设置的,而且线上的服务器都使用了nginx进行反向代理,所以并不是该原因导致的。关于该原因上面的oracle文档也谈到了并给出了解释。 此外啰嗦一下,另外还有一种比较常见的错误“Connection reset by peer”,该错误和“Connection reset”是有区别的: 服务器返回了“RST”时,如果此时客户端正在从Socket socket 的输出流中读数据则会提示Connection reset”; 服务器返回了“RST”时,如果此时客户端正在往Socket socket 的输入流中写数据则会提示“Connection reset by peer”。 “Connection reset by peer”如下图所示: 前面谈到了导致“Connection reset”的原因,而具体的解决方案有如下几种: 出错了重试; 客户端和服务器统一使用TCP长连接; 客户端和服务器统一使用TCP短连接。 首先是出错了重试:这种方案可以简单防止“Connection reset”错误,然后如果服务不是“幂等”的则不能使用该方法;比如提交订单操作就不是幂等的,如果使用重试则可能造成重复提单。 然后是客户端和服务器统一使用TCP长连接:客户端使用TCP长连接很容易配置 (直接设置HttpClient就好),而服务器配置长连接就比较麻烦了,就拿tomcat来说,需要设置tomcat的maxKeepAliveRequests、connectionTimeout等参数。另外如果使用了nginx进行反向代理或负载均衡,此时也需要配置nginx以支持长连接 (nginx默认是对客户端使用长连接,对服务器使用短连接)。 使用长连接可以避免每次建立TCP连接的三次握手而节约一定的时间,但是我这边由于是内网,客户端和服务器的3次握手很快,大约只需1ms。ping一下大约0.93ms (一次往返);三次握手也是一次往返 (第三次握手不用返回)。根据80/20原理,1ms可以忽略不计;又考虑到长连接的扩展性不如短连接好、修改nginx和tomcat的配置代价很大 (所有后台服务都需要修改);所以这里并没有使用长连接。ping服务器的时间如下图: 最后的解决方案是客户端和服务器统一使用TCP短连接:我这边正是这么干的,而使用短连接既不用改nginx配置,也不用改tomcat配置,只需在使用HttpClient时使用http1.0协议并增加http请求的header信息 (Connection: Close),源码如下: 最后再补充几句,虽然对于每次请求TCP长连接只能节约大约1ms的时间,但是具体是使用长连接还是短连接还是要衡量下,比如你的服务每天的pv是1亿,那么使用长连接节约的总时间为: 神奇的是,亿万级pv的服务使用长连接一天内节约的总时间为27.78小时 (竟然大于一天)。 ...

2011-09-14 · 1 min · 72 words · -

迭代规划

迭代规划 团队会在Sprint开始之初召开Sprint计划会议并制定目标,团队成员会在Scrum每日例会上分享工作进展。当Sprint快结束时,团队会在评审会议中将进展展示给项目干系人。紧接着评审会议之后是回顾会,会上总结当前Sprint中团队的合作情况并为后续Sprint寻找可改进的地方。 计划会 Sprint开始时,团队与项目负责人共同制定下个Sprint的计划,这需要两个会议:Sprint优先级会议和Sprint计划会议。其中优先级会议需要准备产品Backlog、用户故事,并识别潜在的Sprint目标,而计划会议需要构建当前Sprint的Backlog,以确实际开发任务。 优先级会议 Sprint优先级会议的目的是挑出产品Backlog上优先级高的条目,并选择潜在的Sprint目标。我们在产品需求池通过属性来配置任务的优先级。 (图:任务的优先级设置) 在排序之后,PO和团队便可以挑选出高优先级的需求功能作为Sprint的目标。如果高优先级功能实在太多,无法在一个Sprint中完成,这些功能就要分解成更小、更适宜在同一Sprint中完成的小功能,然后放入已创建好的Sprint中。 (图:一个Sprint中的需求功能) 计划会议 在确定当前Sprint的目标需求后,团队从每个需求中分解出任务条目以构成Sprint的Backlog,这是在Sprint计划会议上面进行的,这个会议的参与者包括PO、Scrum Master以及团队中的每个人,和可以帮团队更好预估工作量的各领域专家。 (图:构建一个Sprint Backlog流程) 大家需要在会上讨论每个需求的设计与实现,最好的预估工作量的方法是检查团队过去Sprint中的工作完成情况,比如团队在近期的几个Sprint中完成了平均400小时的工作量,他们就有把握承诺在下个Sprint中完成同样多的工作量。除此之外,一个Sprint是否包括节假日、是否有重要员工离职以及其他影响 (比如是否在开发需要试错的新模块)等等因素也需要考虑进来,最终形成一个可按时交付的Sprint Backlog。 https://ones-ai.gitbooks.io/ones-ai/content/31-si-ge-gai-nian/43-gui-hua-die-dai.html

2011-09-14 · 1 min · 18 words · -

path, absolute path, and canonical path

path, absolute path, and canonical path http://www.avajava.com/tutorials/lessons/whats-the-difference-between-a-files-path-absolute-path-and-canonical-path.html What’s the difference between a file’s path, absolute path, and canonical path? Author: Deron Eriksson Description: This Java tutorial describes a file’s path, absolute path, and canonical path. Tutorial created using: Windows XP || JDK 1.5.0_09 || Eclipse Web Tools Platform 2.0 (Eclipse 3.3.0) This tutorial will examine the differences between a file’s path, absolute path, and canonical path. The FilePaths class will display data about several files and directories in the project. In JavaSW, a File object can represent a file or a directory. If a File object represents a directory, a call to its isDirectory() method returns true. Our project consists of the FilePaths class plus several files and directories. ...

2011-09-13 · 3 min · 562 words · -

URI, URL, URN

URI, URL, URN http://www.ibm.com/developerworks/cn/xml/x-urlni.html http://www.wiloon.com/en/US/partners/index.html 是一个 URI 方案名: http 域名: www.wiloon.com 路径: /en/US/partners/index.html URI 按照 UNIX® 的惯例采用了正斜杠 (a/b/c),因为在 20 世纪 80 年代后期设计 URI 的时候, 在 Internet 上, UNIX 文化比 PC 文化更流行。 URI 可以进一步分为定位器、名称,或者二者兼具。术语"Uniform Resource Locator" (URL) 涉及的是 URI 的子集,除识别资源外,它还通过描述其最初访问机制 (比如它的网络"位置") 来提供定位资源的方法。 术语"Uniform Resource Name" (URN) 在历史上曾用于引用"urn"方案 [RFC2141] 下的 URI,这个 URI 需要是全球惟一的,并且在资源不存在或不再可用时依然保持不变,对于其他任何拥有名称的一些属性的 URI,都需要使用这样的 URI。 对于单独的方案,没有必要将其分为仅仅是一个 “名称"或者是一个"定位器”。 来自任意特定方案的 URI 实例可能有名称或定位器的特征,或两者兼而有之, 这通常取决于标识符分配中的持久性和命名机构对其关注程度, 而不取决于其他方案的质量。未来的规范和相关的文档应当使用通用术语"URI",而不是使用有更多限制的条目"URL"和"URN" [RFC3305]。

2011-09-13 · 1 min · 61 words · -

java 代理模式

java 代理模式 http://blog.csdn.net/dyh8818/article/details/314668 代理模式 代理模式的作用是: 为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个客户不想或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。 代理模式一般涉及到的角色有: 抽象角色: 声明真实对象和代理对象的共同接口; 代理角色: 代理对象角色内部含有对真实对象的引用,从而可以操作真实对象,同时代理对象提供与真实对象相同的接口以便在任何时刻都能代替真实对象。同时,代理对象可以在执行真实对象操作时,附加其他的操作,相当于对真实对象进行封装。 真实角色: 代理角色所代表的真实对象,是我们最终要引用的对象。(参见文献1) 以下以《Java与模式》中的示例为例: 抽象角色: abstract public class Subject { abstract public void request(); } 真实角色: 实现了Subject的request()方法。 public class RealSubject extends Subject { public RealSubject() { } public void request() { System.out.println(“From real subject.”); } } 代理角色: public class ProxySubject extends Subject { private RealSubject realSubject; //以真实角色作为代理角色的属性 public ProxySubject() { } public void request() //该方法封装了真实对象的request方法 { preRequest(); if( realSubject == null ) { realSubject = new RealSubject(); } realSubject.request(); //此处执行真实对象的request方法 postRequest(); } private void preRequest() { //something you want to do before requesting ...

2011-09-13 · 2 min · 296 words · -

java classloader

java classloader 双亲委托模型 AppClassLoader ExtClassLoader Bootstrap Class Loader URLClassLoader JDK 17 AppClassLoader PlatformClassLoader, 模块加载器 BootClassLoader 不同的 JVM 的实现不同,本文所描述的内容均只限于 Hotspot Jvm. 本文将会从 JDK 默认的提供的 ClassLoader,双亲委托模型,如何自定义 ClassLoader 以及 Java 中打破双亲委托机制的场景四个方面入手去讨论和总结一下。 JDK 默认提供了如下几种 ClassLoader Bootstrap Class Loader, 引导类装载器 虚拟机的内置类加载器 (称为 “bootstrap class loader”) 本身没有父类加载器,但是可以将它用作 ClassLoader 实例的父类加载器。 Bootstrap Class Loader 加载器是由 c++ 实现的 不继承 java.lang.ClassLoader 类, 所以它不属于 “ClassLoader 实例”,也没有办法在 Java 代码中获取到它。 用来加载核心类库,如 java.lang.* 等. 它是在 Java 虚拟机启动后初始化的,它主要负责加载 %JAVA_HOME%/jre/lib, -Xbootclasspath 参数指定的路径以及 %JAVA_HOME%/jre/classes 中的类。 ExtClassLoader, 扩展类装载器 Bootstrp loader 加载 ExtClassLoader, 并且将 ExtClassLoader 的父加载器设置为 Bootstrp loader ExtClassLoader 是用Java写的,具体来说就是 sun.misc.Launcher$ExtClassLoader,ExtClassLoader 主要加载 %JAVA_HOME%/jre/lib/ext,此路径下的所有 classes 目录以及 java.ext.dirs 系统变量指定的路径中类库。 ...

2011-09-09 · 8 min · 1663 words · -

java 反射, reflect

java 反射, reflect http://www.iteye.com/topic/137944 什么是反射 反射的概念是由 Smith 在 1982 年首次提出的,主要是指程序可以访问、检测和修改它本身状态或行为的一种能力。这一概念的提出很快引发了计算机科学领域关于应用反射性的研究。它首先被程序语言的设计领域所采用, 并在 Lisp 和面向对象方面取得了成绩。其中 LEAD/LEAD++ 、OpenC++ 、MetaXa 和 OpenJava 等就是基于反射机制的语言。最近,反射机制也被应用到了视窗系统、操作系统和文件系统中。 反射本身并不是一个新概念,尽管计算机科学赋予了反射概念新的含义。在计算机科学领域,反射是指一类应用,它们能够自描述和自控制。也就是说,这类应用通过采用某种机制来实现对自己行为的描述 (self-representation) 和监测 (examination) ,并能根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义。 什么是Java中的类反射 Reflection 是 Java 程序开发语言的特征之一,它允许运行中的 Java 程序对自身进行检查,或者说"自审",并能直接操作程序的内部属性和方法。Java 的这一能力在实际应用中用得不是很多,但是在其它的程序设计语言中根本就不存在这一特性。例如,Pascal、C 或者 C++ 中就没有办法在程序中获得函数定义相关的信息。 Reflection 是 Java 被视为动态 (或准动态) 语言的关键,允许程序于执行期 Reflection APIs 取得任何已知名称之 class 的內部信息,包括 package、type parameters、superclass、implemented interfaces、inner classes, outer class, fields、constructors、methods、modifiers,並可于执行期生成instances、变更 fields 內容或唤起 methods。 Java类反射中所必须的类 Java的类反射所需要的类并不多,它们分别是: Field、Constructor、Method、Class、Object,下面我将对这些类做一个简单的说明。 Field类: 提供有关类或接口的属性的信息,以及对它的动态访问权限。反射的字段可能是一个类 (静态) 属性或实例属性,简单的理解可以把它看成一个封装反射类的属性的类。 Constructor类: 提供关于类的单个构造方法的信息以及对它的访问权限。这个类和Field类不同,Field类封装了反射类的属性,而Constructor类则封装了反射类的构造方法。 Method类: 提供关于类或接口上单独某个方法的信息。所反映的方法可能是类方法或实例方法 (包括抽象方法) 。 这个类不难理解,它是用来封装反射类方法的一个类。 ...

2011-09-09 · 5 min · 953 words · -

动态语言

动态语言 动态语言,是指程序在运行时可以改变其结构: 新的函数可以被引进,已有的函数可以被删除等在结构上的变化。比如众所周知的ECMAScript(JavaScript)便是一个动态语言。除此之外如Ruby、Python等也都属于动态语言,而C、C++等语言则不属于动态语言。 Dynamic Programming Language (动态语言或动态编程语言) Dynamically Typed Language (动态类型语言) Statically Typed Language (静态类型语言) 所谓的动态类型语言,意思就是类型的检查是在运行时做的,比如如下代码是不是合法的要到运行时才判断 (注意是运行时的类型判断) : def sum(a, b): return a + b 而静态类型语言的类型判断是在运行前判断 (如编译阶段) ,比如C#就是一个静态类型语言,静态类型语言为了达到多态会采取一些类型鉴别手段, 如继承、接口,而动态类型语言却不需要,所以一般动态语言都会采用dynamic typing,常出现于脚本语言中。 这里我需要明确说明一点,那就是,是不是动态类型语言与这门语言是不是类型安全的完全不相干的,不要将它们联系在一起! 静态类型语言的主要优点在于其结构非常规范,便于调试,方便类型安全;缺点是为此需要写更多的类型相关代码,导致不便于阅读、不清晰明了。动态类型语言的优点在于方便阅读,不需要写非常多的类型相关的代码;缺点自然就是不方便调试,命名不规范时会造成读不懂,不利于理解等。顺便说一下,现在有这样一种趋势,那就是合并动态类型与静态类型在一种语言中,这样可以在必要的时候取长补短,Boo就是一个很好的试验性例子。^_^ 最后说一下Boo,Boo是一个静态类型语言,虽然用duck typing可以模拟dynamic typing,但是duck并不支持所有类型的操作替代,所以即使完全使用duck typing也不能达到dynamic typing。就像FantasySoft所述,Type Inference不是动态类型语言的特性,所以支持Type Inference不代表这门语言就是dynamically typed。 再特地为Ninputer这个VB的fans说一下VB.NET^_^,VB.NET是dynamically typed语言。

2011-09-09 · 1 min · 42 words · -

可扩展性, scalability

可扩展性, scalability 可扩展的本质是什么? 可扩展的意思是在面对变化时,用最少的代价去实现,平时我们听得最多的是面向抽象(接口)编程,如果只是把这里的抽象理解成接口,那么就有些狭隘了,抽象是通式通法,而接口只是其中一个,所以在谈可扩展实现之前一定要讲清楚可扩展的本质是什么,连本质都不知道,怎么提出系统性解决方案。 1.1 扩展的本质 扩展的本质就是占位符,明确告诉你这里被占了,具体谁占了不清楚。那么问题来了:占位符到底是什么?它是怎么表达的?又要如何实现的?如果可以把这三个问题理清楚,就可以想到很多可扩展性方案,而不再是单一的面向接口编程。 占位符到底是什么:占位符仅仅是一个标识,标志这里会有变化,一句话可以概括:凡是可以表达变化的就是占位符,然而具体的变化实现又没有给出,真正体现了做什么和怎么做的分离。 占位符怎么表达:要回答这个标识是用什么来表达,变量、接口、配置项…这些都可以表达占位符,变量能被赋值同一类型的数据;接口可以有不同的实现;配置项也可以被赋予不同的值…所以,实现可扩展的思路一下就打开了。 如何实现:再往深层次思考,实现一个接口,如何在执行时动态找到实现类?如果把这个问题想清楚,在实际中实现可扩展又会有一套系统性解决方案。整个过程就两点:识别和执行,识别的意思就是要找到对应目标,接下来就是执行。 综上,到这里可能已经有自己应对可扩展的方法,上面已经给了从不同角度看可扩展性的示例,接下来就是系统化提出应对可扩展的方法。 结论一:扩展的本质就是占位符,凡是可以表达变化的就是占位符。 1.2 应对可扩展的方法 先给出应对可扩展的方法:规范、识别、注册、使用,这 4 点都是从上面可推导出来的,下面一一进行详细说明。 规范:规范是从占位符推导出来的,既然是标志有变化,一定要遵循一定的规范表达,否则别人是不知道的,如接口,就是很直接地表达这里是有变化的,具体的实现还不知道;变量天然地表达这里是变化的数据。 识别:有了规范定义之后,接下来就是识别,之前为什么可扩展一直对我们来讲很虚,那是因为规范和识别都是系统帮我们做的,我们只是知道而没有真正实践。规范是定义,识别是找出有哪些实现了规范。 注册:识别出来之后,就要把信息存储起来,可以存储在本地,也可以存储在远程,如果存储在远程就是一个注册的过程,这里的注册就是存储的意思。简单理解就是识别出来之后要集中管理。 使用:使用就很简单,找到具体实现并执行逻辑处理。 上面四个单词看起来简单,除了使用是终极目标外,其它三个都是抽象的表达,比如规范如何定义、怎么识别、如何注册?通过上面的表述可以看到具体要怎么实践,这里再总结下: 规范如何去定义:凡是可以表达变化的就能用它来定义,常见的有配置项、变量、接口、注解等; 怎么去识别:这个要具体去看如何定义规范,如配置项的变化有一个监听变化;注解是要扫描类来识别 annotation; 如何去注册:如果系统的交互只是一个,那么存储在本地就行,如果系统的交互是多个,那么要注册到一个注册中心上去。 结论二:应对可扩展的方法:规范、识别、注册、使用。 https://www.infoq.cn/article/1w2mjzzx-0dm9j9vysam

2011-09-08 · 1 min · 28 words · -

java final

java final final 根据程序上下文环境,Java关键字final有"这是无法改变的"或者"终态的"含义,它可以修饰非抽象类、非抽象类成员方法和变量。你可能出于两种理解而需要阻止改变: 设计或效率。 final类不能被继承,没有子类,final类中的方法默认是final的。 final方法不能被子类的方法覆盖,但可以被继承。 final 成员变量表示常量,只能被赋值一次,赋值后值不再改变。 final不能用于修饰构造方法。 注意: 父类的private成员方法是不能被子类方法覆盖的,因此private类型的方法默认是final类型的。 final类 final类不能被继承,因此final类的成员方法没有机会被覆盖,默认都是final的。在设计类时候,如果这个类不需要有子类,类的实现细节不允许改变,并且确信这个类不会载被扩展,那么就设计为final类。 final方法 如果一个类不允许其子类覆盖某个方法,则可以把这个方法声明为final方法。 使用final方法的原因有二: 第一、把方法锁定,防止任何继承类修改它的意义和实现。 第二、高效。编译器在遇到调用final方法时候会转入内嵌机制,大大提高执行效率。 final变量 (常量) 用final修饰的成员变量表示常量,值一旦给定就无法改变! final修饰的变量有三种: 静态变量、实例变量和局部变量,分别表示三种类型的常量。 另外,final变量定义的时候,可以先声明,而不给初值,这种变量也称为 final 空白,无论什么情况,编译器都确保空白final在使用之前必须被初始化。但是,final 空白在final关键字final的使用上提供了更大的灵活性,为此,一个类中的final数据成员就可以实现依对象而有所不同,却有保持其恒定不变的特征。 final参数 当函数参数为final类型时,你可以读取使用该参数,但是无法改变该参数的值。

2011-09-08 · 1 min · 30 words · -

java static

java static static表示"全局"或者"静态"的意思,用来修饰成员变量和成员方法,也可以形成静态static代码块,但是Java语言中没有全局变量的概念。 被static修饰的成员变量和成员方法独立于该类的任何对象。也就是说,它不依赖类特定的实例,被类的所有实例共享。只要这个类被加载,Java虚拟机就能根据类名在运行时数据区的方法区内定找到他们。因此,static对象可以在它的任何对象创建之前访问,无需引用任何对象。 用public修饰的static成员变量和成员方法本质是全局变量和全局方法,当声明它类的对象时,不生成static变量的副本,而是类的所有实例共享同一个static变量。 static变量前可以有private修饰,表示这个变量可以在类的静态代码块中,或者类的其他静态成员方法中使用 (当然也可以在非静态成员方法中使用) ,但是不能在其他类中通过类名来直接引用,这一点很重要。private是访问权限限定,static表示不要实例化就可以使用。static前面加上其它访问权限关键字的效果也以此类推。 static修饰的成员变量和成员方法习惯上称为静态变量和静态方法,可以直接通过类名来访问,访问语法为: 类名.静态方法名(参数列表…) 类名.静态变量名 用static修饰的代码块表示静态代码块,当Java虚拟机 (JVM) 加载类时,就会执行该代码块。 static变量 按照是否静态的对类成员变量进行分类可分两种: 一种是被static修饰的变量,叫静态变量或类变量;另一种是没有被static修饰的变量,叫实例变量。两者的区别是: 对于静态变量在内存中只有一个拷贝 (节省内存) ,JVM只为静态分配一次内存,在加载类的过程中完成静态变量的内存分配,可用类名直接访问 (方便) ,当然也可以通过对象来访问 (但是这是不推荐的) 。 对于实例变量,每创建一个实例,就会为实例变量分配一次内存,实例变量可以在内存中有多个拷贝,互不影响 (灵活) 。 静态方法 静态方法可以直接通过类名调用,任何的实例也都可以调用,因此静态方法中不能用this和super关键字,不能直接访问所属类的实例变量和实例方法(就是不带static的成员变量和成员成员方法),只能访问所属类的静态成员变量和成员方法。因为实例成员与特定的对象关联! static代码块 static代码块也叫静态代码块,是在类中独立于类成员的static语句块,可以有多个,位置可以随便放,它不在任何的方法体内,JVM加载类时会执行这些静态的代码块,如果static代码块有多个,JVM将按照它们在类中出现的先后顺序依次执行它们,每个代码块只会被执行一次。 static和final一块用表示什么 static final用来修饰成员变量和成员方法,可简单理解为"全局常量"! 对于变量,表示一旦给值就不可修改,并且通过类名可以访问。 对于方法,表示不可覆盖,并且可以通过类名直接访问。 因为static方法独立于任何实例,因此static方法必须被实现,而不能是抽象的abstract 定义一个类成员,使它的使用完全独立于该类的任何对象。通常情况下,类成员必须通过它的类的对象访问,但是可以创建这样一个成员,它能够被它自己使用,而不必引用特定的实例。在成员的声明前面加上关键字static(静态的)就能创建这样的成员。如果一个成员被声明为static,它就能够在它的类的任何对象创建之前被访问,而不必引用任何对象。你可以将方法和变量都声明为static。static 成员的最常见的例子是main( ) 。因为在程序开始执行时必须调用main() ,所以它被声明为static。 当声明一个对象时,并不产生static变量的拷贝,而是该类所有的实例变量共用同一个static变量。声明为static的方法有以下几条限制: 仅能调用其他的static 方法。 只能访问static数据。 不能以任何方式引用this 或super 可以声明一个static块,Static 块仅在该类被加载时执行一次

2011-09-08 · 1 min · 50 words · -