Java自动拆装箱机制

概述


Java自动拆装箱机制从Java 1.5开始引入,目的是将原始类型值转换成对应的对象。
在自动拆装箱机制引入前,由于Java不允许直接向集合类(Connections)中放入原始类型值,只能接收对象。通常这种情况下的做法是,将原始类型值转换为对象,然后将这些对象放入集合中。为了让代码更为简洁,Java 1.5引入了自动拆装箱机制,但该机制并非完美,如果有些细节问题不注意,会引起难以察觉的bug。有很多公司笔试题也爱考相关的问题,博主最近在准备应聘,所以就来好好谈谈这个自动拆装机制。

什么是自动装箱和拆箱


自动装箱就是Java自动将原始类型值转换成对应的对象,比如将int的变量转换成Integer对象,这个过程叫做装箱,反之将Integer对象转换成int类型值,这个过程叫做拆箱。因为这里的装箱和拆箱是自动进行的非人为转换,所以就称作为自动装箱和拆箱。
原始类型:byte,short,char,int,long,float,double,boolean
对应的封装类分别为:Byte,Short,Character,Integer,Long,Float,Double,Boolean。

什么时候发生自动拆装箱


赋值时

这是最常见的一种情况。

1
2
3
4
5
6
7
//before autoboxing
Integer iObject = Integer.valueOf(3);
Int iPrimitive = iObject.intValue()

//after java5
Integer iObject = 3; //autobxing - primitive to wrapper conversion
int iPrimitive = iObject; //unboxing - object to primitive conversion

方法调用时

方法调用时,传入的参数编译器会帮我们转换,个人认为传参的过程就是赋值的过程,所以这种情况和赋值时发生的自动拆装箱本质上应该是相同的。

1
2
3
4
5
6
7
8
public static Integer show(Integer iParam) {
System.out.println("autoboxing example - method invocation i: " + iParam);
return iParam;
}

//autoboxing and unboxing in method invocation
show(3); //autoboxing
int result = show(3); //unboxing because return type of method is Integer

自动装箱的弊端


自动装箱的过程会创建对象,如果在循环中不断的执行自动装箱,就会创建多余的对象,影响程序性能。如下面例子所示:

1
2
3
4
Integer sum = 0;
for(int i=1000; i<5000; i++) {
sum+=i;
}

上面的代码 sum+=i 可以看成 sum = sum + i,但是 + 这个操作符不适用于Integer对象,首先sum进行自动拆箱操作,进行数值相加操作,最后发生自动装箱操作转换成 Integer对象。其内部变化如下:

1
2
sum = sum.intValue() + i;
Integer sum = new Integer(result);

在上面的循环中会创建将近4000个无用的Integer对象,在这样庞大的循环中,会降低程序的性能并且加重了垃圾回收的工作量。因此在我们编程时,需要注意到这一点。

重载与自动装箱


当重载遇上自动装箱时,情况会比较有些复杂,可能会让人产生有些困惑。在1.5之前,value(int)和value(Integer)是完全不相同的方法,开发者不会因为传入是int还是Integer调用哪个方法困惑,但是由于自动装箱和拆箱的引入,处理重载方法时稍微有点复杂。一个典型的例子就是ArrayList的remove方法,它有remove(index)和remove(Object)两种重载,我们可能会有一点小小的困惑,其实这种困惑是可以验证并解开的,通过下面的例子我们可以看到,当出现这种情况时,不会发生自动装箱操作。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public void test(int num) {
System.out.println("method with primitive argument");

}

public void test(Integer num) {
System.out.println("method with wrapper argument");

}

//calling overloaded method
AutoboxingTest autoTest = new AutoboxingTest();
int value = 3;
autoTest.test(value); //no autoboxing
Integer iValue = value;
autoTest.test(iValue); //no autoboxing

Output:
method with primitive argument
method with wrapper argument

要注意的事项


对象相等比较

这是一个比较容易出错的地方,”==“可以用于原始值进行比较,也可以用于对象进行比较,当用于对象与对象之间比较时,比较的不是对象代表的值,而是检查两个对象是否是同一对象,这个比较过程中没有自动装箱发生。进行对象值比较不应该使用”==“,而应该使用对象对应的equals方法。看一个能说明问题的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
public class AutoboxingTest {

public static void main(String args[]) {

// Example 1: == comparison pure primitive – no autoboxing
int i1 = 1;
int i2 = 1;
System.out.println("i1==i2 : " + (i1 == i2)); // true

// Example 2: equality operator mixing object and primitive
Integer num1 = 1; // autoboxing
int num2 = 1;
System.out.println("num1 == num2 : " + (num1 == num2)); // true

// Example 3: special case - arises due to autoboxing in Java
Integer obj1 = 1; // autoboxing will call Integer.valueOf()
Integer obj2 = 1; // same call to Integer.valueOf() will return same
// cached Object

System.out.println("obj1 == obj2 : " + (obj1 == obj2)); // true

// Example 4: equality operator - pure object comparison
Integer one = new Integer(1); // no autoboxing
Integer anotherOne = new Integer(1);
System.out.println("one == anotherOne : " + (one == anotherOne)); // false

}

}

Output:
i1==i2 : true
num1 == num2 : true
obj1 == obj2 : true
one == anotherOne : false

值得注意的是第三个小例子,这是一种极端情况。obj1和obj2的初始化都发生了自动装箱操作。但是处于节省内存的考虑,JVM会缓存-128到127的Integer对象。因为obj1和obj2实际上是同一个对象。所以使用”==“比较返回true。

容易混乱的对象和原始数据值

另一个需要避免的问题就是混乱使用对象和原始数据值,一个具体的例子就是当我们在一个原始数据值与一个对象进行比较时,如果这个对象没有进行初始化或者为Null,在自动拆箱过程中obj.xxxValue,会抛出NullPointerException,如下面的代码:

1
2
3
4
5
6
private static Integer count;

//NullPointerException on unboxing
if( count <= 0){
System.out.println("Count is not started yet");
}

缓存的对象

这个问题就是我们上面提到的极端情况,在Java中,会对-128到127的Integer对象进行缓存,当创建新的Integer对象时,如果符合这个这个范围,并且已有存在的相同值的对象,则返回这个对象,否则创建新的Integer对象。

在Java中另一个节省内存的例子就是字符串常量池,感兴趣的同学可以了解一下。

生成无用对象增加GC压力

因为自动装箱会隐式地创建对象,像前面提到的那样,如果在一个循环体中,会创建无用的中间对象,这样会增加GC(Garbage Collection,垃圾收集)压力,拉低程序的性能。所以在写循环时一定要注意代码,避免引入不必要的自动装箱操作。

总结


自动拆装箱机制的引入极大的方便了程序的编写,虽然同是也增加了一些问题,不过只要注意上述事项,就可以很好的使用自动拆装箱机制以及应对相关问题。

参考文章:javarevisited

评论

还有这种操作?—— eclipse 篇

概述


所谓工欲善其事必先利其器,用好一个开发工具,可以成倍的提高你的开发效率。所以接下来我就总结一下我在开发过程中常用的一些操作。好了,废话不多说,直接上干货。

代码高亮


开发工具是程序员们吃饭的家伙,基本上每天都要面对它,有一个赏心悦目的代码高亮能让你有更多的耐心去看代码,同时能提高你对代码的视觉识别能力,快速地发现想要的关键字。戳这个地址 Eclipse Color Themes 下载EPF配置文件。下载之后打开 eclipse,按照如下步骤进行操作。

  1. 点击【File】->【Import】。
    设置代码高亮一

  2. 选择【General】->【Preferences】->【Next】。
    设置代码高亮二

  3. 点击【Browse】选择刚才下载的 EPF 文件,点击【Finish】,到此为止,我们的代码高亮就设置好了。
    设置代码高亮三

代码自动补全


  1. 打开 eclipse,点击【Window】->【Preferences】。
    代码自动补全一
  2. 找到【Java】->【Editor】->【Content Assist】。
  3. 在右侧【Auto Activation】项目下找到【Auto activation delay (ms):】用于设置自动补全提示延迟,越低越好,根据自己的电脑性能进行设置。【Auto activation triggers for Java:】在这一项中添加想要触发自动补全的字母,如“.ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz”,注意前面的小点点不要丢。
    代码自动补全二

PS:添加了代码自动补全之后,会存在空格和等号也会自动补全的问题,如何关闭请参照下文操作。
关闭Eclipse按空格和等号键自动补全内容

常用快捷键


Ctrl+1 快速修复(这个东西谁用谁知道)
Ctrl+Shift+F:格式化代码(很常用的快捷键)
Ctrl+Shift+O:自动引入包和删除无用包
Ctrl+Z:回退(撤销)
Ctrl+Y:前进
Ctrl+D: 删除当前行
Ctrl+Q 定位到最后编辑的地方
Ctrl+L 定位在某行
Ctrl+/ 注释当前行
Ctrl+Shift+/:自动注释掉选择的代码块
Ctrl+Shift+X和Ctrl+Shift+Y:英文字母大小写的转换(SQL 语句编写和常量命名时长会需要用到大写,如果你不擅长编写大写字幕或者大小写切换影响效率,直接使用快捷键大大提高效率)
Ctrl+T 快速显示当前类的继承结构
Ctrl+O:快速 outline 视图
Alt+↓ 当前行和下面一行交互位置
Alt+↑ 当前行和上面一行交互位置(同上)
Alt+Shift+R 重命名(重构会经常用到)
以上仅为本人常用的一些快捷键,并不全面,更多请查看:参考链接

总结


相信看完这篇文章,你的 eclipse 使用效率应该会比以前有所提升了吧。文章还有不足之处,本人可能会持续更新自己的使用技巧。另外,本文如有不足之处,欢迎大家在评论区补充。

评论

八大排序算法(一)—— 直接插入排序

概述


本系列博客一共8篇,讲解常用的8种排序算法:直接插入排序、希尔排序(最小增量排序)、简单选择排序、堆排序、冒泡排序、快速排序、归并排序、分配排序(基数排序)。8种排序方式的基本关系如下图所示:排序算法基本关系

8种排序方式的时间复杂度、空间复杂度、稳定性等如下图所示:排序算法基本信息

本篇博客主要讲解直接插入排序算法的基本思想和Java代码实现。

基本思想


将一个记录插入到已经排好序的序列中。先将序列的第一个记录看作是有序的子序列,再把第二个记录与第一个记录进行比较,然后再进行插入操作,以此类推,不断循环,直到最后一个记录插入,整个序列的排序工作就完成了。
如下图所示,先将49作为第一个有序子序列,与后一个记录38进行比较,然后插入,形成新的子序列(38 49),再把后一个记录,插入新的子序列中,又形成新的子序列,直到最后一个记录49插入到序列中,排序完成:直接插入排序基本思想

##Java 代码实现:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
/**
* FileName:StraightInsertSort.java
* 创建一个直接插入排序类,实现一个直接插入排序方法和一个打印输出方法
* 直接插入排序:先将序列的第1个记录看成是一个有序的子序列,
* 再从第2个记录逐个进行插入,
* 直至整个序列有序为止
*
* @author kylezhang
* @date 2017/03/08
*
*
*/

public class StraightInsertSort {
public static void main(String[] args) {
//长度为10的数组
int[] c = new int[10];

Random rd = new Random(47);
//随机生成数组
for(int i = 0; i < c.length; i++) {
c[i] = rd.nextInt(10);
}

StraightInsertSort sis = new StraightInsertSort();
System.out.print("原序列:");
sis.print(c);
sis.straightInsertSort(c);
System.out.println();
System.out.print("排序后:");
sis.print(c);
}
/**
* 遍历数组,并打印输出
*
* @param a 需要打印输出的数组
*
*/

public void print(int a[]) {
for(int b : a) {
System.out.print(b + " ");
}
}
/**
* 实现直接插入排序操作
*
* @param a 需要进行直接插入排序操作的数组
*
*/

public void straightInsertSort(int a[]) {
//从第二个记录开始遍历数组,即 i = 1 处。
for(int i = 1; i < a.length; i++) {
//如果小于前一个记录,则插入到前一个记录前面,
//否则不用处理,直接插入前一个有序子数组的后面
if(a[i] < a[i-1]) {
int j;
int x; //用于插入
x = a[i];

//从后向前遍历前一个有序子数组
//,直到上一个有序子数组已经遍历完且
//找到合适的插入位置,跳出循环
for(j = i - 1; j >= 0 && x < a[j]; j--) {
a[j+1] = a[j]; //每次遍历都将数组后移一位
}
//当跳出循环时有两种可能,第一,当 a[j] >= x 时,
//则将 x 插入 a[j] 的后一个位置;第二,当 j < 0 时
//,此时上一个有序子数组已经遍历完,所有记录都大于
//需要插入的数,则直接将 x 插入到上一个数组的第一个
//位置。
a[j+1] = x;
}
}
}
}

运行结果


原序列:8 5 3 1 1 9 8 0 2 7
排序后:0 1 1 2 3 5 7 8 8 9

结果仅供参考,因为采用的随机数组,所以每个人运行的结果应该是不一样的。

总结


代码中的注释已经把代码解释的非常详细了,如果还有不理解的地方欢迎在文章下方评论或戳博客中的联系方式联系我。
注:以上解析均为个人理解,如有不妥或错误望指正。

评论

Java 吸血鬼数字(高效版详解)

先来看题


吸血鬼数字是指位数为偶数的数字,可以由一堆数字相乘而得到,而这对数字各包含乘积的一半位数的数字,其中从最初的数字中选取的数字可以任意排序。以两个0结尾的数字是不允许的,例如,下列数字都是“吸血鬼”数字:
1260 = 21 * 60
1827 = 21 * 87
2187 = 27 * 81
写出一个程序,找出4位数的所有吸血鬼数字。

再看代码


实现方法有很多种,我主要解析一下网上流传的不知是哪位大牛写的高效率版本。
代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
   public class VampireNum {
public static void main(String[] args) {
String[] ar_str1, ar_str2;
int sum = 0;
int from;
int to;
int i_val;
int count = 0;
//双重循环穷举
for (int i = 10; i < 100; i++) {
//j=i+1避免重复
from = Math.max(1000 / i, i + 1);
// to = Math.min(10000 / i, 100);
for (int j = from; j < 100; j++) {
i_val = i * j;
//如果对100取余等于0,则该4位数位数为00,不符合要求
//或i_val-i-j对9取余不等于0,也不符合要求
//不符合要求就从新开始循环,继续查找
if (i_val % 100 == 0 || (i_val - i - j) % 9 != 0) {
continue;
}
count++;
//将i_val转换成字符串,然后排序,并进行比较,如果比较结果相等,进行sum+1
ar_str1 = String.valueOf(i_val).split("");
ar_str2 = (String.valueOf(i) + String.valueOf(j)).split("");
Arrays.sort(ar_str1);
Arrays.sort(ar_str2);
if (Arrays.equals(ar_str1, ar_str2)) {
sum++;
System.out.println("第" + sum + "组: " + i + " * " + j + " = " + i_val);
}
}
}
System.out.println("共找到" + sum + "组吸血鬼数");
System.out.println(count);
}
}

运行结果


第1组: 15 * 93 = 1395
第2组: 21 * 60 = 1260
第3组: 21 * 87 = 1827
第4组: 27 * 81 = 2187
第5组: 30 * 51 = 1530
第6组: 35 * 41 = 1435
第7组: 80 * 86 = 6880
共找到7组吸血鬼数 232

解析


因:

吸血鬼数字是四位数的。

得出取值范围:

10 <= i < 100
10 <= j < 100
1000 <= i * j < 10000
1000 / i <= j < 10000/i

为避免重复,j 的起始值应等于 i + 1:

i + 1 < = j

1000 / i < i+1 时:

i +1 <= j

1000 / i > i+1 时:

1000/i <= j

所以区间最小值应该在 j + 11000 / i 中取最大值:

1
from = Math.max(1000 / i, i + 1);

j < 100j < 10000 / i

100 < 10000 / i 时:

j < 100

100 > 1000 / i 时:

j < 1000 / i

所以区间最大值应在 10010000 / i 中取最小值:

1
//			to = Math.min(10000 / i, 100);

为什么这句可以注销呢?

i < 100,所以100 永远小于 10000 / i。
得出:

j 始终小于 100。

再看看代码的主体算法部分:

1
i_val % 100 == 0 || (i_val - i - j) % 9 != 0

因:

末尾两位不能为0

所以能整除100的就过滤掉:

1
i_val % 100 == 0

假设:

i_val = 1000 * a + 100 * b + 10 * c + d
i_val = i * j
i = 10 * a + b
j = 10 * c + d

得出:

i_val - i - j = 990 * a + 99 * b = 9 * (110 * a + 11 * b)

所以 i_val - i - j 一定能被9整除,不能整除的就过滤掉:

1
(i_val - i - j) % 9 != 0

总结


从结果可以看出,该算法循环次数仅为232次,的确是非常高效率的一个精致的小算法,值得品味和学习。
注:以上解析均为个人理解,如有不妥或错误望指正。同时,有不理解的地方请评论或联系我。

评论

简洁强大的 Hexo 主题 Icarus

最近把博客主题更换为 icarus,作者是 PPOffice。这个主题界面简洁,具有分类、归档、导航等功能,非常适合博文较多的博主整理自己的博客。网上该主题的资料不多,github 上的文档又是纯英文的,所以我就翻译了搬运过来,供大家参考。

主题预览:

icarus预览图

正文


安装


1.在 Hexo 根目录下,输入指令克隆 Icarus 到 theme/icarus

1
2
$ git clone https://github.com/ppoffice/hexo-theme-icarus.git
themes/icarus

或 fork 本仓库,将其作为 git submodule 安装:

1
$ git submodule add https://github.com/<your-username>/hexo-theme-icarus.git themes/icarus

2.修改博客配置文件 _config.yml,将 theme 更换为 icarus 来启动主题:

1
theme: icarus

3.将主题文件夹中的 _config.yml.example 重命名为 _config.yml

4.(可选)别忘了检查最新版本:

1
2
$ cd themes/icarus
$ git pull

5.(可选)启动 Insight-Search 作为默认搜索,需要先安装 hexo-generator-json-content

1
$ npm install -S hexo-generator-json-content

配置


  • 主题

主题配置包括两部分:menucustomize

Menu


Menu

菜单(导航栏)可以直接找到主页,归档,目录,自定义页面等。你可以通过简单地添加菜单名和链接来设置导航栏:

1
2
3
4
menu:
Home: .
Archives: archives
+ GitHub: https://github.com

同时支持绝对地址和相对地址

如果你想启用 CategoriesTags,请把 _source/categories-source/tags 文件夹复制到博客根目录下的 source 文件夹中,然后到 _config.yml 中的 menu 选项里添加如下配置(About 同理):

1
2
3
4
5
menu:
Home: .
Archives: archives
+ Categories: categories
+ Tags: tags

Customize


自定义配置控制你的主题外观。

logo

你可以使用自定义图片替换默认 logo。widthheight 属性决定了 logo 的尺寸(in pixels),url 属性是 logo 图片的地址。你也可以通过设置 enabled: false 隐藏 logo。

1
2
3
4
5
logo:
enabled: true
width: 165
height: 60
url: images/logo-header.png

widthheight 属性仅支持纯数字。
即便 enabled: false 时,也请保留 widthheighturl属性值。

Profile

Profile图片

这里用来简单地展示你的个人信息。

1
2
3
4
5
6
7
8
profile:
enabled: true
avatar: css/images/avatar.png
gravatar:
author: PPOffice
author_title: Web Developer & Designer
location: Harbin, China
follow: https://github.com/ppoffice/

Highlight

highlight

Icarus支持超过60种代码高亮,从 Highlight.js 中导入。你可以从 icarus/source/css/_highlight 文件夹中查看可选选项。

Sidebar

改变 sidebar 的位置,可选的有 leftright

1
sidebar: left

Thumbnail(缩略图)

设置 turefalse 来开启或关闭该功能。

1
thumbnail: true

如何添加为文章添加一个缩略图?
front-matter 中添加 bannerthumbnail 属性。

1
2
3
title: Hello World
date: 2013/7/13 20:46:25
+ thumbnail: https://example.com/image.jpg

Favicon

给博客添加一个 favicon:

1
favicon: favicon.png

Social Links

社交链接

设置链接名和链接地址来添加社交链接,仅可使用由 Fontawesom 提供的图标(直接输入 Fontawesome 中的图标名再添加地址即可)。

1
2
3
social_links:
github: https://github.com/ppoffice/hexo-theme-icarus
+ youtube: https://youtube.com

确保链接地址不会空着,否则社交链接会失效。

  • 控件

Icarus 目前支持的控件:

1
2
3
4
5
6
7
widgets:
- recent_posts
- category
- archive
- tag
- tagcloud
- links

Recent Posts

在 sidebar(边条)上展示最近五篇文章。

Category

在 sidebar(边条)上展示目录。

Archive

在 sidebar(边条)上展示近几个月文章的归档。

Tag

在 sidebar(边条)上展示标签。

Tag Cloud

在 sidebar(边条)上展示标签云。

Links

在 sidebar(边条)上展示自定义链接。可以在 Miscellaneous Configurations 中设置自定义链接。

  • 搜索

Insight Search(笔者选用的是此搜索)

Insight Search

Esc 键关闭搜索框,通过 浏览搜素结果,Enter 键显示搜索结果

- links
1
insight: true

注意:需要先安装 hexo-generator-json-content 才能使用 Insight Search。

1
$ npm install -S hexo-generator-json-content

Swiftype(此搜索要收费)

Swiftype

先注册一个 Swiftype 账号。

1
swiftype: XXXXXXXXXXXXXXXXXXXX

install key 可以在下面的页面中找到:

install key

Baidu(主题作者不推荐)

添加这个就应该可以使用了。

1
baidu: true

  • 评论

Disqus

Disqus

先注册 Disqus 账号。再在配置中输入 shortname,shortname 可以在图中页面找到。

shortname

1
disqus: hexo-theme-icarus

Duoshuo(笔者使用的此评论)

Duoshuo

同样也是先注册 Duoshuo 账号,再输入 shortname。

Duoshuo

1
duoshuo: hexo-theme-icarus

  • 分享

分享按钮会在文章的末尾,评论框的上方显示。Icarus 提供几种分享插件,每一种都已经根据主题进行了风格的调整。

可选的有:

  • default
  • addtoany
  • jiathis
  • bdshare

Default

1
share: default

Default

AddToAny

1
share: addtoany

AddToAny

JiaThis

1
share: jiathis

JiaThis

Baidu Share(笔者使用的百度分享)

1
share: bdshare

bdshare

  • 插件

lightgallery

lightgallery.js 是一个全特性 JavaScript lightbox gallery ,不需要任何依赖。设置 true 来启用该功能。

lightgallery

1
lightgallery: true

Justified Gallery

Justified Gallery 是一个 JQuery 插件,它允许用户创建高质量的图片整理图库。设置 true 再在你的图片两边加上 <div class="justified-gallery"></div> 就能启用该功能。

Justified Gallery

1
justifiedgallery: true

Google Analytics(国内不是很方便,你懂的)
在配置中输入谷歌分析的 tracking ID 为你的站点启用谷歌提供的网站分析功能。在如下的页面中可以找到 tracking ID。

1
google_analytics: UA-66666666-6

tracking ID

Baidu Analytics(笔者使用的百度分析)

在配置中输入百度分析的 hash key 可以启用该功能。百度分析的 hash key 可以在 Get JS 框中找到。

1
baidu_analytics: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

hash key

  • 其它

Open Graph

关于 Open Graph:Open Graph protocol
可设置的选项:

1
2
3
4
5
open_graph:
fb_app_id:
fb_admins:
twitter_id:
google_plus:

Links

向 sidebar 添加友情链接。

1
2
links:
Hexo: http://hexo.io

  • 常见问题

如何修改站点的语言?

编辑博客根目录下的 _config.yml,进行如下更改:

1
2
- language: en
+ language: zh-CN

可以在 icarus/languages 文件夹下找到可使用的语言。

如何为文章添加摘要?
在文章中添加 <!-- more --> 标签,在上传内容前该标签会被标记为摘要。

为什么我的更改没有部署到 Github 页面上?
hexo deploy 之前,运行如下指令:

1
2
$ hexo clean
$ rm -r .deploy_git

怎么为指定文章、页面添加元标签(meta tags)?

通过 font-mater 为文章、页面添加 meta tags。

1
2
3
4
5
6
7
title: test post
date: 2015-01-26 21:55:37
tags:
comments: false
+ meta:
+ - name="robots";content="noindex, follow"
+ - name="another-meta";value="hello world";enabled=false

参考链接

hexo-theme-icarus
hexo博客换主题–icarus

评论

关于本博客

一、概述

本文只对博客的搭建过程,使用的主题等做一个大概的说明,不给出详细的教程,网上已经有很多很详细的教程了。同时,如果有什么问题,可以戳左边的个人信息联系我,或者在评论里留言。

二、搭建的过程

  1. 博客的搭建:hexo + github
  2. 博客的域名:使用学生证加入腾讯校园计划,免费使用一年“.cn”域名
  3. 博客的图床:七牛云,注册认证后每月赠送10G空间+10G免费流量
  4. 博客的主题:icarus,github 地址(我会抽空搬运并翻译该主题的使用方法)
  5. 博客的编写:Cmd Markdown 编辑器

综上,本博客的搭建几乎零基础、零成本(不过我免费一年的“.cn”域名快到期了),适合大多数人搭建,感兴趣的话可以试试。

三、博客的内容

本博客主要会分享一些我最近在研究的内容或者个人经历:

  • 数据结构和算法
  • Java 开发
  • Android 开发
  • 开发工具的详细使用教程(eclipse、 Android studio)
  • 搬运 github 上的一些优秀项目
  • 分享一些自己旅行的游记

暂时就先挖这些坑吧,慢慢填。

评论