之前一直使用的是阿里云上ubuntu 12.04系统,为了使用docker方便有过一次升级,不过那个时候升级比较粗暴,我直接更新了源,然后用apt-get upgrade升的级。
今天想升级到16.04才突然发现了do–release–upgrade,整个过程轻松加愉快。
直接运行
sudo do-release-upgrade -d
升级之后检查一下
lsb_release -a
…
之前一直使用的是阿里云上ubuntu 12.04系统,为了使用docker方便有过一次升级,不过那个时候升级比较粗暴,我直接更新了源,然后用apt-get upgrade升的级。
今天想升级到16.04才突然发现了do–release–upgrade,整个过程轻松加愉快。
直接运行
sudo do-release-upgrade -d
升级之后检查一下
lsb_release -a
…
最近由于各种原因,需要将之前的一个网站关闭。
关闭之后因为域名没有到期,所以还是希望能够有一个静态页面让平时的常客至少下载一下存档,所以就做了一个静态网站。
因为静态网站只有一个页面和一个zip存档,所以需要在nginx中将所有请求都转发到这个页面上。
配置如下:
location / {
try_files $uri /index.html;
}
这样的话默认请求存在的文件的时候就会直接访问这些文件,否则就会跳转回首页。…
通常一个项目,特别是开源项目有很多常见的操作,比如merge一个pull request或者发布一个版本。
merge一个pull request可以通过github的issue页面完成,但是发布版本通常需要一些准备,特别是证书等等。
Rultor是一个辅助工具,可以完成合并,发布等功能。
Rultor的配置是.rultor.yml,这是一个例子
decrypt:
settings.xml: "repo/settings.xml.asc"
pubring.gpg: "repo/pubring.gpg.asc"
secring.gpg: "repo/secring.gpg.asc"
docker:
image: "yegor256/java8"
release:
script: |
mvn versions:set "-DnewVersion=${tag}"
git commit -am "${tag}"
mvn clean deploy -P central-deploy --settings /home/r/settings.xml -P cxf-spring-boot-starter-maven-plugin
使用的时候很简单,比如需要发布新版本,直接创建一个issue,在其中@tultor即可
@rultor release, tag is…
Jenkins应该是最常用的CI/CD工具了,而Jenkins也有官方的Docker版本,可以很方便的获得一个可用的Jenkins。
但是大部分时候我们期待的是从Docker启动Jenkins之后一切环境都是准备就绪的,比如对应的插件啥的。
对于插件来说还比较简单,直接提供一个plugin.txt文件即可
credentials:1.18 maven-plugin:2.7.1
Jenkins的任务是可以在master直接运行的,但是很多时候,特别会需要很多不同构建环境的时候我们就会需要多个不同的Jenkins Slave了。
Docker-Compose可以做到启动多个容器,这样我们就可以直接在其中就行配置了,比如一个java7的Slave,一个java8的,再来一个node的,但是最后还是需要到jenkins中添加这些Slave。
Jenkins提供了Groovy脚本来实现一些配置和功能,比如需要修改执行器数量(默认为2),可以使用一些
import jenkins.model.* Jenkins.instance.setNumExecutors(5)
对于添加Slave的脚本就稍微复杂一些,需要用到import hudson.plugins.sshslaves.*
大概的脚本如下
List<Entry> env = new ArrayList<Entry>();
EnvironmentVariablesNodeProperty envPro = new EnvironmentVariablesNodeProperty(env);
Slave slave = new DumbSlave(
"java-7-node","",
"/var/jenkins_home",
"1",
Node.Mode.NORMAL,
"agent-node-label",
new SSHLauncher("java-7-node",22,"jenkins","password","","","","",""),
new RetentionStrategy.Always(),
new …Gdx-ai提供了常见的AI算法,当然也包括寻路算法,比如常用的A*。
Gdx-ai自身的API抽象也很易懂,也方便自定义寻路。
首先由Graph和Connection提供图中的连通性和对应连接的开销。 简单一点直接用DefaultConnection,它提供的默认开销为1。
而PathFinder就是具体执行寻路的类,而返回的结果是GraphPath,它包含了路的结果,对应的连接还有其他一些数据。
这是Meritxell Calvo Palanques画的示意图

另外就是Heuristic,它并不是必须的,但是一个有效的Heuristic函数可以加快搜索,不过不方便提供,或者不想提供,最坏的结果无非就是退化为Dijkstra。(我提供的例子会直接返回一个错误的启发函数,不过依然可以获得结果)。
例子就简单一点吧,一般地图的数据是从Tiled地图或者其他格式的文件中获得的,这里我直接用硬编码来。
这个图只有四个点,其中点1,2,3相互连接,点3连接点4,我们要寻找从点1到点4的路径。
首先表示这个图
IndexedGraph<Node> graph = new IndexedGraph<Node>() {
@Override
public Array<Connection<Node>> getConnections(Node fromNode) {
Array<Connection<Node>> connections = new Array<Connection<Node>>();
switch (fromNode.getId()) {
case 1:
connections.add(new DefaultConnection<Node>(n1, n2));
connections.add(new DefaultConnection<Node>(n1, …LIbgdx旗下的gdx-ai库提供了大量使用的AI算法,其中包括了最常见的有限状态机FSM。
gdx-ai是一个普通的java库,并不存在平台相关依赖,所以直接在core中引入就可。
dependencies {
compile "com.badlogicgames.gdx:gdx-ai:1.7.0"
}
StateMachine是有限状态机的接口,对应的实现目前有两个DefaultStateMachine和StackStateMachine。
StackStateMachine以栈的形式保存状态,所以可以提供了方法获取上一个状态,一般使用DefaultStateMachine就行了。
FSM的例子很多,我们直接来一个简单的。
首先主体对象是人,而人只有两个状态,一个走路,一个打伞。
状态切换的条件是时间,也就是假定下雨的时间符合一定的条件。
首先创建一个Person类
public class Person extends Image {
private TextureRegion walk;
private TextureRegion rain;
private StateMachine<Person, PersonState> stateMachine;
private float time;
public Person(final TextureRegion walk, final TextureRegion rain) {
…Libgdx对于资源管理提供了AssetManager来做资源的管理,如果你需要使用它那么你就不得不使用这样的代码
manager.load("data/mytexture.png", Texture.class);
manager.load("data/myfont.fnt", BitmapFont.class);
manager.load("data/mymusic.ogg", Music.class);
其中的文件路径是字符串。然后在你使用的地方
Texture tex = manager.get("data/mytexture.png", Texture.class);
BitmapFont font = manager.get("data/myfont.fnt", BitmapFont.class);
这样使用其实蛮不方便的,如果你把文件路径作为一个全局变量的话,其实很多代码是重复的。
而AnnotationAssetManager提供了反射的方法来完成这个工作
package com.huangyunkun.hundred;
import com.badlogic.gdx.graphics.Texture;
import net.dermetfan.gdx.assets.AnnotationAssetManager;
public class Assets {
@AnnotationAssetManager.Asset(Texture.class)
public static final String ball = "ball.png";
}
比如有一个球的图片,那么只需要声明一个字符串。然后加载的时候直接传入这个类本身,由加载器自己去寻找所有需要加载的资源即可。…
之前用的ubuntu一直配置的上海交通大学的源,速度也不错,最近升级到16.04以后又准备继续使用,突然发现可以直接使用mirrors自动选择最合适的源。
默认的可用的列表文件在这里 http://mirrors.ubuntu.com/mirrors.txt
在source.list直接使用
deb mirror://mirrors.ubuntu.com/mirrors.txt xenial main restricted universe multiverse deb mirror://mirrors.ubuntu.com/mirrors.txt xenial-updates main restricted universe multiverse deb mirror://mirrors.ubuntu.com/mirrors.txt xenial-backports main restricted universe multiverse deb mirror://mirrors.ubuntu.com/mirrors.txt xenial-security main restricted universe multiverse…
Spring Boot提供了一个很便利的命令bootRun来快速启动应用,项目中的依赖会在启动时作为classpath的一部分传递给java,但是windows系统下有一个问题,如果classpath很长的时候就会直接报错,无法运行。但是如果你生成jar文件,再运行jar文件本身就不会遇到这个问题。
bootRun是一个很便利的功能,自然我们不希望这个功能无法使用,有个取巧的办法。
首先生成一个jar,这个jar文件的manifest中包含了所有依赖,然后bootRun直接依赖这个jar。
task pathingJar(type: Jar) {
dependsOn configurations.runtime
appendix = 'pathing'
doFirst {
manifest {
attributes "Class-Path": configurations.runtime.files.collect {
it.toURL().toString().replaceFirst(/file:/+/, '/')
}.join(' ')
}
}
}
bootRun {
dependsOn pathingJar
doFirst {
classpath = files("$buildDir/classes/main", "$buildDir/resources/main", pathingJar.archivePath)
}
…Docker的镜像拉取有时候会花很长的时间,而国内有很多提供镜像服务的公司,随便找一个即可。
但是在配置的时候经常会出现无法配置成功的问题,比如DaoCloud会告诉你修改profile文件,要么使用它的主机监控程序。一般情况我只想用镜像加速,并不想主机监控服务,所以选用修改profile文件,但是每次重启之后都没有生效。
比较了阿里百川还有灵雀云的加速配置文档,基本是一个逻辑,但是依照文档,修改镜像的方法只有两种,第一种是创建的时候直接指定
docker-machine create ... --engine-registry-mirror=<你的加速地址>
或者是修改config.json中的RegistryMirror配置

这样在docker-machine重启以后配置才会真正生效。
参考文档:
https://github.com/docker/machine/blob/master/docs/reference/create.md…