月度归档: 2014 年 3 月

  • 第三方库的更新和升级

    第三方库的更新和升级

    模块化、代码重用等思维的引领下,各种不同功能的库不断出现,基本涵盖了所有功能需求,极大加速了软件开发效率。

    另一方面,包管理工具的流行简化了引用过程。不再需要下载库文件,添加到项目目录。

    第三方库也是一种产品,一样存在生命周期,这样就会有升级的问题产生。

    为什么要升级

    第三方库也是人创造的,同样会有效率,代码质量等问题。伴随着升级会有各种修复、优化和新的特性。

    及时的升级可以排除潜在的bug,提升效率,如果有需要还可以根据API的升级简化代码并优化流程。

    对于一个成熟的、经过广泛验证的第三方库,比如Spring、Hibernate等等。它们的方方面面经过时间的考研,在一个稳定的版本范围内都是可信的。所谓的版本范围是指标准版本号

    如果第三方依赖库的管理是手动的,那么升级的步骤就很无趣了。你需要定期访问你所使用的库的主页,检查是否有升级,然后手动下载新版本,覆盖旧版本。

    如果使用包管理工具或者构建工具,如npm、gradle等,那么升级就比较简单了,直接修改配置本身然后执行更新命令就可以完成了。

    Gradle中的版本管理

    npm很方便,使用也简单,所以下面的例子都是以gradle为例的。

    在gradle中如果你需要引入一个第三方包,你只需要在配置中写道:

    apply plugin:'java'
    
    repositories {
    mavenCentral()
    }
    
    dependencies {
    compilegroup:'org.hibernate', name:'hibernate-core', version:'3.6.7.Final'
    testCompilegroup:'junit', name:'junit', version:'4.11'
    }

    这样gradle就可以自动下载相关的库,而当你需要升级的时候你只需要修改version配置即可。

    当然更多的人可能习惯偏好更紧凑的写法:

    dependencies {
    compile'org.hibernate:hibernate-core:3.6.7.Final'
    testCompile'junit:junit:4.11'
    }

    不过以上的修改都需要你在一大篇缩进不同的字符串中来回寻找,特别是以下情况的时候你可以就觉得有点不方便了:

    testCompile(
    "org.hamcrest:hamcrest-core:1.3",
    "org.hamcrest:hamcrest-library:1.3"
    )
  • 改善Hexo生成页面的描述信息

    改善Hexo生成页面的描述信息

    其实严格来讲这是针对具体的模板而言,不过其中涉及到Hexo的一些数据的调用,所以还是算作Hexo的一个优化吧。

    问题主要源于检查自己的博客被收录的情况,Google很给力,收录了200+,而百度就一页…

    如图所示,Google的很多搜索结果的描述部分是一样的,看着死活觉得不爽,所以来改进一下。

    原因分析

    首先看看这句话出自哪里,是在_config.yml的配置中出现的。根据这个配置这些文字又被写到html页面的head中。

    对于描述信息的具体细节可以参考Google站长帮助—标题和描述

    简单说我们要尽可能提供清晰的描述,这些描述要准确且不重复,可以手动也可以程序生成。当然在Hexo中我们肯定首推程序生成。

    修改

    不同的主题可能具体的文件不一样,不过原理是一致的。我以我使用的Pacman模板为例。

    需要修改的是head.ejs,先看看原始定义:

    <% } if (page.description){ %>
    <meta name="description" itemprop="description" content="<%= page.description %>">
    <% } else if (config.description&&(!is_post())){ %>
    <meta name="description" content="<%= config.description %>">
    <% } else if 
  • 使用Vagrant配置一个稳定的Hexo书写环境

    使用Vagrant配置一个稳定的Hexo书写环境

    Vagrant是一个工具,它可以让你轻松的配置虚拟机。利用它你可以快速的搭建环境,并共享环境。

    它本质上是使用了Virtual Box等虚拟机作为支撑,在此之上对配置分享等做简化。

    很早就知道了Vagrant的存在,但是一直不知道它的用处何在,直到我最近离开了我的笔记本一小段时间才真正享受了它的遍历。

    背景

    我的笔记本安装的是ubuntu,写博客用的hexo。在ubuntu下什么都很方便,特别是hexo的环境,ssh密钥等等都是配置好的。

    其实用ubuntu的原因真的很单纯,因为笔记本性能太差了。跑Window那简直是一卡一卡的,用ubuntu就可以有个很流畅的速度。

    但是最近我回家没有带笔记本,又想写写东西,就觉得各种不适应了。

    家里的系统是Windows的,各种纠结以后装上Virtual Box开始配置虚拟机,在下载镜像的时候放弃了,因为觉得麻烦。

    所以视线有回到Vagrant了。

    准备工作

    Vagrant有各个平台的安装包,Windows下100+M,加上Virtaul Box的100+M,总大小不大,我家小水管也可以接受。从Vagrant Cloud拖一个Ubuntu 12.04的Box下来,300M。

    然后就是安装并重启。

    不要忘记配置一下环境变量。

    创建并启动

    根据官方的说明,使用vagrant init hashicorp/precise32初始化一下,然后使用vagrant up启动。

    这里会自动下载对应的Box,但是速度很慢。

    拿出我们刚才下载好的Box,我用迅雷下的,速度完全不能比呀。

    随便放在哪里,然后执行命令

    vagrant box add precise32 file:///C:/Users/sdx/.vagrant.d/boxes/precise32.box

    再次声明,文件位置随意。我放在那个目录是因为我以为它可以自动识别。

    重新初始化

    vagrant init precise32
  • JDBC驱动加载和Class.forName

    我很少直接使用原生的JDBC,更多是使用mybatis或者hibernate。

    上周需要用一用,就到网上Copy了一段代码,一切运行正常。但是有一句话有点奇怪

    Class.forName("com.mysql.jdbc.Driver")

    这句话我原来也用过,一直是以为这是加载对应驱动用的,直到我删除了它,我才发现好像它不是必须的。那这东西是干嘛的?

    虽然网上的很多代码片段是抄来抄去的,但是我觉得这样写一定是有原因。

    Class.forName

    实现看看这句话本身的用处。

    在Java世界中,类只有在被使用的时候才本加载,更准确的是说在你寻求类的相关信息的时候才加载。

    比如有一个类名为SomeOne

    publicclass SomeOne {
    
    }

    然后在一个调用它的类名为SomeOneCaller

    publicclass SomeOneCaller {
    publicstatic SomeOne someOne =null;
    publicstatic Class<?> someOne = SomeOne.class;
    }

    第一句话并没有导致类的加载,而第二句话触发了加载。

    而Class.forName语句是加载对应名称的类,这里的加载是指读取了字节码,并执行static代码块。

    也就是在使用JDBC时调用这句话可以保证我们在执行DriverManager的getConnection
    方法时它已经被载入JVM中了。

    也就是说Class.forName本身和JDBC没有什么关系,它所做的只是加载对应名称的类。

    JDBC

    JDBC是一套标准API,用于数据库连接和SQL语句执行等等。
    既然是标准,那么一定是有相关规范的。

    要在getConnection时调用正确的类,一般的JDBC驱动都会调用registerDriver方法注册自己。

    比如在Mysql的驱动中:

    static 
  • libGDX基于RoboVM对IOS平台的支持

    libGDX基于RoboVM对IOS平台的支持

    Libgdx这款跨平台的游戏开发引擎,我之前的很多文章都介绍过了,可以点击Libgdx查看。

    Libgdx在0.99版本正式加入对IOS的支持。

    Libgdx之前其实也是支持IOS的,只是需要先转化成C#,然后使用收费的工具实现。

    而现在Libgdx使用了RoboVM,这是开源免费的。目前已经有超过百款的Libgdx游戏发布到App Store了。

    RoboVM

    RoboVM将Java的字节码转为本地代码,并封装了UI和各种API。这样可以最大程度重用你原有的Java代码。

    RoboVM需要一个Mac OS X,虽然在其他平台,比如ubuntu,也是可以使用的。不过为了更好的集成和开发,最好还是入手一个Mac吧。

    RoboVM提供了Eclipse插件,安装地址:http://download.robovm.org/eclipse/

    插件安装

    在安装完成后复制以下代码测试以下:

    import org.robovm.cocoatouch.coregraphics.*;
    import org.robovm.cocoatouch.foundation.*;
    import org.robovm.cocoatouch.uikit.*;
    
    publicclass IOSDemo extends UIApplicationDelegate.Adapter {
    
    private UIWindow window =null;
    privateint clickCount =0;
    
    @Override
    publicbooleandidFinishLaunching(UIApplication application,
    NSDictionary launchOptions) {
    
    
  • 模块化的Grunt配置

    Grunt是Javascript任务运行工具,它可以让一切自动化。

    简而言之,它可以帮你完成代码压缩,代码编译,单元测试,代码规范验证等必须但高度重复的工作。

    极大程度简化你的工作,同时又保证你的代码质量。

    Grunt的同类工具很多,但是Grunt的一大特点就是生态庞大,有各种插件可以选择,而且都是可以通过npm安装的。

    GruntFile

    Gruntfile.js文件都是位于项目根目录中的一个JavaScript文件,并且它也应该与你的项目源文件一起提交。

    一个Gruntfile由下面几部分组成:

    • wrapper函数
    • 项目和任务配置
    • 加载的Grunt插件和任务
    • 自定义任务
    • 一个Gruntfile示例

    比如下面的例子,它从package.json中读取配置,再调用grunt-contrib-uglify插件来压缩源文件,同时根据读取的配置生成一个标语注释。同时注册默认任务为uglify任务。

    module.exports =function(grunt){
    
    grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),
    uglify: {
    options: {
    banner:'/*! <%= pkg.name %> <%= grunt.template.today("yyyy-mm-dd") %> */n'
    },
    build: {
    src:'src/<%=pkg.name %>.js',
    dest:'build/<%= pkg.name %>.min.js'
    }
    }
    
  • 海外博客使用CDN加速

    海外博客使用CDN加速

    因为在祖国的怀抱中自建博客很麻烦,所以最后还是选择全套购买海外的东西。

    不过博客主要的访客还是祖国的,所以这响应速度还是比较重要的。

    Hexo的一个好处就是全站静态化,生成以后再压缩一下,轻松加愉快。

    参考了网上很多博主的文章,决定CDN是个不错的东西,可以考虑一下。

    百度加速乐

    因为本身空间不错,访问速度也很快,所以国外的CDN基本就不考虑了,英文折腾起来太麻烦。

    国内的话看了一下挺多的,对于未备案的网站也可以分配海外节点。

    因为百度的云引擎BAE不错,所以对百度的服务期待很高。

    百度的CDN是百度加速乐,免费版3G/h,30万PV/日。

    这个数据大家别觉得特别好…这么大的量一般站点还用不上。

    我选用的别名接入,接入以后可以看大部分请求被香港节点处理了。速度有轻微提升,感觉还可以,就用着吧…然后就遇到坑爹的400(unknown virtual host)错误了。

    400错误

    我当时还琢磨这估计是抽风一下吧,刷新无数次都没有用。

    在百度经验和加速乐的论坛看了看,说需要等等或者删除再创建一下。

    确实管用,不过几分钟以后又会出现400错误,这样折腾不起呀,考虑到速度提升也不大,果断放弃之。

    毕竟是百度的服务,估计也不会太差。不过国内节点必须备案…所以也就只是看看。

    安全宝

    安全宝是一家名为星云融创的公司提供的,同样是未备案分配海外节点。

    安全宝的海外节点在美国,不过速度还挺快的。

    使用方法差不多,不过接入和解析生效都是人工审核的,一般一个小时左右。

    安全宝使用起来比较流畅,速度提升也比较明显,本站现在使用的就是它,安全宝把节点换到了日本的,基本不能用。不是速度慢,而是基本无法访问,慎用之。

    域名界面

    不过这个数据统计我就有些疑惑了。

    我是在购买了主机刚刚迁移完博客就去申请的服务,凌晨时分接入的。

    第二天早上就提示我拦截了恶意攻击

    控制面板的恶意攻击提示

    要不要这样…我一个静态博客,才搬迁就有攻击…

    不过一看就知道是自动攻击,我主机上一个php文件都没有。…

  • Hexo模板系统和pacman的修改

    Hexo模板系统和pacman的修改

    Hexo的原理是解析_posts中的md格式文件,然后根据模板的解析规则进行解析。

    我使用的风格修改自pacman,主要它看着比官方默认的主题要充实很多。

    但是毕竟是别人做好的,还是有很多不合自己意的,所以还是需要稍微修改一下。

    Hexo模板系统

    要做出修改,首先要看看Hexo的模板系统是怎么实现的。

    Hexo使用的是ejs,类似的东西就多了,比如Jade,swig,doT等等。

    ejs效率比较慢(相比其他的),这里有一个测评,也没有Jade有那么多特性。不过好处也是明显的,不需要太多的时间和精力就可以掌握。

    在Hexo中有post、page等不同的布局,而选用哪种布局是在md文件中声明的。

    Hexo首先解析md文件,然后根据layout.ejs判断布局类型,再转发给其他布局文件。在布局中可以引入其他文件,比如

    <%- partial('_partial/header')%>

    这样每一块内容都是单独的,方便二次使用,也可以几个不同布局引用一个代码片段。

    简要流程

    修改几处英文

    我没有从官方风格慢慢改,而是选用了pacman,修改了主题色以后感觉就不错了,不过有几处英文显示感觉不舒服。

    Hexo是支持多语言的,在_config.xml中配置就可以了,一般使用zh-CN。

    首先看看文章末尾的上一篇和下一篇

    language中没有对于这个的定义,首先我们补充nextpostprevpostzh-CN.yml

    nextpost:下一篇
    prevpost:上一篇

    然后修改post文件夹中的pagination.ejs,将PREVIOUS和NEXT替换掉

    <nav class="article-nav 
  • 通过ssh使用git更新hexo内容

    Hexo每次新增一篇文章都会引起很多页面的变动。

    比如page页面,因为增加一篇文章,所以分页情况都改变了,这里会有将近10个页面的变化。

    其次是tag和categories目录,因为文章一般都会指定tag和categories,所以这里也会有几个页面的变动。

    最后就是文章页面本身了。

    这么算下来新增一篇文章会更新十多个页面,还有若干图片。

    每次使用ftp更新都很慢,虽然可以设置各种跳过规则,但是对比文件列表也是会花费相当的时间。加之hexo提供的ftp发布比一般的ftp客户端还慢(ftp发布工具是给予lftp的,只适用于linux)。

    我本来准备做一个版本管理工具,或者让hexo只生成最近几天的文章(issue链接)已减少更新量。

    不过折腾起来挺费劲的,最后作罢了。

    刚才突然想到我需要的其实就是一个git而已,加上主机本身支持ssh,所以决定使用在服务器搭建一个git服务器来更新网站。

    创建Git仓库

    其实创建Git仓库挺简单的,因为git自身就支持ssh方式的连接,我们只需要在服务端建立一个Git仓库,然后将页面生成到Git仓库中就行了。

    在目标目录执行命令:

    git init
    git add .
    git commit -m'init git repo with remote files'

    初始化仓库并将现有文件全部添加到其中。

    然后在本地执行命令将库拉去回来

    git clone username@host:~/path/to/www

    也可以直接在本地执行初始化一个Git仓库,然后添加一个remote

    git init
    git remote add web username@host:~/path/to/www
  • 从博客园迁移到Hexo

    备注:该文章写于2014年,相关思路可以作为参考,但是hexo的版本更新相关导致相关工具无法使用了。

    很早以前就开始使用博客园的服务,虽然有这样那样的问题,但是始终还是觉得不错。

    一来不用自己维护空间什么的,二来博客园的原创文章很好被收录,偶尔写写文章也不操心。

    大概从去年起将操作系统全面切换到ubuntu,没有想到最不习惯的居然是没有live writer。博客园的在线编辑器实在太难用了,反复折腾决定用node-webkit快速的做一个linux下的编辑器。

    就在这之间接触到了Hexo,最终决定从博客园迁移出来,自建博客。

    这里分享一下迁移中的各种收获。

    Hexo

    Hexo是基于Nodejs的静态博客工具。所谓静态博客区别于Wordress之类的博客系统主要是并不是由动态语言在服务端生成,而是使用者在使用完博客后生成全站静态文件。

    Hexo的优点其实我没有啥深刻的体会,这是我接触到的第一款静态博客工具。对我而言它的优势有三:

    • 书写方便,使用markdown书写。

    很多人觉得md很潮,其实我很现实的,只要好用就行了。用md来写不需要专用软件支持,一个记事本就好了。

    • 容易保存原始资料

    在博客园的时候就有定期备份数据的习惯,倒也不是害怕哪天它突然关闭了,只是决定数据在自己手中有一份比较安全。

    Hexo的原始资料可以纳入版本管理之中,还是挺方便的。

    • 使用方便,易于扩展

    Hexo在设计上预留了扩充点,而且本身原理很简单,实在不行也是可以自己修改的。这样如果有不合意的地方可以自己动手完成。接下来我也会谈到我为了迁移做的一个迁移插件。

    准备工作

    Hexo要求nodejs环境,具体安装大家随意搜索以下就可以找到。而npm是nodejs的包管理器,默认也会自动安装上。
    然后运行

    npm install -g hexo
    hexo init <blogFolder>

    初始化完成以后运行hexo server可以看到效果。

    基本的配置在_config.xml文件中,有部分配置也会在对应的主题目录的_config.xml中。

    从博客园迁移数据

    博客园是由一个未公开的API的,不过API中没有提供分类和标签,所以不适合迁移时的数据获取,所以还是抓取网页比较值得信赖。

    首先来看看插件列别。

    Hexo将插件分类7类。分别是生成,渲染,迁移,标签,辅助,其他。…