奋斗的小盗 Java & Developer A backend developer who loves design awesome things.

写给大忙人看的JavaSE8读书笔记(二)Stream

Stream

什么是Stream? Stream支持顺序和并行聚合操作的一系列元素,为了执行计算,流操作被组成一个流管道。 集合和流,虽然有一些表面上的相似之处,但却有不同的目标。集合主要关注对它们元素的有效管理和访问。相比之下,流不直接访问或操纵元素,与之相反,流主要提供对集合进行的各种操作。

  • 流自己不会存储元素,元素存储在原始的集合中,或者根据需要产生
  • Stream的操作符不会改变源对象
  • Stream操作时延迟执行的,在最后需要结果的时候才会执行。

使用Stream通常保含3个流程:

  1. 创建一个Stream
  2. 在一个或多个步骤中,指定将初始Stream转换为另一个Stream的中间操作。
  3. 使用一个终止操作来产生一个结果。该操作会强制它之前的延迟操作立即执行,在这之后该Stream就不会再被使用了。

比如如下代码,根据一个User列表,获取年龄超过20岁的用户,然后再将user列表终止收集结果为userId=>User的Map对象。

List<User> userList = createUserList();
Map<String, User> userIdMap = userList.stream().filter(u -> u.getAge() > 20)
			.collect(Collectors.toMap(User::getId, Function.identity()));

常见函数:

  • filter操作:从一个T到boolean的函数,产生一个符合某种特定条件的新流。
  • map操作:对流中的值进行某种形式的转换,生成一个新的流,如:获取一个User列表的所有name列表:

      userList.stream().map(u ->u.getName()).collect(Collectors.toList());
    
  • limit操作: 提取流中的n个元素,如果流没有这么多个元素返回流本身。

      userList.stream().limit(20);
    
  • concat操作: 连接两个流。
  • skip 操作: 丢掉前面n个元素,从1开始。

聚合方法

写给大忙人看的JavaSE8读书笔记(一)Lambda表达式

Lambda表达式

含义:什么是Lambda表达式? lambda表达式在Java中就是一段匿名函数的代码。函数式编程中这段代码叫做函数。跟java原有的匿名内部类很像,但是实现原理和代码简洁性匿名内部类好。这段代码在Java8中通过一个java.lang.function包中的Function接口进行定义(函数式接口) 比如:我们获取文件目录下子目录时,传入FileFilter通常用Lambda表达式写法为:

File file=...
file.listFiles(d -> d.isDirectory())
//or
file.listFiles(File::isDirectory)

没有lambda表达式时,写法为:

file.listFiles(new FileFilter() {

		@Override
		public boolean accept(File pathname) {
			if (pathname.isDirectory()) {
				return true;
			}
			return false;
		}
	});

可以看到通过lambda表达式,提供更好的代码简洁性和可读性。

一个Lambda表达式通常包括3个部分:

  • 参数(可能为空,没有参数)
  • 一段代码(lambda表达式的主要代码段)
  • 自由变量的值(不是参数,不是lambda表达式内部代码段定义的变量)

其中含义自由变量的Lambda表达式通常就是所谓的“闭包”。

使用场景:什么时候使用Lambda表达式? 所有的Lambda表达式都是延迟执行的。这里的“延迟执行”场景包括:

  • 在另一个线程中运行代码
  • 多次运行代码
  • 在某个算法的时间点运行代码
  • 某些事件发生时运行代码
  • 在需要使用的时候运行代码

注意:延迟执行不是说代码是异步执行。

函数式接口

只包含一个抽象方法的接口叫做函数式接口,可以认为Java中所有的Lambda表达式都是某种函数式接口的实例。函数式接口是Java lambda表达式的模型定义。函数式接口通常用:@FunctionalInterface注解。

注意: java是强类型语言,如果将一个lambda代码块赋值个一个函数式接口变量,需要处理检查期异常。 比如,你可以将如下代码:

Runnable fPrint = {()->System.out.print("XXXX");};

赋值给Runnable接口变量,fPrint,但是如果lambda表达式会抛出异常,该赋值就会报错。如:

Runnable fPrint = {()->System.out.print("xxx");Thread.sleep(1000);};

需要用Callable接口进行声明:

Callable<Void> fPrint = {()->System.out.print("xxx");Thread.sleep(1000);};

此外Java8中为了支持Lambda表达式,对接口定义做了修改,Java8之前,对于接口只会包含:

  • static final 的常量(默认public)
  • 抽象方法

Java8之后还可以添加:

  • 默认方法
  • 静态方法

示例如下:

public interface IWorkEngine {

	public static final String DEFAULT_NAME = "scorch";

	public void work(WorkEngineContext context);

	public default String getName() {//默认方法
		return DEFAULT_NAME;
	}
	public static void checkNameIlegal() throws ScorchException {
		if (DEFAULT_NAME.startsWith("sc")) {
			throw new ScorchException("name valiad");
		}
	}	
}

jekyll Windows下安装

###安装 Ruby 前往 http://rubyinstaller.org/downloads/

在 “RubyInstallers” 部分,选择某个版本点击下载。 例如, Ruby 2.0.0-p451 (x64) 是适于64位 Windows 机器上的 Ruby 2.0.0 x64 安装包。

通过安装包安装. (可能国内下载很么,需要通过翻墙)

###安装 DevKit

DevKit 是一个在 Windows 上帮助简化安装及使用 Ruby C/C++ 扩展如 RDiscount 和 RedCloth 的工具箱。 详细的安装指南可以在程序的wiki 页面 阅读。

再次前往 http://rubyinstaller.org/downloads/

下载同系统及 Ruby 版本相对应的 DevKit 安装包。 例如,DevKit-mingw64-64-4.7.2-20130224-1432-sfx.exe 适用于64位 Windows 系统上的 Ruby 2.0.0 x64。

运行安装包并解压缩至某文件夹,如 C:\DevKit

通过初始化来创建 config.yml 文件。在命令行窗口内,输入下列命令:

cd “C:\DevKit”
ruby dk.rb init
notepad config.yml

在打开的记事本窗口中,于末尾添加新的一行 - C:\Ruby200-x64,保存文件并退出。

回到命令行窗口内,审查(非必须)并安装。

ruby dk.rb review
ruby dk.rb install

###安装 Jekyll 国内需要VPN翻墙,否则基本上安装失败,使用淘宝替换sources

gem sources --remove https://rubygems.org/
gem sources -a http://ruby.taobao.org/
gem sources -l
CURRENT SOURCES ***
http://ruby.taobao.org
请确保只有 ruby.taobao.org
gem install rails

确保 gem 已经正确安装:

gem -v

输出示例: 2.0.14

###安装 Jekyll gem

gem install jekyll

###Jekyll 操作 在项目目录下执行命令部署,生产_site文件本地允许: jekyll serve

Apache Cassandra介绍

Apache Cassandra 是一个开源的,分布式的,无中心的,具有弹性并且可以扩展性,高可用性,容错性,一致性可调,面向列的数据库。

它基于Amazon Dynamo的分布式设计和Google BigTable的数据模型,它有Facebook创建,目前在很多最流行的网站上应用。 Cassandra是分布式的,这意味着它能够运行在很多机器上面,然后呈现给用户一个统一的整体的样子。在事实上,在一个节点上运行Cassandra没有多大的意义。它的很多设计和实现让系统不仅可以在多节点上运行,更为多机架部署进行了优化,甚至一个Cassandra集群可以运行在分散于各地的多个数据中心上,可以放心地把数据写到集群中的任意一个机器上,Cassandra都会得到数据。 对于很多存储系统(如MySQL,BigTable),一旦开始扩展它就要把某些节点设为主节点,其他则为从节点。但是,Cassandra是无中心的,也就是说每个节点都是一样的,没有节点用于承担特殊的管理任务。与主从结构相反,Cassandra使用的是P2P协议,而且使用gossip来维护存活或死亡节点的列表。

无中心这一事实意味着Cassandra不会存在单点失效。Cassandra集群中的所有节点的功能完全一样,有时这被叫做“服务器对称”。与你见过的MySQL,BigTable这样的主从结构式的系统不同,这是因为Cassandra的所有节点的工作内容都是相同的,从根本上就没有一个特殊的机器作为主节点来承担协调任务。

总之无中心架构有两个关键的优势,不仅比主从结构更简单,而且可以避免系统宕机。比起主从结构的数据存储系统来说,无中心架构的维护更方便,因为所有节点都可以一视同仁。这也就意味着你不必要为扩展来考虑更多的东西,搭建一个50个节点的系统和搭建一个单节点的系统没什么区别。也没有什么配置上的特别需要来支持单节点扩展。更进一步,对于主从结构来说主节点很容易出现单点失效来支持节点扩展。更进一步对于主从结构来说,主节点很容易出现单点失效(SPOF)。要想避免单点失效,常常需要增加系统的复杂度,构成多主节点。而因为所有的Cassandra节点都是一样的,损失任何一个节点对于系统服务都没什么大影响。

综上所述,由于Cassandra是分布式的,无中心的,因此他不会有单点失效,能拥有高可用性。 从一般的结构的角度考虑,系统的可用性是满足请求的能力来量度的。但计算机可能会有各种各样的故障,从硬件故障到网络中断都有可能。计算机都可能发生这种情况。当然有某些非常复杂或者复杂昂贵的计算机可以自己应付很多情况,它们一般都会用在硬件上的冗余,并且在发生故障事件的时候会自动响应并进行热切换。但是任何人都可能会偶然碰到以太网线断连,这时候一个单独的数据中心就会有灾难发生,这是无法避免的。所以对于一个需要高搞可用的系统,它必须有多台联网的计算机构成,并且运行于其上的软件也必须能够在集群条件下工作,有设备能够识别节点故障,并将发生故障的中断的功能在剩余系统上进行修复。

Cassandra就是高可用的。你可以在不中断系统的情况下替换故障地点,还可以把数据分布到多个数据中心里,从而提高更好的本地访问性能,并且在某以数据中心发生火灾、洪水等不可抗灾难的时候防止系统彻底瘫痪。 可扩展性是指系统架构可以让系统提供更多的服务而不降低使用性能的特性。仅仅通过给现有的机器增加硬件的容量、内存进行垂直扩展,是最简单的达到可扩展行的手段,而水平扩展则需要增加更多机器每台机器提供全部或部分数据,这样所有主机都不必负担全部业务请求。但软件自己需要有内部机制来保证集群中节点间的数据同步。

弹性可扩展是指水平扩展的特性,意即你的集群可以不间断服务地扩展或缩减规模。要做到这点,集群必须能够在不大幅修改或重新配置的情况下,接收那些新加入,获得全部或部分数据的节点,让它们开始提供服务。不需要重新启动进程,不必修改应用的查询,也无需自己手工重新均衡数据分布。在Cassandra里,你只要加入新的计算机,Cassandra就会自动地发现它并开始让它工作。 当然缩减规模意味着要从集群中移走部分处理能力,当应用要迁移到别的平台上,或者应用失去用户,你不得不卖掉部分硬件的时候,你可能不得不这么做。让我们祈祷这永远不发生。不过如果发生了,使用Cassandra无需为规模的缩减而引起系统的混乱。 一致性的基本含义是读操作一定会返回最新写入的结果。考虑电子商务网站的两个客户同时要把一个商品放到他们的购物车里的情景。如果我在你刚刚拿走最后一个商品的时候也要把商品放到自己的购物车里,那么你应该得到这个商品,而我应该被告知商品已经售完了。在把状态一致地写到所有有此数据的节点的时候,这点是得到保证的。

但是天下没有免费的午餐,后面我们可以看到,扩展数据存储系统就意味着我们不得不在数据一致性,节点可用性和分区耐受性之间做某些折中。Cassandra使用的一致性常被称作是“最终一致性”,这实际有些让人误解。简单的来说,Cassandra牺牲了一些一致性来换取完全的可用性。但是Cassandra的一致性准确表述为“可调一致性”,它允许选定需要的一致性水平与可用性水平,在二者之间找到平衡。

先让我们解释一下“最终一致性”,这个词曾经引起业界的震动。

有些人对“最终一致性”的系统很不放心。

对于“最终一致性”,批评最终一致性的人有个说法。也许最终一致性对社交应用可能还可以,因为数据并非那么重要。毕竟早餐吃了一块蛋糕等等这样的数据丢了并不会太重要。但有些数据非常重要,在我的数据模型里,绝对不会允许最终一致性这种可笑的事情发生。 可是事实上,大部分流行的网络应用都在使用这一模型。它有其可取之处,这些数据对运营它们的公司来说应该是非常重要的,因为这是它们赖以生存的产品,而且这些公司在竞争如此激烈的世界里已经成长为数十亿美元盈收的巨头,拥有几十亿用户。或许真的有系统可以保障在 这样一个高流量、接入不同网络的系统里,能够得到即时有保障而且完美的一致性,不过现在还找不到这样完美的系统。

严格一致性。有时也叫做顺序一致性,是最严格的一致性要求。它要求所有读操作总是返回最新的写结果。这听起来似乎很好,好像就是我们所需要的。但是再仔细看看,我们还会看到什么?“最新的写结果”到底意味着什么?最新写给谁的?在一个单处理器的机器里,不会看出任何问题,因为无论如何操作都会逐一顺序进行。但是,当系统分布在位置分散的多个数据中心的时候就变得不那么可顺序进行。但是,当系统分布在位置分散的多个数据中心的时候就变得不那么可靠。要达到严格一致性,需要某种全局锁机制来给每个操作加上一个时间戳,不论数据位于何处,用户位于何处,也不论得到响应需要访问多少服务,而且服务还可能是分散的。

因果一致性。这种一致性模型比严格一致性稍弱。这种模型消除了幻想中的需要同步一切操作的单一的全局锁。避免了无法承受的瓶颈。因果一致性不依赖于时间戳,它使用更为语义化的方法,尝试去判断事件的原因,并按照因果关系来达到一致性。这意味着潜在相关的写操作必须被顺序读出。如果两个彼此无关的不同操作同时写同一个域,那么这些写操作可以被推断为并不是因果相关的。而如果一个操作紧接着另一个进行,这就可能是因果相关的了。因果一致性要求相关的写操作必须别顺序读出。 弱一致性(最终一致性)

最终一致性从单词的意思解释是更新最终将传播到整个分布式系统的各个角落,但这需要一定的时间。最终,所有的副本都会是一致的。

当考虑需要如何才能达到更好的一致性的情况,最终一致性可能会变得很有吸引力。在考虑一致性、可用性和分区可用性时,对于一个给定的系统……

GIT使用

git作为分布式的版本控制系统,与传统的集中式版本控制系统到底有什么不同。 ###Git原理### Git和其他版本控制系统的一个主要差别在于:GIT只关心文件数据的整体是否发生变化,而多数其他版本控制系统则只关心文件内容的具体差异。其他的文件系统(如svn,cvs)每次记录有哪些文件发生了变化,做了更新,更新了什么内容)如下图:

git保存每次更新的文件快照

GIT的更新,是把变化的文件做快照后,记录在一个微型的文件系统中。每次提交更新时,它会纵览一遍所有文件的指纹信息并对文件作一快照然后保存一个指向这次快照的索引。为了提高性能,若文件没有变化,git不会再次保存,而只对保存的快照作一连接,Git工作方式就像如下图所示:

git保存每次更新的文件快照

Git撤销操作

###Git Reset### 有时候,你可能想要撤销 Git 操作。通常,git reset 就是你需要的命令。但是,使用 git reset 可能会非常复杂,取决于你的撤销操作。如果本文没有提到你需要的,查看 git reset 官方文档。

假设,你正在进行一个项目,想要取消所有的改变,返回到最近一次的提交,命令如下:

$ git reset --hard HEAD –hard flag 将指定提交(上例中,HEAD)中的任意内容放入工作目录和缓存区内。因为 HEAD 是最近一次提交,所以我们没有做任何改变。运行 git status,会看到提示没有需要提交的。

还有其它一些 git reset 使用的 flag。假设你想要回滚你的项目到多个提交之前,但是想要保存没有提交的改变,尝试下面的:

$ git reset --soft 3ce072c72d948abfa 当然,替换为你自己需要的 hash。–soft flag 将保存你的改变在工作目录和缓存区。换句话来说,最新的提交将会是你选择的提交。

还有很多情况,你可以使用 git reset。如果你认为需要这个名利概念的功能,查看文档。

###Git Checkout### 我们之前就提到过 git checkout 命令:用于切换分支。但是还有更多的特性。比如使用 -b flag 同一时间,建立并切换到新分支:

$ git checkout -b newBranchName  Switched to a new branch ‘newBranchName’ git checkout 也可以进行回滚撤销工作。git reset 回滚整个提交,而 git checkout 可以回滚单个文件。回滚在缓存区内的文件:

$ git checkout -- file.ext 如果需要回滚提交中的文件,替换指定提交的指针,如下所示:

$ git checkout HEAD file.ext
$ git checkout master~2 file.exe ###Git Diff### 另外一个很有用的 Git 命令是 git diff。使用这个命令找出两个文件,提交或分支之间的改变。假设你想看自从上一次提交后工作目录都有什么改变,可以执行如下命令:

$ git diff 如果只是想看一个文件的改变,添加文件名作为参数:

$ git diff index.html 如果想要比较最新提交和缓存区内的文件,使用 –cached flag。

$ git diff --cached
$ git diff --cached index.html 比较工作目录和一个提交,使用想要比较的提交的指针,代替上例中的 –cached flag。

$ git diff be96dbeab1
$ git diff HEAD^2 index.html 也可以使用 git diff 比较分支。将两个分支名作为参数,两个分支名中间为两个 “.”:

$ git diff master..otherBranch 这样 Git 将会 diff 两个分支的最新提交。如果需要 diff otherBranch 分支和 master 主分支,在分支名间加入三个 “.”。当然,使用你的分支名。

$ git diff master...otherBranch ###Git Stash### 有一个有趣的情景:假设你正在编写新特性,但是发现代码中有 bug。而这个bug 与新特性无关,你想要 fix 这个 bug 再继续开发新特性。但是如何处理为新特性写的代码的改变?这里就是 git stash 的用武之地!

git stash 就像是临时提交。当你想要隐藏一些改变,首先将这些改变加入缓存区,再运行下面的:

$ git stash 在主分区,保存工作目录和索引状态 (index state):

HEAD is now at 3d0b0a4 other commit 你会得到一个跟上面很相似的信息,告诉你在特定分支正在进行的工作已经保存。

当你提交过 bug-fix 之后,你可以从 stash 中取出之前的改变。

$ git stash apply 这样会将 stash 中的内容放回缓存区,同时会得到一个很象 git status 的信息。

你可以进行多次 stash,使用 list 命令查看所有的 stashes:

$ git status list
 stash@{0}: On master: started form on contact list
 stash@{1}: On master: README changes 在这个例子中,有两个 stashed 项。但是看到了清晰的 stash message 了嘛?如果需要 stash 多次,描述信息会让你清楚你的项目状态。使用 save 命令来添加 stash message:

$ git stash save “message here” 如果想要将特定 stash 放入缓存区,使用 stash 序号名称,在 list 命令看到的每行开头的信息;如果是将上例中 README 文件放入缓存中,运行如下命令:

$ git stash apply stash@{1} 以上内容转自:[http://blog.maxiang.net/git-advance-git-reset-checkout-diff-stash/239/](http://blog.maxiang.net/git-advance-git-reset-checkout-diff-stash/239/ "http://blog.maxiang.net/git-advance-git-reset-checkout-diff-stash/239/")

2013年网络搞笑话语

1.今年你二十多岁,在论坛上卖萌、愤青、勾搭姑娘,活跃在QQ群里,认识了各种妹子,高矮胖瘦,善良或是善妒或是贫穷或是富有,每一个人都可以搭话,都能说上两句. 可是少年,终究还是没有一个妹子把你始终放在她的心里,此生不换.

2.叹!!人生最寂寞的不是思念,而是,思念的时候没有,,,思念的对象!!

3.今天天气很好,在房间里宅久了,准备去客厅散散心。

4.我是个得瑟的孩子,给点阳光就灿烂, 好了伤疤就忘了疼,别说好听的话,我很容易相信的。

5.我讨厌我等了半天你的消息,结果一句“哦”就完了,你当我是讲故事的?

6.此次起床共用了5分钟,你已击败了全国88%学生,寝室还有一位同学起床失败,正在重起,隔壁全部死机

7.有人考试靠实力,有人考试靠视力,TMD我们考试得靠想象力。

8.每次QQ发出:“咳咳”的声音,还以为是帅哥加我好友,没想到是被群主踢出去了…

9.理科的强大在于你抄了答案也看不懂。文科的强大在于你看了答案就不想抄了。

10.不要脸这事,如果干的好,叫心理素质过硬

11.世界上本没有胖子,瘦的人多了,也就有了胖子!

12.小时候,我老是想长大是考清华还是北大呢?长大后,我发现我想太多了。

13.恭喜你中了大奖,请于今天晚上十点整,带着马刀、鸟枪、土炮到中国人民银行蒙面领取。

14..你们把函数导出来,又微回去,再积过去,又定回来,你们考虑过函数的感受吗?

15.在中国,活活最牛,活活把人逼死,活活把人打死,活活把人气死,看吧,活活最牛了。

16.上课点名!同学急忙打电话给其舍友悄悄的说:快来!老师点名了……舍友淡定的说:把免提打开……

17.孟婆 给我来碗汤,。‘你TM给我一碗可口可乐 。。。

18..春眠不觉晓,哈欠上门找,晚上睡不着,白天醒不了。

19.太姥姥说:“停电了,把蜡烛点上,接着看电视。”

20.此地严禁大小便,违者没收工具。

21.如果有一天我变成了流氓,请告诉他们我曾经单纯过。

22.我们都很傻,可我是装傻,你是真傻。

23.希望兜兜里的钱都相亲相爱 然后生很多很多小孩~

24.咳~ 该说的说,不该说的小声说。

25.我这辈子能拿的起放的下只有筷子

26.早起的鸟儿不一定有虫吃,很可能让通宵的鸟儿捷足先登了。

27.本来智商就不高,连情商都为零,还让不让人活了。

28.和同学们约好了,三十晚上,一边看春晚,一边烧寒假作业取暖!

29.问苍天晴为何物,直叫人加条棉裤。

30.永远不要觉得自己是世界是最倒霉的人,否则上帝会认为你低估了他的能力。

31.自信的女人不一定漂亮,比如说凤姐。

32.出问题多从自己身上找原因,别TM一便秘就怪地球没引力。

33.屁股是身体上最容易脏的地方,因为有个词叫尘埃落腚。

34.谢谢你的不开心,让我开心了那么久。

35.玉,不会因为忧伤而风情万种。

36.第一个知道牛奶可以喝的家伙,你到底对牛做了什么

37.不是所有牛奶都叫特仑苏,不是所有人我都叫他猪。

38.有时候你以为天要塌下来了,其实是自己站歪了。

39.其实早晨起来,可以做很多事,比如;再睡一觉。

40.抽,是一种生活艺术;找抽,是一种生活态度。

41.本先知自从得了神经病。整个人变得精神多勒。