2.2 内核源码树
arch 特定体系结构的源码
block Crypto API
crypto 内核源码文档
drivers 设备驱动程序
firmware
fs VFS和各种文件系统
include 内核头文件
init 内核引导和初始化
ipc 进程间通信代码
kernel 像调度程序这样的核心子系统
lib 通用内核函数
Makefile
Makefile.common
mm 内存管理子系统和VM
Module.symvers
net 网络子系统
samples
scripts 编译内核所用的脚本
security Linux安全模块
sound 语音子系统
System.map
tools
usr 早期用户空间代码
virt

2.3 编译内核
配置内核(不同的选项)

1
2
3
4
make config
make menuconfig
make xconfig
make gconfig

创建默认配置

1
2
make defconfig
make oldconfig

编译

1
make

记录编译信息

1
make >../log.txt

忽略编译信息

1
make >/dev/null

衍生多个编译作业

1
make -j? 

如双核处理器上,每个处理器衍生两个作业

1
make -j4

安装内核
把arch/i386/boot/bzImage拷贝到/boot
依照vmlinuz-version来命名
编辑/boot/grub/grub.conf文件,为新内核建立新的启动项
使用LILO的系统则编辑/etc/lilo.conf,然后运行lilo

安装模块

1
make modules_install

2.4 内核开发的特点
1.没有libc库
大部分常用的C库函数在内核中都已经得到了实现
2.GNU C
内联函数
把对时间要求比较高而本身长度又比较短的函数定义成内联函数
static inline void test(unsigned long tail_size)
内联函数必须在使用前就定义好,一般在头文件或者文件头中定义内联函数
内联汇编
分支声明(为了优化)

1
2
3
4
5
6
7
8
9
likely()
unlikely()
if(unlikely(foo){
`/*****/
}

if (likely(foo)){
`/****/
}

3.没有内存保护机制
4.不要轻易在内核中使用浮点数
5.内核空间具有容积小而固定的栈
6.同步和并发
7.可移植性

三.进程管理
进程是处于执行期的程序以及它所包含的资源的总称
3.1进程描述符及任务结构
内核把进程存放在任务队列中
任务队列是各双向循环链表,链表中的每一项都是类型为task_struct,成为进程描述符的结构
定义在<linux/sched.h>文件中
进程描述符中包含一个具体进程的所有信息
task_struct在32位机器上有1.7k字节
其中包含的数据能完整的描述一个正在执行的程序
(打开的文件,进程的地址空间,挂起的信号,进程的状态还有其他更多信息)
3.1.1分配进程描述符
通过slab分配器分配task_struct结构
3.1.2进程描述符的存放
内核通过一个唯一的进程标识值或PID类标识每个进程
PID最大默认值为32768(short int的最大值)
也可以修改/proc/sys/kernle/pid_max来提高上限
3.1.3进程状态
进程描述符中的state域描述了进程的当前状态,系统中每个进程都必须处于五种状态中的一种

1
2
3
4
5
TASK_RUNNING(运行)
TASK_INTERRUPTIBLE(可中断)
TASK_UNINTERRUPTIBLE(不可中断)
TASK_ZOMBIE(僵死)
TASK_STOPPED(停止)

3.1.4 设置当前进程状态

1
2
3
set_task_state(task,state);
/*将任务task的状态设置为state*/
set_current_state(state) <=> set_stask_state(current,state)

3.1.5进程上下文
3.1.6进程家族树
所有的进程都是PID为1的init进程的后台
内核在系统启动的最后阶段启动init进程
该进程读取系统的初始化脚本并执行其他的相关程序

进程间的关系存放在进程描述符中
每个tack_struct都包含一个指向其父进程task_struct,叫做parent的指针
获取其父进程的进程描述符:
struct task_struct *my_parent = ourrent->parent;
访问子进程:

1
2
3
4
5
6
7
8
9
10
11
12
struct task_struct *task;
struct list_head *list;

list_for_each(list,$current->children){
task = list_entry(list,sruct task_struct,sibling);
/* task 现在指向当前的某个子进程*/
}
struct task_struct *task;
for (task =current;task != $init_task; task= task->parent)
/* task 现在指向init */

}

五.系统调用
5.1 API.POSIX.C
5.2 系统调用(系统调用号)
5.3 系统调用处理程序
int $0x80(十进制128) system_call()
第128号异常处理程序
系统调用号通过eax寄存器传递给内核
call *sys_call_table(,%eax,4)
系统调用表的表项是以32位类型存放的,所以内核需要将给定的系统调用号乘以4,然后查询
参数传递:ebx,ecx,edx,esi和edi按照顺序存放前五个参数
5.4 系统调用的实现
5.5 系统调用上下文
entry.s(系统调用表)

六.中断和中断处理程序
IRQ:中断请求
ISR:中断服务例程

6.3 注册中断处理程序

1
2
3
4
5
int request_irq(unsigned int irq,
irqreturn_t(*handler)(int,void *,struct pt_regs *),
unsighed long irqflags,
const char* devname,
void *dev_id)

参数说明:

1
2
3
4
5
6
7
8
9
10
11
12
irq:要分配的中断号
handler:指针,指向处理这个中断的世纪中断处理程序。
handler函数的原型是特定的,接受三个参数,并有一个类型为irqresutn_t的返回值。
irqflags:可以为0,也可以为下列标志的位掩码
SA_INTERRUPT:表示给定的中断处理程序是一个快速中断处理程序
SA_SAMPLE_RANDOM:
SA_SHIRQ:
devname:与中断相关的ASCII文本表示法.
dev_id:

request_irq()成功执行会返回0.

站点地图这个东西,目的是为了对搜索引擎友好。搜索引擎每天来爬你的网站,如果能给它提供一份实时更新的站点地图,自然会让搜索引擎在爬取网站的时候更加有效率。

这里用php实现了一个自动化的站点地图生成器,可以在爬虫访问站点地图的时候动态的创建页面,来提供一份实时更新的sitemap.xml。
具体的实现,首先你需要让apache服务器支持将xml文件作为php来解析,这样sitemap.xml中的php语句得以执行。
可在站点根目录下的.htaccess文件的<IfModule mod_rewrite.c>和</IfModule>之间加入这一句:

1
AddType application/x-httpd-php .xml

至于php部分,其实就是先获取网站首页所有的url,再将url写入页面,同时将创建的日期设为今天。这样爬虫就会认为站点是实时更新的,从而提高搜索排名。
然后就是sitemap.xml的源代码:

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
75
76
77
78
79
80
81
82
83
<?php
error_reporting(0);//禁止报错
header("Content-type:text/xml"); //输出xml作为文档的头部
echo '<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.chorder.net">';

function _getUrlContent($url) {
$handle = fopen($url, "r");
if ($handle) {
$content = stream_get_contents($handle, 1024 * 1024);
return $content;
} else {
return false;
}
}

function _filterUrl($web_content) {
$reg_tag_a = '/<[a|A].*?href=[\'\"]{0,1}([^>\'\"\ ]*).*?>/';
$result = preg_match_all($reg_tag_a, $web_content, $match_result);
if ($result) {
return $match_result[1];
}
}

function _reviseUrl($base_url, $url_list) {
$url_info = parse_url($base_url);
$base_url = $url_info["scheme"] . '://';
if ($url_info["user"] && $url_info["pass"]) {
$base_url .= $url_info["user"] . ":" . $url_info["pass"] . "@";
}
$base_url .= $url_info["host"];
if ($url_info["port"]) {
$base_url .= ":" . $url_info["port"];
}
$base_url .= $url_info["path"];
if (is_array($url_list)) {
foreach ($url_list as $url_item) {
if (preg_match('/^http/', $url_item)) {
$result[] = $url_item;
} else {
$real_url = $base_url . '/' . $url_item;
$result[] = $real_url;
}
}
return $result;
} else {
return;
}
}

function crawler($url) {
$content = _getUrlContent($url);
if ($content) {
$url_list = _reviseUrl($url, _filterUrl($content));
if ($url_list) {
return $url_list;
} else {
return ;
}
} else {
return ;
}
}

function main() {
$current_url = "https://chorder.net";
$result_url_arr = crawler($current_url);
if ($result_url_arr) {
foreach ($result_url_arr as $url) {
echo '
<url>
<loc>'.$url.'</loc>
<lastmod>'.date("Y/m/d").'</lastmod>
<changefreq>always</changefreq>
<priority>1.0</priority>
</url>
';
}
}
echo '</urlset>';
}
main();
?>

效果可以见 https://chorder.net/sitemap.xml

一直想给安装一个缩略图点击弹出的插件,但是找了找几乎都是用的php来做的,插件的使用和安装极其繁琐,于是上网查了些demo,自己实现了一个纯js的图片弹出插件。

实现的思路是通过编写hook图片的onclick事件的函数,在函数中对body追加div元素,再将传入的图片对象放入元素中,同时再监听div的onclilck事件,当捕捉到点击,再关闭(其实是隐藏)弹出的div。
通过在函数初始化的时候收集页面所有的img元素,再为每个img元素增加onclick=”picHook(this)”这条属性,这样当图片在被点击时,这个函数就能自动创建div蒙板背景,并获取被点击图片的宽度和高度,同时生成一个新的和图片一样大小的div来显示图片。当蒙板再次被点击时,hook事件再次响应,并将蒙板和图片div的style置为none,弹出的图片就被关闭了。
实现效果见本博客,任意点击一个图片即可查看效果。
说起来很简单,做起来就更简单了,简单到只需要一个函数即可实现。
talking is cheap,show you my code:

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
75
76
77
78
<script>
function picHook(pic){
/*图片对象*/
var imgs = document.getElementsByTagName("img");
/*前景div*/
var light = document.getElementById('light') || document.createElement("div");
/*背景div*/
var bg = document.getElementById('bg') || document.createElement("div");
/*图片放大*/
var s_pic = document.getElementById('s_pic') || document.createElement("img");
/*css对象*/
var css = document.createElement("style");
/*css样式*/
var csstext = '\
.pic_bg{\
position: absolute;\
margin:0 auto; \
top: 0%;\
left: 0%;\
right: 0%;\
width: 100%;\
padding-bottom: 1000%;\
background-color: black;\
z-index:1001;\
opacity:.80;\
filter: alpha(opacity=80);\
overflow:scroll;\
}\

.pic_div {\
margin-bottom: auto;\
position: fixed;\
left:30%;\
top:20%;\
width: 100%;\
padding-top:25px;\
margin-left:-250px;\
margin-top:-100px;\
z-index:1002;\
}';
/*收集页面所有图片对象*/
for(i=0; i<imgs.length;i++){
imgs[i].setAttribute("onclick", "picHook(this)" );
}
css.type = "text/css";

/*关闭图像*/
if( !pic ){
bg.style.display = light.style.display = "none";
}

/*ie兼容*/
if(css.styleSheet){
css.styleSheet.cssText = csstext;
}else{
css.appendChild(document.createTextNode(csstext));
}

s_pic.setAttribute("id", "s_pic");
s_pic.setAttribute("src", pic.src);
s_pic.setAttribute("width","70%");
s_pic.setAttribute("height","65%");
s_pic.setAttribute("margin","0 auto");
s_pic.style.display = 'block';
light.setAttribute("id", "light");
light.setAttribute("class", "pic_div");
light.style.display = 'block';
light.appendChild(s_pic);
light.setAttribute("onclick", "picHook()");
bg.setAttribute("id", "bg");
bg.setAttribute("class", "pic_bg");
bg.setAttribute("onclick", "picHook()");
bg.style.display = light.style.display;
document.getElementsByTagName("head")[0].appendChild(css);
document.body.appendChild(bg);
document.body.appendChild(light);
}
</script>

将这段代码保存在页面的head中,再将body的onload事件绑定到picHook()函数,你的页面中就也可以实现图片点击弹出大图啦。
还存在一点小bug,主要是因为我不太熟悉css,导致div的样式做的有点难看。
css的样式我是直接声明在js里的,这样就不用再另外创建css文件了。
强迫症,没办法。
等有时间再琢磨琢磨css,优化下样式。
喜欢就拿去吧。
你可以点击下面的图片测试一下看看效果:

距离上一篇文章已经过去很久了,今天想起来截了几张图,来继续巴拉巴拉AVWS这个神器的使用,作为续集吧。

http sniffer
先说说AVWS自带的http sniffer功能吧,大部分人一想起抓包,嗅探这些就会想到诸如burpsuite,fiddler之类,其实AWVS本身也是自带这个功能的,请看截图:

在这里可以看见它默认启动的是8080端口作为本地监听,浏览器只要配置好代理端口为8080,流量就会经过这里。
同时右键可以点击发送到http editor和http fuzzer,方便对捕捉到的数据包进一步操作。

http editor
经过http_sniffer捕捉到的数据包,可以直接send到http editor,也可以通过复制text格式的数据包内容复制进http editor中,使用http editor进行编辑和重放,如图:

这里可以编辑http包的各个部分,点击start即可发送。

http fuzzer
这个功能是我最喜欢的功能,比起burpsuite中的Intruder要方便的多。

如上图,在这个部分,可以添加fuzzer的generator,generator的类型可以在右边的选项中指定。
配置完成后插入数据包的任何位置,点击start即可开始fuzz,唯一的遗憾应该就是不能指定线程。
fuzz动作完成后,在result一栏即可看到fuzz之后的结果。

用这个功能,省去了很多时候需要写fuzz脚本的困扰,操作起来也比burpsuite要轻松许多。

authentication tester
这个功能看名字就知道,使用来测试认证的。其实就是一个登录爆破工具,可以爆破三种类型的认证,看图:

blind sql injector
这个功能也是相当有用的一个功能,它可以代理穿山甲,sqlmap等工具来测试SQL注入。
首先需要配置好注入测试的选项,主要是指定数据库类型等等。目前貌似只支持mssql和mysql两种类型,还是略显鸡肋。

配置好选项之后,切回HTTP Request选项卡,点击Default Value输入框右边加号在需要测试的位置加入标记,并输入一个默认值,即可开始注入测试。测试完成后即可在下方观测测试结果。

通过我的多次测试结果来看,测试还是比较准确的。AWVS自带的一千多条payload,基本涵盖了sql注入所需的常规输入。

compare results
这个功能用的不怎么多,是用来比较两次扫描的结果。
扫描完成后将扫描结果保存成wvs格式的报告,通过这个功能载入后即可快速的比对出两份报告的结果异同。
因为手头上没有现成的报告,就没有测试了。感兴趣的小伙伴可以自行利用。

神器的使用就先介绍到这里,如果后续还有更多使用经验的话我再来继续补充。

【原创内容,转载请注明来自Chorder’s Mainpage:https://www.chorder.net】

玩转AWVS(一):https://chorder.net/2015/12/02/玩转AWVS(一)/
玩转AWVS(二):https://chorder.net/2016/02/03/玩转AWVS(二)/

先查看无线网卡是否有驱动:
搜索Realtek驱动:

1
apt-cache search realtek

显示如下:

1
firmware-realtek - Binary firmware for Realtek wired and wireless network adapters

安装Realtek驱动:

1
sudo apt-get install firmware-realtek

接着编辑/etc/wpa_supplicant/wpa_supplicant.conf这个文件
添加网络相关配置,类似:

1
2
3
4
5
network={
ssid="tplink-home"
key_mgmt=WPA-PSK
psk="12345678"
}

还要修改下/etc/network/interfaces文件,把无线网卡设为dhcp方式获取地址
方法是将iface wlan0 inet manual这一行注释掉,改为

1
iface wlan0 inet dhcp

基本上全部完成了,重启无线网卡即可:

1
ifup wlan0

有了Ruby笔记,怎么能少了python笔记呢。
这里主要记录我的python使用心得和调错笔记。

No module named win32api
安装pywin32
进入这个链接:

http://sourceforge.net/projects/pywin32/
http://sourceforge.net/projects/pywin32/files/pywin32/Build%20220/

选择对应的版本,例如64位windows,python版本2.7.1,则选择

pywin32-220.win-amd64-py2.7.exe

Python比较难找的cffi包

1
pypi.python.org/packages/source/c/cffi/cffi-1.4.2.tar.gz

最近手上多了一个树莓派2代,于是折腾就这么开始了。
因为总是得要个显示屏或者路由器或者插根网线才能玩,有点麻烦,所以有了此文。

设备清单:

树莓派2代
EDUP EP-N8508GS无线网卡(USB)
普通网线一根

最终实现的效果是树莓派的有线网卡用来作为wan口,无线网卡建立热点
笔记本可以通过连接wifi连接上树莓派进行操作

下面说说过程:
首先我参考了
http://elinux.org/RPI-Wireless-Hotspot
这篇文章中的方法,但是并没有成功。后来看到文章的末尾才知道,是驱动对不上号,文章末尾明确标明默认的hostapd程序不支持rtl8188系列网卡,而我的usb网卡就是rtl8188cus系列。
所以在开始之前,建议先用lsusb命令看一下网卡的型号再考虑进行下一步。

如果你的网卡不是rtl8188系列那你可以参考上面文章中的方法来配置,如果是那么可以参考我的方法。

根据那篇文章最后给出的连接,找到了这个驱动:

https://github.com/lostincynicism/hostapd-rtl8188

然而当编译好驱动重新运行之后仍然是不行,还是不支持。

最后还是参考了这篇文章:

http://wangye.org/blog/archives/845/?_t_t_t=0.7382462719884554

原因可能就是因为我这个系列网卡比较特殊。但是最后在这个文章中发现了编译好的第三方驱动,虽然有点不满意,但还是凑合着用了。
http://www.daveconroy.com/turn-your-raspberry-pi-into-a-wifi-hotspot-with-edimax-nano-usb-ew-7811un-rtl8188cus-chipset/
具体步骤:
先切换为root用户,可以省去很多不必要的麻烦。
所以以下操作都是以root用户:
1.安装hostapd和udhcpd服务并且更换hostapd程序

1
2
3
4
5
6
7
8
apt-get install udhcpd hostapd
wget http://www.daveconroy.com/wp3/wp-content/uploads/2013/07/hostapd.zip
unzip hostapd.zip
mv /usr/sbin/hostapd /usr/sbin/hostapd.bak
mv hostapd /usr/sbin/hostapd.edimax
ln -sf /usr/sbin/hostapd.edimax /usr/sbin/hostapd
chown root.root /usr/sbin/hostapd
chmod 755 /usr/sbin/hostapd

2.编辑/etc/udhcpd.conf文件,配置dhcp服务:
确保文件当中有下列内容

1
2
3
4
5
6
7
8
start 192.168.1.2
end 192.168.1.254
interface wlan0
remaining yes
opt dns 223.5.5.5 223.6.6.6
opt subnet 255.255.255.0
opt router 192.168.1.1
opt lease 864000 #

相信一般都能看懂,其中的interface需要根据情况来写。

3.编辑/etc/default/udhcpd 文件,将下面这行注释掉。

1
DHCPD_ENABLED="no"

4.将无线网卡wlan0的ip设为192.168.1.1

1
ifconfig wlan0 192.168.42.1

5.修改/etc/network/interfaces文件,添加下面的内容

1
2
3
iface wlan0 inet static
address 192.168.1.1
netmask 255.255.255.0

并且将下面这两条注释掉

1
2
wpa-roam /etc/wpa_supplicant/wpa_supplicant.conf
iface default inet manual

6.接着就正式开始配置无线相关的选项了,编辑/etc/hostapd/hostapd.conf,如果没有这个文件就自行创建它。

1
2
3
4
5
6
7
8
9
10
11
12
13
interface=wlan0
driver=rtl871xdrv
ssid=无线名称
hw_mode=g
channel=6
macaddr_acl=0
auth_algs=1
ignore_broadcast_ssid=0
wpa=2
wpa_passphrase=无线密码
wpa_key_mgmt=WPA-PSK
wpa_pairwise=TKIP
rsn_pairwise=CCMP

7.在/etc/default/hostapd文件中指定hostapd服务的配置文件,内容如下

1
DAEMON_CONF="/etc/hostapd/hostapd.conf"

8.更改系统的转发规则和iptables规则,依次运行下列命令:

1
2
3
4
5
6
7
8
9
echo 1 > /proc/sys/net/ipv4/ip_forward
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
iptables -A FORWARD -i eth0 -o wlan0 -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -i wlan0 -o eth0 -j ACCEPT
iptables-save > /etc/iptables.nat
service hostapd start
service udhcpd start
update-rc.d hostapd enable
update-rc.d udhcpd enable

9.最后一点点收尾工作:
编辑/etc/network/interfaces文件,在末尾加上着一条:

1
up iptables-restore < /etc/iptables.nat

以及/etc/sysctl.conf文件,确保下面的选项存在

1
net.ipv4.ip_forward=1

到此为止就全部完成了,用手机,电脑等无线设备都可以连接上树莓派了。
为后续的折腾打下基础。

折腾的整个过程还挺复杂的,需要修改多处文件,而且每一处修改都会微妙的影响到最后路由器的运行,小小的改变都有可能造成瘫痪或者影响性能。由此可见,想DIY一款高性能的个性无线路由器还是很有挑战性的。

1
2
3
4
5
6
7
8
crontab file [-u user]-用指定的文件替代目前的 crontab
crontab-[-u user]-用标准输入替代目前的 crontab
crontab-1[user]-列出用户目前的 crontab
crontab-e[user]-编辑用户目前的 crontab
crontab-d[user]-删除用户目前的 crontab
crontab-c dir- 指定 crontab 的目录
$crontab -l 列出用户目前的 crontab
crontab 文件的基本格式 :
1
2
3
4
5
6
7
8
9
10
*    *     *     *     *     command
分 时 日 月 周 命令


第 1 列表示分钟 1~59 每分钟用*或者 */1 表示
第 2 列表示小时 1~23(0 表示 0 点)
第 3 列表示日期 1~31
第 4 列表示月份 1~12
第 5 列标识号星期 0~6(0 表示星期天)
第 6 列要运行的命令

一些范例:

1
30 21 * * * /usr/local/etc/rc.d/lighttpd restart

上面的例子表示每晚的 21:30 重启 apache。

1
45 4 1,10,22 * * /usr/local/etc/rc.d/lighttpd restart

上面的例子表示每月 1、10、22 日的 4 : 45 重启 apache。

1
10 1 * * 6,0 /usr/local/etc/rc.d/lighttpd restart

上面的例子表示每周六、周日的 1 : 10 重启 apache。

1
0,30 18-23 * * * /usr/local/etc/rc.d/lighttpd restart

上面的例子表示在每天 18 : 00 至 23 : 00 之间每隔 30 分钟重启 apache。

1
0 23 * * 6 /usr/local/etc/rc.d/lighttpd restart

上面的例子表示每星期六的 11 : 00 pm 重启 apache。

1
* */1 * * * /usr/local/etc/rc.d/lighttpd restart

每一小时重启 apache

1
* 23-7/1 * * * /usr/local/etc/rc.d/lighttpd restart

晚上 11 点到早上 7 点之间,每隔一小时重启 apache

1
0 11 4 * mon-wed /usr/local/etc/rc.d/lighttpd restart

每月的 4 号与每周一到周三的 11 点重启 apache

1
0 4 1 jan * /usr/local/etc/rc.d/lighttpd restart

一月一号的 4 点重启 apache

C
C:1 3 5
Cm:1 b3 5
C7:1 3 5 b7
Caug(C+):1 3 #5
Cdim(C°):1 b3 b5 6
C6:1 3 5 6
Cm6:1 b3 5 6
C9:1 2 3 5
Cm9:1 2 b3 5
Cm7:1 b3 5 b7
Cmaj7:1 3 5 7
alt C7(C7-5):1 3 b5 7

C#=Db
C#(Db):#1 4(#3) #5
C#m(Dbm):#1 3 #5
C#7(Db7):#1 4(#3) #5 7
C#aug(C#+)Dbaug(Db+):#1 4(#3) 6
C#dim(C#°)Dbdim(Db°):#1 3 5 b7
C#6(Db6):#1 4(#3) #5 #6
C#m6(Dbm6):#1 3 #5 #6
C#9(Db9):#1 #2 4(#3) #5
C#m9(Dbm9):#1 #2 3 #5
C#m7(Dbm7):#1 3 #5 7
C#maj7(Dbmaj7):#1 4 #5 1(g).
altC#m7(C#m7-5)altDbm7(Dbm7-5):#1 4 5

D
D:2 #4 6
Dm:2 4 6
D7:2 #4 6 1(g)
Daug(D+):2 #4 #6
Ddim(D°):2 4 b6 7
D6:2 #4 6 7
Dm6:2 4 6 7
D9:2 3 #4 6
Dm9:2 3 4 6
Dm7:2 4 6 1(g)
Dmaj7:2 #4 6 #1(g)
alt D7(D7-5):2 #4 b6 1(g)

Eb=D#
Eb(D#):b3 5 b7
Ebm(D#m):b3 b5 b7
Eb7(D#7):b3 5 b7 b2(g)
Ebaug(Eb+)D#aug(D#+):b3 5 7
Ebdim(Eb°)D#dim(D#°):b3 b5 6 b7
Eb6(D#6):b3 5 b7 1(g)
Ebm6(D#):b3 b5 b7 1(g)
Eb9(D#6):b3 4 5 b7
Ebm9(D#m9):b3 4 b5 b7
Ebm7(D#m7):b3 b5 b7 b2(g)
alt Eb7(Eb7-5)altD#7(D#7-5):b3 5 6 b2(g)

E
E:3 #5 7
Em:3 5 7
E7:3 #5 7 2(g)
Eaug(E+):3 #5 1(g)
Edim(E°):3 5 b7 #1(g)
E6:3 #5 7 #1(g)
Em6:3 5 7 #1(g)
E9:3 #4 #5 7
Em9:3 #4 5 7
Em7:3 5 7 2(g)
Emaj7:3 #5 7 #2(g)
altE7(E7-5):3 #5 b7 2(g)

F
F:4 6 1(g)
Fm:4 b6 1(g)
F7:4 6 1(g) b3(g)
Faug(F+):4 6 #1(g)
Fdim(F°):4 b6 7 2(g)
F6:4 6 1(g) 2(g)
Fm6:4 b6 1(g) 2(g)
F9:4 5 6 1(g)
Fm9:4 5 b6 1(g)
Fm7:4 b6 1(g) b3(g)
Fmaj7:4 6 1(g) 3(g)
altF7(F7-5)altGb7(Gb7-5):4 6 b1(g)(7) b3(g)

G
G:5 7 2(g)
Gm:5 b7 2(g)
G7:5 7 2(g) 4(g)
Gaug(G+):5 7 #2(g)
Gdim(G°):5 b7 b2 3
G6:5 7 2(g) 3(g)
Gm6:5 b7 2(g) 3(g)
G9:5 6 7 2(g)
Gm9:5 6 b7 2(g)
Gm7:5 b7 2(g) 4(g)
Gmaj7:5 7 2 #4
altG7(G7-5):5 7 b2(g) 4(g)

Ab=G#
Ab(G#):b6 1(g) b3(g)
Ab7(G#7):b6 1(g) b3(g) b5(g)
Abaug(Ab+)G#aug(G#+):b6 1(g) 3(g)
Abdim(Ab°)G#dim(G#°):b6 7 2(g) 4(g)
Abm7G#m7:b6 b1(g) b3(g) b5(g)
Abmaj7G#maj7:b6 1(g) b3(g) 5(g)
altAb7(Ab7-5) altG#7(G#7-5):b6 1(g) 2(g) b6(g)

A
A:6 #1(g) 3(g)
Am:5 1(g) 3(g)
A7:5 #1(g) 3(g) 5(g)
Aaug(A+):5 #1(g) 4
Adim(A°):6 1(g) b3(g) b5(g)
A6:5 #1(g) 3(g) #4(g)
Am6:5 1(g) 3(g) #4(g)
A9:6 7 #1(g) 3(g)
Am9:6 7 1(g) 3(g)
Am7:6 1(g) 3(g) 5(g)
Amaj7:5 #1(g) 3(g) #5(g)
altA7(A7-5):5 #1(g) b3(g) 5(g)

Bb=A#
Bb(A#):b7(d) 2 4
Bbm(A#m):b7(d) b2 4
Bb7(A#7):b7(d) 2 4 b6
Bbaug(Bb+)A#aug(A#+):b7(d) 2 #4
Bbdim(Bb°)A#dim(A#°):b7(d) b2 3 5
Bb6(A#6):b7(d) 2 4 5
Bbm6(A#m6):b7(d) b2 4 5
Bb9(A#9):b7(d) 1 2 4
Bbm9(A#m9):b7(d) 1 b2 4
Bbm7(A#m7):b7(d) b2 4 b6
Bbmaj7A#maj7:b7(d) 2 4 6
altBb7(Bb7-5)altA#7(A#7-5):b7(d) 2 3 b6

B
B:7(d) #2 #4
Bm:7(d) 2 #4
B7:7(d) #2 #4 6
Baug(B+):7(d) #2 5
Bdim(B°):7(d) 2 4 b6
B6:7(d) #2 #4 #5
Bm6:7(d) 2 #4 #5
B9:7(d) #1 #2 #4
Bm9:7(d) #1 2 #4
Bm7:7(d) 2 #4 6
Bmaj7:7(d) #2 #4 #6
altB7(B7-5):7(d) #2 4 b6

定义类
定义类的过程就是定义类的属性的过程;
类的属性就是累的静态属性的简称,指类内包含的各项数据。

类的服务被称为成员函数或方法。

继承extends
通过定义继承方法,子类可以获得父类的所有属性和方法

接口implements
说明当前类中实现了哪个接口定义的功能和方法
是Java语言中实现多重继承的一种机制

类的修饰符分为:
访问控制符
抽象类说明符
最终说明符

类的属性:
描述了类内部的信息,又称为类的静态属性
类属性为简单变量

【修饰符】 变量类型 变量名【=变量初值】
【修饰符】 类名 对象名 【=new 类名(实际参数列表)】

若使用另一个类的对象作为当前类所定义的类的属性,
要保证该对象所在的类在当前类中是可已被当前类所引用的

类属性的修饰符包括:
访问控制符
静态修饰符static
最终修饰符final
易失修饰符volatile
过渡丢师傅transient

类的方法(成员函数)
用来规定类属性上的操作
实现类内部功能的机制
也是类与外界交互的窗口

声明方法的语法:
【修饰符】返回值类型 方法名(参数列表)
Trows 例外名1,例外名2,…
{
方法体:
局部变量声明;
语句序列;
}

方法的修饰符包括:
访问控制符
静态修饰符static
抽象修饰符abstract
最终修饰符final
同步修饰符synchronous
本地修饰符native

类的构造函数

特殊之处:
构造函数的方法名与类名相同
构造函数没有返回类型
构造函数的主要作用是完成对类对象的初始化工作

在创建一个类的新对象的同时,系统会自动调用该类的构造函数为新对象初始化

Java在声明类是,可以不定义构造函数,系统会自动为该类生成一个默认的构造函数
此时这个构造函数的名字与类名相同,没有任何形式参数,也不完成任何操作

类的访问控制符只有一个public
属性和方法的访问控制符有:
public

private
protected
private protected

对于同一个包中的类可以不需任何说明,方便的互相访问和引用

在不同包中的类,只有他们都声明为public时,然后再在程序头部声明import后才可以被访问和引用相应的类。

publici修饰的类的属性称为公共属性
如果公共属性属于一个公共类,则可以被所有的其他类使用

public修饰符会造成安全性和数据封装性下降,应尽量减少public属性的使用

缺省访问控制符规定该类只能被同一个包中的类访问和引用,而不可以被其他包中的类引用,这种特性称为包访问性。

类内的属性和方法如果没有访问控制符来限定,也说明他们具有包访问性,可以被同一个包中的其他类所访问和调用

用private修饰的属性或方法只能被该类自身所访问和修改,而不能被任何其他类,包括该类的子类来获取和引用。
procted修饰的属性可以被该类自身和包中的类访问
public可以被任意访问

静态属性
被static修饰的属性称为静态属性
静态属性是一个公共的存储单元
任何一个类的对象访问它时取到的都是相同的值
任何一个类的对象去修改它时,都是在对同一个内存单元做操作。

static修饰符修饰的属性是属于类的公共属性
static修饰符修饰的方法是属于整个类的方法
不用static修饰符修饰的方法是属于某个具体对象或实例的方法

声明一个方法的static至少有三重含义
调用这个方法时,应该使用类名做前缀,而不是某一个具体的对象名
非static的方法是属于某个对象的方法,在这个对象创建时对象的方法在内存中拥有自己的专用代码段
而static的方法是属于整个类的
它在内存中的代码段将随着类的定义而分配和装载,不被任何一个对象专有
static方法只能处理static类型的数据

静态初始化器
石油关键字static引导的一对大括号括起的语句组

静态初始化器与构造函数的区别:
构造函数是对每个新创建的对象初始化,而静态初始化器是对每个类进行初始化
构造函数是在用new运算符产生新对象时由系统自动执行,而静态初始化器则是在它所属的类加载入内存时由系统调用运行的
不同于构造函数,静态初始化器不是方法,没有方法名,返回值和参数列表

抽象类
当一个类被生命为abstract时,这个类被称为抽象类
所谓抽象类就是没有具体实例对象的类
抽象类是它所有子类的公共属性的集合
使用抽象类的一大优点就是可以利用这些公共属性来提高开发和维护程序的效率

最终类,最终属性,最终方法,终结器
最终类
如果一个类被final修饰符所修饰和限定,说明这个类不可能拥有子类
最终属性
final就是用来修饰常量的修饰符,一个类的成员变量如果被声明为final,那么它的取值在程序的执行过程中都不会改变,也就是一个常量

用final修饰符说明常量时:
需要说明常量的数据类型
需要同时指出常量的具体取值
因为所有类的对象的常量成员,其数值都固定一致,为了节省空间,常量通常都被声明为static

final修饰符所修饰的类方法,是功能和内部语句都不能被更改的最终方法,即是不能被当前类的子类重载的方法
final方法固定所对应的具体操作,防止子类对父类关键方法的错误的重定义,保证了程序的安全性和正确性

所有已被private修饰符限定为私有的方法,以及所包含在final类中的方法,都被缺省的认为是final的

终结器
终结器是回收对象时执行的方法
protected void finalize(){}
终结器是一个名为finalize的方法,没有产生列表和返回值

volatile修饰符
被volatile修饰的类的属性可能同时被几个线程控制和修改
通常用来修饰受外部输入的属性

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×