优化 SQL 语句

CHAR vs VARCHAR

在设计数据库字段时经常需要保存字符,MySQL 中有两个容易混淆的字段 CHAR 和 VARCHAR。

  • VARCHAR 是可变长度,仅使用必要的空间,需要额外使用 1 个或者 2 个字节来记录字符串长度,最大长度小于等于 255 字节,只需要额外使用一个字节,否则需要 2 个字节
  • CHAR 是固定长度,MySQL 在存储 CAHR 时会删除所有末尾空格,适合存储很短的字符串,或者所有值都接近同一个长度

VARCHAR(10) 需要 11 个字节存储空间,VARCHAR(1000) 列需要 1002 字节存储,2 个字节用来存储长度信息。

适用场景:

  • 字符串 COLUMN 的最大长度比平均长度大很多,列很少更新,不容易产生碎片
  • 如果预测到要保存的内容是固定长度,可以使用 CHAR,比如保存 MD5 值,保存性别代号等等;对于经常需要更新的数据 CHAR 也比 VARCHAR 更好,定长 CHAR 不容易产生碎片

与 CHAR 和 VARCHAR 类似的类型还有 BINARY 和 VARBINARY,存储的是二进制字符串。二进制字符串存储的是字节码而不是字符,填充也不一样,MySQL 填充 BINARY 采用的是 \0 零字节,而不是空格,检索时也不会去掉填充值。

当存储二进制,并且希望 MySQL 使用字节码而不是字符进行比较时,这些类型比较有用。MySQL 比较 BINARY 字符串时,每次按一个字节,并且根据该字节的数值比较。因此,二进制比较比字符比较简单很多,也就更快。

合并语句

把对同一个表的修改合并为一个 alter 语句,避免多次拷贝,提高改表效率

合并

altertable t1 addcolumn a int;
altertable t1 addcolumn b int;

合并后

altertable t1 addcolumn a int, add column b int;

更新语句

执行更新语句时尽量将同一张表的内容合并到一行。

UPDATE tablename SET column1 = "value1", column2 = "value2" ....

主键

自增主键设置为 unsigned 类型, MySQL 表只能有一个主键,但是可以有多个唯一键,可以尝试将自增 ID 作为主键,实际有意义的字段作为唯一键。

冗余索引

假如有 idx1(a,b) 和 idx2(a) 时,idx2 是没有必要的,当查询语句是 where a=xx 时会使用 idx1


2014-06-04 mysql , sql , optimize , slow-query , database

毕设相关

##Word目录自动生成 如果想要目录自动生成,就必须事先对文章标题进行格式化,我使用的方式是在大纲视图中对章节标题进行一级二级三级格式化。另外的方法是通过格式中标题去给每一个标题添加样式。网上的教程太多了,我就做一个备忘吧,以后说不定在其他论文中也要生成目录。在格式化标题之后,导航窗口基本上就能显示一个简单的目录了,此时再自动生成目录一般不会出现太大的问题。

##Word页眉页脚 有些页需要重新从1页开始编号,则要在该页之前插入分节符。如需生成第1页 共XX页这种格式的页码,最好不要手工输入总共的页码,因为可能需要修改论文内容,而如果手工修改可能最后不会自动更新,会造成很大的问题。最好是在文档部件->域->编号里面插入总页数。

##MP4转gif 项目因为在Android手机上,需要录制视频展示,Android(API level 19) 开发工具中提供了录制视频的方法:

adb shell screenrecord /sdcard/demo.mp4

在PC下连接手机,运行以上命令即可录制手机屏幕,视频格式为MP4,存放在手机SD卡,默认录制时间180s. 该命令还有其他一些参数,运行:

adb shell screenrecord --help

可以查看所有参数。几个可能会使用到的参数是:

  • --time-limit 10 录制时长
  • --size 1280*720 录制分辨率大小
  • --bit-rate 6000000 比特率

官方文档: http://developer.android.com/tools/help/adb.html#screenrecord 中文参考: http://blog.csdn.net/wirelessqa/article/details/22725581

录制完视频之后面临的一个问题是,怎么转成gif供PPT或者演示使用。最初想到的方法是使用Photoshop,也找到了一些方法能够将MP4视频转成Web使用gif,但是因为Photoshop将视频每一帧都保存,消耗内存太大,之后适当的调整了几次效果都不是很好,生成的文件也比较大。所以后来就直接使用了迅雷看看的gif生成了,不过缺点很明显,分辨率被调到很小,图像变得不清晰了。


2014-05-31 skills

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

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

比如创建一个空文件:

dd if=/dev/zero of=test.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 请求,用来加速访问过的地址速度。

Install

Debian/Ubuntu:

sudo apt install dnsmasq

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

dnsmasq 解析流程

dnsmasq 会先去 hosts 文件中查看配置,然后再解析 /etc/dnsmasq.d/*.conf 下的 conf 配置,这些文件配置优先级高于 dnsmasq.conf。

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 (resident memory usage)常驻内存,进程使用的、未被换出的物理内存大小,单位 kb。RES=CODE+DATA
  • SHR (shared memory) 共享内存大小,单位 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 使用百分比排序

macOS 区别

在 Linux 机器上使用 top 命令。常用的快键键是:

  • p 键 - 按 CPU 使用率排序
  • m 键 - 按内存使用量排序

这 2 个快捷键在 macOS 上都不一样。对应的是,先输入 o,然后输入 CPU 则按 CPU 使用量排序,输入 rsize 则按内存使用量排序。

如果记不清了,可以在 top 的界面上按 ?,在弹出的帮助界面中即可看到。


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 (essential binaries)系统所需的二进制命令,比如 ls、cp、mkdir 等命令,该目录中包含单用户模式下所有可执行的文件,功能和 /usr/bin 类似,这个目录中的文件都是可执行的、普通用户都可以使用的命令。作为基础系统所需要的最基础的命令就是放在这里
  • /dev 设备文件存储目录,比如磁盘,光驱…
  • /boot (static files of boot loader) Linux 的内核及引导系统程序所需要的文件目录,比如 vmlinuz initrd.img 文件都位于这个目录中。在一般情况下,[[GNU GRUB]] 或 LILO 系统引导管理器也位于这个目录
  • /etc (Host specific system config) 系统配置文件所在
  • /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 的 HOME 目录
  • /sbin (system binary)大多是系统管理的命令的存放位置,是超级权限用户 root 的可执行命令存放地,普通用户无权限执行这个目录下的命令,这个目录和 /usr/sbin; /usr/X11R6/sbin 或 /usr/local/sbin 目录是相似的;我们记住凡是目录 sbin 中包含的都是 root 权限才能执行的。
  • /usr (shareable and read-only data)是系统存放程序的目录,比如命令、帮助文件等。这个目录下有很多的文件和目录。当我们安装一个 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 (variable data files)目录存放经常变化的内容
  • /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

电子书

最近文章

  • 修复突然断电后 git 仓库 corrupt 今天在 Ubuntu 下编译项目,突然负载飙升到 140 多,然后整个系统就卡住,所有 UI 卡死,无奈之下只能对系统强制重启,不过重启之后发生了一件更严重的问题,当我访问我的项目,执行 git status 之后,显示:
  • 金融的本质 读书笔记 《金融的本质》是美联储主席[[本 伯南克]]关于美联储历史,以及在 2008 年应对金融危机手段的一本科普读物。本伯南克以非常通俗的语言讲述了美联储的历史,以及央行的职能。每一章节后面都有一个答学生的提问,所以看起来就像是一本写给学生的科普读物,读完可以对美联储是做什么的?为什么要成立美联储?以及当危机来临时美联储能够做什么?有非常详细的介绍和解释。
  • 若为自由故 读书笔记 《若为自由故:自由软件之父理查德·斯托曼传》是 [[Richard Stallman]] 的个人传记,在读完 [[自由软件 自由社会]] 的时候就把这一本书加入了待看列表。《自由软件 自由社会》中只介绍了 Stallman 关于自由软件的哲学思考,没有涉及到 Stallman 是怎么形成自己的思想的原由。而这一本传记能够更清楚的看到 Stallman 如何争取一台打印机驱动,到对争取软件自由运动的全部过程。
  • 微软新一代 CEO 萨提亚 纳德拉自传《刷新》 读书笔记 《刷新:重新发现商业与未来》是微软第三任 CEO [[萨提亚 纳德拉]] 的传记,好朋友之前推荐过一次,后来在听《无人知晓》播客的时候又再一次被提到,所以就把这一本列在了 [[20220605 21 天挑战计划]] 中。
  • 在 Proxmox VE 上使用 S.M.A.R.T 信息监控硬盘状态 自己组的 NAS,是用 Proxmox VE 做虚拟化,然后再其中安装了 OpenMediaVault 作为 NAS 系统,因为时间有些久1,所以不免有点担心硬盘的寿命,所以今天来好好了解一下 SMART 信息,并对磁盘进行一个全面的诊断,以保护数据的安全。 从零开始搭建 NAS 硬件篇 ↩