小小马里奥的博客

Little Mario's blog


  • 首页

  • 关于

  • 标签

  • 分类

  • 归档

[转]46个Linux面试常见问题

发表于 2019-01-28
字数统计: 3,635 | 阅读时长 ≈ 13

问题一:

绝对路径用什么符号表示?当前目录、上层目录用什么表示?主目录用什么表示? 切换目录用什么命令?


答案:
绝对路径: 如/etc/init.d
当前目录和上层目录: ./  ../
主目录: ~/
切换目录: cd

问题二:


怎么查看当前进程?怎么执行退出?怎么查看当前路径?
答案:
查看当前进程: ps
执行退出: exit
查看当前路径: pwd

问题三:


怎么清屏?怎么退出当前命令?怎么执行睡眠?怎么查看当前用户 id?查看指定帮助用什么命令?
答案:
清屏: clear
退出当前命令: ctrl+c 彻底退出
执行睡眠 : ctrl+z 挂起当前进程fg 恢复后台
查看当前用户 id: ”id“:查看显示目前登陆账户的 uid 和 gid 及所属分组及用户名
查看指定帮助: 如 man adduser 这个很全 而且有例子; adduser –help 这个告诉你一些常用参数; info adduesr;

问题四:


Ls 命令执行什么功能? 可以带哪些参数,有什么区别?
答案:
ls 执行的功能: 列出指定目录中的目录,以及文件
哪些参数以及区别: a 所有文件l 详细信息,包括大小字节数,可读可写可执行的权限等

问题五:


建立软链接(快捷方式),以及硬链接的命令。
答案:
软链接: ln -s slink source
硬链接: ln link source

问题六:


目录创建用什么命令?创建文件用什么命令?复制文件用什么命令?
答案:
创建目录: mkdir
创建文件:典型的如 touch,vi 也可以创建文件,其实只要向一个不存在的文件输出,都会创建文件
复制文件: cp

问题七:


文件权限修改用什么命令?格式是怎么样的?
文件权限修改: chmod
格式如下:



$ chmod u+x file 给 file 的属主增加执行权限
$ chmod 751 file 给 file 的属主分配读、写、执行(7)的权限,给 file 的所在组分配读、执行(5)的权限,给其他用户分配执行(1)的权限
$ chmod u=rwx,g=rx,o=x file 上例的另一种形式
$ chmod =r file 为所有用户分配读权限
$ chmod 444 file 同上例
$ chmod a-wx,a+r file同上例
$ chmod -R u+r directory 递归地给 directory 目录下所有文件和子目录的属主分配读的权限

 


问题八:


查看文件内容有哪些命令可以使用?
答案:
vi 文件名 #编辑方式查看,可修改
cat 文件名 #显示全部文件内容
more 文件名 #分页显示文件内容
less 文件名 #与 more 相似,更好的是可以往前翻页
tail 文件名 #仅查看尾部,还可以指定行数
head 文件名 #仅查看头部,还可以指定行数

问题九:


随意写文件命令?怎么向屏幕输出带空格的字符串,比如”hello world”? 


答案:


写文件命令:vi


向屏幕输出带空格的字符串:echo hello world


 


问题十:


终端是哪个文件夹下的哪个文件?黑洞文件是哪个文件夹下的哪个命令?
答案:
终端  /dev/tty


黑洞文件  /dev/null

问题十一:


移动文件用哪个命令?改名用哪个命令?
答案:
mv mv

问题十二:


复制文件用哪个命令?如果需要连同文件夹一块复制呢?如果需要有提示功能呢?
答案:
cp cp -r  ????

问题十三:


删除文件用哪个命令?如果需要连目录及目录下文件一块删除呢?删除空文件夹用什么命令?
答案:
rm rm -r rmdir

问题十四: 


Linux 下命令有哪几种可使用的通配符?分别代表什么含义?
答案:
“?”可替代单个字符。


“*”可替代任意多个字符。


方括号“[charset]”可替代 charset 集中的任何单个字符,如[a-z],[abABC]


 


问题十五:


用什么命令对一个文件的内容进行统计?(行号、单词数、字节数)
答案:


wc 命令 - c 统计字节数 - l 统计行数 - w 统计字数。

问题十六:


Grep 命令有什么用? 如何忽略大小写? 如何查找不含该串的行?
答案:
是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹 配的行打印出来。
grep [stringSTRING] filename grep [^string] filename

问题十七:


Linux 中进程有哪几种状态?在 ps 显示出来的信息中,分别用什么符号表示的?
答案:
(1)、不可中断状态:进程处于睡眠状态,但是此刻进程是不可中断的。不可中断, 指进程不响应异步信号。
(2)、暂停状态/跟踪状态:向进程发送一个 SIGSTOP 信号,它就会因响应该信号 而进入 TASK_STOPPED 状态;当进程正在被跟踪时,它处于 TASK_TRACED 这个特殊的状态。
“正在被跟踪”指的是进程暂停下来,等待跟踪它的进程对它进行操作。


(3)、就绪状态:在 run_queue 队列里的状态


(4)、运行状态:在 run_queue 队列里的状态
(5)、可中断睡眠状态:处于这个状态的进程因为等待某某事件的发生(比如等待 socket 连接、等待信号量),而被挂起
(6)、zombie 状态(僵尸):父亲没有通过 wait 系列的系统调用会顺便将子进程的尸体(task_struct)也释放掉
(7)、退出状态



D 不可中断 Uninterruptible(usually IO)
R 正在运行,或在队列中的进程
S 处于休眠状态
T 停止或被追踪
Z 僵尸进程
W 进入内存交换(从内核 2.6 开始无效)
X 死掉的进程

 


问题十八:


怎么使一个命令在后台运行?
答案:
一般都是使用 & 在命令结尾来让程序自动运行。(命令后可以不追加空格)


问题十九:


利用 ps 怎么显示所有的进程? 怎么利用 ps 查看指定进程的信息?
答案:
ps -ef (system v 输出) 


ps -aux bsd 格式输出


ps -ef | grep pid

问题二十:


哪个命令专门用来查看后台任务? 


答案:


job -l


问题二十一:


把后台任务调到前台执行使用什么命令?把停下的后台任务在后台执行起来用什么命令?
答案:
把后台任务调到前台执行 fg


把停下的后台任务在后台执行起来 bg


 


问题二十二:


终止进程用什么命令? 带什么参数? 


答案:


kill [-s <信息名称或编号>][程序] 或 kill [-l <信息编号>] 


kill-9 pid


 


问题二十三:


怎么查看系统支持的所有信号?


答案:


kill -l

问题二十四:


搜索文件用什么命令? 格式是怎么样的? 


答案:


find <指定目录> <指定条件> <指定动作>


whereis 加参数与文件名


locate 只加文件名


find 直接搜索磁盘,较慢。


find / -name “string*”


 


问题二十五:


查看当前谁在使用该主机用什么命令? 查找自己所在的终端信息用什么命令?
答案:
查找自己所在的终端信息:who am i


查看当前谁在使用该主机:who


 


问题二十六:


使用什么命令查看用过的命令列表?


答案:


history


问题二十七:


使用什么命令查看磁盘使用空间? 空闲空间呢?


答案:


df -hl
文件系统 容量 已用 可用 已用% 挂载点
Filesystem Size Used Avail Use% Mounted on /dev/hda2 45G 19G 24G 44% /
/dev/hda1 494M 19M 450M 4% /boot

问题二十八:


使用什么命令查看网络是否连通?
答案:
netstat

问题二十九:


使用什么命令查看 ip 地址及接口信息?


答案:


ifconfig

问题三十:


查看各类环境变量用什么命令?


答案:


查看所有 env
查看某个,如 home: env $HOME

问题三十一:


通过什么命令指定命令提示符?


答案:



\u:显示当前用户账号


\h:显示当前主机名


\W:只显示当前路径最后一个目录


\w:显示当前绝对路径(当前用户目录会以~代替)


$PWD:显示当前全路径


\$:显示命令行’$’或者’#’符号


#:下达的第几个命令


\d:代表日期,格式为week day month date,例如:”MonAug1”


\t:显示时间为24小时格式,如:HH:MM:SS


\T:显示时间为12小时格式


\A:显示时间为24小时格式:HH:MM


\v:BASH的版本信息 如export PS1=’[\u@\h\w#]\$‘

 


问题三十二:


查找命令的可执行文件是去哪查找的? 怎么对其进行设置及添加? 


答案:


whereis [-bfmsu][-B <目录>…][-M <目录>…][-S <目录>…][文件…]


补充说明:whereis 指令会在特定目录中查找符合条件的文件。这些文件的烈性应属于原始代码,二进制文件,或是帮助文件。



-b   只查找二进制文件。


-B<目录> 只在设置的目录下查找二进制文件。 -f 不显示文件名前的路径名称。
-m   只查找说明文件。
-M<目录> 只在设置的目录下查找说明文件。 -s 只查找原始代码文件。
-S<目录> 只在设置的目录下查找原始代码文件。 -u 查找不包含指定类型的文件。
which 指令会在 PATH 变量指定的路径中,搜索某个系统命令的位置,并且返回第一个搜索结果。
-n 指定文件名长度,指定的长度必须大于或等于所有文件中最长的文件名。
-p 与-n 参数相同,但此处的包括了文件的路径。 -w 指定输出时栏位的宽度。
-V   显示版本信息

 


问题三十三:


通过什么命令查找执行命令?
答案:
which 只能查可执行文件


whereis 只能查二进制文件、说明文档,源文件等


问题三十四:


怎么对命令进行取别名?
答案:
alias la=’ls -a’

问题三十五:


du 和 df 的定义,以及区别?
答案:


du 显示目录或文件的大小


df 显示每个<文件>所在的文件系统的信息,默认是显示所有文件系统。
(文件系统分配其中的一些磁盘块用来记录它自身的一些数据,如 i 节点,磁盘分布图,间接块,超级块等。这些数据对大多数用户级的程序来说是不可见的,通常称为 Meta Data。) du 命令是用户级的程序,它不考虑 Meta Data,而 df 命令则查看文件系统的磁盘分配图并考虑 Meta Data。
df 命令获得真正的文件系统数据,而 du 命令只查看文件系统的部分情况。

问题三十六:


awk 详解。
答案:



awk ‘{pattern + action}’ {filenames}
#cat /etc/passwd |awk -F ‘:’ ‘{print $1”\t”$7}’ //-F 的意思是以’:’分隔 root /bin/bash
daemon /bin/sh 搜索/etc/passwd 有 root 关键字的所有行

#awk -F: ‘/root/‘ /etc/passwd root:x:0:0:root:/root:/bin/bash

 


问题三十七:


当你需要给命令绑定一个宏或者按键的时候,应该怎么做呢?


答案:


可以使用bind命令,bind可以很方便地在shell中实现宏或按键的绑定。


在进行按键绑定的时候,我们需要先获取到绑定按键对应的字符序列。


比如获取F12的字符序列获取方法如下:先按下Ctrl+V,然后按下F12 .我们就可以得到F12的字符序列 ^[[24~。


接着使用bind进行绑定。


[root@localhost ~]# bind ‘”\e[24~”:”date”‘


注意:相同的按键在不同的终端或终端模拟器下可能会产生不同的字符序列。


【附】也可以使用showkey -a命令查看按键对应的字符序列。


 


问题三十八:


如果一个linux新手想要知道当前系统支持的所有命令的列表,他需要怎么做?


答案:


使用命令compgen ­-c,可以打印出所有支持的命令列表。



[root@localhost ~]$ compgen -c


l.


ll


ls


which


if


then


else


elif


fi


case


esac


for


select


while


until


do


done


…

 


问题三十九:


如果你的助手想要打印出当前的目录栈,你会建议他怎么做?


答案:


使用Linux 命令dirs可以将当前的目录栈打印出来。



[root@localhost ~]# dirs

/usr/share/X11

【附】:目录栈通过pushd popd 来操作。


 


问题四十:


你的系统目前有许多正在运行的任务,在不重启机器的条件下,有什么方法可以把所有正在运行的进程移除呢?


答案:


使用linux命令 ’disown -r ’可以将所有正在运行的进程移除。


 


问题四十一:


bash shell 中的hash 命令有什么作用?


答案:


linux命令’hash’管理着一个内置的哈希表,记录了已执行过的命令的完整路径, 用该命令可以打印出你所使用过的命令以及执行的次数。



[root@localhost ~]# hash


hits command


2 /bin/ls


2 /bin/su

 


问题四十二:


哪一个bash内置命令能够进行数学运算。


答案:


bash shell 的内置命令let 可以进行整型数的数学运算。



#! /bin/bash
…
…
let c=a+b
…
…

 


问题四十三:


怎样一页一页地查看一个大文件的内容呢?


答案:


通过管道将命令”cat file_name.txt” 和 ’more’ 连接在一起可以实现这个需要.


[root@localhost ~]# cat file_name.txt | more


 


问题四十四:


数据字典属于哪一个用户的?


答案:


数据字典是属于’SYS’用户的,用户‘SYS’ 和 ’SYSEM’是由系统默认自动创建的


 


问题四十五:


怎样查看一个linux命令的概要与用法?假设你在/bin目录中偶然看到一个你从没见过的的命令,怎样才能知道它的作用和用法呢?


答案:


使用命令whatis 可以先出显示出这个命令的用法简要,比如,你可以使用whatis zcat 去查看‘zcat’的介绍以及使用简要。



[root@localhost ~]# whatis zcat


zcat [gzip] (1) – compress or expand files

 

问题四十六:

使用哪一个命令可以查看自己文件系统的磁盘空间配额呢?

答案:

使用命令repquota 能够显示出一个文件系统的配额信息

【附】只有root用户才能够查看其它用户的配额。


转载来源:https://www.cnblogs.com/hystj/p/8552757.html

对linux命令的学习总结

发表于 2019-01-09
字数统计: 1,973 | 阅读时长 ≈ 7

1.一些简单的linux命令

$passwd
修改用户登陆口令

$date
显示当前日期和时间

$cal
显示指定年份或指定月份的日历表

$login
登录提示

$help
通过显示一系列的菜单选择和提问,引导用户学校大多数常用的linux命令

$man
显示在线系统文档的内容

$who
列出当前系统所有用户的登录名、终端号和登录时间

命令键 功能
$who -q 或 $who –count 快速who命令 ;仅显示用户名和用户数
$who -H 或 $who –heading 在每一列上显示列标题
$who -b 显示系统的启动日期和时间
$who –help 显示使用方法信息

2.vi编辑器的命令

$vi myfirst
使用vi编辑器编辑名为myfirst的文件,若文件不存在则创建一个名为myfirst的文件

切换模式键

命令键 功能
i 在光标的左侧输入正文
I 在光标所在行的开头输入正文
a 在光标的右侧输入正文
A 在光标所在行的末尾输入正文
o 在光标所在行的下一行增添新行,并且光标位于新行的开头
O 在光标所在行的上一行增添新行,并且光标位于新行的开头

文本修改键

命令键 功能
x 删除光标位置指定的字符
dd 删除光标所在的行
u 撤销最近的修改
U 撤销对当前行所做的所有修改
r 替换光标位置上的一个字符
R 替换从光标位置开始的字符,同时改变vi到文本输入模式
.(点) 重复上一次的修改

光标移动键

命令键 功能
h或[left] 将光标向左移动一格
j或[down] 将光标向下移动一格
k或[Up] 将光标向上移动一格
l或[right] 将光标向右移动一格
$ 将光标移到当前行的行尾
w 将光标向右移动一个字
b 将光标向左移动一个字
e 将光标移到字尾
0(零) 将光标移到当前行的行首
[Return] 将光标移到下一行的行首
[Spacebar] 将光标向右移动一格
[Backspace] 将光标向左移动一格

退出命令

命令键 功能
wq 保存文件,退出vi编辑器
w 保存文件,但不退出vi编辑器
q 退出vi编辑器
q! 不保存文件,退出vi编辑器
ZZ 保存文件,退出vi编辑器

搜索命令

命令键 功能
/ 向前搜索指定的字符串
? 向后搜索指定的字符串

3.Linux文件系统

linux的文件结构

  • bin 用户二进制文件
  • sbin 系统二进制文件
  • home 用户的家目录
  • root 系统管理员的家目录
  • usr 用户程序
  • lib 系统库
  • var 变量文件
  • etc 配置文件
  • dev 设备文件
  • tmp 临时文件
  • proc 进程信息
  • srv 服务数据
  • mnt 挂在目录
  • boot 引导加载程序文件

$cd
将当前目录改变到另一个目录

$pwd
显示用户工作目录或指定的其他目录的路径名

$mkdir
在工作目录或指定的其他目录下创建一个新的目录

$rmdir
删除指定的目录。该目录必须为空

$cat
连接/显示文件

$|
管道操作符

$rm
删除当前目录或指定的其他目录下的文件

命令键 功能
$rm -i 或 –interactive 删除文件前,给出确认信息
$rm -r 或 –recursive 删除指定的目录及目录下的所有文件和子目录
$rm –help 显示帮助信息

$ls
列出当前目录或指定的其他目录的内容

命令键 功能
$ls -a 或 $ls –all 列出所有文件,包括隐藏文件
$ls -C 或 $ls –fomat=vertical –format=horizontal 用多列格式列出文件,按列排序
$ls -F 或 $ls –classify 在每个目录文件名后加(/),在可执行文件后加(*)
$ls -I 或 $ls –format=single-column 以长格式列出文件,显示文件的详细信息
$ls -m 或 $ls –format=commas 按页宽列文件,以逗号隔开
$ls -p 在目录文件名后加(/)
$ls -r 或 $ls –reverse 以字母反序列出文件
$ls -R 或 $ls –recursive 循环列出子目录的内容
$ls -s 或 $ls –size 以块为单位显示每个文件的大小
$ls -x 或 $ls –format=horizontal –format=across 以多列格式列出文件,按行排序
$ls –help 显示帮助信息

4.Linux文件系统高级操作

$cp
从当前目录或其他目录复制文件到另一个目录下

$cut
从文件中取出指定的列或域

命令键 功能
$cut -f 或 $cut –fields 指定域位置
$cut -c 或 $cut –characters 指定字符位置
$cut -d 或 $cut –delimiter 指定域分隔符(分界符)
$cut –help 显示帮助也并退出
$cut –version 显示版本信息并退出

$find
定位在层次目录中匹配给定规则的文件

命令键 功能
$find -name filename 根据给定的文件名filename查找文件
$find -size+n 查找文件大小为n的文件
$find file type 查找指定类型的文件
$find -atime+n 查找n天以前访问的文件
$find -mtime+n 查找n天以前修改的文件
$find newer filename 查找比filename更近期更新的文件
$find -print 显示找到的每个文件的路径名
$find -exec command\; 对找到的文件执行command
$find -ok command\; 执行command之前要求确认

$head
显示指定文件的头部。

$In
在已存在的文件和另一个文件名或目录直接创建链接。这样可以使文件有一个以上的名字

$more
以一次显示一屏的方式显示文件。这个命令对读大文件很有用

$mv
给文件改名或将文件从一个位置移到另一个位置

$wc
计算指定文件中的字符数、字数或行数

命令键 功能
$wc -l 或 $wc –lines 报告行数
$wc -w 或 $wc –words 报告字数
$wc -c 或 $wc -chars 报告字符数
$wc –help 显示帮助页并退出
$wc –version 显示版本信息并退出

$tail
显示指定文件的最后部分(尾部)

5.Linux中shell的使用

$alias
创建命令的别名

$echo
在输出设备上显示其参数输出

$fc
可以列出、编辑和重新执行以前输入的存储在history文件中的命令

$grep
在文件中搜索指定的样式

$history
保存用户在会话中所输入的命令列表

$kill
结束一个不需要或失控的进程。用户需指定进程的ID号。进程的ID号为0表示结束所有与终端相关的进程

$nohup
用户退出系统时不终止后台程序

$ps
显示所有与终端相关的进程ID

命令键 功能
$ps -a 显示所有活动进程的状态,而不仅仅是用户进程
$ps -f 显示信息的完整列表,包括完整的命令行

$r
重复执行最后一条命令或history文件中的命令

$set
在输出设备上先试试环境/shell变量。

$unset
取消不需要的变量

$sleep
使进程休眠(等待)指定的时间,以秒计

$sort
用不同规格将文本文件中的内容排序

$tee
分离输出。一份显示在输出终端上,另一份保存在文件中

$chmod
改变选项字母指定的用户类型对某特定文件的访问权限。用户类型有:u(用户/所有者)、g(同组用户)、o(其他用户)和a(所有用户)。访问权限有:r(读)、w(写)、x(执行)

$exit

终止当前的shell程序。也可以返回一个状态码(RC)来指示程序执行的成功与否。如果用户在$提示下输入该命令,它将终止用户登录shell并使用户退出系统

在oracle中通过身份证号获取出生日期,性别

发表于 2018-12-05
字数统计: 1,311 | 阅读时长 ≈ 5

首先弄清身份证18位的构成(这里只讲18位的 ):

位数 作用
第1、2位数字 表示所在省份的代码
第3、4位数字 表示所在城市的代码
第5、6位数字 表示所在区县的代码
第7~14位数字 表示出生年、月、日(1到9的月份和日用01到09表示)
第15、16位数字 表示所在地的派出所的代码
第17位数字 表示性别,奇数表示男性,偶数表示女性
第18位数字 是校检码,是随计算机的随机产生, 用来检验身份证的正确性。校检码可以是0~9的数字,当校验码为10时,则在身份证上用X代替显示,以符合国家公民身份证要求标准。

我们要用的就是第7~14位和第17位,来获取出生日期和性别
先来看一下sql和查询结果

1
2
3
4
5
6
7
select substr('123456198909210248',7,8) AS BRITH,
regexp_replace(
regexp_substr(substr('123456198909210248',17,1 ),'^\d*[13579]$') ,'^\d*[13579]$','男'
)||regexp_replace(
regexp_substr(substr('123456198909210248',17,1 ),'^\d*[02468]$') ,'^\d*[02468]$','女'
)AS SEX
from dual

查询结果:
这里写图片描述
让我们一起来看看sql代码:
1、substr函数 格式: substr(string string, int a, int b)
       (1)string 需要截取的字符串
       (2)a截取字符串的开始位置(注:当a等于0或1时,都是从第一位开始截取)
       (3)b 要截取的字符串的长度
而这里substr(‘123456198909210248’,7,8) 就表示截取证件号的第7~14位数字即出生日期
2、再看一下正则式

^\d*[13579]$

我们逐个了解各个字符的含义

字符 含义
^ 匹配一个字符串的开始。如果与“m” 的match_parameter一起使用,则匹配表达式中任何位置的行的开头。
\b 匹配一个数字字符。
* 匹配零个或多个。
[ ] 用于指定一个匹配列表,您尝试匹配列表中的任何一个字符。
$ 匹配字符串的结尾。如果与“m” 的match_parameter一起使用,则匹配表达式中任何位置的行的末尾。

这个式子就表示匹配10以内的奇数,同理

^\d*[02468]$

就表示匹配10以内的偶数
3、regexp_substr(expression, regexp) –返回满足条件的字符或字符串,

regexp_substr(substr(‘123456198909210248’,17,1 ),’^\d*[13579]$’)

就表示只返回奇数(偶数的只返回偶数)
4、 regexp_replace(expression, regexp, replacement) –将expression中的按regexp匹配到的部分用replacement代替.

1
2
3
regexp_replace(
regexp_substr(substr('123456198909210248',17,1 ),'^\d*[13579]$') ,'^\d*[13579]$','男'
)

就表示若为奇数返回男,若为偶数返回空,

1
2
3
regexp_replace(
regexp_substr(substr('123456198909210248',17,1 ),'^\d*[02468]$') ,'^\d*[02468]$','女'
)AS SEX

就表示若为偶数返回女,若为奇数返回空
将这两个用 || 拼接起来就能实现若为奇数返回男,若为偶数返回女
5、常用的正则式字符

字符 含义
^ 匹配一个字符串的开始。如果与“m” 的match_parameter一起使用,则匹配表达式中任何位置的行的开头。
$ 匹配字符串的结尾。如果与“m” 的match_parameter一起使用,则匹配表达式中任何位置的行的末尾。
* 匹配零个或多个。
+ 匹配一个或多个出现。
? 匹配零次或一次出现。
。 匹配任何字符,除了空。
[ ] 用于指定一个匹配列表,您尝试匹配列表中的任何一个字符。
[^] 用于指定一个不匹配的列表,您尝试匹配除列表中的字符以外的任何字符。
( ) 用于将表达式分组为一个子表达式。
{M} 匹配m次。
{M,} 至少匹配m次。
{M,N} 至少匹配m次,但不多于n次。
\n n是1到9之间的数字。在遇到\ n之前匹配在()内找到的第n个子表达式。
[ . . ] 匹配一个可以多于一个字符的整理元素。
[:] 匹配字符类。
[==] 匹配等价类。
\d 匹配一个数字字符。
\D 匹配一个非数字字符。
\w 匹配包括下划线的任何单词字符。
\W 匹配任何非单词字符。
\s 匹配任何空白字符,包括空格,制表符,换页符等等。
\S 匹配任何非空白字符。
\A 在换行符之前匹配字符串的开头或匹配字符串的末尾。
\Z 匹配字符串的末尾。
*? 匹配前面的模式零次或多次发生。
+? 匹配前面的模式一个或多个事件。
?? 匹配前面的模式零次或一次出现。
{N}? 匹配前面的模式n次。
{N,}? 匹配前面的模式至少n次。
{N,M}? 匹配前面的模式至少n次,但不超过m次。

6、常用正则表达式

用途表达式
用户名/^[a-z0-9_-]{3,16}$/
密码/^[a-z0-9_-]{6,18}$/
十六进制/^#?([a-f0-9]{6}|[a-f0-9]{3})$/
电子邮箱 /^([a-z0-9_.-]+)@([\da-z.-]+).([a-z.]{2,6})$/
/^[a-z\d]+(.[a-z\d]+)@(\da-z?)+(.{1,2}[a-z]+)+$/
URL/^(https?:\/\/)?([\da-z.-]+).([a-z.]{2,6})([\/\w .-])\/?$/
IP地址/((2[0-4]\d|25[0-5]|[01]?\d\d?).){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)/
/^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/
HTML标签 /^<([a-z]+)([^<]+)(?:>(.)<\/\1>|\s+\/>)$/
删除代码\注释(?<!http:|\S)//.$
Unicode编码中的汉字范围/^[\u2E80-\u9FFF]+$/

oracle快速生成上千万条测试数据

发表于 2018-11-27
字数统计: 606 | 阅读时长 ≈ 2

话不多说直接上代码

1
2
3
4
5
6
7
8
9
10
11
12
insert into student
(ID,XM,ZJH,ZL,DJSJ,XYSJ)
select rownum as ID,
dbms_random.string('x',2) as XM,
trunc(dbms_random.value(100000000000000000,999999999999999999)) as ZJH,
decode(trunc(dbms_random.value(1,3)),1,'11111111',
2, 'abcdefg',
3,'返回值可以是数字,字符串,汉字等'
)as ZL,
to_char(sysdate+rownum/24/3600,'yy-mm-dd hh24:mi:ss') as DJSJ,
systimestamp as XYSJ
from xmltable('1 to 10000000')

上面SQL是利用了Oracle数据库语法的几个实用小技巧实现的:
1、利用xmltable(在10g开始支持XML后可用),如本例中的from xmltable(‘1 to 10000000’)即表示生成1000万条数据,也可以利用Oracle特有的“connect by”树形连接语法生成测试记录,只是将

from xmltable(‘1 to xx’)
换成
from dual
connect by level <= xx;

例“level <= 10”表示要生成10记录,但是connect by level有上限,如果超出上限,系统会报,”connect by level”内存不足,我试过100万条数据可以,但是再多就不行了,
2、利用rownum虚拟列生成递增的整数数据;
3、利用sysdate函数加一些简单运算来生成日期数据,本例中是每条记录的时间加1秒;
4、利用dbms_random.value函数生成随机的数值型数据,然后用trunc函数返回处理后的数值,其工作机制与ROUND函数极为类似,只是该函数不对指定小数前或后的部分做相应舍入选择处理,而统统截去,本例中是生成100000000000000000到999999999999999999之间的随机整数;
5、利用dbms_random.string函数生成随机的字符型数据,本例中是生成长度为2的随机字符串,字符串中可以包括字符或数字。
6、to_char(sysdate + rownum, ‘yyyy-mm-dd hh24:mi:ss’) 这里是转换为字符串,如果该字段的类型为TimeStamp时间戳,那这里可以改写一下方法,转换为时间戳 to_timestamp(sysdate + rownum, ‘yyyy-mm-dd hh24:mi:ss’)
7、使用了decode函数,decode函数的格式为:decode(条件,值1,返回值1,值2,返回值2,…值n,返回值n,缺省值),使用trunc(dbms_random.value(1,3))随机产生数字1,2,3,再分别对应不同的返回值(返回值可以是数字,字符串,汉字等),即可实现随机插入汉字列。
8、systimestamp函数返回本机数据库上当前系统日期和时间(包括微秒和时区)。

[转]Java中的static关键字解析

发表于 2018-11-27
字数统计: 2,846 | 阅读时长 ≈ 11

  static关键字是很多朋友在编写代码和阅读代码时碰到的比较难以理解的一个关键字,也是各大公司的面试官喜欢在面试时问到的知识点之一。下面就先讲述一下static关键字的用法和平常容易误解的地方,最后列举了一些面试笔试中常见的关于static的考题。以下是本文的目录大纲:


  一.static关键字的用途


  二.static关键字的误区


  三.常见的笔试面试题


  若有不正之处,希望谅解并欢迎批评指正。


一.static关键字的用途


  在《Java编程思想》P86页有这样一段话:


  “static方法就是没有this的方法。在static方法内部不能调用非静态方法,反过来是可以的。而且可以在没有创建任何对象的前提下,仅仅通过类本身来调用static方法。这实际上正是static方法的主要用途。”


  这段话虽然只是说明了static方法的特殊之处,但是可以看出static关键字的基本作用,简而言之,一句话来描述就是:


  方便在没有创建对象的情况下来进行调用(方法/变量)。


  很显然,被static关键字修饰的方法或者变量不需要依赖于对象来进行访问,只要类被加载了,就可以通过类名去进行访问。


  static可以用来修饰类的成员方法、类的成员变量,另外可以编写static代码块来优化程序性能。


1)static方法


  static方法一般称作静态方法,由于静态方法不依赖于任何对象就可以进行访问,因此对于静态方法来说,是没有this的,因为它不依附于任何对象,既然都没有对象,就谈不上this了。并且由于这个特性,在静态方法中不能访问类的非静态成员变量和非静态成员方法,因为非静态成员方法/变量都是必须依赖具体的对象才能够被调用。


  但是要注意的是,虽然在静态方法中不能访问非静态成员方法和非静态成员变量,但是在非静态成员方法中是可以访问静态成员方法/变量的。举个简单的例子:



  在上面的代码中,由于print2方法是独立于对象存在的,可以直接用过类名调用。假如说可以在静态方法中访问非静态方法/变量的话,那么如果在main方法中有下面一条语句:


  MyObject.print2();


  此时对象都没有,str2根本就不存在,所以就会产生矛盾了。同样对于方法也是一样,由于你无法预知在print1方法中是否访问了非静态成员变量,所以也禁止在静态成员方法中访问非静态成员方法。


  而对于非静态成员方法,它访问静态成员方法/变量显然是毫无限制的。


  因此,如果说想在不创建对象的情况下调用某个方法,就可以将这个方法设置为static。我们最常见的static方法就是main方法,至于为什么main方法必须是static的,现在就很清楚了。因为程序在执行main方法的时候没有创建任何对象,因此只有通过类名来访问。


  另外记住,关于构造器是否是static方法可参考:http://blog.csdn.net/qq_17864929/article/details/48006835


2)static变量


  static变量也称作静态变量,静态变量和非静态变量的区别是:静态变量被所有的对象所共享,在内存中只有一个副本,它当且仅当在类初次加载时会被初始化。而非静态变量是对象所拥有的,在创建对象的时候被初始化,存在多个副本,各个对象拥有的副本互不影响。


  static成员变量的初始化顺序按照定义的顺序进行初始化。


3)static代码块


  static关键字还有一个比较关键的作用就是 用来形成静态代码块以优化程序性能。static块可以置于类中的任何地方,类中可以有多个static块。在类初次被加载的时候,会按照static块的顺序来执行每个static块,并且只会执行一次。


  为什么说static块可以用来优化程序性能,是因为它的特性:只会在类加载的时候执行一次。下面看个例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
class Person{
private Date birthDate;

public Person(Date birthDate) {
this.birthDate = birthDate;
}

boolean isBornBoomer() {
Date startDate = Date.valueOf("1946");
Date endDate = Date.valueOf("1964");
return birthDate.compareTo(startDate)>=0 && birthDate.compareTo(endDate) < 0;
}
}

  isBornBoomer是用来这个人是否是1946-1964年出生的,而每次isBornBoomer被调用的时候,都会生成startDate和birthDate两个对象,造成了空间浪费,如果改成这样效率会更好:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Person{
private Date birthDate;
private static Date startDate,endDate;
static{
startDate = Date.valueOf("1946");
endDate = Date.valueOf("1964");
}

public Person(Date birthDate) {
this.birthDate = birthDate;
}

boolean isBornBoomer() {
return birthDate.compareTo(startDate)>=0 && birthDate.compareTo(endDate) < 0;
}
}

  因此,很多时候会将一些只需要进行一次的初始化操作都放在static代码块中进行。


二.static关键字的误区


1.static关键字会改变类中成员的访问权限吗?


  有些初学的朋友会将java中的static与C/C++中的static关键字的功能混淆了。在这里只需要记住一点:与C/C++中的static不同,Java中的static关键字不会影响到变量或者方法的作用域。在Java中能够影响到访问权限的只有private、public、protected(包括包访问权限)这几个关键字。看下面的例子就明白了:



  提示错误”Person.age 不可视”,这说明static关键字并不会改变变量和方法的访问权限。


2.能通过this访问静态成员变量吗?


  虽然对于静态方法来说没有this,那么在非静态方法中能够通过this访问静态成员变量吗?先看下面的一个例子,这段代码输出的结果是什么?

1
2
3
4
5
6
7
8
9
10
11
12
public class Main {  
static int value = 33;

public static void main(String[] args) throws Exception{
new Main().printValue();
}

private void printValue(){
int value = 3;
System.out.println(this.value);
}
}

输出结果:

33

  这里面主要考察队this和static的理解。this代表什么?this代表当前对象,那么通过new Main()来调用printValue的话,当前对象就是通过new Main()生成的对象。而static变量是被对象所享有的,因此在printValue中的this.value的值毫无疑问是33。在printValue方法内部的value是局部变量,根本不可能与this关联,所以输出结果是33。在这里永远要记住一点:静态成员变量虽然独立于对象,但是不代表不可以通过对象去访问,所有的静态方法和静态变量都可以通过对象访问(只要访问权限足够)。


3.static能作用于局部变量么?


  在C/C++中static是可以作用域局部变量的,但是在Java中切记:static是不允许用来修饰局部变量。不要问为什么,这是Java语法的规定。


  具体原因可以参考这篇博文的讨论:http://www.debugease.com/j2se/178932.html


三.常见的笔试面试题


  下面列举一些面试笔试中经常遇到的关于static关键字的题目,仅供参考,如有补充欢迎下方留言。


1.下面这段代码的输出结果是什么?

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
public class Test extends Base{

static{
System.out.println("test static");
}

public Test(){
System.out.println("test constructor");
}

public static void main(String[] args) {
new Test();
}
}

class Base{

static{
System.out.println("base static");
}

public Base(){
System.out.println("base constructor");
}
}

输出结果:

1
2
3
4
base static
test static
base constructor
test constructor

  至于为什么是这个结果,我们先不讨论,先来想一下这段代码具体的执行过程,在执行开始,先要寻找到main方法,因为main方法是程序的入口,但是在执行main方法之前,必须先加载Test类,而在加载Test类的时候发现Test类继承自Base类,因此会转去先加载Base类,在加载Base类的时候,发现有static块,便执行了static块。在Base类加载完成之后,便继续加载Test类,然后发现Test类中也有static块,便执行static块。在加载完所需的类之后,便开始执行main方法。在main方法中执行new Test()的时候会先调用父类的构造器,然后再调用自身的构造器。因此,便出现了上面的输出结果。


2.这段代码的输出结果是什么?

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 Test {
Person person = new Person("Test");
static{
System.out.println("test static");
}

public Test() {
System.out.println("test constructor");
}

public static void main(String[] args) {
new MyClass();
}
}

class Person{
static{
System.out.println("person static");
}
public Person(String str) {
System.out.println("person "+str);
}
}


class MyClass extends Test {
Person person = new Person("MyClass");
static{
System.out.println("myclass static");
}

public MyClass() {
System.out.println("myclass constructor");
}
}

输出结果:

1
2
3
4
5
6
7
test static
myclass static
person static
person Test
test constructor
person MyClass
myclass constructor

  类似地,我们还是来想一下这段代码的具体执行过程。首先加载Test类,因此会执行Test类中的static块。接着执行new MyClass(),而MyClass类还没有被加载,因此需要加载MyClass类。在加载MyClass类的时候,发现MyClass类继承自Test类,但是由于Test类已经被加载了,所以只需要加载MyClass类,那么就会执行MyClass类的中的static块。在加载完之后,就通过构造器来生成对象。而在生成对象的时候,必须先初始化父类的成员变量,因此会执行Test中的Person person = new Person(),而Person类还没有被加载过,因此会先加载Person类并执行Person类中的static块,接着执行父类的构造器,完成了父类的初始化,然后就来初始化自身了,因此会接着执行MyClass中的Person person = new Person(),最后执行MyClass的构造器。


3.这段代码的输出结果是什么?

1
2
3
4
5
6
7
8
9
10
11
12
13
public class Test {

static{
System.out.println("test static 1");
}
public static void main(String[] args) {

}

static{
System.out.println("test static 2");
}
}

输出结果:

1
2
test static 1
test static 2

  虽然在main方法中没有任何语句,但是还是会输出,原因上面已经讲述过了。另外,static块可以出现类中的任何地方(只要不是方法内部,记住,任何方法内部都不行),并且执行是按照static块的顺序执行的。

  参考资料:

  http://lavasoft.blog.51cto.com/62575/18771/

  http://www.51cto.com/specbook/24/35011.htm

  http://blog.csdn.net/zhu_apollo/article/details/1888219

  http://blog.sina.com.cn/s/blog_70b845780100n9zz.html

  http://hi.baidu.com/yuiezt/item/b71ff5fbfe9c385cc8f3370d

  http://bbs.csdn.net/topics/330251070

  http://yezixingchen.iteye.com/blog/1597186

  《Java编程思想》

转载来源:http://www.cnblogs.com/dolphin0520/

[转]Java 集合之 ArrayList详细介绍(源码解析)和使用示例

发表于 2018-11-27
字数统计: 3,977 | 阅读时长 ≈ 20

 

概要

对Collection的具体实现类进行讲解;首先,讲解List,而List中ArrayList又最为常用。因此,本章我们讲解ArrayList。先对ArrayList有个整体认识,再学习它的源码,最后再通过例子来学习如何使用它。内容包括:
第1部分 ArrayList简介
第2部分 ArrayList数据结构
第3部分 ArrayList源码解析(基于JDK1.6.0_45)
第4部分 ArrayList遍历方式
第5部分 toArray()异常
第6部分 ArrayList示例



 


第1部分 ArrayList介绍


ArrayList简介


ArrayList 是一个数组队列,相当于 动态数组。与Java中的数组相比,它的容量能动态增长。它继承于AbstractList,实现了List, RandomAccess, Cloneable, java.io.Serializable这些接口。


ArrayList 继承了AbstractList,实现了List。它是一个数组队列,提供了相关的添加、删除、修改、遍历等功能。
ArrayList 实现了RandmoAccess接口,即提供了随机访问功能。RandmoAccess是java中用来被List实现,为List提供快速访问功能的。在ArrayList中,我们即可以通过元素的序号快速获取元素对象;这就是快速随机访问。稍后,我们会比较List的“快速随机访问”和“通过Iterator迭代器访问”的效率。


ArrayList 实现了Cloneable接口,即覆盖了函数clone(),能被克隆。


ArrayList 实现java.io.Serializable接口,这意味着ArrayList支持序列化,能通过序列化去传输。


 


和Vector不同,ArrayList中的操作不是线程安全的!所以,建议在单线程中才使用ArrayList,而在多线程中可以选择Vector或者CopyOnWriteArrayList。


 


ArrayList构造函数

1
2
3
4
5
6
7
// 默认构造函数
ArrayList()
// capacity是ArrayList的默认容量大小。当由于增加数据导致容量不足时,容量会添加上一次容量大小的一半。
ArrayList(int capacity)

// 创建一个包含collection的ArrayList
ArrayList(Collection<? extends E> collection)

 


ArrayList的API

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
// Collection中定义的API
boolean add(E object)
boolean addAll(Collection<? extends E> collection)
void clear()
boolean contains(Object object)
boolean containsAll(Collection<?> collection)
boolean equals(Object object)
int hashCode()
boolean isEmpty()
Iterator<E> iterator()
boolean remove(Object object)
boolean removeAll(Collection<?> collection)
boolean retainAll(Collection<?> collection)
int size()
<T> T[] toArray(T[] array)
Object[] toArray()
// AbstractCollection中定义的API
void add(int location, E object)
boolean addAll(int location, Collection<? extends E> collection)
E get(int location)
int indexOf(Object object)
int lastIndexOf(Object object)
ListIterator<E> listIterator(int location)
ListIterator<E> listIterator()
E remove(int location)
E set(int location, E object)
List<E> subList(int start, int end)
// ArrayList新增的API
Object clone()
void ensureCapacity(int minimumCapacity)
void trimToSize()
void removeRange(int fromIndex, int toIndex)

 


第2部分 ArrayList数据结构


ArrayList的继承关系

1
2
3
4
5
6
java.lang.Object
↳ java.util.AbstractCollection<E>
↳ java.util.AbstractList<E>
↳ java.util.ArrayList<E>
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable {}

 


ArrayList与Collection关系如下图:



ArrayList包含了两个重要的对象:elementData 和 size。


(01) elementData 是”Object[]类型的数组”,它保存了添加到ArrayList中的元素。实际上,elementData是个动态数组,我们能通过构造函数 ArrayList(int initialCapacity)来执行它的初始容量为initialCapacity;如果通过不含参数的构造函数ArrayList()来创建ArrayList,则elementData的容量默认是10。elementData数组的大小会根据ArrayList容量的增长而动态的增长,具体的增长方式,请参考源码分析中的ensureCapacity()函数。


(02) size 则是动态数组的实际大小。


 


第3部分 ArrayList源码解析(基于JDK1.6.0_45)


为了更了解ArrayList的原理,下面对ArrayList源码代码作出分析。ArrayList是通过数组实现的,源码比较容易理解。 

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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
package java.util;

public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
// 序列版本号
private static final long serialVersionUID = 8683452581122892189L;

// 保存ArrayList中数据的数组
private transient Object[] elementData;

// ArrayList中实际数据的数量
private int size;

// ArrayList带容量大小的构造函数。
public ArrayList(int initialCapacity) {
super();
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
// 新建一个数组
this.elementData = new Object[initialCapacity];
}

// ArrayList构造函数。默认容量是10。
public ArrayList() {
this(10);
}

// 创建一个包含collection的ArrayList
public ArrayList(Collection<? extends E> c) {
elementData = c.toArray();
size = elementData.length;
// c.toArray might (incorrectly) not return Object[] (see 6260652)
if (elementData.getClass() != Object[].class)
elementData = Arrays.copyOf(elementData, size, Object[].class);
}


// 将当前容量值设为 =实际元素个数
public void trimToSize() {
modCount++;
int oldCapacity = elementData.length;
if (size < oldCapacity) {
elementData = Arrays.copyOf(elementData, size);
}
}


// 确定ArrarList的容量。
// 若ArrayList的容量不足以容纳当前的全部元素,设置 新的容量=“(原始容量x3)/2 + 1”
public void ensureCapacity(int minCapacity) {
// 将“修改统计数”+1
modCount++;
int oldCapacity = elementData.length;
// 若当前容量不足以容纳当前的元素个数,设置 新的容量=“(原始容量x3)/2 + 1”
if (minCapacity > oldCapacity) {
Object oldData[] = elementData;
int newCapacity = (oldCapacity * 3)/2 + 1;
if (newCapacity < minCapacity)
newCapacity = minCapacity;
elementData = Arrays.copyOf(elementData, newCapacity);
}
}

// 添加元素e
public boolean add(E e) {
// 确定ArrayList的容量大小
ensureCapacity(size + 1); // Increments modCount!!
// 添加e到ArrayList中
elementData[size++] = e;
return true;
}

// 返回ArrayList的实际大小
public int size() {
return size;
}

// 返回ArrayList是否包含Object(o)
public boolean contains(Object o) {
return indexOf(o) >= 0;
}

// 返回ArrayList是否为空
public boolean isEmpty() {
return size == 0;
}

// 正向查找,返回元素的索引值
public int indexOf(Object o) {
if (o == null) {
for (int i = 0; i < size; i++)
if (elementData[i]==null)
return i;
} else {
for (int i = 0; i < size; i++)
if (o.equals(elementData[i]))
return i;
}
return -1;
}

// 反向查找,返回元素的索引值
public int lastIndexOf(Object o) {
if (o == null) {
for (int i = size-1; i >= 0; i--)
if (elementData[i]==null)
return i;
} else {
for (int i = size-1; i >= 0; i--)
if (o.equals(elementData[i]))
return i;
}
return -1;
}

// 反向查找(从数组末尾向开始查找),返回元素(o)的索引值
public int lastIndexOf(Object o) {
if (o == null) {
for (int i = size-1; i >= 0; i--)
if (elementData[i]==null)
return i;
} else {
for (int i = size-1; i >= 0; i--)
if (o.equals(elementData[i]))
return i;
}
return -1;
}


// 返回ArrayList的Object数组
public Object[] toArray() {
return Arrays.copyOf(elementData, size);
}

// 返回ArrayList的模板数组。所谓模板数组,即可以将T设为任意的数据类型
public <T> T[] toArray(T[] a) {
// 若数组a的大小 < ArrayList的元素个数;
// 则新建一个T[]数组,数组大小是“ArrayList的元素个数”,并将“ArrayList”全部拷贝到新数组中
if (a.length < size)
return (T[]) Arrays.copyOf(elementData, size, a.getClass());

// 若数组a的大小 >= ArrayList的元素个数;
// 则将ArrayList的全部元素都拷贝到数组a中。
System.arraycopy(elementData, 0, a, 0, size);
if (a.length > size)
a[size] = null;
return a;
}

// 获取index位置的元素值
public E get(int index) {
RangeCheck(index);

return (E) elementData[index];
}

// 设置index位置的值为element
public E set(int index, E element) {
RangeCheck(index);

E oldValue = (E) elementData[index];
elementData[index] = element;
return oldValue;
}

// 将e添加到ArrayList中
public boolean add(E e) {
ensureCapacity(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}

// 将e添加到ArrayList的指定位置
public void add(int index, E element) {
if (index > size || index < 0)
throw new IndexOutOfBoundsException(
"Index: "+index+", Size: "+size);

ensureCapacity(size+1); // Increments modCount!!
System.arraycopy(elementData, index, elementData, index + 1,
size - index);
elementData[index] = element;
size++;
}

// 删除ArrayList指定位置的元素
public E remove(int index) {
RangeCheck(index);

modCount++;
E oldValue = (E) elementData[index];

int numMoved = size - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--size] = null; // Let gc do its work

return oldValue;
}

// 删除ArrayList的指定元素
public boolean remove(Object o) {
if (o == null) {
for (int index = 0; index < size; index++)
if (elementData[index] == null) {
fastRemove(index);
return true;
}
} else {
for (int index = 0; index < size; index++)
if (o.equals(elementData[index])) {
fastRemove(index);
return true;
}
}
return false;
}


// 快速删除第index个元素
private void fastRemove(int index) {
modCount++;
int numMoved = size - index - 1;
// 从"index+1"开始,用后面的元素替换前面的元素。
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
// 将最后一个元素设为null
elementData[--size] = null; // Let gc do its work
}

// 删除元素
public boolean remove(Object o) {
if (o == null) {
for (int index = 0; index < size; index++)
if (elementData[index] == null) {
fastRemove(index);
return true;
}
} else {
// 便利ArrayList,找到“元素o”,则删除,并返回true。
for (int index = 0; index < size; index++)
if (o.equals(elementData[index])) {
fastRemove(index);
return true;
}
}
return false;
}

// 清空ArrayList,将全部的元素设为null
public void clear() {
modCount++;

for (int i = 0; i < size; i++)
elementData[i] = null;

size = 0;
}

// 将集合c追加到ArrayList中
public boolean addAll(Collection<? extends E> c) {
Object[] a = c.toArray();
int numNew = a.length;
ensureCapacity(size + numNew); // Increments modCount
System.arraycopy(a, 0, elementData, size, numNew);
size += numNew;
return numNew != 0;
}

// 从index位置开始,将集合c添加到ArrayList
public boolean addAll(int index, Collection<? extends E> c) {
if (index > size || index < 0)
throw new IndexOutOfBoundsException(
"Index: " + index + ", Size: " + size);

Object[] a = c.toArray();
int numNew = a.length;
ensureCapacity(size + numNew); // Increments modCount

int numMoved = size - index;
if (numMoved > 0)
System.arraycopy(elementData, index, elementData, index + numNew,
numMoved);

System.arraycopy(a, 0, elementData, index, numNew);
size += numNew;
return numNew != 0;
}

// 删除fromIndex到toIndex之间的全部元素。
protected void removeRange(int fromIndex, int toIndex) {
modCount++;
int numMoved = size - toIndex;
System.arraycopy(elementData, toIndex, elementData, fromIndex,
numMoved);

// Let gc do its work
int newSize = size - (toIndex-fromIndex);
while (size != newSize)
elementData[--size] = null;
}

private void RangeCheck(int index) {
if (index >= size)
throw new IndexOutOfBoundsException(
"Index: "+index+", Size: "+size);
}


// 克隆函数
public Object clone() {
try {
ArrayList<E> v = (ArrayList<E>) super.clone();
// 将当前ArrayList的全部元素拷贝到v中
v.elementData = Arrays.copyOf(elementData, size);
v.modCount = 0;
return v;
} catch (CloneNotSupportedException e) {
// this shouldn't happen, since we are Cloneable
throw new InternalError();
}
}


// java.io.Serializable的写入函数
// 将ArrayList的“容量,所有的元素值”都写入到输出流中
private void writeObject(java.io.ObjectOutputStream s)
throws java.io.IOException{
// Write out element count, and any hidden stuff
int expectedModCount = modCount;
s.defaultWriteObject();

// 写入“数组的容量”
s.writeInt(elementData.length);

// 写入“数组的每一个元素”
for (int i=0; i<size; i++)
s.writeObject(elementData[i]);

if (modCount != expectedModCount) {
throw new ConcurrentModificationException();
}

}


// java.io.Serializable的读取函数:根据写入方式读出
// 先将ArrayList的“容量”读出,然后将“所有的元素值”读出
private void readObject(java.io.ObjectInputStream s)
throws java.io.IOException, ClassNotFoundException {
// Read in size, and any hidden stuff
s.defaultReadObject();

// 从输入流中读取ArrayList的“容量”
int arrayLength = s.readInt();
Object[] a = elementData = new Object[arrayLength];

// 从输入流中将“所有的元素值”读出
for (int i=0; i<size; i++)
a[i] = s.readObject();
}
}

总结:
(01) ArrayList 实际上是通过一个数组去保存数据的。当我们构造ArrayList时;若使用默认构造函数,则ArrayList的默认容量大小是10。
(02) 当ArrayList容量不足以容纳全部元素时,ArrayList会重新设置容量:新的容量=“(原始容量x3)/2 + 1”。
(03) ArrayList的克隆函数,即是将全部元素克隆到一个数组中。
(04) ArrayList实现java.io.Serializable的方式。当写入到输出流时,先写入“容量”,再依次写入“每一个元素”;当读出输入流时,先读取“容量”,再依次读取“每一个元素”。


 


第4部分 ArrayList遍历方式


ArrayList支持3种遍历方式


(01) 第一种,通过迭代器遍历。即通过Iterator去遍历。

1
2
3
4
5
Integer value = null;
Iterator iter = list.iterator();
while (iter.hasNext()) {
value = (Integer)iter.next();
}

(02) 第二种,随机访问,通过索引值去遍历。
由于ArrayList实现了RandomAccess接口,它支持通过索引值去随机访问元素。

1
2
3
4
5
Integer value = null;
int size = list.size();
for (int i=0; i<size; i++) {
value = (Integer)list.get(i);
}

(03) 第三种,for循环遍历。如下:

1
2
3
4
Integer value = null;
for (Integer integ:list) {
value = integ;
}

 


下面通过一个实例,比较这3种方式的效率,实例代码(ArrayListRandomAccessTest.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
import java.util.*;
import java.util.concurrent.*;

/*
* @desc ArrayList遍历方式和效率的测试程序。
*
* @author skywang
*/
public class ArrayListRandomAccessTest {

public static void main(String[] args) {
List list = new ArrayList();
for (int i=0; i<100000; i++)
list.add(i);
//isRandomAccessSupported(list);
iteratorThroughRandomAccess(list) ;
iteratorThroughIterator(list) ;
iteratorThroughFor2(list) ;

}

private static void isRandomAccessSupported(List list) {
if (list instanceof RandomAccess) {
System.out.println("RandomAccess implemented!");
} else {
System.out.println("RandomAccess not implemented!");
}

}

public static void iteratorThroughRandomAccess(List list) {

long startTime;
long endTime;
startTime = System.currentTimeMillis();
for (int i=0; i<list.size(); i++) {
list.get(i);
}
endTime = System.currentTimeMillis();
long interval = endTime - startTime;
System.out.println("iteratorThroughRandomAccess:" + interval+" ms");
}

public static void iteratorThroughIterator(List list) {

long startTime;
long endTime;
startTime = System.currentTimeMillis();
for(Iterator iter = list.iterator(); iter.hasNext(); ) {
iter.next();
}
endTime = System.currentTimeMillis();
long interval = endTime - startTime;
System.out.println("iteratorThroughIterator:" + interval+" ms");
}


public static void iteratorThroughFor2(List list) {

long startTime;
long endTime;
startTime = System.currentTimeMillis();
for(Object obj:list)
;
endTime = System.currentTimeMillis();
long interval = endTime - startTime;
System.out.println("iteratorThroughFor2:" + interval+" ms");
}
}

 


运行结果:


iteratorThroughRandomAccess:3 ms
iteratorThroughIterator:8 ms
iteratorThroughFor2:5 ms


由此可见,遍历ArrayList时,使用随机访问(即,通过索引序号访问)效率最高,而使用迭代器的效率最低!


 


第5部分 toArray()异常


当我们调用ArrayList中的 toArray(),可能遇到过抛出“java.lang.ClassCastException”异常的情况。下面我们说说这是怎么回事。


ArrayList提供了2个toArray()函数:



Object[] toArray()
<T> T[] toArray(T[] contents)


调用 toArray() 函数会抛出“java.lang.ClassCastException”异常,但是调用 toArray(T[] contents) 能正常返回 T[]。


toArray() 会抛出异常是因为 toArray() 返回的是 Object[] 数组,将 Object[] 转换为其它类型(如如,将Object[]转换为的Integer[])则会抛出“java.lang.ClassCastException”异常,因为Java不支持向下转型。具体的可以参考前面ArrayList.java的源码介绍部分的toArray()。
解决该问题的办法是调用 <T> T[] toArray(T[] contents) , 而不是 Object[] toArray()。


调用 toArray(T[] contents) 返回T[]的可以通过以下几种方式实现。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// toArray(T[] contents)调用方式一
public static Integer[] vectorToArray1(ArrayList<Integer> v) {
Integer[] newText = new Integer[v.size()];
v.toArray(newText);
return newText;
}
// toArray(T[] contents)调用方式二。最常用!
public static Integer[] vectorToArray2(ArrayList<Integer> v) {
Integer[] newText = (Integer[])v.toArray(new Integer[0]);
return newText;
}

// toArray(T[] contents)调用方式三
public static Integer[] vectorToArray3(ArrayList<Integer> v) {
Integer[] newText = new Integer[v.size()];
Integer[] newStrings = (Integer[])v.toArray(newText);
return newStrings;
}

  


第6部分 ArrayList示例


本文通过一个实例(ArrayListTest.java),介绍 ArrayList 中常用API的用法。 

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
import java.util.*;

/*
* @desc ArrayList常用API的测试程序
* @author skywang
* @email kuiwu-wang@163.com
*/
public class ArrayListTest {

public static void main(String[] args) {

// 创建ArrayList
ArrayList list = new ArrayList();

// 将“”
list.add("1");
list.add("2");
list.add("3");
list.add("4");
// 将下面的元素添加到第1个位置
list.add(0, "5");

// 获取第1个元素
System.out.println("the first element is: "+ list.get(0));
// 删除“3”
list.remove("3");
// 获取ArrayList的大小
System.out.println("Arraylist size=: "+ list.size());
// 判断list中是否包含"3"
System.out.println("ArrayList contains 3 is: "+ list.contains(3));
// 设置第2个元素为10
list.set(1, "10");

// 通过Iterator遍历ArrayList
for(Iterator iter = list.iterator(); iter.hasNext(); ) {
System.out.println("next is: "+ iter.next());
}

// 将ArrayList转换为数组
String[] arr = (String[])list.toArray(new String[0]);
for (String str:arr)
System.out.println("str: "+ str);

// 清空ArrayList
list.clear();
// 判断ArrayList是否为空
System.out.println("ArrayList is empty: "+ list.isEmpty());
}
}

运行结果:

1
2
3
4
5
6
7
8
9
10
11
12
the first element is: 5
Arraylist size=: 4
ArrayList contains 3 is: false
next is: 5
next is: 10
next is: 2
next is: 4
str: 5
str: 10
str: 2
str: 4
ArrayList is empty: true

 


 


转载来源:http://www.cnblogs.com/skywang12345/p/3308556.html

超详细的使用Github+Hexo搭建属于自己的博客

发表于 2018-08-12
字数统计: 1,506 | 阅读时长 ≈ 5

Github是什么

gitHub是一个面向开源及私有软件项目的托管平台,因为只支持git 作为唯一的版本库格式进行托管,故名gitHub。这里用到Github,是因为我们需要通过Github得到自己的博客网站域名,而且需要使用gitHub同步我们个人博客的相关文件

Hexo是什么

Hexo 是一个快速、简洁且高效的博客框架。Hexo 使用 Markdown(或其他渲染引擎)解析文章,在几秒内,即可利用靓丽的主题生成静态网页。

话不多说咱们进入正题

准备相关的工具

1, Git: 我这里放的是Windows版本,如果要在其他系统上部署请到Git官网下载

2, Node.js:Node.js下载安装程序

打开cmd命令行(win+r 输入cmd回车)分别执行

1
2
3
node -v
npm -v
git --version

得到如下相对应的版本信息说明安装成功
这里写图片描述

hexo

安装

打开Git Bash(在任意文件夹下单击右键即可看到Git Bash),输入以下命令安装Hexo

$ npm install -g hexo-cli

初始化

打开Git Bash,输入命令

$ hexo init [folder]

例 $ hexo init hexotext

[folder]代表的是你的hexo文件夹名,如果不写,就默认在当前文件夹初始化。

然后进入你的hexo文件夹

$ cd [folder]

生成静态文件

需要执行generate命令生成静态文件,才能部署到服务器

$ hexo g

启动服务器

由于还没有配置Github,所以我们先部署到本地服务器

$ hexo s

在浏览器上输入http://localhost:4000/ 即可看到下图
这里写图片描述
若没有出现也不要着急可能是你的4000的端口被占用,可以重设端口

$ hexo -p 5000 server

打开浏览器输入http://localhost:5000/ 即可看到你的初始博客

Github配置

注册Github账号

进入Github官网
点击这里写图片描述进入注册界面
注意:注册Github的时候一定要选择一个合适的名字,因为后来博客网站的域名也会用到这个名字。虽然Github用户名支持后期修改,但是还是会带来很多不必要的麻烦。

创建Github仓库

创建与你的Github用户名相对应的Github Page仓库,格式必须是username.github.io。(如图)
这里写图片描述

建立关联

进入你刚创建的仓库,复制仓库的地址
这里写图片描述
这里写图片描述
打开hexo文件夹下的_config.yml文件,拉倒最下面,修改deploy为以下代码,repository后面的是你的仓库地址

deploy:
  type: git
  repo: git@github.com:jcxzzy/jcxzzy.github.io.git
  branch: master

这里有一个需要注意的地方是所有的配置“:”符号后面都要带空格,否则执行本地测试直接失败

部署

在Git Bash输入以下命令部署到Github Page

$ hexo d

然后在浏览器输入username.github.io就可以看到你的博客啦,如:jcxzzy.github.io

以后进行文章或主题的更新需要三步

清空缓存

$ hexo clean

生成静态文件

$ hexo g

部署

$ hexo d

到此你的博客已经正式上线了,下面介绍一些优化方案

更换主题

现在我们已经看见个人博客的雏形了,但是现在的博客网页一点也不高大上。为了让它看起来更美观一些,我们可以为其更换主题
介绍一个强大的主题库可以在里面选择喜欢的主题进行更换:https://hexo.io/themes/
这里分享一个NexT主题优化:https://www.jianshu.com/p/1f8107a8778c

写作

选择一个markdown编辑器,我觉得csdn自带的md编辑器就挺好用的。
写完之后直接导出到本地MarkDown格式,在本地找到后缀为.mb文件,把它复制到你hexo博客文件夹中 source 下的 _posts 中,默认只有一个 hello-world.md;
复制完之后然后使用文本编辑器打开它,在第一行加上title,内容自定,如

title:超详细的使用Github+Hexo搭建属于自己的博客

再将其发布就可以看到你发布的文章了

在不同电脑管理hexo博客

其实,这也是我在使用Hexo搭建博客遇到的一个问题,如果我们检查自己博客在Github上的文件就会发现,github仓库里的文件和我们本地博客站点的文件夹是不同的,确切来说是少了很多内容。如果我们想在不同的电脑上管理自己的博客,就必须有源文件存在远端供我们随时下载、然后修改后重新部署到远端。

我们要理解这样一个过程:hexo -d是把本地博客源文件生成的静态网页文件同步到github上,实现部署。但是博客网站的源文件仍需要我们自己保存。这里主要有两种思路可以选择:

1.在github存放我们博客静态网页文件的仓库里另建分支brach,单独用于存放源文件。
2.将本地博客文件存放在码云上。

这些都是关于git的操作,所以这里不用细说了。单对于这两种方法来说,我更倾向于第二种。因为毕竟这些都是我们搭建个人博客的源文件,将来还要在网站上发表文章,很多数据都在这里。使用码云我们可以创建私有仓库,将这些源文件私有存放更好一些,而且源文件和静态博客网页文件分开存放也避免使用分支频繁切换。

最后

一个简单的博客至此就搭建完毕了,如果你想让你的博客变得与众不同这就需要你继续学习探索了,其实搭建一个博客是很简单的事情,坚持总结和写作才是最难的事,让我们一起加油吧。

小小马里奥

小小马里奥

想在自己的代码里找出一个错误是十分困难的。而当你认为你的代码没有错误时,那就更难了。

7 日志
RSS
友情链接
  • 印记中文
© 2018 — 2019 小小马里奥
由 Hexo 强力驱动
|
主题 — NexT.Pisces v5.1.3 Total Words:15.9k
本站访问总量 次