每天学习一个命令:dd 读取转换输出数据

dd 命令可以复制文件并对原文件内容进行转换和格式处理。dd 命令经常被用来备份设备。

dd if=/dev/zero of=sun.txt bs=1M count=1

解释:

  • if 输入文件,不指定从 stdin
  • of 输出文件,不指定默认 stdout 作为默认输出
  • bs 字节为单位的块大小
  • count 表示被复制的块

几个设备:

  • /dev/null 向其输入任何内容都会被吞掉
  • /dev/zero 输入设备,用来初始化文件,提供无穷的 0.

使用实例

注意: 运行 dd 命令需要非常小心,如下命令如果不清楚其含义请千万不要轻易尝试。

测试硬盘读写速度

dd if=/dev/zero bs=1024 count=1000000 of=/root/1Gb.file

备份整块磁盘

将整块磁盘 /dev/sda 备份到 /dev/sdb,注意 sdb 上的数据将会被覆盖!!!

dd if=/dev/sda of=/dev/sdb bs=4M

创建空文件

创建一个 512M 大小的空文件

dd if=/dev/zero of=/path/to/file count=1024 bs=500000

销毁磁盘数据

利用随机数据填充磁盘,用以销毁数据

dd if=/dev/urandom of=/dev/sda1

全盘数据备份与恢复

备份

dd if=/dev/sda of=/root/sda.img

恢复镜像到指定盘

dd if=/root/sda.img of=/dev/sda

使用 gzip 压缩备份

dd if=/dev/sda | gzip > /root/image.gz

将压缩文件恢复

gzip -dc /root/image.gz | dd of=/dev/sda

2014-05-26 dd , linux , command

Jekyll 修改全纪录

对于本博客的 Jekyll 修改全纪录

Rakefile 修改

增加中文拼音支持 参考:

自动隐藏 Bootstrap 导航条

开源项目 Github

404 页面

参考:

http://yizeng.me/2013/05/26/create-a-custom-jekyll-404-page/


2014-05-25 jekyll , rankfile

使用 dnsmasq 转发 dns 请求

首先,什么是 dnsmasq,从官方页面,或者 WikiPedia 上能知道,dnsmasq 可以提供 DNS Forward, 可以作为 DHCP, 它被设计在低功耗,小内存的路由器,防火墙等小型设备上使用。现在的大部分 Linux 发行版都内置了 dnsmasq . dnsmasq 也常常被用来缓存 DNS 请求,用来加速访问过的地址速度。

DNS

使用 dnsmasq 很大一部分应用场景就是缓存 DNS 解析,dnsmasq 首先会检查 /etc/hosts 等本地静态的 hosts 文件,然后使用 /etc/resolv.conf 配置的 DNS 服务器地址。

配置

通常 dnsmasq 的配置文件都在 /etc/dnsmasq.conf 文件中,该文件配置详细内容可以参考如下注释。

这里主要配置 dnsmasq 作为 DNS Cache 服务器来使用。

# 配置额外的上级 DNS 主机 (nameserver)
# 通常会在定义的文件中配置域名服务器地址 nameserver 127.0.0.53
# 如果访问没有被解析过的域名,那么就会尝试使用文件中定义的地址去解析
resolv-file=/etc/resolv.conf

# 默认情况下 Dnsmasq 会发送查询到它的任何上游 DNS 服务器上,如果取消注释,则 Dnsmasq 则会严格按照 /etc/resolv.conf 中定义的 DNS Server 顺序进行查询,直到成功为止
# strict-order

# 如果不想 Dnsmasq 读取 /etc/resolv.conf 文件获得它的上级 servers。即不使用上级 DNS 主机配置文件 (/etc/resolv.conf 和 resolv-file)可以开启改选项
#no-resolv

# 不允许 Dnsmasq 通过轮询 /etc/resolv.conf 或者其他文件来获取配置的改变,则取消注释。
#no-poll
# 向上游所有服务器查询
all-servers
# 启用转发循环检测
dns-loop-detect
# 重启后清空缓存
clear-on-reload
# 完整域名才向上游服务器查询,如果是主机名仅查找 hosts 文件
domain-needed

# 为特定的域名指定解析它专用的 nameserver。一般是内部 dns name server
# server=/myserver.com/192.168.55.1

# 指定 dnsmasq 默认查询的上游服务器,此处以 Google Public DNS 为例。
server=8.8.8.8
server=8.8.4.4

# 比如把所有.cn 的域名全部通过 114.114.114.114 这台国内 DNS 服务器来解析
server=/cn/114.114.114.114
server=/taobao.com/114.114.114.114
server=/jd.com/114.114.114.114
server=/qq.com/114.114.114.114


# no-hosts, 默认情况下这是注释掉的,dnsmasq 会首先寻找本地的 hosts 文件,再去寻找缓存下来的域名,最后去上级 dns 服务器中寻找;而 addn-hosts 可以使用额外的 hosts 文件。
# DNS 解析 hosts 时对应的 hosts 文件,对应 no-hosts
addn-hosts=/etc/hosts
# DNS 缓存大小,DNS 解析条数
cache-size=1024
# 不缓存未知域名缓存,默认情况下 dnsmasq 会缓存未知域名并直接返回客户端
no-negcache
# 指定 DNS 同时查询转发数量
dns-forward-max=1000

# 增加一个域名,强制解析到所指定的地址上,强行指定 domain 的 IP 地址
address=/doubleclick.net/127.0.0.1
# 知道这个原理之后,比如说可以屏蔽广告,把地址解析到一个本地地址
address=/ad.youku.com/127.0.0.1
address=/ad.iqiyi.com/127.0.0.1


# 多个 IP 用逗号分隔,192.168.x.x 表示本机的 ip 地址,只有 127.0.0.1 的时候表示只有本机可以访问。
# 通过这个设置就可以实现同一局域网内的设备,通过把网络 DNS 设置为本机 IP 从而实现局域网范围内的 DNS 泛解析(注:无效 IP 有可能导至服务无法启动)
# 监听的服务器地址,通过该地址提供服务
listen-address=192.168.x.x,127.0.0.1

# 对于新添加的接口不进行绑定。仅 Linux 系统支持,其他系统等同于 bind-interfaces 选项。
# bind-dynamic

# hosts 中主机有多个 IP 地址,仅返回对应子网的 IP
localise-queries

# 如果反向查找的是私有地址例如  192.168.x.x,仅从 hosts 文件查找,不转发到上游服务器
bogus-priv

# 对于任何解析到该 IP 的域名,将响应 NXDOMAIN 使得其解析失效,可多次指定
# 禁止跳转运营商广告站点
#bogus-nxdomain=64.xx.xx.xx

# 如果你想在某个端口只提供 dns 服务,则可以进行配置禁止 dhcp 服务
no-dhcp-interface=

配置完成后,可以使用如下语法来检查正确性

dnsmasq --test

如果没有问题会输出 dnsmasq: syntax check OK.

管理 dnsmasq 服务

在 Debian/Ubuntu 系电脑上可以使用:

sudo systemctl status dnsmasq.service
# or
sudo /etc/init.d/dnsmasq status

查询

使用 nslookup 或者 dig 来查询 DNS 解析结果。

比如向 Google 提供的 DNS 服务器请求查询 einverne.info 域名的解析结果:

➜ dig einverne.info @8.8.8.8

; <<>> DiG 9.11.3-1ubuntu1.9-Ubuntu <<>> einverne.info @8.8.8.8
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 53970
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;einverne.info.                 IN      A

;; ANSWER SECTION:
einverne.info.          2398    IN      A       69.163.x.x

;; Query time: 4 msec
;; SERVER: 8.8.8.8#53(8.8.8.8)
;; WHEN: Fri Sep 20 16:26:54 CST 2019
;; MSG SIZE  rcvd: 47

在 dig 的结果中可以看到一个 Query time, 连续查询某一个域名两次,可以观察该时间是否从之前的几十或者几百毫秒,变成 0 毫秒,由此来判断 dnsmasq 有没有生效。

或者直接 nslookup

➜ nslookup youtube.com
Server:         127.0.0.53
Address:        127.0.0.53#53

Non-authoritative answer:
Name:   youtube.com
Address: 2.1.1.2

DHCP

DHCP 配置

dnsmasq 配置文件 (/etc/dnsmasq.conf),必要的配置如下:

# 选定需要侦听的网口
# Only listen to routers' LAN NIC.  Doing so opens up tcp/udp port 53 to
# localhost and udp port 67 to world:
interface=<LAN-NIC>

# dnsmasq will open tcp/udp port 53 and udp port 67 to world to help with
# dynamic interfaces (assigning dynamic ips). Dnsmasq will discard world
# requests to them, but the paranoid might like to close them and let the
# kernel handle them:
bind-interfaces

#设定可分配的 ip 地址段和租约时间
# Dynamic range of IPs to make available to LAN pc
dhcp-range=192.168.1.50,192.168.1.100,12h

#绑定某些机器的 ip-mac 地址对,使其具有固定的 ip 地址
# If you’d like to have dnsmasq assign static IPs, bind the LAN computer's
# NIC MAC address:
dhcp-host=aa:bb:cc:dd:ee:ff,192.168.1.50
dhcp-host=00:0e:7b:ca:1c:6e,daunbook,192.168.0.12
#为 192.168.0.12 设置主机名:dannbook

# dhcp 动态分配的地址范围
dhcp-range=192.168.2.100,192.168.2.240,24h

# 同上,不过给出了掩码
#dhcp-range=192.168.2.100,192.168.2.240,255.255.255.0,12h

# dhcp 服务的静态绑定
# dhcp-host=08:00:27:D1:CF:E2,192.168.8.201,infinite 无限租期
dhcp-host=08:00:27:D1:CF:E2,192.168.2.201,db2
dhcp-host=08:00:27:D6:F0:9F,192.168.2.202,db3

# 设置默认租期
# Set the limit on DHCP leases, the default is 150
#dhcp-lease-max=150

# 租约保存文件路径
#dhcp-leasefile=/var/lib/dnsmasq/dnsmasq.leases

# 通过 /etc/hosts 来分配对应的 hostname
#dhcp-host=judge

# 忽略下面 MAC 地址的 DHCP 请求
#dhcp-host=11:22:33:44:55:66,ignore

# dhcp 所在的 domain
domain=freeoa.net

# 设置默认路由出口
# dhcp-option 遵循 RFC 2132(Options and BOOTP Vendor Extensions), 可以通过 dnsmasq --help dhcp 来查看具体的配置
# 很多高级的配置,如 iSCSI 连接配置等同样可以由 RFC 2132 定义的 dhcp-option 中给出。
# option 3 为 default route
dhcp-option=3,192.168.8.1

# 设置 NTP Server. 这是使用 option name 而非选项名来进行设置
#dhcp-option=option:ntp-server,192.168.8.4,10.10.0.5

reference


2014-05-02 dns , dnsmasq , domain , network

Vim 中 buffer 操作及管理

通常情况下工作的内容都会是打开一个文件进行编辑,但是 Vim 的强大之处不仅在于单文件编辑,更重要的是可以对多文件编辑,这些文件可以存在不同的 Tab 中,不同的 Windows 中,甚至不同的 buffer 中,这一篇主要就是集中整理一下 buffer 相关的操作内容。

A buffer is an area of Vim’s memory used to hold text read from a file. In addition, an empty buffer with no associated file can be created to allow the entry of text. –vim.wikia

Vim 中的 Buffer 是打开的文件,这意味着 Buffer 可能并不是当前可见的,Buffers 是 Vim 打开,存在于内存某个地方。通常只有一个 Buffer 可见。可以使用 :ls 来查看当前打开的 Buffers.

Vim 中的 Windows 是一个 viewport onto a single buffer,可以通过 :spit 或者 :vsplit 来水平或者垂直打开文件。

Vim 中的 Tab 是 collection of one or more windows. 可以允许用户来组织 Windows.

Buffer 创建

通常情况下 vim file1 file2 便是将两个文件放到了 buffer 中。

  • :e /path/to/file 也可以打开文件到 buffer 中
  • :new:vnew
  • :badd {filename} 添加到缓冲区,光标保持在当前缓冲

buffer delete

移除缓冲区

:bd[elete]
:bunload
:bwipeout
:3,5bdelete
:bd file1

如果未保存会退出失败,强行退出

:bd!

删除缓冲区并不会影响缓冲区关联的文件,只是简单地把文件从内存中删除。

:bd2

:bd2 会将第二个 Buffer 从内存中移除。

buffer navigation

使用 Ctrl + ^ 可以来在最近的缓冲去中切换。这个快捷键非常有用,得记住。可以使用如下命令来列出所有缓冲区:

:ls, :buffers          " 列出所有缓冲区

在展示的列表中有一些 buffer 的状态:

  • - 非活动的缓冲区
  • a 光标所在缓冲区
  • h 隐藏缓冲区
  • % 当前的缓冲区
  • # 交换缓冲区, 可以使用 Ctrl + ^
  • = 只读缓冲区
  • + 已经更改的缓冲区

切换缓冲区:

:bn[ext]
:bp[revious]
:b {number, bufname}
:bfirst
:blast

说明:

  • :b <Tab> “ 循环滚动 buffer 中的文件

假如在后面对 vim 了解更多之后,安装了 fzf-vim 插件,那么也可以直接使用 :Buffers 来模糊查找当前打开的 Buffers.

buffer 替换

在打开的所有 buffer 中替换操作:

:bufdo %s/pattern/replace/ge | update

2014-05-01 vim , buffer , vim-buffer

每天学习一个命令:top 查看资源占用

top 命令能够实时显示系统中各个进程资源占用情况。可以用它来快速排查系统性能问题。

先行概念

  • 用户空间,常规进程所在空间,用户空间非特权区域,不能直接访问硬件设备
  • 内核空间,操作系统所在空间,能与设备控制器通讯,控制用户区域进程运行状态

使用举例

直接使用

默认进入 top 时,各进程是按照 CPU 的占用量来排序的:

top

解释:

  • 第一行,系统时间,已运行天数,登录用户数,1 分钟,5 分钟,15 分钟负载
  • 第二行,运行任务数
  • 第三行,CPU 运行状态
    • us 用户空间占用 CPU 百分比
    • sy 内核空间占用 CPU 百分比
    • ni 改变过优先级的进程占用 CPU 百分比
    • id 空闲 CPU 百分比
    • wa IO 等待占用 CPU 的百分比
    • hi 硬中断(Hardware IRQ)占用 CPU 的百分比
    • si 软中断(Software Interrupts)占用 CPU 的百分比
  • 第四行,内存使用
    • total 全部物理内存
    • free 空闲内存
    • used 已使用内存
    • buff/cache 缓存内存
  • 第五行,swap 交换分区信息
  • 第六行,空行
  • 第七行及以下,各进程的运行状态

第七行信息,包括:

  • PID
  • USER
  • PR 进程优先级
  • NI 负值表示高优先级
  • VIRT 进程使用的虚拟内存总量,单位 kb。VIRT=SWAP+RES
  • RES 进程使用的、未被换出的物理内存大小,单位 kb。RES=CODE+DATA
  • SHR 共享内存大小,单位 kb
  • S 进程状态,D= 不可中断的睡眠状态;R= 运行;S= 睡眠;T= 跟踪 / 停止;Z= 僵尸进程
  • %CPU 上次更新到现在的 CPU 时间占用百分比
  • %MEM 进程使用的物理内存百分比
  • TIME+ 进程使用的 CPU 时间总计,单位 1/100 秒
  • COMMAND 进程名

查看每个 CPU 状态

在交互状态下按下 1 展开,查看每个 CPU 情况。

改变排序规则

按下 Shift + < 或者 > 来改变排序规则。

显示完整命令:

top -c

显示指定进程信息

top -p 12002

交互命令

  • h 显示帮助
  • c 切换名字与完整路径
  • m 切换内存显示方式
  • i 忽略闲置和僵死进程
  • r 重新设置进程优先级别
  • P CPU 使用百分比排序

2014-04-27 top , linux , command , io , cpu , memory

Linux 常见目录结构说明

主要总结 Linux 下常用的目录,主要是为了学习 Linux, 以及了解各个目录的作用,以便于方便的管理 Linux 下的配置以及文件。绝大多数的 Unix-like 操作系统都遵循 Filesystem Hierarchy Standard 这个标准,这个标准规定了哪些目录作为什么功能,存放一些什么内容。

什么是文件系统

了解 Linux 文件系统的目录结构,是学好 Linux 的至关重要的一步。

当您使用 Linux 的时候,如果您通过 ls -l / 查询根目录结构,就会发现,根目录下包含了很多的目录,比如 etc、usr、var、bin 等等,而在这些目录中,也有很多的目录或文件。文件系统在 Linux 下看上去就象树形结构,所以我们可以把文件系统的结构形象的称为树形结构。

Linux 文件系统的最顶端是 /,我们称 / 为 Linux 的 root,也就是 Linux 操作系统的文件系统。Linux 的文件系统的入口就是 /,所有的目录、文件、设备都在 / 之下,/ 就是 Linux 文件系统的组织者,也是最上级的领导者。

文件系统的类型

Linux 有四种基本文件系统类型:

  • 普通文件:比如文本文件、C 语言源代码、SHELL 脚本、二进制的可执行文件等,可用 cat、less、more、vi、emacs 来察看内容
  • 目录文件:包括文件名、子目录名及其指针。它是 Linux 储存文件名的唯一地方,可用 ls 列出目录文件时,用 d 来标识
  • 连接文件:指向同一索引节点的那些目录条目。可以使用 ln 来创建,用 ls 来查看时,连接文件会用 l 来标识,而文件面后以”->”指向所连接的文件。
  • 特殊文件:Linux 的一些设备如磁盘、终端、打印机等都在文件系统中表示出来,这类文件就是特殊文件,常放在 /dev 目录内,Linux 使用类似于 /dev/sda1, /dev/sda2 这样的方式来表示磁盘分区

文件类型可以用 file 命令来识别。

Linux 文件系统的目录结构

/ 是 Linux 文件系统的入口,目录树的根节点。

  • /bin 系统所需的命令,比如 ls、cp、mkdir 等命令,该目录中包含单用户模式下所有可执行的文件,功能和 /usr/bin 类似,这个目录中的文件都是可执行的、普通用户都可以使用的命令。作为基础系统所需要的最基础的命令就是放在这里
  • /dev 设备文件存储目录,比如磁盘,光驱…
  • /boot Linux 的内核及引导系统程序所需要的文件目录,比如 vmlinuz initrd.img 文件都位于这个目录中。在一般情况下,GRUB 或 LILO 系统引导管理器也位于这个目录
  • /etc 系统配置文件所在地
  • /home 普通用户目录默认存放目录,不同用户会在该目录下有对应用户名的子目录,保存用户个人文件以及个人配置
  • /lib 库文件存放目录,一般用来存放给 /bin 或者 /sbin 目录下可执行文件的依赖库
  • /mnt 临时挂载点,这个目录一般是用于存放挂载储存设备的挂载目录的,比如有 cdrom 等目录。可以参看 /etc/fstab 的定义。有时我们可以把让系统开机自动挂载文件系统,把挂载点放在这里也是可以的。主要看 /etc/fstab 中怎么定义了;比如光驱可以挂载到 /mnt/cdrom 。
  • /opt 表示的是可选择的意思,有些软件包也会被安装在这里,也就是自定义软件包,比如在 Fedora Core 5.0 中,OpenOffice 就是安装在这里。有些我们自己编译的软件包,就可以安装在这个目录中;通过源码包安装的软件,可以通过 ./configure –prefix=/opt/ 目录
  • /proc 操作系统运行时,进程信息及内核信息(比如 cpu、硬盘分区、内存信息等)存放在这里。/proc 目录伪装的文件系统 proc 的挂载目录,proc 并不是真正的文件系统,它的定义可以参见 /etc/fstab
  • /root 超级权限用户 root 的家目录
  • /sbin 大多是系统管理的命令的存放位置,是超级权限用户 root 的可执行命令存放地,普通用户无权限执行这个目录下的命令,这个目录和 /usr/sbin; /usr/X11R6/sbin 或 /usr/local/sbin 目录是相似的;我们记住凡是目录 sbin 中包含的都是 root 权限才能执行的。
  • /usr 是系统存放程序的目录,比如命令、帮助文件等。这个目录下有很多的文件和目录。当我们安装一个 Linux 发行版官方提供的软件包时,大多安装在这里。如果有涉及服务器配置文件的,会把配置文件安装在 /etc 目录中。/usr 目录下包括涉及字体目录 /usr/share/fonts ,帮助目录 /usr/share/man 或 /usr/share/doc,普通用户可执行文件目录 /usr/bin 或 /usr/local/bin 或 /usr/X11R6/bin ,超级权限用户 root 的可执行命令存放目录,比如 /usr/sbin 或 /usr/X11R6/sbin 或 /usr/local/sbin 等;还有程序的头文件存放目录 /usr/include。
  • /var 目录存放经常变化的内容
  • /lost+found 在 ext2 或 ext3 文件系统中,当系统意外崩溃或机器意外关机,而产生一些文件碎片放在这里。当系统启动的过程中 fsck 工具会检查这里,并修复已经损坏的文件系统。有时系统发生问题,有很多的文件被移到这个目录中,可能会用手工的方式来修复,或移到文件到原来的位置上
  • /tmp 临时文件目录,有时用户运行程序的时候,会产生临时文件。/tmp 就用来存放临时文件的。/var/tmp 目录和这个目录相似

root

开机过程中仅有根目录会被挂载, 其他分区则是在开机完成之后才会持续的进行挂载的行为。

  • /etc:配置文件
  • /bin:重要执行档
  • /dev:所需要的装置文件
  • /lib:执行档所需的函式库与核心所需的模块
  • /sbin:重要的系统执行文件

以上目录不可与根目录分开在不同的分区。

usr

包含 multi-user 可以使用的工具和应用。

  • /usr/bin 所有用户都能使用的二进制可执行文件
  • /usr/lib/usr/bin/usr/sbin 的库文件
  • /usr/sbin 非必须的系统二进制文件
  • /usr/local 这台机器使用的本地文件,一般也有bin, lib, share 等几个目录

etc

/etc 目录用来存放系统及应用配置文件。

  • /etc/opt 附加包的配置信息存放地
  • /etc/X11 X Window System, version 11 配置文件存放地
  • /etc/passwd 系统用户名

其他插件的软件一般会在 /etc 目录下新建一个以自己名字命名的文件夹并将自己的配置文件放在其中,比如 /etc/nginx, /etc/mysql, /etc/redis 等等。

var

/var 该目录用来存放经常会发生变化的数据,程序运行中的数据存放地,比如系统日志、邮件内容、网站内容等,/varvariable 的缩写。

  • /var/log 用来存放系统日志
  • /var/www 存放 Apache/Nginx 服务器内容
  • /var/mail存放邮箱内容
  • /var/lib 用来存放一些库文件,比如程序运行时的持久化内容
  • /var/run 某些程序或者服务启动后会将 PID 存放于此
  • /var/spool 队列数据,这些数据经常在使用后被删除,比如 crontab 数据就在该目录

2014-04-26 linux , dir-structure , file-system , command

Visual Assist And Eclipse使用doxygen注释

##修改Visual Assist中的方法注释样式

Visual Assist生成的方法注释又长又丑有木有?那就简单修改一下吧~

  • 如下面的两张图所示,打开在Visual Assist的选项卡,按图中标示顺序打开Refactor Document Method脚本,就可以按照自己喜欢的风格修改了~不同版本的Visual Assist中设置的路径可能不一样,总之都在Suggestions选项卡下。
  • 可用的宏可以点左上角最后一个图标查看,意思看名字就能推断出来了~
  • 是不是还想来个快捷键什么的,在想要注释的函数定义上方敲 /** 回车就行

visual assist 1

visual assist 2

###Eclipse中使用doxygen注释C++方法 修改一下选项就可以了~然后在要注释的方法的上一行输入 /** 按回车即可. enter image description here

参考: http://cherishlc.iteye.com/blog/1777034


2014-04-25 doxygen , Visual Studio , Eclipse

Java 字节码 类文件结构

Java 文件编译后会生成 .class 二进制文件,这个文件以 8 字节为单元组织。在 Class 文件中定义了一些数据类型,u1,u2,u4,u8 分别代表 1 个字节、2 个字节、4 个字节、8 个字节的无符号数。

Class 文件像一张大表格,以一定的格式记录。

ClassFile
{
	 magic_number;
	 minor_version;
	 major_version;
	 constant_pool_count;
	 constant_pool[];
	 access_flags;
	 this_class;
	 super_class;
	 interfaces_count;
	 interfaces[];
	 fields_count;
	 fields[];
	 methods_count;
	 methods[];
	 attributes_count;
	 attributes[];
}

Magic Number

每个 Class 文件头 4 个字节称为 Magic Number,用于确认该文件是否能被虚拟机接受。

java class magic number

Class 文件的 Magic Number 是 0xCAFEBABE .

apt install ghex

Class 版本

接着 Magic Number 后面 4 个字节就是 Class 文件的版本号

  • 第 5,6 个字节是次版本号 Minor Version
  • 第 7,8 个字节是主版本号 Major Version

Java 版本号从 45 开始,JDK 1.1 后每个 JDK 大版本发布主版本加 1,高版本的 JDK 向下兼容以前的 Class 文件,但不能运行以后的版本。

看到上图里面,5,6 个字节 0x0000,主版本号 0x0033,就是十进制的 51,说明这个 Class 文件可以被 JDK 1.7 或者以上版本虚拟机执行。

常量值 constant_pool

在主版本号后面是常量池入口,所有的变量,方法都会在该常量池有一份引用。因为常量值数量不固定,所以常量值入口会放置 u2 类型数据,表示常量池容量计数 constant_pool_count ,这个容量计数是从 1 开始。

常量池主要存放两大类常量:

  • 字面值 Literial
  • 符号引用 Symbolic References , 包含

      - 类和接口的全限定名 Fully Qualified Name
      - 字段名和描述符 Descriptor
      - 方法的名称和描述符
    

常量池中每一项都是一个表

第一位是 u1 类型标志位,取值 1 到 12,缺少标志为 2 的数据类型,该标志表示当前常量属于哪种类型。

类型 标志 描述
CONSTANT_Utf8_info 1 UTF-8 编码字符串
CONSTANT_Integer_info 3 整型字面值
CONSTANT_Float_info 4 浮点
CONSTANT_Long_info 5 长整型
CONSTANT_Double_info 6 双精度浮点
CONSTANT_Class_info 7 类或者接口符号引用
CONSTANT_String_info 8 字符串类型
CONSTANT_Fieldref_info 9 字符的符号引用
CONSTANT_Methodref_info 10 类中方法的符号引用
CONSTANT_InterfaceMethodref_info 11 接口中方法的符号引用
CONSTANT_NameAndType_info 12 字段或方法的部分符号引用

如果看二进制的 Class 文件比较麻烦,JDK 中提供了了分析 Class 文件字节码的工具:javap

javap -verbose filename.class

可以看到类似如下的内容:

Constant pool:
   #1 = Methodref          #11.#36        // java/lang/Object."<init>":()V
   #2 = Fieldref           #37.#38        // java/lang/System.out:Ljava/io/PrintStream;
   #3 = String             #39            // hello
   #4 = Methodref          #40.#41        // java/io/PrintStream.println:(Ljava/lang/String;)V

访问标志 access flags

常量池结束后接 2 字节代表访问标志 access_flag. 用于识别类或接口层次的访问信息,包括 Class 是类还是接口,是否定义为 public,是否定义为 abstract 类型,类是否被声明为 final .

类索引 this_class 父索引 super_class 接口索引 interfaces

Class 文件由这个三个数据来确定类的继承关系。

  • 类索引确定类的全限定名
  • 父类索引确定这个父类的全限定名,除 java.lang.Object 外,所有 Java 类的父类索引都不是 0
  • 接口索引描述类实现了哪些接口,按照实现的顺序排列

类索引、父类索引和接口索引都按照顺序排列在访问标志后,类索引和父类索引用两个 u2 类型索引值表示,各自指向 CONSTANT_Class_info 的类描述符常量,通过 CONSTANT_Class_info 类型的常量中的索引值来找到定义在 CONSTANT_Utf8_info 类型的常量中的全限定名字符串。

接口索引,入口是 u2 类型数据的接口计数 interfaces_count ,表示索引表容量,如果没有实现任何接口,则计数器为 0。

字段表集合 field info

用于描述接口或者类中声明的变量,包括类级变量或者实例级变量,但不包括方法内部声明变量。

  • 字段作用域 public private protected
  • 类级变量还是实例变量 static
  • 可变性 final
  • 并发可见性 volatile,是否强制从主存读写
  • 可否序列化 transient
  • 字段基本类型,对象,数组
  • 字段名称

方法表集合

方法表结构和字段表相同,依次包括了访问标志 access flags, 名称索引 name index, 描述符索引 descriptor index , 属性表集合 attributes

属性表集合 attribute info

与 Class 文件中其他数据项目要求严格的顺序、长度和内容不同,属性表集合限制宽松,不要求属性表具有严格顺序,只要不与已有的属性名重复,任何人实现的编译器都可以向属性中写入自己定义的属性信息,Java 虚拟机在运行时会忽略掉它不认识的属性。


2014-04-05 java , class , cross-platform , bytecode

CPU知识

###步进 所谓步进:同一处理器型号随着时间推移,会有一些小的改进,厂商把这些小的改进通过新的步进来体现。 (通过汉语意思理解:就是与之前相比进了一小步,针对同一型号) 酷睿 i3/i5全线将从C2步进转换到K0,预计在品质等诸多方面比上一个步进要更加出色。 现在知道了吧,不用去关注它,只要知道是处理器在架构或者其他方面提高了就行。 步进更多的知识详见百度百科,里面讲到了用CPU-z识别当前使用的CPU的步进信息,如何通过编码知道步进信息。

###CPU各版本信息 ####ES 测试版CPU,发给制造商用于各类测试的版本,因为不是免费提供,intel无法回收CPU,测试结束以后部分CPU会流入市场,该类CPU如要购买最好先搜一下看看ES版是否存在一些BUG

####QS 最后一个版本的ES,一般用工具检测,固件烧录的也是ES,用于区分正式版

####BGA、PGA

BGA和PGA是intel的两种封装类型,BGA没有阵脚,直接焊在主板上,PGA带有阵脚,可以插在socket插座上使用,一些JS把BGA的CPU拆掉私自焊针脚来销售,稳定性极差,价格要低很多,温度要高一些,BGA和PGA无法用软件区分,只能拆开自己检查

引用:低电压板,L,SP,SU开头的型号,基本都是bga的 引用:http://www.xj123.info/1717.html

###CPU后面跟随的数字 I3 后面有四个数字 拿I3 3220为例, 第一个3就是第三代,所以2100就是第二代,530(三个数字)就是第一代 第二个2就是规格,一般取比第一个数字小1的数字,比如第一个是4,后面就是3,如果小于3,那就是进一步降低主频或删减缓存的缩水货。 第三个2就是等级,档次,越高越好。 最后一个0只是加上去为了英语发音好读。

I5也是一样,比如I5 3570K 第一个数字3代表第三代,第二个数字固定为5,小于5的就是精简过规格的产品,第三个是等级。

另外关于第二个数字还有一个小秘密,一般3以下都是I3(也有双核I5,很少),3-5是I5,6-9是I7。 引用:http://zhidao.baidu.com/question/573950249.html


2014-03-13

Android SDK环境变量配置

Android SDK就是Google提供的Android开发工具包,之前请先配置好JDK

###Android SDK下载地址

  • Google搜索Android SDK
  • 或者https://developer.android.com/sdk/index.html

###配置Android SDK环境变量

  1. 下载Android SDK,点击安装,直接默认路径即可! 下载地址:https://developer.android.com/sdk/index.html

  2. 默认路径安装后,安装完成,开始配置环境变量。

  3. 打开计算机属性——高级系统设置——环境变量(如上文)

  4. 新建一个环境变量,变量名:ANDROID_HOME,变量值:D:\Android\android-sdk(以你安装目录为准,确认里面有tools和add-ons等多个文件夹),点击确认。

  5. 在用户变量PATH后面加上变量值;%ANDROID_HOME%\platform-tools;%ANDROID_HOME%\tools;点击确认即可

  6. Android SDK配置完成,接下来验证配置是否成功。

  7. 点击运行——输入cmd——回车——输入adb——回车,如果出现一堆英文,即表示配置成功,输入Android,启动Android SDK Manager。

###目录tools和platform-tools的区别

Android sdk目录里,有一些文件夹:

  • tools:该目录存放大量的Android开发,调试工具,该目录下存放大量Android开发工具,例如SDK Manager、androidavd、emulator、ddms等等。
  • platforms-tools:该文件夹存放Android平台和相关工具,存放Android不同平台的相关工具;随着SDK更新版本,这里的工具会有相应更新变化,但是一般都是向后兼容。最常用的是Android Debug Bridge(adb)工具
  • add-ons:该目录存放额外的附件软件。刚解压时该目录为空。
  • platforms:该目录存放不同版本的Android版本。刚解压时该目录为空。
  • SDK Manager.exe:该程序就是Andriod SDK管理器。
  • AVD Manager.exe:该程序就是Andoid虚拟设备。
  • docs:该文件夹存放了Android SDK开发文件和API文档等
  • samples:该文件夹存放不同的Android平台和示例程序。

参考:http://blog.csdn.net/rflyee/article/details/8973529


2014-03-04 Android , JDK

电子书

最近文章

  • 使用 assh 来管理 SSH config 前两天一直在思考如何管理我的 SSH config 配置,最后的解决办法就是通过 git 版本管理起来。但这两天由冒出一个新的问题,那就是经常在国内直连 aws 或者 oracle 的机器时 ssh 连不上,但是通过国内的 VPS 中转就非常快,那这就意味着,我每一次连接国外的机器时必须先登录腾讯云的机器,然后在从腾讯云的机器上连过去,有些麻烦,但那天在 Twitter 上看到有人分享了一个 SSH 管理的命令行工具 assh,大致的看了一下使用简介,通过配置就可以完美的解决这个问题。
  • 备份和恢复从 Chrome Webstore 中下架的 Google Chrome Extension 这两天重装系统同步 Chrome 的数据才发现,我一直使用的 Dream Afar New Tab 这个我用了很久的扩展从 Chrome Webstore 消失了,不清楚是 Google 主动下架,还是作者很久没有更新被 Webstore 下了还是为什么。但这个扩展经过了很多的 Chrome 版本依然运行良好至今为止都能每天给我提供世界不同地方的美景。
  • Docker 网络与容器互联 简单整理一下 Docker 中 network 子命令,以及 docker 中相关 network 方面的内容。
  • MacBook Pro 初始设置记录 这里就简单的记录一下我从 Linux Mint 迁移到 MacOS 根据我的个人需求来初始化新的 MacBook Pro 的一些设置,和一些基本的感想。下面的内容会按照我自身的需求出发,我会列举我想要的功能然后在此基础上我需要借助哪些工具来实现。在切换到 MacBook Pro 之前,我使用了大约 6 年多的 Linux Mint,我已经有一套我自己的 Workflow,在切换到 Mac OS 之前我就在想哪一些的事情我是必须有 Mac 的软硬件才能做到,并且很提高某一方面的效率的,我列了一些
  • 多设备间同步 ssh 配置及密钥 ssh 客户端会在用户目录 ~/.ssh/ 目录下存放配置信息 (~/.ssh/config) 和公钥和私钥,如果有多个设备不同设备间的同步和管理就会成为一个比较头疼的问题。我在 Reddit 上抛出这个问题 后,我本来想的是通过 git 版本控制来进行管理,但有人说因为公钥和私钥都是二进制的文件,其实没有必要使用 git,任何一个同步工具就能够解决。