5个小时写一个扑克牌游戏——金钩钓鱼

  罗大佑有歌云:“无聊的日子总是会写点无聊的歌曲……”,我不是歌手,我是程序员,于是无聊的日子总是会写点无聊的程序。程序不能太大,不然没有时间完成;程序应该有趣,不然就达不到消磨时间的目的;程序应该有那么一点挑战性,不然即使写完了也没有进步。 金钩钓鱼游戏是我儿时经常玩的一种扑克牌游戏,规则非常简单,两个玩家,一旦牌发到手里之后,接下来每个人出什么牌基本上已经就定了,玩家没有自己做决策的机会,所以这个游戏很容易用程序自动模拟出来。 (一)关于金钩钓鱼游戏 基本规则(简化版):两个玩家(Player),一副扑克(Deck),大小王(Joker)可要可不要,我们的游戏假定包含大小王,洗牌(Shuffle)之后,每个玩家得到同样数目的牌(27张),玩家任何时候不能看自己手里的牌,玩家依次出牌,每次出一张,轮到自己出牌时,抽出自己手中最底下的一张牌放到牌桌(Board)上,牌桌上的牌按照玩家出牌的顺序摆成一条长链。J(钩)是最特殊的一张牌,当某个玩家出到J时,便将牌桌上的所有牌都归为己有,并放到自己牌池的最上面(与出牌时恰恰相反),此即所谓“金钩钓鱼”,此时牌桌清空,再由此玩家重新出牌。另外,当自己出的牌与牌桌上的某张牌点数相同时,便将牌桌中那张牌及其之后的牌都归为己有(包含自己刚出的那张),再由此玩家重新出牌,比如牌桌上的牌为3,7,8,4,9,当某个玩家出了8,便将牌桌上的8,4,9连同自己刚出的8一并收回,派桌上剩下3,7。最后,谁手中的牌最先出完,谁就输了。 (二)对于一副牌的建模 由于花色(Suit)对于此游戏并不重要,所以对扑克牌建模时省略了对花色的建模,同样,由于不需要比较大小,牌的点数(Rank)可以用String来表示(其中王用”W”表示)。 package com.thoughtworks.davenkin.simplefishinggame; public class Card { private String rank; public Card(String rank) { this.rank = rank; } public String getRank() { return rank; }…

重温大师经典:Martin Fowler的持续集成

持续集成 作者:Martin Fowler 译者:滕云 原文发布时间:2006年5月1日 翻译时间:2012年2月25日 原文链接:http://www.martinfowler.com/articles/continuousIntegration.html (此翻译已获原作者同意)   持续集成(Continuous Integration, CI)是一种软件开发实践,在实践中项目成员频繁地进行集成,通常每个成员每天都会做集成工作,如此,每天整个项目将会有多次集成。每次集成后都会通过自动化构建(包括测试)来尽快发现其中的错误。许多团队都发现这种方法大大地减少了集成问题并且能够快速地开发出高内聚性的软件。本文简要地总结了持续集成技术及其现状。 我还清楚地记得我刚加入一个大型软件项目时的情形,那时我正在英国一个电子公司做暑期实习。我的经理(属于QA部门)领我参观了一个巨大并很压抑的房间,里面全是格子间。经理告诉我这个项目已经开发了有些年头,现在正在做集成,并且已经集成了好几个月了。经理还告诉我说,没有人真正知道完成集成工作需要多少时间。由此我学到了软件项目的一个通病:软件集成是一个漫长并且无法预测的过程。 然而,软件集成不必像这样的。在ThoughtWorks的大多数项目还有世界上许多其它组织的软件项目中,软件集成并不是什么难事。每个开发人员离共享的工程状态只有咫尺之遥,并且可以在几分钟之内将自己的代码集成进去。任何集成错误都能被快速地发现并得到快速的修正。 这种鲜明的对比并不是源自于后者有多么昂贵或复杂的工具,而关键在于每人都频繁集成这种简单实践,通常是每天向一个被管控的代码库集成。 当我向人们阐述这种实践时,通常得到两种反应:“(在我们这里)行不通”和“无关紧要”。当人们尝试了这种实践之后,他们发现其实做起来比说起来简单,而且这样的实践对于开发“至关重要”。因此有了第三种反应:“是的,我们就是这么做的,不然该怎么活啊?” “持续集成”源自于极限编程(XP),并且是XP最初的12种实践之一。当我以咨询师的角色加入ThoughtWorks时,我鼓励我的团队使用这种技术。Matthew Foemmel将我的建议变成了实实在在的行动,由此软件集成从少有发生并且复杂的状态变成了一桩易事。Matthew和我将我们的经验写在了本文的第一版中,而本文也是我的个人网站上最受欢迎的文章之一。 虽然持续集成并不需要使用特别的工具来部署,但是我们发现拥有一台持续集成服务器将大有益处,其中最著名的有开源的CruiseControl,该软件最初由ThoughtWorks的几个员工开发,现在由一个很大的社区维护着。后来几款其它的持续集成服务器也相继出现了,有开源的,也有商业化的,包括ThoughtWorks Studios的Cruise。 在开发中使用持续集成 对于我来说,解释持续集成及其工作原理最简单的方法便是以一个小的软件功能的开发为例来进行演示。假设我们需要向软件添加一点功能,至于是什么样的功能并不重要,我们假定它很小并且可以在几个小时内完成。 首先我们需要在本地机器上保留一份当前已经处于集成状态的代码的拷贝。我通过代码管理系统在代码库的主线(mainline)上拉下(check out)一份工作代码拷贝。 上一段文字主要针对使用代码控制系统的人,对于不使用代码控制系统的人来说便是胡言乱语了。因此,我将向后者解释一下。代码控制系统用于将项目所有的代码保存在一个代码库(repository)中,项目当前的状态通常被称为主线。任何时候开发人员都可以从主线上获得一份拷贝到本地机器,这被称为“checking out”。本地机器上的代码拷贝称为“working copy”。(多数时候,实际上你是在更新(update)本地代码到主线状态,实践中它们是一样的效果。) 现在,为了完成软件的功能添加,我对本地代码进行修改,其中既包括修改产品代码,也包括添加自动化测试。持续集成非常看重测试,并且在软件代码本身中达到了测试自动化——我将其称为自测试代码,通常使用流行的XUnit测试框架的一个版本。 当我完成了功能开发(或者在我开发过程的不同阶段),我将在本地开发机上完成自动化构建。构建过程将编译并链接本地代码,然后跑自动化测试。只有当构建和测试都没有错误时,该次构建才能算是好的构建。 有了本地的成功构建,我便可以考虑将我修改的代码提交到代码库了。但是,在我提交之前,其他开发人员可能已经向主线提交了他们的修改,所以首先我需要将他们的修改更新到我本地并且重新构建。如果他人的修改与我的修改有冲突,那么在本地编译或者测试阶段将会发生错误,这种情况下,我需要负责修改本地代码直到与主线代码保持适当同步为止。 当本地代码与主线代码同步之后,我便可以向主线提交自己的修改了,代码库也得以更新。…

十步搭建 OpenVPN

摘要: 十步搭建 OpenVPN,享受你的隐私生活 我们支持保护隐私,不为我们有自己的秘密需要保护,只是我们认为保护隐私应该成为一项基本人权。所以我们坚信无论谁在什么时候行使这项权利,都应该不受拘束的获取必须的工具和服务。 十步搭建 OpenVPN,享受你的隐私生活 我们支持保护隐私,不为我们有自己的秘密需要保护,只是我们认为保护隐私应该成为一项基本人权。所以我们坚信无论谁在什么时候行使这项权利,都应该不受拘束的获取必须的工具和服务。OpenVPN就是这样一种服务并且有多种工具(客户端) 来让我们利用并享受这种服务。 通过与一个OpenVPN服务器建立连接,我们基本上在我们的设备和远端运行OpenVPN的主机之间建立了一个安全的通信通道。尽管在两个端点之间的通信可能被截获,但是信息是经过高强度加密的所以实际上它对于攻击者没什么用。OpenVPN除了扮演加密通信通道的调解人,我们也可以通过设置使服务器扮演互联网网关的角色。通过这种方式,我们可以连接任何不安全的Wifi,然后迅速的链接到远程的OpenVPN服务器,然后在不需要考虑偷窥的人或者无聊的管理员的情况下运行需要上网的程序。(注意:OpenVPN服务器旁还是需要信任的管理员的。) 这篇文章将一步一步的教会你如何在Ubuntu Server 14.04 LTS上安装OpenVPN。OpenVPN所在的主机可能是云上的一台VPS,一台在我们家里某台电脑上运行的虚拟机,或者是一个老到你都快忘了的设备。 第一步 准备系统 我们需要Ubuntu Server主机的一个命令行终端,比如通过SSH从远程访问它。首先需要更新它的本地仓库数据: sub0@delta:~$ sudo apt-get update 进行操作系统和已安装的包的升级,输入: sub0@delta:~$ sudo apt-get dist–upgrade 如果升级了新内核,那就需要重启。当更新完成后,就该安装OpenVPN了: sub0@delta:~$ sudo apt-get…

大型网站后台架构的演变

随着用户访问量的不断增加,网站的后台也会不断变化以应对需求。本文主要从一个小型网站到大型网站的过度与变化来陈述。   1.1 网站后台架构 主要指由web server 、应用服务器、数据库、存储、监控等组成的网站后台系统。   1.2 架构演变 个人站点后台架构。如图2-1所示。 图2-1 单台一组 如图所示,如果是个人站点,访问量不大,一般都是将web server、应用服务器、数据库部署在一台物理服务器上。从图中也可以看到,一个网站最基本的后台需要web server、应用服务器、数据库三部分组成。   1.2.1 网站架构的进一步演变 考虑到网站访问量的不断增加,网站的后台架构也必须不断调整和优化,进一步实现功能分离。特别是随着访问量不断增加以及考虑到数据库的负载和数据的重要性,数据库需要分离出来。从web server到数据库实现各个层次的负载均衡。   1.2.1.1 数据库功能分离,数据库单台部署 考虑到数据库的安全性和处理性能,数据库单台部署。如图2-2-1-1所示。 图2-2-1-1 数据库分离 如图所示,数据库与web server 、应用服务器分离出来,单台部署。这样做有两个好处: (1)数据库服务器性能提高,不再和webserver 、应用服务器抢占资源。 (2)数据库服务器安全性能提高,不会因为一台服务器宕机而影响所有服务,特别是数据库服务。   1.2.1.2…

Centos7下使用ELK(Elasticsearch + Logstash + Kibana)搭建日志集中分析平台

日志监控和分析在保障业务稳定运行时,起到了很重要的作用,不过一般情况下日志都分散在各个生产服务器,且开发人员无法登陆生产服务器,这时候就需要一个集中式的日志收集装置,对日志中的关键字进行监控,触发异常时进行报警,并且开发人员能够查看相关日志。logstash+elasticsearch+kibana3就是实现这样功能的一套系统,并且功能更强大。 Logstash:负责日志的收集,处理和储存 Elasticsearch:负责日志检索和分析 Kibana:负责日志的可视化 1、环境介绍 elkServer IP:192.168.7.27 OS:Centos7.1 FQDN:elk.server.com elkClient IP:192.168.31.23 OS:Centos7.1 2、下载准备 官网下载最新的安装包:https://www.elastic.co/downloads(目前有些版本的包可能下载不到了,请到该地址下载——链接:http://pan.baidu.com/s/1gfohO2Z 密码:5s1f) elasticsearch-1.7.3.noarch.rpm (server上安装) kibana-4.1.2-linux-x64.tar.gz (server上安装) logstash-1.5.4-1.noarch.rpm (server上安装) logstash-forwarder-0.4.0-1.x86_64.rpm (client上安装) 3、Server端安装 3.1安装jdk1.7 # yum install java-1.7.0-openjdk Loaded…

CentOS7 安装ffmpeg

安装EPEL Release,因为安装需要使用其他的repo源,所以需要EPEL支持: yum install -y epel-release #如果出现缺少Code提示,可以: sudo rpm –import /etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7 #安装完成之后,可以查看是否安装成功 yum repolist 安装Nux-Dextop源 #导入一个Code sudo rpm –import http://li.nux.ro/download/nux/RPM-GPG-KEY-nux.ro #安装nux-dextop 源 sudo rpm -Uvh http://li.nux.ro/download/nux/dextop/el7/x86_64/nux-dextop-release-0-1.el7.nux.noarch.rpm #查看repo源是否安装成功 yum repolist yum安装ffmpeg:…

CentOS7 Tomcat 启动过程很慢,JVM上的随机数与熵池策略

1. CentOS7 Tomcat 启动过程很慢 在centos启动官方的tomcat时,启动过程很慢,需要几分钟,经过查看日志,发现耗时在这里:是session引起的随机数问题导致的: <code class="hljs css has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;">14<span…

linux tomcat 无法关闭 :8005端口未启动

配置tomcat的时候 发现了一个问题,tomcat启动的时候,8005端口未启动,故无法关闭tomcat,后经查询解决了,记录一下子 tomcat启动的时候看不出异常,关闭的时候回报错类似: Jul 17, 2015 9:47:54 AM org.apache.catalina.startup.Catalina stopServer SEVERE: Could not contact localhost:8005. Tomcat may not be running. Jul 17, 2015 9:47:54 AM org.apache.catalina.startup.Catalina stopServer SEVERE: Catalina.stop: java.net.ConnectException:…

dubbox服务监控与日志采集

继上一篇dubbox2.8.4的配置和使用后,我们要进一步考虑dubbox服务的部署和监控。 dubbox日志的采集方案 dubbox服务部署 采用的是ELK的日志采集方案(http://blog.csdn.net/u011282930/article/details/52771237),我们选择将dubbox的服务单独拆分为独立的部署jar包,在系统上部署。结构如下: logstash日志采集 其中,logstash就是用来收集运行的服务的日志,采用的是2.3.1版本,通过配置对应的解析文件来监控,我的解析文件如下 input { file { path => "F:\log.txt" ## 填写文件的绝对路径 start_position => "beginning" ## 从头开始进行收集 codec => multiline { ## 通过配置识别日志开头,来保证多行可以被合并 pattern => "^" ##…