diff --git a/Alibaba_Druid/README.md b/Alibaba_Druid/README.md
index 425e004..12dc801 100644
--- a/Alibaba_Druid/README.md
+++ b/Alibaba_Druid/README.md
@@ -1,4 +1,4 @@
-###Alibaba Druid数据源监控
+### Alibaba Druid数据源监控
在[阿里巴巴Druid](https://github.com/Alibaba/Druid)数据库连接池上写着这一句话,"为监控而生的数据库连接池",确实,Druid在数据库连接池监控上做得非常完善。
diff --git a/AngularJS_String_SubString/README.md b/AngularJS_String_SubString/README.md
new file mode 100644
index 0000000..913246d
--- /dev/null
+++ b/AngularJS_String_SubString/README.md
@@ -0,0 +1,36 @@
+### angularjs 字符串截取 filter,用于截取字符串
+
+```JavaScript
+
+angular.module('ng').filter('cut', function () {
+ return function (value, wordwise, max, tail) {
+ if (!value) return '';
+
+ max = parseInt(max, 10);
+ if (!max) return value;
+ if (value.length <= max) return value;
+
+ value = value.substr(0, max);
+ if (wordwise) {
+ var lastspace = value.lastIndexOf(' ');
+ if (lastspace != -1) {
+ value = value.substr(0, lastspace);
+ }
+ }
+
+ return value + (tail || ' …');
+ };
+ });
+```
+
+### Usage:
+
+{{some_text | cut:true:100:' ...'}}
+
+### Options:
+
+* wordwise (boolean) - if true, cut only by words bounds,
+
+* max (integer) - max length of the text, cut to this number of chars,
+
+* tail (string, default: ' …') - add this string to the input string if the string was cut.
\ No newline at end of file
diff --git a/Big_Data_ETL/README.md b/Big_Data_ETL/README.md
index 7c661ca..4a9c324 100644
--- a/Big_Data_ETL/README.md
+++ b/Big_Data_ETL/README.md
@@ -1,4 +1,4 @@
-###ETL
+### ETL
ETL,是英文 Extract-Transform-Load 的缩写,用来描述将数据从来源端经过抽取(extract)、转换
(transform)、加载(load)至目的端的过程。ETL一词较常用在数据仓库,但其对象并不限于数据仓库。
@@ -6,7 +6,7 @@ ETL是构建数据仓库的重要一环,用户从数据源抽取出所需的
信息是现代企业的重要资源,是企业运用科学管理、决策分析的基础。目前,大多数企业花费大量的资金和时间来构建联机事务处理OLTP的业务系统和办公自动化系统,用来记录事务处理的各种相关数据。据统计,数据量每2~3年时间就会成倍增长,这些数据蕴含着巨大的商业价值,而企业所关注的通常只占在总数据量的2%~4%左右。因此,企业仍然没有最大化地利用已存在的数据资源,以致于浪费了更多的时间和资金,也失去制定关键商业决策的最佳契机。于是,企业如何通过各种技术手段,并把数据转换为信息、知识,已经成了提高其核心竞争力的主要瓶颈。而ETL则是主要的一个技术手段。
-####主要特点
+#### 主要特点
* ETL负责将分布的、异构数据源中的数据如关系数据、平面数据文件等抽取到临时中间层后进行清洗、转换、集成,最后加载到数据仓库或数据集市中,成为联机分析处理、数据挖掘的基础。
* ETL一词较常出现在数据仓库,但其对象并不局限于数据仓库。
@@ -18,22 +18,22 @@ ETL是构建数据仓库的重要一环,用户从数据源抽取出所需的
ETL过程在很大程度上受企业对源数据的理解程度的影响,也就是说从业务的角度看数据集成非常重要。一个优秀的ETL设计应该具有如下功能:
-#####1、管理简单
+##### 1、管理简单
采用元数据方法,集中进行管理;接口、数据格式、传输有严格的规范;尽量不在外部数据源安装软件;数据抽取系统流程自动化,并有自动调度功能;抽取的数据及时、准确、完整;可以提供同各种数据系统的接口,系统适应性强;提供软件框架系统,系统功能改变时,应用程序很少改变便可适应变化;可扩展性强。
-#####2、标准定义数据
+##### 2、标准定义数据
合理的业务模型设计对ETL至关重要。数据仓库是企业唯一、真实、可靠的综合数据平台。数据仓库的设计建模一般都依照三范式、星型模型、雪花模型,无论哪种设计思想,都应该最大化地涵盖关键业务数据,把运营环境中杂乱无序的数据结构统一成为合理的、关联的、分析型的新结构,而ETL则会依照模型的定义去提取数据源,进行转换、清洗,并最终加载到目标数据仓库中。
模型的重要之处在于对数据做标准化定义,实现统一的编码、统一的分类和组织。标准化定义的内容包括:标准代码统一、业务术语统一。ETL依照模型进行初始加载、增量加载、缓慢增长维、慢速变化维、事实表加载等数据集成,并根据业务需求制定相应的加载策略、刷新策略、汇总策略、维护策略。
-#####3、拓展新型应用
+##### 3、拓展新型应用
对业务数据本身及其运行环境的描述与定义的数据,称之为元数据(metadata)。元数据是描述数据的数据。从某种意义上说,业务数据主要用于支持业务系统应用的数据,而元数据则是企业信息门户、客户关系管理、数据仓库、决策支持和B2B等新型应用所不可或缺的内容。
元数据的典型表现为对象的描述,即对数据库、表、列、列属性(类型、格式、约束等)以及主键/外部键关联等等的描述。特别是现行应用的异构性与分布性越来越普遍的情况下,统一的元数据就愈发重要了。“信息孤岛”曾经是很多企业对其应用现状的一种抱怨和概括,而合理的元数据则会有效地描绘出信息的关联性。
而元数据对于ETL的集中表现为:定义数据源的位置及数据源的属性、确定从源数据到目标数据的对应规则、确定相关的业务逻辑、在数据实际加载前的其他必要的准备工作,等等,它一般贯穿整个数据仓库项目,而ETL的所有过程必须最大化地参照元数据,这样才能快速实现ETL。
-####其他资料
+#### 其他资料
ETL(Extract-Transform-Load的缩写,即数据抽取、转换、装载的过程)作为BI/DW(Business Intelligence)的核心和灵魂,能够按照统一的规则集成并提高数据的价值,是负责完成数据从数据源向目标数据仓库转化的过程,是实施数据仓库的重要步骤。如果说数据仓库的模型设计是一座大厦的设计蓝图,数据是砖瓦的话,那么ETL就是建设大厦的过程。在整个项目中最难部分是用户需求分析和模型设计,而ETL规则设计和实施则是工作量最大的,约占整个项目的60%~80%,这是国内外从众多实践中得到的普遍共识。
@@ -41,7 +41,7 @@ ETL是数据抽取(Extract)、清洗(Cleaning)、转换(Transform)
信息是现代企业的重要资源,是企业运用科学管理、决策分析的基础。目前,大多数企业花费大量的资金和时间来构建联机事务处理OLTP的业务系统和办公自动化系统,用来记录事务处理的各种相关数据。据统计,数据量每2~3年时间就会成倍增长,这些数据蕴含着巨大的商业价值,而企业所关注的通常只占在总数据量的2%~4%左右。因此,企业仍然没有最大化地利用已存在的数据资源,以致于浪费了更多的时间和资金,也失去制定关键商业决策的最佳契机。于是,企业如何通过各种技术手段,并把数据转换为信息、知识,已经成了提高其核心竞争力的主要瓶颈。而ETL则是主要的一个技术手段。
-####ETL工具应用
+#### ETL工具应用
目前,ETL工具的典型代表有:Informatica、Datastage、OWB、微软DTS、Beeload、Kettle……
开源的工具有eclipse的etl插件。cloveretl.
diff --git a/C#/HTML2Word/README.md b/C#/HTML2Word/README.md
new file mode 100644
index 0000000..d0f7973
--- /dev/null
+++ b/C#/HTML2Word/README.md
@@ -0,0 +1,113 @@
+### HTML转出到Word中 ###
+通过系统剪切板把HTML复制到Word中,并且保留原来的格式
+
+```C#
+
+ class HTMLUtils
+ {
+ // 将HTML代码复制到Windows剪贴板,并保证中
+ [DllImport("user32.dll")]
+ static extern bool OpenClipboard(IntPtr hWndNewOwner);
+ [DllImport("user32.dll")]
+ static extern bool EmptyClipboard();
+ [DllImport("user32.dll")]
+ static extern IntPtr SetClipboardData(uint uFormat, IntPtr hMem);
+ [DllImport("user32.dll")]
+ static extern bool CloseClipboard();
+ [DllImport("user32.dll", SetLastError = true)]
+ static extern uint RegisterClipboardFormatA(string lpszFormat);
+
+ [DllImport("kernel32.dll", SetLastError = true)]
+ static extern IntPtr GlobalLock(IntPtr hMem);
+ [DllImport("kernel32.dll", SetLastError = true)]
+ static extern uint GlobalSize(IntPtr hMem);
+ [DllImport("kernel32.dll", SetLastError = true)]
+ static extern IntPtr GlobalUnlock(IntPtr hMem);
+
+ ///
+ /// copy the html into clipboard
+ ///
+ ///
+ ///
+ static public bool CopyHTMLToClipboard(string html)
+ {
+ uint CF_HTML = RegisterClipboardFormatA("HTML Format");
+ bool bResult = false;
+ if (OpenClipboard(IntPtr.Zero))
+ {
+ if (EmptyClipboard())
+ {
+ byte[] bs = System.Text.Encoding.UTF8.GetBytes(html);
+
+ int size = Marshal.SizeOf(typeof(byte)) * bs.Length;
+
+ IntPtr ptr = Marshal.AllocHGlobal(size);
+ Marshal.Copy(bs, 0, ptr, bs.Length);
+
+ IntPtr hRes = SetClipboardData(CF_HTML, ptr);
+ CloseClipboard();
+ }
+ }
+ return bResult;
+ }
+
+ //将HTML代码按照Windows剪贴板格进行格式化
+ public static string HtmlClipboardData(string html)
+ {
+ StringBuilder sb = new StringBuilder();
+ Encoding encoding = Encoding.UTF8; //Encoding.GetEncoding(936);
+ string Header = @"Version: 1.0
+ StartHTML: {0:000000}
+ EndHTML: {1:000000}
+ StartFragment: {2:000000}
+ EndFragment: {3:000000}
+ ";
+ string HtmlPrefix = @"
+
+
+
+
+
+
+ ";
+ HtmlPrefix = string.Format(HtmlPrefix, "gb2312");
+
+ string HtmlSuffix = @"";
+
+ // Get lengths of chunks
+ int HeaderLength = encoding.GetByteCount(Header);
+ HeaderLength -= 16; // extra formatting characters {0:000000}
+ int PrefixLength = encoding.GetByteCount(HtmlPrefix);
+ int HtmlLength = encoding.GetByteCount(html);
+ int SuffixLength = encoding.GetByteCount(HtmlSuffix);
+
+ // Determine locations of chunks
+ int StartHtml = HeaderLength;
+ int StartFragment = StartHtml + PrefixLength;
+ int EndFragment = StartFragment + HtmlLength;
+ int EndHtml = EndFragment + SuffixLength;
+
+ // Build the data
+ sb.AppendFormat(Header, StartHtml, EndHtml, StartFragment, EndFragment);
+ sb.Append(HtmlPrefix);
+ sb.Append(html);
+ sb.Append(HtmlSuffix);
+
+ //Console.WriteLine(sb.ToString());
+ return sb.ToString();
+ }
+ }
+```
+
+调用:
+
+```C#
+ string html = "abc
";
+ html = HTMLUtils.HtmlClipboardData(html);
+ HTMLUtils.CopyHTMLToClipboard(html);
+ //then you can paste into word using WdPasteDataType.wdPasteHTML parameter
+ object dataType = Word.WdPasteDataType.wdPasteHTML;
+ newapp.Selection.PasteSpecial(ref nothing, ref nothing, ref nothing, ref nothing, ref dataType, ref nothing, ref nothing); ;
+```
+具体的实现请看[https://github.com/scalad/MathML2MathTypeEquation](https://github.com/scalad/MathML2MathTypeEquation)
+
diff --git a/C#/WordObjectModel/README.md b/C#/WordObjectModel/README.md
new file mode 100644
index 0000000..3c3021b
--- /dev/null
+++ b/C#/WordObjectModel/README.md
@@ -0,0 +1,47 @@
+### Word对象模型 ###
+
+#### 一、开发环境布置 ####
+C#中添加对Word的支持,只需添加对Microsoft.Office.Interop.Word的命名空间,如下图所示,右键点击“引用”,在弹出的“添加引用”对话框中选中COM标签页,找到“Microsoft Word 12.0 Object Library”。
+
+
+
+点击确定按钮后,可在引用中添加显示名称为Microsoft.Office.Interop.Word的引用:
+
+
+
+#### 二、Word的对象模型介绍 ####
+Word中共有5种常用的对象模型:应用程序对象Application、文档对象Document、Selection对象、Range对象和Bookmark对象。
+下图显示了 Word 对象模型层次结构中这些对象的一个视图。
+
+
+
+初看起来,对象似乎重叠在一起。 例如,Document 和 Selection 对象都是 Application 对象的成员,但 Document 对象也是 Selection 对象的成员。 Document 和 Selection 对象都包含 Bookmark 和 Range 对象。 因为有多种方法可以访问相同类型的对象,所以存在重叠。 例如,你将格式设置应用于 Range 对象;但你可能想要访问当前选定内容、某一特定段落,某一节或整个文档的范围。
+
+下面分别介绍五种模型对象的含义和作用。
+
+#### 2.1 Applicatin对象。 ####
+Application 对象表示 Word 应用程序,并且是所有其他对象的父级。 其成员通常作为一个整体应用于 Word。 你可以使用其属性和方法来控制 Word 环境。
+
+在文档级项目中,可以通过使用 ThisDocument 类的 Application 属性来访问 Application 对象。
+
+#### 2.2 Document对象 ####
+`Microsoft.Office.Interop.Word.Document` 对象是 Word 编程的中心。 它表示一个文档及其所有内容。 当你打开文档或创建新文档时,将创建新的 `Microsoft.Office.Interop.Word.Document` 对象,并将其添加到 Application 对象的 T:`Microsoft.Office.Interop.Word.Documents` 集合。 具有焦点的文档被称为活动文档。 它由 Application 对象的 P:`Microsoft.Office.Interop.Word._Application.ActiveDocument` 属性表示。
+
+#### 2.3 Selection对象 ####
+Selection 对象表示当前所选的区域。 在 Word 用户界面中执行操作(如文本加粗)时,可以选择或突出显示文本,然后应用格式设置。 文档中始终存在 Selection 对象。 如果未选中任何内容,则它表示插入点。 此外,选定内容可包含多个不相邻的文本块。
+
+#### 2.4 Range对象 ####
+Range 对象表示文档中的相邻区域,并由起始字符位置和结束字符位置进行定义。 并不仅限于单个 Range 对象。 你可以在同一文档中定义多个 Range 对象。 Range 对象具有以下特性:
+
+* 它可以只包含单独的插入点,也可包含一个文本范围或整个文档。
+* 它包括非打印字符,如空格、制表符和段落标记。
+* 它可以是当前选定内容所表示的区域,也可以表示不同于此内容的区域。
+* 它在文档中不可见,这与选定内容不同,后者总是可见。
+* 它不随文档一起保存,且仅在代码运行时才存在。
+* 当在某个范围的末尾插入文本时,Word 会自动扩展该范围以包括插入的文本。
+
+#### 2.5 Bookmark对象 ####
+Microsoft.Office.Interop.Word.Bookmark 对象表示文档中的相邻区域,同时具有起始位置和结束位置。 你可以使用书签标记文档中的某个位置,也可将其作为文档中文本的容器。 Microsoft.Office.Interop.Word.Bookmark 对象可以包含插入点,也可以与整个文档一样大。Microsoft.Office.Interop.Word.Bookmark 具有下列特征,以将其与 Range 对象区别开来:
+* 你可以在设计时命名书签。
+* Microsoft.Office.Interop.Word.Bookmark 对象随文档一起保存,因此在代码停止运行或文档关闭时不会被删除。
+* 通过将 T:Microsoft.Office.Interop.Word.View 对象的 P:Microsoft.Office.Interop.Word.View.ShowBookmarks 属性设置为 false 或 true,可以隐藏或显示书签。
\ No newline at end of file
diff --git a/C#/WordObjectModel/image/20161109112442139.png b/C#/WordObjectModel/image/20161109112442139.png
new file mode 100644
index 0000000..8be72e5
Binary files /dev/null and b/C#/WordObjectModel/image/20161109112442139.png differ
diff --git a/C#/WordObjectModel/image/20161109112637339.png b/C#/WordObjectModel/image/20161109112637339.png
new file mode 100644
index 0000000..625ec10
Binary files /dev/null and b/C#/WordObjectModel/image/20161109112637339.png differ
diff --git a/C#/WordObjectModel/image/20161109112800937.png b/C#/WordObjectModel/image/20161109112800937.png
new file mode 100644
index 0000000..feeca01
Binary files /dev/null and b/C#/WordObjectModel/image/20161109112800937.png differ
diff --git a/CROS/README.md b/CROS/README.md
new file mode 100644
index 0000000..aadf9a1
--- /dev/null
+++ b/CROS/README.md
@@ -0,0 +1,77 @@
+## CROS实现跨域时授权问题
+
+ Response to preflight request doesn't pass access control check:
+ No 'Access-Control-Allow-Origin' header is present on the requested resource.
+ Origin 'null' is therefore not allowed access. The response had HTTP status code 403
+
+### 问题的提出
+如果我们访问的资源是不需要授权的,也就是在HTTP请求头中不包含authentication头那么以上做法就足够了。但是如果该资源是需要权限验证的,那么这个时候跨域请求的预检测option请求,由于不会携带身份信息而被拒绝。浏览器会报出401错误。错误信息如下:
+
+ Failed to load resource:
+ the server responded with a status of 401 (Unauthorized)
+ XMLHttpRequest cannot load http://localhost/api/test.
+ Response for preflight has invalid HTTP status code 401
+
+既然知道了问题的原因,答案也就很容易得出:对需要进行跨域请求的资源(api),当服务端检测到是OPTONS请求时候统统放行,给出HTTP.OK(200)的状态和必要的响应头,哪怕它是不带身份信息的。
+这个问题既可以通过编写对应的后端代码实现,也可以通过设置服务器配置文件实现。也就是如何设置响应头和返回200状态码的办法了。
+
+### Spring+Shrio的解决方案
+shiro中可以在自己实现的身份验证filter中加入以下代码:
+
+```Java
+@Override protected boolean preHandle(ServletRequest servletRequest, ServletResponse servletResponse) throws Exception { HttpServletRequest request = (HttpServletRequest) servletRequest; HttpServletResponse response = (HttpServletResponse) servletResponse; if(request.getMethod().equals(RequestMethod.OPTIONS.name())) { response.setStatus(HttpStatus.OK.value()); return false; } return super.preHandle(request, response); }
+```
+
+shiro中AccessControlFilter提供了访问控制的基础功能;比如是否允许访问/当访问拒绝时如何处理等,也是我们一般自定义权限验证时候的一个父类,我们通过重写他的onPreHandle方法判断是否是option请求,如果是则设置相应状态,(响应头已经在之前文章中通过filter配置过了)返回false表示该拦截器实例已经处理了,将直接返回即可。
+
+### Tomcat配置
+需要修改tomcat的全局web.xml文件在CATALINA_HOME/conf下,加入以下配置。
+
+```Xml
+
+ CorsFilter
+ org.apache.catalina.filters.CorsFilter
+
+
+ CorsFilter
+ /*
+
+```
+
+### Nginx配置
+
+ add_header 'Access-Control-Allow-Methods' 'GET,OPTIONS,PUT,DELETE' always;
+ add_header 'Access-Control-Allow-Credentials' 'true' always;
+ add_header 'Access-Control-Allow-Origin' '$http_origin' always;
+ add_header 'Access-Control-Allow-Headers' 'Authorization,DNT,User-Agent,
+ Keep-Alive,Content-Type,accept,origin,X-Requested-With' always;
+
+ if ($request_method = OPTIONS ) {
+ return 200;
+ }
+
+### Apache配置
+
+ Header always set Access-Control-Allow-Origin "http://waffle"
+ Header always set Access-Control-Allow-Methods "POST, GET, OPTIONS"
+ Header always set Access-Control-Allow-Credentials "true"
+ Header always set Access-Control-Allow-Headers "Authorization,DNT,User-Agent,Keep-Alive,Content-Type,accept,origin,X-Requested-With"
+
+ RewriteCond %{REQUEST_METHOD} OPTIONS
+ RewriteRule ^(.*)$ $1 [R=200,L]
+
+### js请求示例
+请求时候需要加上Authorization和Content-Type头。
+
+ $http({
+ method: 'POST',
+ url: scope.webdav.url,
+ withCredentials: true,
+ headers: {
+ Authorization: 'Basic ' + btoa(user + ':' + password),
+ 'Content-Type': 'application/vnd.google-earth.kml+xml; charset=utf-8'
+ },
+ data: getKml()
+ })
+
+参考文章:[http://www.jujens.eu/posts/en/2015/Jun/27/webdav-options/](http://www.jujens.eu/posts/en/2015/Jun/27/webdav-options/)
\ No newline at end of file
diff --git a/CrossOrigin_Request/README.md b/CrossOrigin_Request/README.md
new file mode 100644
index 0000000..3d65af3
--- /dev/null
+++ b/CrossOrigin_Request/README.md
@@ -0,0 +1,79 @@
+[关于使用JS解决跨域问题](http://www.cnblogs.com/dojo-lzz/p/4265637.html)
+
+服务器端解决跨域请求问题,拦截请求并重新设置响应头
+
+服务器端拦截器
+
+```Java
+
+ package com.silence.util;
+
+ import java.io.IOException;
+ import java.text.SimpleDateFormat;
+ import java.util.Date;
+
+ import javax.servlet.Filter;
+ import javax.servlet.FilterChain;
+ import javax.servlet.FilterConfig;
+ import javax.servlet.ServletException;
+ import javax.servlet.ServletRequest;
+ import javax.servlet.ServletResponse;
+ import javax.servlet.http.HttpServletResponse;
+
+ import org.slf4j.Logger;
+ import org.slf4j.LoggerFactory;
+
+ public class CrossOriginFilter implements Filter {
+
+ private String allowDomain = "";
+ private static final Logger logger = LoggerFactory.getLogger(CrossOriginFilter.class);
+
+ public void init(FilterConfig filterConfig) throws ServletException {
+ allowDomain = filterConfig.getInitParameter("domain");
+ }
+
+ public void doFilter(ServletRequest request, ServletResponse response,
+ FilterChain chain) throws IOException, ServletException {
+ logger.info("CrossOriginFilter 跨域请求拦截 " + new SimpleDateFormat("YYYY-DD-MM").format(new Date()));
+ HttpServletResponse httpResponse = (HttpServletResponse) response;
+ setAccessControl(httpResponse);
+ chain.doFilter(request, response);
+ }
+
+ public void destroy() {
+
+ }
+ /**
+ *在某域名下使用Ajax向另一个域名下的页面请求数据,会遇到跨域问题。另一个域名必须在response中添加
+ *Access-Control-Allow-Origin 的header,才能让前者成功拿到数据。
+ *只有当目标页面的response中,包含了 Access-Control-Allow-Origin 这个header,并且它的值里有我们自己的域名时,
+ *浏览器才允许我们拿到它页面的数据进行下一步处理。
+ *如果它的值设为 * ,则表示谁都可以用
+ */
+ private void setAccessControl(HttpServletResponse response) {
+ response.setHeader("Access-Control-Allow-Origin", allowDomain);
+ response.setHeader("Access-Control-Allow-Credentials", "true");
+ String headers = "Origin, Accept-Language, Accept-Encoding,X-Forwarded-For, Connection, Accept, User-Agent, Host, Referer,Cookie, Content-Type, Cache-Control";
+ response.setHeader("Access-Control-Allow-Headers", headers);
+ response.setHeader("Access-Control-Request-Method", "GET,POST");
+ }
+
+ }
+```
+
+在web.xml中配置
+
+
+ CrossOriginFilter
+ com.silence.util.CrossOriginFilter
+
+ domain
+ *
+
+
+
+ CrossOriginFilter
+ /*
+
+
+默认拦截所有的请求,允许来自任何链接的请求
\ No newline at end of file
diff --git a/Eclipse_Referenced_File_Contains_Errors/README.md b/Eclipse_Referenced_File_Contains_Errors/README.md
new file mode 100644
index 0000000..47d0288
--- /dev/null
+++ b/Eclipse_Referenced_File_Contains_Errors/README.md
@@ -0,0 +1,35 @@
+### Eclipse Xml编译错误Referenced file contains errors - spring-beans-4.0.xsd
+
+在eclipse中,有时候在xml文件中,特别是于spring相关的配置文件中,会出现一些不影响程序正常运行的编译错误,如:
+
+Referenced file contains errors (http://www.springframework.org/schema/beans/spring-beans-4.0.xsd).
+
+可通过如下步骤解决这个编译错误:
+
+1. Spring的版本变更了,但是Eclipse的编译器还是使用之前缓存的spring-beans-**.xsd文件。其原因是
+
+对于Eclipse编译器来说有个缓存会缓存这些配置文件,这样验证的时候会告诉你版本不统一。
+
+解决办法是清空这些文件并强制eclipse重新加载这些文件。
+
+> 1) Preferences -> General -> Network Connections -> Cache
+
+选择响应的文件病点击删除或者直接点击删除全部。
+
+> 2) 如果是Maven工程,右击工程,并选择Maven,选择Update Project.
+
+> 3)如果以上两步都不行,则可关闭project并重新打开强制eclipse进行编译。
+
+
+2 . 当前使用的spring版本和配置文件中配置的不相同,导致xsd等文件不会被正确加载,改成当前版本即可。
+
+如果不成功则重复上面的2)3)两步即可。
+
+3 . 在使用spring时,使用多个配置文件,那么头里面的配置一定要统一。
+
+如果不成功则重复上面的2)3)两步即可。
+
+
+从网上http://stackoverflow.com/questions/7267341/validation-error-of-spring-beans-schema-inside-application-context看到可能又另外一种情况:
+
+就是你在spring的配置文件中混合使用了不同版本的xsd文件,你可以把这些xsd文件的版本设置为一样,然后重新更新下项目
\ No newline at end of file
diff --git a/Git_Language_Show/README.md b/Git_Language_Show/README.md
new file mode 100644
index 0000000..d22ce8d
--- /dev/null
+++ b/Git_Language_Show/README.md
@@ -0,0 +1,42 @@
+### 修改Github上项目语言显示问题
+
+#### 问题
+最近将自己写的博客放到github上了。由于使用了富文本编辑器、jQuery、Bootstrap等第三方插件,导致js、css等代码远远超过你自己写的代码
+
+于是也就成这样了
+
+
+
+而且这里也显示JavaScript
+
+
+
+这样的情况很不能忍,尤其对于强迫症来说。而且github也没有bitbucket项目语言的设置
+
+搜索了一下发现github是使用 Linguist 来detect所使用的语言。 Linguist 是什么鬼我也不了解,大致就是通过统计哪种语言代码数量最多的作为当前项目主语言。这样很不公平有木有,像Scala这种支持函数式编程而且语法简洁的语言,代码量完全拼不过其他语言
+
+#### 解决
+
+解决起来也简单,有2种方法
+
+#### 1、使用外链接
+
+将项目中的静态文件如jQuery、Bootstrap等放到别处用连接导入即可
+
+#### 2、使用 .gitattributes 配置文件
+
+具体就是在项目根目录添加文件名为.gitattributes的文本文件,写入
+
+ *.js linguist-language=Scala
+ *.css linguist-language=Scala
+ *.html linguist-language=Scala
+
+意思就是将.js、css、html当作Scala语言来统计
+
+另外,说一下,在windows系统中并不好直接创建名为 .gitattributes 的文件,会提示:
+
+
+
+那么只需要用命令行创建就行了,或者使用VI也是可以的:
+
+touch .gitattributes
\ No newline at end of file
diff --git a/Git_Language_Show/image/EBFZJrr.png b/Git_Language_Show/image/EBFZJrr.png
new file mode 100644
index 0000000..9e24002
Binary files /dev/null and b/Git_Language_Show/image/EBFZJrr.png differ
diff --git a/Git_Language_Show/image/u2UVna.png b/Git_Language_Show/image/u2UVna.png
new file mode 100644
index 0000000..d96ed0f
Binary files /dev/null and b/Git_Language_Show/image/u2UVna.png differ
diff --git a/Git_Language_Show/image/vQz6FjB.png b/Git_Language_Show/image/vQz6FjB.png
new file mode 100644
index 0000000..fe23448
Binary files /dev/null and b/Git_Language_Show/image/vQz6FjB.png differ
diff --git a/Gradle_Dependencies/README.md b/Gradle_Denpendencies_Exclude/README.md
similarity index 95%
rename from Gradle_Dependencies/README.md
rename to Gradle_Denpendencies_Exclude/README.md
index 111af6a..1098ae8 100644
--- a/Gradle_Dependencies/README.md
+++ b/Gradle_Denpendencies_Exclude/README.md
@@ -1,4 +1,4 @@
-##Gradle排除依赖关系
+## Gradle排除依赖关系
在IDE中发现了C3P0的依赖,但是在build.gradle并没有手动导入,所以说某个jar包依赖了,在STS中没有像Maven可以直接查看依赖的窗口
diff --git a/Gradle_Dependencies/image/1.png b/Gradle_Denpendencies_Exclude/image/1.png
similarity index 100%
rename from Gradle_Dependencies/image/1.png
rename to Gradle_Denpendencies_Exclude/image/1.png
diff --git a/Gradle_Denpendency_Management/README.md b/Gradle_Denpendency_Management/README.md
new file mode 100644
index 0000000..b464a1f
--- /dev/null
+++ b/Gradle_Denpendency_Management/README.md
@@ -0,0 +1,234 @@
+### Gradle系列之依赖管理
+Gradle依赖管理看起来很容易,但是当出现依赖解析冲突时就会很棘手, 复杂的依赖关系可能导致构建中依赖一个库的多个版本。Gradle通过分析依赖树得到依赖报告,你将很容易找到一个指定的依赖的来源.
+
+Gradle有自己的依赖管理实现,除了支持ant和Maven的特性外,Gradle关心的是性能、可靠性和复用性.
+
+#### 简要概述依赖管理
+几乎所有基于JVM的项目都会或多或少依赖其他库,假设你在开发一个基于web的项目,你很可能会依赖很受欢迎的开源框架比如Spring MVC来提高效率。Java的第三方库一般以JAR文件的形式存在,一般用库名加版本号来标识。随着开发的进行依赖的第三方库增多小的项目变的越来越大, 组织和管理你的JAR文件就很关键.
+
+#### 不算完美的依赖管理技术
+由于Java语言并没提供依赖管理的工具,所以你的团队需要自己开发一套存储和检索依赖的想法。你可能会采取以下几种常见的方法:
+
+* 手动复制JAR文件到目标机器,这是最原始的很容易出错的方法
+
+* 使用一个共享的存储介质来存储JAR文件(比如共享的网盘),你可以加载网络硬盘或者通过FTP检索二进制文件。这种方法需要开发者事先建立好与仓库的连接,手动添加新的依赖到仓库中
+
+* 把依赖的JAR文件同源代码都添加到版本控制系统中。这种方法不需要任何额外的步骤,你的同伴在拷贝仓库的时候就能检索依赖的改变。另一方面,这些JAR文件占用了不必要的空间,当你的项目存在相互之间依赖的时候你需要频繁的check-in的检查源代码是否发生了改变.
+
+#### 自动管理依赖的重要性
+尽管上面的方法都能用,但是这距离理想的解决方案差远了,因为他们没有提供一个标准化的方法来命名和管理JAR文件。至少你得需要开发库的准确版本和它依赖的库(传递依赖),这个为什么这么重要?
+
+#### 准确知道依赖的版本
+如果在项目中你没有准确声明依赖的版本这将会是一个噩梦,如果没有文档你根本无法知道这个库支持哪些特性,是否升级一个库到新的版本就变成了一个猜谜游戏因为你不知道你的当前版本.
+
+#### 管理传递依赖
+在项目的早期开发阶段传递依赖就会是一个隐患,这些库是第一层的依赖需要的,比如一个比较常见的开发方案是将Spring和Hibernate结合起来这会引入超过20个其他的开发库,一个库需要很多其他库来正常工作。下图展示了Hibernate核心库的依赖图:
+
+
+
+如果没有正确的管理依赖,你可以会遇到没想到过的编译期错误和运行期类加载问题。我们可以总结到我们需要一个更好的方式来管理依赖,一般来讲你想在 项目元数据中声明你的依赖和它的版本号。作为一个项目自动化的过程,这个版本的库会自动从中央仓库下载、安装到你的项目中,我们来看几个现有的开源解决方 案。
+
+#### 使用自动化的依赖管理
+在Java领域里支持声明的自动依赖管理的有两个项目:Apache Ivy(Ant项目用的比较多的依赖管理器)和Maven(在构建框架中包含一个依赖管理器),我不再详细介绍这两个的细节而是解释自动依赖管理的概念和机制
+
+Ivy和Maven是通过XML描述文件来表达依赖配置,配置包含两部分:依赖的标识加版本号和中央仓库的位置(可以是一个HTTP链接),依赖管 理器根据这个信息自动定位到需要下载的仓库然后下载到你的机器中。库可以定义传递依赖,依赖管理器足够聪明分析这个信息然后解析下载传递依赖。如果出现了 依赖冲突比如上面的Hibernate core的例子,依赖管理器会试着解决。库一旦被下载就会存储在本地的缓存中,构建系统先检查本地缓存中是否存在需要的库然后再从远程仓库中下载。下图显 示了依赖管理的关键元素:
+
+
+
+Gradle通过DSL来描述依赖配置,实现了上面描述的架构
+
+#### 自动依赖管理面临的挑战
+虽然依赖管理器简化了手工的操作,但有时也会遇到问题。你会发现你的依赖图中会依赖同个库的不同版本,使用日志框架经常会遇到这个问题,依赖管理器 基于一个特定的解决方案只选择其中一个版本来避免版本冲突。如果你想知道某个库引入了什么版本的传递依赖,Gradle提供了一个非常有用的依赖报告来回 答这个问题。下一节我会通过一个例子来讲解
+
+#### 声明依赖
+DSL配置block dependencies用来给配置添加一个或多个依赖,你的项目不仅可以添加外部依赖,下面这张表显示了Gradle支持的各种不同类型的依赖.
+
+
+
+这一章直接扫外部模块依赖和文件依赖,我们来看看Gradle APi是怎么表示依赖的
+
+#### 理解依赖的API表示
+
+每个Gradle项目都有一个DependencyHandler的实例,你可以通过getDependencies()方法来获取依赖处理器的引 用,上表中每一种依赖类型在依赖处理器中都有一个相对应的方法。每一个依赖都是Dependency的一个实例,group, name, version, 和classifier这几个属性用来标识一个依赖,下图清晰的表示了项目(Project)、依赖处理器(DependencyHandler)和依赖 三者之间的关系:
+
+
+
+#### 外部模块依赖
+在Gradle的术语里,外部库通常是以JAR文件的形式存在,称之为外部模块依赖,代表项目层次外的一个模块,这种类型的依赖是通过属性来唯一的标识,接下来我们来介绍每个属性的作用
+
+#### 依赖属性
+
+当依赖管理器从仓库中查找依赖时,需要通过属性的结合来定位,最少需要提供一个name。
+
+* group: 这个属性用来标识一个组织、公司或者项目,可以用点号分隔,Hibernate的group是org.hibernate。
+
+* name: name属性唯一的描述了这个依赖,hibernate的核心库名称是hibernate-core。
+
+* version: 一个库可以有很多个版本,通常会包含一个主版本号和次版本号,比如Hibernate核心库3.6.3-Final。
+
+* classifier: 有时候需要另外一个属性来进一步的说明,比如说明运行时的环境,Hibernate核心库没有提供classifier。
+
+#### 依赖的写法
+
+你可以使用下面的语法在项目中声明依赖:
+
+ dependencies {
+ configurationName dependencyNotation1, dependencyNotation2, ...
+ }
+
+你先声明你要给哪个配置添加依赖,然后添加依赖列表,你可以用map的形式来注明,你也可以直接用冒号来分隔属性,比如这样的:
+
+
+
+ //声明外部属性
+ ext.cargoGroup = 'org.codehaus.cargo'
+ ext.cargoVersion = '1.3.1'
+
+ dependencies {
+ //使用映射声明依赖
+ compile group: cargoGroup, name: 'cargo-core-uberjar',version: cargoVersion
+ //用快捷方式来声明,引用了前面定义的外部属性
+ cargo "$cargoGroup:cargo-ant:$cargoVersion"
+ }
+
+如果你项目中依赖比较多,你把一些共同的依赖属性定义成外部属性可以简化build脚本.
+
+Gradle没有给项目选择默认的仓库,当你没有配置仓库的时候运行deployTOLocalTomcat任务的时候回出现如下的错误:
+
+ $ gradle deployToLocalTomcat
+ :deployToLocalTomcat FAILED
+ FAILURE: Build failed with an exception.
+
+ Where: Build file '/Users/benjamin/gradle-in-action/code/chapter5/cargo-configuration/build.gradle' line: 10
+
+ What went wrong:
+ Execution failed for task ':deployToLocalTomcat'.
+ > Could not resolve all dependencies for configuration ':cargo'.
+ > Could not find group:org.codehaus.cargo, module:cargo-core-uberjar, version:1.3.1.
+ Required by:
+ :cargo-configuration:unspecified
+ > Could not find group:org.codehaus.cargo, module:cargo-ant,version:1.3.1.
+ Required by:
+ :cargo-configuration:unspecified
+
+到目前为止还没讲到怎么配置不同类型的仓库,比如你想使用MavenCentral仓库,添加下面的配置代码到你的build脚本中:
+
+ repositories {
+ mavenCentral()
+ }
+
+#### 检查依赖报告
+
+当你运行dependencies任务时,这个依赖树会打印出来,依赖树显示了你build脚本声明的顶级依赖和它们的传递依赖:
+
+
+
+仔细观察你会发现有些传递依赖标注了*号,表示这个依赖被忽略了,这是因为其他顶级依赖中也依赖了这个传递的依赖,Gradle会自动分析下载最合适的依赖.
+
+#### 排除传递依赖
+
+Gradle允许你完全控制传递依赖,你可以选择排除全部的传递依赖也可以排除指定的依赖,假设你不想使用UberJar传递的xml-api的版本而想声明一个不同版本,你可以使用exclude方法来排除它:
+
+ dependencies {
+ cargo('org.codehaus.cargo:cargo-ant:1.3.1') {
+ exclude group: 'xml-apis', module: 'xml-apis'
+ }
+ cargo 'xml-apis:xml-apis:2.0.2'
+ }
+
+exclude属性值和正常的依赖声明不太一样,你只需要声明group和(或)module,Gradle不允许你只排除指定版本的依赖.
+
+有时候仓库中找不到项目依赖的传递依赖,这会导致构建失败,Gradle允许你使用transitive属性来排除所有的传递依赖:
+
+ dependencies {
+ cargo('org.codehaus.cargo:cargo-ant:1.3.1') {
+ transitive = false
+ }
+ // 选择性的声明一些需要的库
+ }
+
+#### 动态版本声明
+
+如果你想使用一个依赖的最新版本,你可以使用latest.integration,比如声明 Cargo Ant tasks的最新版本,你可以这样写org.codehaus .cargo:cargo-ant:latest-integration,你也可以用一个+号来动态的声明:
+
+ dependencies {
+ //依赖最新的1.x版本
+ cargo 'org.codehaus.cargo:cargo-ant:1.+'
+ }
+
+Gradle的dependencies任务可以清晰的看到选择了哪个版本,这里选择了1.3.1版本:
+
+ $ gradle –q dependencies
+ ------------------------------------------------------------
+ Root project
+ ------------------------------------------------------------
+ Listing 5.4 Excluding a single dependency
+ Listing 5.5 Excluding all transitive dependencies
+ Listing 5.6 Declaring a dependency on the latest Cargo 1.x version
+ Exclusions can be
+ declared in a shortcut
+ or map notation.
+ 120 CHAPTER 5 Dependency management
+ cargo - Classpath for Cargo Ant tasks.
+ \--- org.codehaus.cargo:cargo-ant:1.+ -> 1.3.1
+ \--- ...
+
+#### 文件依赖
+如果你没有使用自动的依赖管理工具,你可能会把外部库作为源代码的一部分或者保存在本地文件系统中,当你想把项目迁移到Gradle的时候,你不想去重构,Gradle很简单就能配置文件依赖。下面这段代码复制从Maven中央仓库解析的依赖到libs/cargo目录。
+
+ task copyDependenciesToLocalDir(type: Copy) {
+ //Gradle提供的语法糖
+ from configurations.cargo.asFileTree
+ into "${System.properties['user.home']}/libs/cargo"
+ }
+
+运行这个任务之后你就可以在依赖中声明Cargo库了,下面这段代码展示了怎么给cargo配置添加JAR文件依赖:
+
+ dependencies {
+ cargo fileTree(dir: "${System.properties['user.home']}/libs/cargo",include: '*.jar')
+ }
+
+#### 配置远程仓库
+Gradle支持下面三种不同类型的仓库:
+
+
+
+下图是配置不同仓库对应的Gradle API:
+
+
+
+下面以Maven仓库来介绍,Maven仓库是Java项目中使用最为广泛的一个仓库,库文件一般是以JAR文件的形式存在,用XML(POM文 件)来来描述库的元数据和它的传递依赖。所有的库文件都存储在仓库的指定位置,当你在构建脚本中声明了依赖时,这些属性用来找到库文件在仓库中的准确位 置。group属性标识了Maven仓库中的一个子目录,下图展示了Cargo依赖属性是怎么对应到仓库中的文件的:
+
+
+
+RepositoryHandler接口提供了两个方法来定义Maven仓库,mavenCentral方法添加一个指向仓库列表的引用,mavenLocal方法引用你文件系统中的本地Maven仓库.
+
+#### 添加Maven仓库
+
+要使用Maven仓库你只需要调用mavenCentral方法,如下所示:
+
+ repositories {
+ mavenCentral()
+ }
+
+添加本地仓库
+
+本地仓库默认在 /.m2/repository目录下,只需要添加如下脚本来引用它:
+
+ repositories {
+ mavenLocal()
+ }
+
+#### 添加自定义Maven仓库
+
+如果指定的依赖不存在与Maven仓库或者你想通过建立自己的企业仓库来确保可靠性,你可以使用自定义的仓库。仓库管理器允许你使用Maven布局 来配置一个仓库,这意味着你要遵守artifact的存储模式。你也可以添加验证凭证来提供访问权限,Gradle的API提供两种方法配置自定义的仓 库:maven()和mavenRepo()。下面这段代码添加了一个自定义的仓库,如果Maven仓库中不存在相应的库会从自定义仓库中查找:
+
+ repositories {
+ mavenCentral()
+ maven {
+ name 'Custom Maven Repository',
+ url 'http://repository.forge.cloudbees.com/release/')
+ }
+ }
+
+来自:[http://coolshell.info/blog/2015/05/gradle-dependency-management.html](http://coolshell.info/blog/2015/05/gradle-dependency-management.html)
\ No newline at end of file
diff --git a/Gradle_Denpendency_Management/image/20150512084408_658.png b/Gradle_Denpendency_Management/image/20150512084408_658.png
new file mode 100644
index 0000000..6f3e3f5
Binary files /dev/null and b/Gradle_Denpendency_Management/image/20150512084408_658.png differ
diff --git a/Gradle_Denpendency_Management/image/20150512084409_161.png b/Gradle_Denpendency_Management/image/20150512084409_161.png
new file mode 100644
index 0000000..dc23031
Binary files /dev/null and b/Gradle_Denpendency_Management/image/20150512084409_161.png differ
diff --git a/Gradle_Denpendency_Management/image/20150512084409_541.png b/Gradle_Denpendency_Management/image/20150512084409_541.png
new file mode 100644
index 0000000..0140a86
Binary files /dev/null and b/Gradle_Denpendency_Management/image/20150512084409_541.png differ
diff --git a/Gradle_Denpendency_Management/image/20150512084410_225.png b/Gradle_Denpendency_Management/image/20150512084410_225.png
new file mode 100644
index 0000000..3935455
Binary files /dev/null and b/Gradle_Denpendency_Management/image/20150512084410_225.png differ
diff --git a/Gradle_Denpendency_Management/image/20150512084410_595.png b/Gradle_Denpendency_Management/image/20150512084410_595.png
new file mode 100644
index 0000000..cfb5f65
Binary files /dev/null and b/Gradle_Denpendency_Management/image/20150512084410_595.png differ
diff --git a/Gradle_Denpendency_Management/image/20150512084410_977.png b/Gradle_Denpendency_Management/image/20150512084410_977.png
new file mode 100644
index 0000000..d5c908c
Binary files /dev/null and b/Gradle_Denpendency_Management/image/20150512084410_977.png differ
diff --git a/Gradle_Denpendency_Management/image/20150512084411_208.png b/Gradle_Denpendency_Management/image/20150512084411_208.png
new file mode 100644
index 0000000..3f1b8dc
Binary files /dev/null and b/Gradle_Denpendency_Management/image/20150512084411_208.png differ
diff --git a/Gradle_Denpendency_Management/image/20150512084411_990.png b/Gradle_Denpendency_Management/image/20150512084411_990.png
new file mode 100644
index 0000000..f0d4b8f
Binary files /dev/null and b/Gradle_Denpendency_Management/image/20150512084411_990.png differ
diff --git a/Gradle_Denpendency_Management/image/20150512084412_417.png b/Gradle_Denpendency_Management/image/20150512084412_417.png
new file mode 100644
index 0000000..5debad0
Binary files /dev/null and b/Gradle_Denpendency_Management/image/20150512084412_417.png differ
diff --git a/Gradle_Gretty/README.md b/Gradle_Gretty/README.md
index a98a57d..9ea523a 100644
--- a/Gradle_Gretty/README.md
+++ b/Gradle_Gretty/README.md
@@ -1,4 +1,4 @@
-###Gretty插件实现Gradle Web项目热部署
+### Gretty插件实现Gradle Web项目热部署
在build.gradle配置文件中
buildscript {
@@ -31,7 +31,7 @@ gradle jetty* / gradle tomcat*
// serlvetContainer 支持 jetty7/8/9,tomcat7/8
// contextPath 设置根路径,默认为项目名称
port = 8080
- serlvetContainer = 'tomcat8'
+ servletContainer = 'tomcat8'
contextPath = '/'
}
@@ -93,4 +93,4 @@ gradle buildProduct
项目启动,修改项目文件,自动编译部署
-
\ No newline at end of file
+
diff --git a/Gradle_Linux_Install/README.md b/Gradle_Linux_Install/README.md
new file mode 100644
index 0000000..4343e68
--- /dev/null
+++ b/Gradle_Linux_Install/README.md
@@ -0,0 +1,76 @@
+### Gradle Linux安装
+#### 使用SDKMAN安装
+
+sdkman(The Software Development Kit Manager), 中文名为:软件开发工具管理器.这个工具的主要用途是用来解决在类unix操作系统(如mac, Linux等)中多种版本开发工具的切换, 安装和卸载的工作.对于windows系统的用户可以使用Powershell CLI来体验.
+
+例如: 项目A使用Jdk7中某些特性在后续版本中被移除(尽管这是不好的设计),项目B使用Jdk8,我们在切换开发这两个项目的时候,需要不断的切换系统中的JAVA_PATH,这样很不方便,如果存在很多个类似的版本依赖问题,就会给工作带来很多不必要的麻烦.
+
+sdkman这个工具就可以很好的解决这类问题,它的工作原理是自己维护多个版本,当用户需要指定版本时,sdkman会查询自己所管理的多版本软件中对应的版本号,并将它所在的路径设置到系统PATH.
+
+直接打开终端,执行如下命令:
+
+ curl -s http://get.sdkman.io | bash
+
+上面的命令的含义: 首先sdkman官网下载对应的安装shell script,然后调用bash解析器去执行.
+
+
+
+
+可以通过输入sdk help或sdk version确认安装是否完成
+
+ root@iZ286714gzoZ:~# sdk version
+ SDKMAN 5.1.18+191
+
+ sroot@iZ286714gzoZ:~# sdk help
+ Usage: sdk [candidate] [version]
+ sdk offline
+ commands:
+ install or i [version]
+ uninstall or rm
+ list or ls [candidate]
+ use or u [version]
+ default or d [version]
+ current or c [candidate]
+ upgrade or ug [candidate]
+ version or v
+ broadcast or b
+ help or h
+ offline [enable|disable]
+ selfupdate [force]
+ flush
+ candidate : the SDK to install: groovy, scala, grails, gradle, kotlin, etc.
+ use list command for comprehensive list of candidates
+ eg: $ sdk list
+ version : where optional, defaults to latest stable if not provided
+ eg: $ sdk install groovy
+
+
+#### 安装指定版本的gradle
+打开一个新的终端执行以下命令安装指定版本的gradle
+
+ $ sdk install gradle 3.3
+
+
+#### 移除安装的gradle
+
+ sdk uninstall gradle
+ or
+ sdk rm gradle
+
+#### 使用临时版本
+
+ sdk use gradle 3.0
+
+#### 设置默认版本
+
+ sdk default gradle 3.0
+
+#### 查看安装的sdk版本列表
+
+ sdk current gradle
+
+#### Grale其他地址
+
+[Binary only distribution (no documentation or source code)](https://services.gradle.org/distributions/gradle-3.3-all.zip)
+
+[Gradle source code (just the Gradle source code; not a usable Gradle installation)](https://services.gradle.org/distributions/gradle-3.3-src.zip)
\ No newline at end of file
diff --git a/Gradle_Linux_Install/image/install.jpg b/Gradle_Linux_Install/image/install.jpg
new file mode 100644
index 0000000..3f8a036
Binary files /dev/null and b/Gradle_Linux_Install/image/install.jpg differ
diff --git a/Gradle_Linux_Install/image/sdk1.jpg b/Gradle_Linux_Install/image/sdk1.jpg
new file mode 100644
index 0000000..127c818
Binary files /dev/null and b/Gradle_Linux_Install/image/sdk1.jpg differ
diff --git a/Gradle_Linux_Install/image/sdk2.jpg b/Gradle_Linux_Install/image/sdk2.jpg
new file mode 100644
index 0000000..01db707
Binary files /dev/null and b/Gradle_Linux_Install/image/sdk2.jpg differ
diff --git a/Gradle_Test/README.md b/Gradle_Test/README.md
new file mode 100644
index 0000000..c88275f
--- /dev/null
+++ b/Gradle_Test/README.md
@@ -0,0 +1,158 @@
+### Gradle单元测试
+
+我们可以通过在Gradle添加Java插件来执行单元测试的任务,默认的,在项目中所有的测试都会被执行,如果我们只想测试其中一个类,我们可以使用Java系统属性`test.single`作为测试的名字,事实上,这个系统属性的模式是`taskName.single`,其中`taskName`是我们工程中单元测试类型的名称。以下将会看到我们如何构建单元测试
+
+1.创建Gradle工程,并在build.gradle配置文件中加入:
+```Java
+
+ // File: build.gradle
+ apply plugin: 'java'
+ repositories {
+ mavenCentral()
+ }
+ dependencies {
+ testCompile 'junit:junit:[4,)'
+ }
+ test {
+ testLogging {
+ // Show that tests are run in the command-line output
+ events 'started', 'passed'
+ }
+ }
+```
+2.第二步,我们创建一个测试类,每个测试类一个测试方法,这样子让我们可以在后面单独的调用他们
+
+```Java
+
+ // File: src/test/java/com/mrhaki/gradle/SampleTest.java
+ package com.mrhaki.gradle;
+
+ import static org.junit.Assert.*;
+ import org.junit.*;
+
+ public class SampleTest {
+
+ @Test public void sample() {
+ assertEquals("Gradle is gr8", "Gradle is gr8");
+ }
+
+ }
+
+ // File: src/test/java/com/mrhaki/gradle/AnotherSampleTest.java
+ package com.mrhaki.gradle;
+
+ import static org.junit.Assert.*;
+ import org.junit.*;
+
+ public class AnotherSampleTest {
+
+ @Test public void anotherSample() {
+ assertEquals("Gradle is great", "Gradle is great");
+ }
+ }
+
+```
+
+3.为了只执行SampleTest类中的测试方法,我们必须从命令行中以Java系统属性`-Dtest.single=Sample`来执行单元测试
+
+ $ gradle -Dtest.single=Sample test
+ :compileJava UP-TO-DATE
+ :processResources UP-TO-DATE
+ :classes UP-TO-DATE
+ :compileTestJava
+ :processTestResources UP-TO-DATE
+ :testClasses
+ :test
+
+ com.mrhaki.gradle.SampleTest > sample STARTED
+
+ com.mrhaki.gradle.SampleTest > sample PASSED
+
+ BUILD SUCCESSFUL
+
+ Total time: 11.404 secs
+
+4.注意,现在只有一个测试类被执行,Gradle将会使用查询以`**/*`模式的类中查询出测试方法,因此我们不必要写该测试类的全类名,为了只执行AnotherSampleTest测试类我们也是如此:
+
+ $ gradle -Dtest.single=AnotherSample test
+ :compileJava UP-TO-DATE
+ :processResources UP-TO-DATE
+ :classes UP-TO-DATE
+ :compileTestJava
+ :processTestResources UP-TO-DATE
+ :testClasses UP-TO-DATE
+ :test
+
+ com.mrhaki.gradle.AnotherSampleTest > anotherSample STARTED
+
+ com.mrhaki.gradle.AnotherSampleTest > anotherSample PASSED
+
+ BUILD SUCCESSFUL
+
+ Total time: 5.62 secs
+
+5.我们也可以使用Java系统属性的模式来匹配多个测试类来一次性执行多个测试方法,。例如,我们可以使用`*Sample`来一次性执行SampleTest和AnotherSampleTest类的单元测试。
+
+ $ gradle -Dtest.single=*Sample test
+ :compileJava UP-TO-DATE
+ :processResources UP-TO-DATE
+ :classes UP-TO-DATE
+ :compileTestJava
+ :processTestResources UP-TO-DATE
+ :testClasses UP-TO-DATE
+ :test
+
+ com.mrhaki.gradle.AnotherSampleTest > anotherSample STARTED
+
+ com.mrhaki.gradle.AnotherSampleTest > anotherSample PASSED
+
+ com.mrhaki.gradle.SampleTest > sample STARTED
+
+ com.mrhaki.gradle.SampleTest > sample PASSED
+
+ BUILD SUCCESSFUL
+
+ Total time: 5.605 secs
+
+6.为了证明Java的系统属性同样对其他测试类型起作用,我们在buile.gradle配置文件中加入了新的task,我们把它叫做sampleTest并且包含了我们的测试文件,我们同样的使用了testLogging方便看测试结果在控制台的输出
+
+ // File: build.gradle
+ apply plugin: 'java'
+
+ repositories {
+ mavenCentral()
+ }
+
+ dependencies {
+ testCompile 'junit:junit:[4,)'
+ }
+
+ task sampleTest(type: Test, dependsOn: testClasses) {
+ include '**/*Sample*'
+ }
+
+ tasks.withType(Test) {
+ testLogging {
+ events 'started', 'passed'
+ }
+ }
+
+7.下一步我们想运行SampleTest类的单元测试,现在我们可以使用`-DsampleTest.single=S*`来作为运行参数
+
+ $ gradle -DsampleTest.single=S* sampleTest
+ :compileJava UP-TO-DATE
+ :processResources UP-TO-DATE
+ :classes UP-TO-DATE
+ :compileTestJava UP-TO-DATE
+ :processTestResources UP-TO-DATE
+ :testClasses UP-TO-DATE
+ :sampleTest
+
+ com.mrhaki.gradle.SampleTest > sample STARTED
+
+ com.mrhaki.gradle.SampleTest > sample PASSED
+
+ BUILD SUCCESSFUL
+
+ Total time: 10.677 secs
+ Code written with Gradle 1.6
\ No newline at end of file
diff --git a/HashSet_VS_TreeSet/README.md b/HashSet_VS_TreeSet/README.md
index c78e342..9de61e9 100644
--- a/HashSet_VS_TreeSet/README.md
+++ b/HashSet_VS_TreeSet/README.md
@@ -1,6 +1,6 @@
-####HashSet And TreeSet
+### HashSet And TreeSet
-####Set接口
+#### Set接口
Set不允许包含相同的元素,如果试图把两个相同元素加入同一个集合中,add方法返回false。
Set判断两个对象相同不是使用==运算符,而是根据equals方法。也就是说,只要两个对象用equals方法比较返回true,Set就不 会接受这两个对象,并且最多包含一个 null 元素。
@@ -11,7 +11,7 @@ HashSet与TreeSet都是基于Set接口的实现类。其中TreeSet是Set的子
Set接口——|——HashSet实现类
|——LinkedHashSet实现类
-####HashSet
+#### HashSet
* 不能保证元素的排列顺序,顺序有可能发生变化
* 不是同步的
* 集合元素可以是null,但只能放入一个null
@@ -65,7 +65,7 @@ HashSet与TreeSet都是基于Set接口的实现类。其中TreeSet是Set的子
}
#
-####TreeSet类
+#### TreeSet类
TreeSet是SortedSet接口的唯一实现类,TreeSet可以确保集合元素处于排序状态。TreeSet支持两种排序方式,自然排序 和定制排序,其中自然排序为默认的排序方式。向TreeSet中加入的应该是同一个类的对象。
TreeSet判断两个对象不相等的方式是两个对象通过equals方法返回false,或者通过CompareTo方法比较没有返回0
@@ -162,6 +162,6 @@ obj1大于obj2,如果是 负数,则表明obj1小于obj2。
8、SortedSet tailSet(fromElement):返回此Set的子集,由大于等于fromElement的元素组成。
-####LinkedHashSet
+#### LinkedHashSet
HashSet还有一个子类LinkedHashSet,其集合也是根据元素hashCode值来决定元素的存储位置,但它同时用链表来维护元素的次序,这样使得元素看起来是以插入的顺序保存的,也就是说,当遍历LinkedHashSet集合元素时,它将会按元素的添加顺序来访问集合里的元素。所以LinkedHashSet的性能略低于HashSet,但在迭代访问全部元素时将有很好的性能,因为它以链表来维护内部顺序。
diff --git a/Http_Code/README.md b/Http_Code/README.md
index dad1e9a..24d6c4c 100644
--- a/Http_Code/README.md
+++ b/Http_Code/README.md
@@ -1,4 +1,4 @@
-###HTTP状态码
+### HTTP状态码
* 100 请求者应继续进行请求。服务器返回此代码以表示,服务器已收到某项请求的第一部分,正等待接收剩余部分。
* 101 请求者已要求服务器切换协议,服务器已确认并准备切换。
diff --git a/Java_ArrayList_Vector/README.md b/Java_ArrayList_Vector/README.md
index 663c153..b04214a 100644
--- a/Java_ArrayList_Vector/README.md
+++ b/Java_ArrayList_Vector/README.md
@@ -1,4 +1,4 @@
-###ArrayList And Vector
+### ArrayList And Vector
List,就如图名字所示一样,是元素的有序列表。当我们讨论List时,将其与Set作对比是一个很好的办法,Set集合中的元素是无序且唯一的。
diff --git a/Java_Bubble_Sort/README.md b/Java_Bubble_Sort/README.md
index 5b1c4ce..ec732da 100644
--- a/Java_Bubble_Sort/README.md
+++ b/Java_Bubble_Sort/README.md
@@ -1,5 +1,5 @@
-###Java冒泡排序
-####排序算法概述
+### Java冒泡排序
+#### 排序算法概述
所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作。排序算法,就是如何使得记录按照要求排列的方法。排序算法在很多领域得到相当地重视,尤其是在大量数据的处理方面。
**稳定性**:一个排序算法是稳定的,就是当有两个相等记录的关键字R和S,且在原本的列表中R出现在S之前,在排序过的列表中R也将会是在S之前。
diff --git a/Java_Copy_On_Write/README.md b/Java_Copy_On_Write/README.md
index e295636..18ae060 100644
--- a/Java_Copy_On_Write/README.md
+++ b/Java_Copy_On_Write/README.md
@@ -1,4 +1,4 @@
-###Java CopyOnWrite容器
+### Java CopyOnWrite容器
Copy-On-Write简称COW,是一种用于程序设计中的优化策略。其基本思路是,从一开始大家都在共享同一个内容,当某个人想要修改这个内容的时候,才会真正把内容Copy出去形成一个新的内容然后再改,这是一种延时懒惰策略。从JDK1.5开始Java并发包里提供了两个使用CopyOnWrite机制实现的并发容器,它们是CopyOnWriteArrayList和CopyOnWriteArraySet。CopyOnWrite容器非常有用,可以在非常多的并发场景中使用到。
**什么是CopyOnWrite容器**
diff --git a/Java_Exception/README.md b/Java_Exception/README.md
index 77948b3..a45a2e1 100644
--- a/Java_Exception/README.md
+++ b/Java_Exception/README.md
@@ -1,6 +1,6 @@
-###Java异常处理机制
+### Java异常处理机制
-####1. 引子
+#### 1. 引子
try…catch…finally恐怕是大家再熟悉不过的语句了,而且感觉用起来也是很简单,逻辑上似乎也是很容易理解。不过,我亲自体验的“教训”告诉我,这个东西可不是想象中的那么简单、听话。不信?那你看看下面的代码,“猜猜”它执行后的结果会是什么?不要往后看答案、也不许执行代码看真正答案哦。如果你的答案是正确,那么这篇文章你就不用浪费时间看啦。
@@ -97,7 +97,7 @@
finally语句块不应该出现 应该出现return。上面的return ret最好是其他语句来处理相关逻辑。
-####2.JAVA异常
+#### 2.JAVA异常
异常指不期而至的各种状况,如:文件找不到、网络连接失败、非法参数等。异常是一个事件,它发生在程序运行期间,干扰了正常的指令流程。Java通 过API中Throwable类的众多子类描述各种不同的异常。因而,Java异常都是对象,是Throwable子类的实例,描述了出现在一段编码中的 错误条件。当条件生成时,错误将引发异常。
diff --git a/Java_ExecutorService/README.md b/Java_ExecutorService/README.md
new file mode 100644
index 0000000..1a53169
--- /dev/null
+++ b/Java_ExecutorService/README.md
@@ -0,0 +1,165 @@
+### ExecutorService 的理解与使用 ###
+接口 java.util.concurrent.ExecutorService 表述了异步执行的机制,并且可以让任务在后台执行。一个 ExecutorService 实例因此特别像一个线程池。事实上,在 java.util.concurrent 包中的 ExecutorService 的实现就是一个线程池的实现。
+
+#### ExecutorService 样例 ####
+```java
+ ExecutorService executorService = Executors.newFixedThreadPool(10);
+
+ executorService.execute(new Runnable() {
+ public void run() {
+ System.out.println("Asynchronous task");
+ }
+ });
+
+ executorService.shutdown();
+```
+
+首先使用 newFixedThreadPool() 工厂方法创建壹個 ExecutorService ,上述代码创建了壹個可以容纳10個线程任务的线程池。其次,向 execute() 方法中传递壹個异步的 Runnable 接口的实现,这样做会让 ExecutorService 中的某個线程执行这個 Runnable 线程。
+
+#### 任务的委托(Task Delegation) ####
+下方展示了一个线程的把任务委托异步执行的ExecutorService的示意图。
+
+
+
+壹旦线程把任务委托给 ExecutorService,该线程就会继续执行与运行任务无关的其它任务。
+
+#### ExecutorService 的实现 ####
+由于 ExecutorService 只是壹個接口,你壹量需要使用它,那麽就需要提供壹個该接口的实现。ExecutorService 接口在 java.util.concurrent 包中有如下实现类:
+
+* ThreadPoolExecutor
+* ScheduledThreadPoolExecutor
+
+#### 创建壹個 ExecutorService ####
+你可以根据自己的需要来创建壹個 ExecutorService ,也可以使用 Executors 工厂方法来创建壹個 ExecutorService 实例。这里有几個创建 ExecutorService 的例子:
+
+```java
+ExecutorService executorService1 = Executors.newSingleThreadExecutor();
+ExecutorService executorService2 = Executors.newFixedThreadPool(10);
+ExecutorService executorService3 = Executors.newScheduledThreadPool(10);
+```
+#### ExecutorService 使用方法 ####
+这里有几种不同的方式让你将任务委托给壹個 ExecutorService:
+
+* execute(Runnable)
+* submit(Runnable)
+* submit(Callable)
+* invokeAny(...)
+* invokeAll(...)
+
+我会在接下来的内容里把每個方法都看壹遍。
+#### execute(Runnable) ####
+方法 execute(Runnable) 接收壹個 java.lang.Runnable 对象作为参数,并且以异步的方式执行它。如下是壹個使用 ExecutorService 执行 Runnable 的例子:
+```java
+ ExecutorService executorService = Executors.newSingleThreadExecutor();
+
+ executorService.execute(new Runnable() {
+ public void run() {
+ System.out.println("Asynchronous task");
+ }
+ });
+
+ executorService.shutdown();
+```
+
+使用这种方式没有办法获取执行 Runnable 之后的结果,如果你希望获取运行之后的返回值,就必须使用 接收 Callable 参数的 execute() 方法,后者将会在下文中提到。
+
+#### submit(Runnable) ####
+方法 submit(Runnable) 同样接收壹個 Runnable 的实现作为参数,但是会返回壹個 Future 对象。这個 Future 对象可以用于判断 Runnable 是否结束执行。如下是壹個 ExecutorService 的 submit() 方法的例子:
+
+```java
+ Future future = executorService.submit(new Runnable() {
+ public void run() {
+ System.out.println("Asynchronous task");
+ }
+ });
+ //如果任务结束执行则返回 null
+ System.out.println("future.get()=" + future.get());
+```
+上述样例代码会输出如下结果:
+
+1 Asynchronous Callable
+
+2 future.get() = Callable Result
+
+#### inVokeAny() ####
+方法 invokeAny() 接收壹個包含 Callable 对象的集合作为参数。调用该方法不会返回 Future 对象,而是返回集合中某壹個 Callable 对象的结果,而且无法保证调用之后返回的结果是哪壹個 Callable,只知道它是这些 Callable 中壹個执行结束的 Callable 对象。
+如果壹個任务运行完毕或者抛出异常,方法会取消其它的 Callable 的执行。
+
+以下是壹個样例:
+
+```java
+ ExecutorService executorService = Executors.newSingleThreadExecutor();
+
+ Set> callables = new HashSet>();
+
+ callables.add(new Callable() {
+ public String call() throws Exception {
+ return "Task 1";
+ }
+ });
+ callables.add(new Callable() {
+ public String call() throws Exception {
+ return "Task 2";
+ }
+ });
+ callables.add(new Callable() {
+ public String call() throws Exception {
+ return "Task 3";
+ }
+ });
+
+ String result = executorService.invokeAny(callables);
+
+ System.out.println("result = " + result);
+
+ executorService.shutdown();
+```
+
+以上样例代码会打印出在给定的集合中的某壹個 Callable 的返回结果。我尝试运行了几次,结果都在改变。有时候返回结果是"Task 1",有时候是"Task 2",等等。
+
+#### invokeAll() ####
+方法 invokeAll() 会调用存在于参数集合中的所有 Callable 对象,并且返回壹個包含 Future 对象的集合,你可以通过这個返回的集合来管理每個 Callable 的执行结果。
+需要注意的是,任务有可能因为异常而导致运行结束,所以它可能并不是真的成功运行了。但是我们没有办法通过 Future 对象来了解到这個差异。
+
+以下是壹個代码样例:
+
+```java
+ ExecutorService executorService = Executors.newSingleThreadExecutor();
+
+ Set> callables = new HashSet>();
+
+ callables.add(new Callable() {
+ public String call() throws Exception {
+ return "Task 1";
+ }
+ });
+ callables.add(new Callable() {
+ public String call() throws Exception {
+ return "Task 2";
+ }
+ });
+ callables.add(new Callable() {
+ public String call() throws Exception {
+ return "Task 3";
+ }
+ });
+
+ List> futures = executorService.invokeAll(callables);
+
+ for(Future future : futures){
+ System.out.println("future.get = " + future.get());
+ }
+
+ executorService.shutdown();
+```
+
+#### ExecuteService 服务的关闭 ####
+当使用 ExecutorService 完毕之后,我们应该关闭它,这样才能保证线程不会继续保持运行状态。
+
+举例来说,如果你的程序通过 main() 方法启动,并且主线程退出了你的程序,如果你还有壹個活动的 ExecutorService 存在于你的程序中,那么程序将会继续保持运行状态。存在于 ExecutorService 中的活动线程会阻止Java虚拟机关闭。
+
+为了关闭在 ExecutorService 中的线程,你需要调用 shutdown() 方法。ExecutorService 并不会马上关闭,而是不再接收新的任务,壹但所有的线程结束执行当前任务,ExecutorServie 才会真的关闭。所有在调用 shutdown() 方法之前提交到 ExecutorService 的任务都会执行。
+
+如果你希望立即关闭 ExecutorService,你可以调用 shutdownNow() 方法。这個方法会尝试马上关闭所有正在执行的任务,并且跳过所有已经提交但是还没有运行的任务。但是对于正在执行的任务,是否能够成功关闭它是无法保证 的,有可能他们真的被关闭掉了,也有可能它会壹直执行到任务结束。这是壹個最好的尝试。
+
+本文英文原文链接:http://tutorials.jenkov.com/java-util-concurrent/executorservice.html#executorservice-example ,中文译文首发开源中国社区 http://my.oschina.net/bairrfhoinn/blog/177639,转载请注明原始出处。
\ No newline at end of file
diff --git a/Java_ExecutorService/image/39824293_1.png b/Java_ExecutorService/image/39824293_1.png
new file mode 100644
index 0000000..7c317a6
Binary files /dev/null and b/Java_ExecutorService/image/39824293_1.png differ
diff --git a/Java_IO/README.md b/Java_IO/README.md
new file mode 100644
index 0000000..8b87158
--- /dev/null
+++ b/Java_IO/README.md
@@ -0,0 +1,38 @@
+### JAVA IO 流 ###
+
+#### 一、Java IO 体系结构 ####
+
+#### (1). 流的概念 ####
+流是对数据传输的总称或抽象,流的本质是数据传输,是数据的有序排列,根据数据传输特性将流抽象为各种类,方便更直观的进行数据操作。
+
+
+
+在C++中,我们将数据从一个对象到另一个对象的流动抽象为"流"。Java继承C++的流机制,不过在具体实现上有别,Java中的"流"就是指把数据从一个对象移动到另一个对象的流动模式的抽象。(专业术语就是拿来装逼的)
+
+James Gosling的Java流模式图与水流模式图概念映射。数据源(data source)即水库,数据目的地(data destination)就是脸盆,数据(data)就是水,流(stream)实例化就是在管子中流动的水流。输入流(input stream)就是用水泵从水库中抽出来要到水管中的水,输出流(output stream)经过水龙头将要达到脸盆中的水,计算机内存(memory)就是上图中的水流管道,关闭输入流(close input stream)就是关闭水泵开关,关闭输出流(close output stream)就是关闭关闭水龙头开关.
+
+
+
+#### (2). IO 流的分类 ####
+* 根据处理数据类型的不同分为:[(3). 字符流和字节流的区别](#字符流和字节流的区别)
+* 根据数据流向不同分为:[输入流和输出流](https://github.com/scalad/Note/tree/master/Java_IO/inputOutputStream)
+* 根据流的功能来分:[节点流(又称低级流)、过滤流(又称高级流、处理流、包装流)](https://github.com/scalad/Note/tree/master/Java_IO/functionStream)
+
+
+
+#### (3). 字符流和字节流的区别 ####
+
+* 读写单位不同:字节流以字节(8bit)为单位,字符流以字符为单位,根据码表映射字符,一次可能读多个字节,在Java流的处理上,字符流处理的单元为 2 个字节的 Unicode 字符,分别操作字符、字符数组或字符串,而字节流处理单元为 1 个字节,操作字节和字节数组
+* 处理对象不同:字节流能处理所有类型的数据(如图片、avi等),而字符流只能处理字符类型的数据
+* 字节流默认是不带缓冲区的,而字符流默认是带缓冲区的
+* 字节流是底层数据流,是数据有意义的最小单位。字符流是字节流的包装,底层实现是字节流
+
+> 提醒:如果只是处理纯文本数据的话优先使用字符流,其他的使用字符流
+
+字节流和字符流在物理层面的实现都是比特流,二进制数据流可以认为是字节流,而字符流是遵循unicode编码规则的字节流。因此计算机中的"流"概念实际上就是指字节数据(bytes data)从源对象对按顺序流向目标对象的一种流动形式
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Java_IO/functionStream/README.md b/Java_IO/functionStream/README.md
new file mode 100644
index 0000000..a71496c
--- /dev/null
+++ b/Java_IO/functionStream/README.md
@@ -0,0 +1,10 @@
+### 节点流和过滤流 ###
+#### 节点流 ####
+节点流(Node Stream)是流管道两端直接连接data source和data destination上的,即为取放数据的真实载体,在流通道本身不对数据做任何加工,因而也被称为低级流。
+
+
+
+#### 过滤流 ####
+过滤流(Filter Stream)是套在节点流或过滤上的,而且过滤流是不能够脱离节点流(低级流)存在的,因此称为高级流。过滤流的流管道本身封装方法,能够对低级流数据进行处理,因此也被称为处理流。究其本质,过滤流就是把不符合通过管道条件的数据过滤掉,而让满足条件的数据通过过滤流管道。
+
+
\ No newline at end of file
diff --git a/Java_IO/functionStream/image/filter_stream.png b/Java_IO/functionStream/image/filter_stream.png
new file mode 100644
index 0000000..a05a102
Binary files /dev/null and b/Java_IO/functionStream/image/filter_stream.png differ
diff --git a/Java_IO/functionStream/image/node_stream.png b/Java_IO/functionStream/image/node_stream.png
new file mode 100644
index 0000000..cfa15bb
Binary files /dev/null and b/Java_IO/functionStream/image/node_stream.png differ
diff --git a/Java_IO/image/Java_IO.png b/Java_IO/image/Java_IO.png
new file mode 100644
index 0000000..cdaf083
Binary files /dev/null and b/Java_IO/image/Java_IO.png differ
diff --git a/Java_IO/image/Java_IO_Detail.png b/Java_IO/image/Java_IO_Detail.png
new file mode 100644
index 0000000..6a9b96e
Binary files /dev/null and b/Java_IO/image/Java_IO_Detail.png differ
diff --git a/Java_IO/image/emoji1.png b/Java_IO/image/emoji1.png
new file mode 100644
index 0000000..39d88eb
Binary files /dev/null and b/Java_IO/image/emoji1.png differ
diff --git a/Java_IO/image/input.png b/Java_IO/image/input.png
new file mode 100644
index 0000000..b22b25f
Binary files /dev/null and b/Java_IO/image/input.png differ
diff --git a/Java_IO/image/io_stream.jpg b/Java_IO/image/io_stream.jpg
new file mode 100644
index 0000000..70ad9c9
Binary files /dev/null and b/Java_IO/image/io_stream.jpg differ
diff --git a/Java_IO/image/io_stream1.png b/Java_IO/image/io_stream1.png
new file mode 100644
index 0000000..b29bc0b
Binary files /dev/null and b/Java_IO/image/io_stream1.png differ
diff --git a/Java_IO/image/output.png b/Java_IO/image/output.png
new file mode 100644
index 0000000..43c89c0
Binary files /dev/null and b/Java_IO/image/output.png differ
diff --git a/Java_IO/inputOutputStream/README.md b/Java_IO/inputOutputStream/README.md
new file mode 100644
index 0000000..5fa58e0
--- /dev/null
+++ b/Java_IO/inputOutputStream/README.md
@@ -0,0 +1,7 @@
+### 输入流、输出流 ###
+
+判断当前流是输入流还是输出流的依据是二进制数据相对于计算机内存的位置,输入流是输入计算机内存是二进制数据,输出流是从计算机内存输出的二进制数据。而计算机程序在运行期间会储存在到计算机内存中,因此总的来说就是数据的来源、取向是相对程序而言的。比如键盘键入数据属于输入流,内存数据持久化到磁盘中属于输出流。
+
+
+
+> 说明:本图片取自互联网,纠正补充为流的来源有网络连接、内存块、磁盘(文件)、键盘等;流的去向也基本是这些。
\ No newline at end of file
diff --git a/Java_IO/inputOutputStream/image/inputoutput.png b/Java_IO/inputOutputStream/image/inputoutput.png
new file mode 100644
index 0000000..57e4da4
Binary files /dev/null and b/Java_IO/inputOutputStream/image/inputoutput.png differ
diff --git a/Java_JVM_Monitor/README.md b/Java_JVM_Monitor/README.md
new file mode 100644
index 0000000..ced634c
--- /dev/null
+++ b/Java_JVM_Monitor/README.md
@@ -0,0 +1,90 @@
+## JVM监控和诊断概述jps、jstak、jstack、jinfo、jmap ##
+程序运行中经常会遇到各种问题,定位问题时通常需要综合各种信息,如系统日志、堆dump文件、线程dump文件、GC日志等。通过虚拟机监控和诊断工具可以帮忙我们快速获取、分析需要的数据,进而提高问题解决速度。可以使用图形化工具如:jconsole,jvisualvm,或者命令进行监控和诊断命令。 本文将介绍虚拟机常用监控和问题诊断命令工具的使用方法,主要包含以下工具:
+
+ jps 显示系统中所有Hotspot虚拟机进程
+ jstat 收集Hotspot虚拟机各方面运行数据
+ jstack 显示虚拟机的线程栈信息
+ jinfo 显示虚拟机的配置信息
+ jmap 用于生成虚拟机的内存快照信息
+
+### 命令介绍 ###
+
+#### 1).jps 命令 ####
+JVM Process Status Tool,该命令用于列出正在运行的虚拟机进程,显示main类的名称和虚拟机进程id。该命令受当前用户的访问权限影响,比如linux下非root用户只列出当前用户启动的虚拟机进程。
+
+命令格式:
+
+ jps [options] [hostid]
+
+ 常用参数:
+ -l 输出主类全名
+ -v 输出虚拟机进程启动的jvm参数
+ -m 输出启动时传递给main函数的参数
+
+#### 2).jstack 命令 ####
+Stack Trace for Java,用于生成虚拟机当前的线程快照信息,包含每一条线程的堆栈信息。该命令通常用于定位线程停顿原因,当出现线程停顿时,可通过stack查看每个线程的堆栈信息,进而分析停顿原因。
+
+命令格式:
+ jstack [ option ] pid
+
+ 常用参数:
+ -l 除堆栈外,显示锁的附加信息
+ -F 当请求不被响应时,强制输出线程堆栈
+ -m 混合模式,打印java和本地C++调用的堆栈信息
+
+#### 3) jstat命令 ####
+JVM Statistics Monitoring Tool,用于监控各种运行状态信息的命令。在只有文本控制台的环境中(如企业中的生产环境),该工具非常有用。 可以用来显示系统中类装载、垃圾回收、运行期编译状况等运行数据。
+
+命令格式:
+ jstat [ generalOption | outputOptions vmid [interval[s|ms] [count]] ]
+ vmid表示虚拟机唯一标识符,如果是本地虚拟机进程,与LVMID一致,通常为本地虚拟机进程号。
+ interval表示查询间隔时间,count表示查询次数。如果省略interval和count参数,表示查询一次。
+
+ 常用参数:
+ class 类装载相关信息.
+ compiler JIT编译器编译过的方法、耗时等.
+ gc java堆信息和垃圾回收状况.
+ gccapacity 关注java堆各个区的最大和最小空间.
+ gccause 类似gcutil,额外输出导致上一次gc的原因.
+ gcnew 新生代gc状况.
+ gcnewcapacity 关注新生代gc使用的最大和最小空间.
+ gcold 老年代gc状况.
+ gcoldcapacity 关注老年代gc使用的最大和最小空间.
+ gcpermcapacity 关注持久代gc使用的最大和最小空间.
+ gcutil 关注已使用空间占总空间比例.
+ printcompilation 输出已经被JIT编译的方法.
+
+#### 4) jinfo命令 ####
+Configuration Info for Java,用于查看和修改虚拟机的各项参数信息。
+
+命令格式:
+
+ jinfo [ option ] pid
+ 常用参数:
+ -flag name 打印虚拟机该参数对应的值.
+ -flag [+\-]name 使该参数生效或失效.
+ -flag name=value 修改相应参数的值.
+ -flags 打印传给jvm的参数值.
+ -sysprops 打印System.getProperties()信息.
+
+#### 5) jmap命令 ####
+Memory Map for Java,可以产生堆dump文件,查询堆和持久代的详细信息等。
+
+命令格式:
+
+ jmap [ option ] pid
+ 常用参数:
+ -dump 生成堆dump文件,格式为: -dump:[live,]format=b,file=
+ -heap 显示java堆的详细信息,包括垃圾回收期、堆配置和分代信息等
+ -histo 显示堆中对象的统计信息,包括类名称,对应的实例数量和总容量
+ -permstat 统计持久代中各ClassLoader的统计信息。
+
+#### 6) jhatk命令 ####
+Jvm Heap Analysis Tool, 与jmap一起使用
+
+示例:
+
+ jhat dump.tmp
+ Reading from dump.tmp...
+ Dump file created Tue Jun 28 13:55:09 CST 2016
+
diff --git a/Java_Jstat/README.md b/Java_Jstat/README.md
new file mode 100644
index 0000000..606f835
--- /dev/null
+++ b/Java_Jstat/README.md
@@ -0,0 +1,109 @@
+## JVM自带命令jstat命令 ##
+Jstat是JDK自带的一个轻量级小工具。全称“Java Virtual Machine statistics monitoring tool”,它位于Java的bin目录下,主要利用JVM内建的指令对Java应用程序的资源和性能进行实时的命令行的监控,包括了对Heap size和垃圾回收状况的监控。可见,Jstat是轻量级的、专门针对JVM的工具,非常适用。
+
+jstat工具特别强大,有众多的可选项,详细查看堆内各个部分的使用量,以及加载类的数量。使用时,需加上查看进程的进程id,和所选参数。
+
+参考格式如下:jstat -options
+
+可以列出当前JVM版本支持的选项,常见的有
+
+ class (类加载器)
+ compiler (JIT)
+ gc (GC堆状态)
+ gccapacity (各区大小)
+ gccause (最近一次GC统计和原因)
+ gcnew (新区统计)
+ gcnewcapacity (新区大小)
+ gcold (老区统计)
+ gcoldcapacity (老区大小)
+ gcpermcapacity (永久区大小)
+ gcutil (GC统计汇总)
+ printcompilation (HotSpot编译统计)
+
+### 1、jstat –class : 显示加载class的数量,及所占空间等信息。 ###
+
+
+ 显示列名 具体描述
+ Loaded 装载的类的数量
+ Bytes 装载类所占用的字节数
+ Unloaded 卸载类的数量
+ Bytes 卸载类的字节数
+ Time 装载和卸载类所花费的时间
+
+### 2、jstat -compiler 显示VM实时编译的数量等信息。 ###
+
+
+ 显示列名 具体描述
+ Compiled 编译任务执行数量
+ Failed 编译任务执行失败数量
+ Invalid 编译任务执行失效数量
+ Time 编译任务消耗时间
+ FailedType 最后一个编译失败任务的类型
+ FailedMethod 最后一个编译失败任务所在的类及方法
+
+### 3、jstat -gc : 可以显示gc的信息,查看gc的次数,及时间。 ###
+
+ 显示列名 具体描述
+ S0C 年轻代中第一个survivor(幸存区)的容量 (字节)
+ S1C 年轻代中第二个survivor(幸存区)的容量 (字节)
+ S0U 年轻代中第一个survivor(幸存区)目前已使用空间 (字节)
+ S1U 年轻代中第二个survivor(幸存区)目前已使用空间 (字节)
+ EC 年轻代中Eden(伊甸园)的容量 (字节)
+ EU 年轻代中Eden(伊甸园)目前已使用空间 (字节)
+ OC Old代的容量 (字节)
+ OU Old代目前已使用空间 (字节)
+ PC Perm(持久代)的容量 (字节)
+ PU Perm(持久代)目前已使用空间 (字节)
+ YGC 从应用程序启动到采样时年轻代中gc次数
+ YGCT 从应用程序启动到采样时年轻代中gc所用时间(s)
+ FGC 从应用程序启动到采样时old代(全gc)gc次数
+ FGCT 从应用程序启动到采样时old代(全gc)gc所用时间(s)
+ GCT 从应用程序启动到采样时gc用的总时间(s)
+
+### 4、jstat -gccapacity :可以显示,VM内存中三代(young,old,perm)对象的使用和占用大小 ###
+
+ 显示列名 具体描述
+ NGCMN 年轻代(young)中初始化(最小)的大小(字节)
+ NGCMX 年轻代(young)的最大容量 (字节)
+ NGC 年轻代(young)中当前的容量 (字节)
+ S0C 年轻代中第一个survivor(幸存区)的容量 (字节)
+ S1C 年轻代中第二个survivor(幸存区)的容量 (字节)
+ EC 年轻代中Eden(伊甸园)的容量 (字节)
+ OGCMN old代中初始化(最小)的大小 (字节)
+ OGCMX old代的最大容量(字节)
+ OGC old代当前新生成的容量 (字节)
+ OC Old代的容量 (字节)
+ PGCMN perm代中初始化(最小)的大小 (字节)
+ PGCMX perm代的最大容量 (字节)
+ PGC perm代当前新生成的容量 (字节)
+ PC Perm(持久代)的容量 (字节)
+ YGC 从应用程序启动到采样时年轻代中gc次数
+ FGC 从应用程序启动到采样时old代(全gc)gc次数
+
+### 5、jstat -gcutil :统计gc信息 ###
+
+
+
+### 6、jstat -gcnew :年轻代对象的信息。 ###
+
+
+
+### 7、jstat -gcnewcapacity: 年轻代对象的信息及其占用量。 ###
+
+
+
+### 8、jstat -gcold :old代对象的信息。 ###
+
+
+
+### 9、stat -gcoldcapacity : old代对象的信息及其占用量。 ###
+
+
+
+### 10、jstat -gcpermcapacity: perm对象的信息及其占用量。 ###
+
+
+
+### 11、jstat -printcompilation :当前VM执行的信息。 ###
+
+
\ No newline at end of file
diff --git a/Java_Jstat/image/10.png b/Java_Jstat/image/10.png
new file mode 100644
index 0000000..544d199
Binary files /dev/null and b/Java_Jstat/image/10.png differ
diff --git a/Java_Jstat/image/11.png b/Java_Jstat/image/11.png
new file mode 100644
index 0000000..d00b0aa
Binary files /dev/null and b/Java_Jstat/image/11.png differ
diff --git a/Java_Jstat/image/5.png b/Java_Jstat/image/5.png
new file mode 100644
index 0000000..4925f55
Binary files /dev/null and b/Java_Jstat/image/5.png differ
diff --git a/Java_Jstat/image/6.png b/Java_Jstat/image/6.png
new file mode 100644
index 0000000..6b9ba14
Binary files /dev/null and b/Java_Jstat/image/6.png differ
diff --git a/Java_Jstat/image/7.png b/Java_Jstat/image/7.png
new file mode 100644
index 0000000..95cb9e9
Binary files /dev/null and b/Java_Jstat/image/7.png differ
diff --git a/Java_Jstat/image/8.png b/Java_Jstat/image/8.png
new file mode 100644
index 0000000..14b4df9
Binary files /dev/null and b/Java_Jstat/image/8.png differ
diff --git a/Java_Jstat/image/9.png b/Java_Jstat/image/9.png
new file mode 100644
index 0000000..e35ef4d
Binary files /dev/null and b/Java_Jstat/image/9.png differ
diff --git a/Java_Lambda/README.md b/Java_Lambda/README.md
index ca50818..02d6cbc 100644
--- a/Java_Lambda/README.md
+++ b/Java_Lambda/README.md
@@ -1,4 +1,4 @@
-###Java8 Lambda表达式
+### Java8 Lambda表达式
**1. 什么是λ表达式**
λ表达式本质上是一个匿名方法。让我们来看下面这个例子:
diff --git a/Java_Memory/README.md b/Java_Memory/README.md
index 9f41ef6..ee090a1 100644
--- a/Java_Memory/README.md
+++ b/Java_Memory/README.md
@@ -1,4 +1,4 @@
-###关于Java内存泄漏
+### 关于Java内存泄漏
**Java是如何管理内存**
diff --git a/Java_Node/README.md b/Java_Node/README.md
index 081714a..c0b40e7 100644
--- a/Java_Node/README.md
+++ b/Java_Node/README.md
@@ -1,4 +1,4 @@
-###二叉树
+### 二叉树
public class Node {
public int value;
diff --git a/Java_Photo_Base64AndZip/README.md b/Java_Photo_Base64AndZip/README.md
new file mode 100644
index 0000000..4c49dd0
--- /dev/null
+++ b/Java_Photo_Base64AndZip/README.md
@@ -0,0 +1,156 @@
+### 图片转Base64并压缩
+
+首先需要Apache下的两个jar包
+
+
+
+ commons-codec
+ commons-codec
+ 1.10
+
+
+
+ commons-io
+ commons-io
+ 2.4
+
+```Java
+ package com.silene.base64;
+
+ import java.io.ByteArrayInputStream;
+ import java.io.ByteArrayOutputStream;
+ import java.io.File;
+ import java.io.FileInputStream;
+ import java.io.IOException;
+ import java.util.zip.GZIPInputStream;
+ import java.util.zip.GZIPOutputStream;
+
+ import org.apache.commons.codec.binary.Base64;
+ import org.apache.commons.io.FileUtils;
+
+ public class TestBase64Zip {
+
+ public static void main(String[] args) {
+
+ String base64 = base64("e:\\question.jpg");
+ System.out.println("经过base64转码和压缩" + base64);
+
+ decode(base64, "test.jpg", "e:\\");
+ }
+
+ /**
+ * 把经过压缩过的base64串解码解压并写入打磁盘中
+ * @param base64 压缩过的base64串
+ * @param fileName 文件名
+ * @param path 路径地址
+ */
+ public static void decode(String base64, String fileName, String path) {
+ //解码
+ byte[] data = Base64.decodeBase64(base64);
+ data = unGZip(data);
+ writeFile(data, fileName, path);
+ }
+
+ /**
+ * 二进制文件写入文件
+ * @param data 二进制数据
+ * @param fileName 文件名
+ * @param path 路径地址
+ */
+ public static void writeFile(byte[] data, String fileName, String path) {
+ try
+ {
+ String url = path + "//" + fileName;
+ FileUtils.writeByteArrayToFile(new File(url), data);
+ }
+ catch (IOException e)
+ {
+ System.out.println("写文件出错" + e);
+ }
+ }
+
+ /**
+ * 解壓Gzip
+ * @param data
+ * @return
+ */
+ public static byte[] unGZip(byte[] data){
+ byte[] b = null;
+ try{
+ ByteArrayInputStream bis = new ByteArrayInputStream(data);
+ GZIPInputStream gzip = new GZIPInputStream(bis);
+ byte[] buf = new byte[1024];
+ int num = -1;
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ while ((num = gzip.read(buf, 0, buf.length)) != -1)
+ {
+ baos.write(buf, 0, num);
+ }
+ b = baos.toByteArray();
+ baos.flush();
+ baos.close();
+ gzip.close();
+ bis.close();
+ }
+ catch (Exception ex){
+ System.out.println("解压数据流出错!!" + ex);
+ }
+ return b;
+ }
+
+ /**
+ * 读取文件并压缩数据然后转Base64编码
+ * @param pathName 图片的绝对路径地址
+ * @return
+ */
+ public static String base64(String pathName) {
+ byte[] data = getPicData(pathName);
+ if (data == null) {
+ return null;
+ }
+ byte[] zipData = gZip(data);
+ return Base64.encodeBase64String(zipData);
+ }
+
+ /**
+ * @description 获取图片的二进制数据
+ * @param pathName 图片的绝对路径地址
+ * @return
+ */
+ public static byte[] getPicData(String pathName) {
+ byte[] data = null;
+ try {
+ FileInputStream fi = new FileInputStream(pathName);
+ int length = fi.available();
+ data = new byte[length];
+ fi.read(data);
+ fi.close();
+ } catch (Exception e) {
+ System.out.println(e);
+ }
+ return data;
+ }
+
+ /***
+ * @description 压缩GZip
+ * @param data 要压缩的二进制数据
+ * @return
+ */
+ public static byte[] gZip(byte[] data) {
+ byte[] b = null;
+ try {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ GZIPOutputStream gzip = new GZIPOutputStream(bos);
+ gzip.write(data);
+ gzip.finish();
+ gzip.close();
+ b = bos.toByteArray();
+ bos.close();
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ }
+ return b;
+ }
+
+ }
+```
\ No newline at end of file
diff --git a/Java_Request_GetIP/README.md b/Java_Request_GetIP/README.md
new file mode 100644
index 0000000..efb6752
--- /dev/null
+++ b/Java_Request_GetIP/README.md
@@ -0,0 +1,47 @@
+### 获取客户端真实的IP地址
+
+```Java
+
+ /**
+ *
+ * @description:获取客户端真实IP
+ * @param request
+ * @return
+ */
+ public static String getIpAddr(HttpServletRequest request)
+ {
+
+ if (request == null)
+ {
+ return "";
+ }
+ String ip = request.getHeader("x-forwarded-for");
+
+ if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
+ {
+ ip = request.getHeader("Proxy-Client-IP");
+ }
+ if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
+ {
+ ip = request.getHeader("WL-Proxy-Client-IP");
+ }
+ if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
+ {
+ ip = request.getRemoteAddr();
+ }
+ if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
+ {
+ ip = request.getHeader("http_client_ip");
+ }
+ if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
+ {
+ ip = request.getHeader("HTTP_X_FORWARDED_FOR");
+ }
+ // 如果是多级代理,那么取第一个ip为客户ip
+ if (ip != null && ip.indexOf(",") != -1)
+ {
+ ip = ip.substring(ip.lastIndexOf(",") + 1, ip.length()).trim();
+ }
+ return ip;
+ }
+```
\ No newline at end of file
diff --git a/Java_Shiro_Session/README.md b/Java_Shiro_Session/README.md
new file mode 100644
index 0000000..8cf09df
--- /dev/null
+++ b/Java_Shiro_Session/README.md
@@ -0,0 +1,497 @@
+### Shiro Session
+session管理可以说是Shiro的一大卖点
+
+Shiro可以为任何应用(从简单的命令行程序还是手机应用再到大型企业应用)提供会话解决方案。
+
+在Shiro出现之前,如果我们想让你的应用支持session,我们通常会依赖web容器或者使用EJB的Session Bean。
+
+Shiro对session的支持更加易用,而且他可以在任何应用、任何容器中使用。
+
+即便我们使用Servlet或者EJB也并不代表我们必须使用容器的session,Shiro提供的一些特性足以让我们用Shiro session替代他们。
+
+* 基于POJO
+
+* 易定制session持久化
+
+* 容器无关的session集群
+
+* 支持多种客户端访问
+
+* 会话事件监听
+
+* 对失效session的延长
+
+* 对Web的透明支持
+
+* 支持SSO
+
+使用Shiro session时,无论是在JavaSE还是web,方法都是一样的。
+
+```Java
+public static void main(String[] args) {
+ Factory factory = new IniSecurityManagerFactory("classpath:shiro/shiro.ini");
+
+ SecurityUtils.setSecurityManager(factory.getInstance());
+ Subject currentUser = SecurityUtils.getSubject();
+ UsernamePasswordToken token = new UsernamePasswordToken("king","t;stmdtkg");
+ currentUser.login(token);
+
+ Session session = currentUser.getSession();
+ System.out.println(session.getHost());
+ System.out.println(session.getId());
+
+ System.out.println(session.getStartTimestamp());
+ System.out.println(session.getLastAccessTime());
+
+ session.touch();
+ User u = new User();
+ session.setAttribute(u, "King.");
+ Iterator