2007年8月1日
在 Win XP 中工作和Windows中工作时一样,利用快捷键代替鼠标。可以利用键盘快捷键打开、关闭和导航“开始”菜单、桌面、菜单、对话框以及网页。键盘还可以让您更简单地与计算机交互。 单击一个标题或按 TAB 键可以突出显示这个标题,然后按 ENTER 键。 一、常规键盘快捷键
按键 |
目的 |
Ctrl + C |
复制。 |
Ctrl + X |
剪切。 |
Ctrl + V |
粘贴。 |
Ctrl + Z |
撤消。 |
DELETE |
删除。 |
Shift + Delete |
永久删除所选项,而不将它放到“回收站”中。 |
拖动某一项时按 CTRL |
复制所选项。 |
拖动某一项时按 CTRL + SHIFT |
创建所选项目的快捷键。 |
F2 |
重新命名所选项目。 |
CTRL + 向右键 |
将插入点移动到下一个单词的起始处。 |
CTRL + 向左键 |
将插入点移动到前一个单词的起始处。 |
CTRL + 向下键 |
将插入点移动到下一段落的起始处。 |
CTRL + 向上键 |
将插入点移动到前一段落的起始处。 |
CTRL + SHIFT + 任何箭头键 |
突出显示一块文本。 |
SHIFT + 任何箭头键 |
在窗口或桌面上选择多项,或者选中文档中的文本。 |
Ctrl + A |
选中全部内容。 |
F3 |
搜索文件或文件夹。 |
Alt + Enter |
查看所选项目的属性。 |
Alt + F4 |
关闭当前项目或者退出当前程序。 |
ALT + Enter |
显示所选对象的属性。 |
Alt + 空格键 |
为当前窗口打开快捷菜单。 |
Ctrl + F4 |
在允许同时打开多个文档的程序中关闭当前文档。 |
Alt + Tab |
在打开的项目之间切换。 |
Alt + Esc |
以项目打开的顺序循环切换。 |
F6 |
在窗口或桌面上循环切换屏幕元素。 |
F4 |
显示“我的电脑”和“Windows 资源管理器”中的“地址”栏列表。 |
Shift + F10 |
显示所选项的快捷菜单。 |
Alt + 空格键 |
显示当前窗口的“系统”菜单。 |
Ctrl + Esc |
显示“开始”菜单。 |
ALT + 菜单名中带下划线的字母 |
显示相应的菜单。 |
在打开的菜单上显示的命令名称中带有下划线的字母 |
执行相应的命令。 |
F10 |
激活当前程序中的菜单条。 |
右箭头键 |
打开右边的下一菜单或者打开子菜单。 |
左箭头键 |
打开左边的下一菜单或者关闭子菜单。 |
F5 |
刷新当前窗口。 |
BackSpace |
在“我的电脑”或“Windows 资源管理器”中查看上一层文件夹。 |
Esc |
取消当前任务。 |
将光盘插入到 CD-ROM 驱动器时按 SHIFT 键 |
阻止光盘自动播放。 |
二、对话框快捷键
按键 |
目的 |
Ctrl + Tab |
在选项卡之间向前移动。 |
Ctrl + Shift +Tab |
在选项卡之间向后移动。 |
Tab |
在选项之间向前移动。 |
Shift + Tab |
在选项之间向后移动。 |
ALT + 带下划线的字母 |
执行相应的命令或选中相应的选项。 |
Enter |
执行活选项动或按钮所对应的命令。 |
空格键 |
如果活选项动是复选框,则选中或清除该复选框。 |
箭头键 |
活选项动是一组选项按钮时,请选中某个按钮。 |
F1 |
显示帮助。 |
F4 |
显示当前列表中的项目。 |
BackSpace |
如果在“另存为”或“打开”对话框中选中了某个文件夹,则打开上一级文件夹。 |
三、自然键盘快捷键 在“Microsoft 自然键盘”或包含 Windows 徽标键(简称WIN) 和“应用程序”键(简称KEY) 的其他兼容键盘中,您可以使用以下快捷键。
按键 |
目的 |
WIN |
显示或隐藏"开始"菜单。 |
WIN+ BREAK |
显示"系统属性"对话框。 |
WIN+ D |
显示桌面。 |
WIN+ M |
最小化所有窗口。 |
WIN+ Shift + M |
还原最小化的窗口。 |
WIN+ E |
打开"我的电脑"。 |
WIN+ F |
搜索文件或文件夹。 |
CTRL+WIN+ F |
搜索计算机。 |
WIN+ F1 |
显示 Windows 帮助。 |
WIN+ L |
如果连接到网络域,则锁定您的计算机,或者如果没有连接到网络域,则切换用户。 |
WIN+ R |
打开"运行"对话框。 |
KEY |
显示所选项的快捷菜单。 |
WIN+ U |
打开"工具管理器"。 |
四、辅助键盘快捷键
按键 |
目的 |
右侧 SHIFT 键八秒钟 |
切换“筛选键”的开和关。 |
左边的 ALT + 左边的 SHIFT + PRINT SCREEN |
切换“高对比度”的开和关。 |
左边的 ALT + 左边的 SHIFT + NUM LOCK |
切换“鼠标键”的开和关。 |
Shift 键五次 |
切换“粘滞键”的开和关。 |
Num Lock 键五秒钟 |
切换“切换键”的开和关。 |
WIN+ U |
打开“工具管理器”。 |
“Windows 资源管理器”键盘快捷键
按键 |
目的 |
END |
显示当前窗口的底端。 |
主页 |
显示当前窗口的顶端。 |
NUM LOCK + 数字键盘的星号 (*) |
显示所选文件夹的所有子文件夹。 |
NUM LOCK + 数字键盘的加号 (+) |
显示所选文件夹的内容。 |
NUM LOCK + 数字键盘的减号 (-) |
折叠所选的文件夹。 |
左箭头键 |
当前所选项处于展开状态时折叠该项,或选定其父文件夹。 |
右箭头键 |
当前所选项处于折叠状态时展开该项,或选定第一个子文件夹。 |
一、排版: 1.关键词和操作符之间加适当的空格。 2.相对独立的程序块与块之间加空行 3.较长的语句、表达式等要分成多行书写。 4.划分出的新行要进行适应的缩进,使排版整齐,语句可读。 5.长表达式要在低优先级操作符处划分新行,操作符放在新行之首。 6.循环、判断等语句中若有较长的表达式或语句,则要进行适应的划分。 7.若函数或过程中的参数较长,则要进行适当的划分。 8.不允许把多个短语句写在一行中,即一行只写一条语句。 9.函数或过程的开始、结构的定义及循环、判断等语句中的代码都要采用缩进风格。 10.C/C++语言是用大括号‘{’和‘}’界定一段程序块的,编写程序块时‘{’和 ‘}’应各独占一行并且位于同一列,同时与引用它们的语句左对齐。在函数体 的开始、类的定义、结构的定义、枚举的定义以及if、for、do、while、 switch、case语句中的程序都要采用如上的缩进方式。
二、注释 1.注释要简单明了。 2.边写代码边注释,修改代码同时修改相应的注释,以保证注释与代码的一致性。 3.在必要的地方注释,注释量要适中。注释的内容要清楚、明了,含义准确,防止 注释二义性。保持注释与其描述的代码相邻,即注释的就近原则。 4.对代码的注释应放在其上方相邻位置,不可放在下面。 5.对数据结构的注释应放在其上方相邻位置,不可放在下面;对结构中的每个域 的注释应放在此域的右方;同一结构中不同域的注释要对齐。 6.变量、常量的注释应放在其上方相邻位置或右方。 7.全局变量要有较详细的注释,包括对其功能、取值范围、哪些函数或过程存取它 以及存取时注意事项等的说明。 8.在每个源文件的头部要有必要的注释信息,包括:文件名;版本号;作者;生成 日期;模块功能描述(如功能、主要算法、内部各部分之间的关系、该文件与其 它文件关系等);主要函数或过程清单及本文件历史修改记录等。 9.在每个函数或过程的前面要有必要的注释信息,包括:函数或过程名称;功能描 述;输入、输出及返回值说明;调用关系及被调用关系说明等。
三、命名 1.较短的单词可通过去掉“元音”形成缩写; 2.较长的单词可取单词的头几发符的优先级,并用括号明确表达式的操作顺序,避 免使用默认优先级。 3.使用匈牙利表示法
四、可读性 1.避免使用不易理解的数字,用有意义的标识来替代。 2.不要使用难懂的技巧性很高的语句。 3.源程序中关系较为紧密的代码应尽可能相邻。
五、变量 1.去掉没必要的公共变量。 2.构造仅有一个模块或函数可以修改、创建,而其余有关模块或函数只访问的公共 变量,防止多个不同模块或函数都可以修改、创建同一公共变量的现象。 3.仔细定义并明确公共变量的含义、作用、取值范围及公共变量间的关系。 4.明确公共变量与操作此公共变量的函数或过程的关系,如访问、修改及创建等。 5.当向公共变量传递数据时,要十分小心,防止赋与不合理的值或越界等现象发生。 6.防止局部变量与公共变量同名。 7.仔细设计结构中元素的布局与排列顺序,使结构容易理解、节省占用空间,并减 少引起误用现象。 8.结构的设计要尽量考虑向前兼容和以后的版本升级,并为某些未来可能的应用保 留余地(如预留一些空间等)。 9.留心具体语言及编译器处理不同数据类型的原则及有关细节。 10.严禁使用未经初始化的变量。声明变量的同时对变量进行初始化。 11.编程时,要注意数据类型的强制转换。
六、函数、过程 1.函数的规模尽量限制在200行以内。 2.一个函数最好仅完成一件功能。 3.为简单功能编写函数。 4.函数的功能应该是可以预测的,也就是只要输入数据相同就应产生同样的输出。 5.尽量不要编写依赖于其他函数内部实现的函数。 6.避免设计多参数函数,不使用的参数从接口中去掉。 7.用注释详细说明每个参数的作用、取值范围及参数间的关系。 8.检查函数所有参数输入的有效性。 9.检查函数所有非参数输入的有效性,如数据文件、公共变量等。 10.函数名应准确描述函数的功能。 11.避免使用无意义或含义不清的动词为函数命名 12.函数的返回值要清楚、明了,让使用者不容易忽视错误情况。 13/明确函数功能,精确(而不是近似)地实现函数设计。 14.减少函数本身或函数间的递归调用。 15.编写可重入函数时,若使用全局变量,则应通过关中断、信号量(即P、V操作) 等手段对其加以保护。
七、可测性 1.在编写代码之前,应预先设计好程序调试与测试的方法和手段,并设计好各种调 测开关及相应测试代码如打印函数等。 2.在进行集成测试/系统联调之前,要构造好测试环境、测试项目及测试用例,同时 仔细分析并优化测试用例,以提高测试效率。
八、程序效率 1.编程时要经常注意代码的效率。 2.在保证软件系统的正确性、稳定性、可读性及可测性的前提下,提高代码效率。 3.不能一味地追求代码效率,而对软件的正确性、稳定性、可读性及可测性造成影 响。 4.编程时,要随时留心代码效率;优化代码时,要考虑周全。 5.要仔细地构造或直接用汇编编写调用频繁或性能要求极高的函数。 6.通过对系统数据结构划分与组织的改进,以及对程序算法的优化来提高空间效率。 7.在多重循环中,应将最忙的循环放在最内层。 8.尽量减少循环嵌套层次。 9.避免循环体内含判断语句,应将循环语句置于判断语句的代码块之中。 10.尽量用乘法或其它方法代替除法,特别是浮点运算中的除法。
九、质量保证 1.在软件设计过程中构筑软件质量。 代码质量保证优先原则 (1)正确性,指程序要实现设计要求的功能。 (2)稳定性、安全性,指程序稳定、可靠、安全。 (3)可测试性,指程序要具有良好的可测试性。 (4)规范/可读性,指程序书写风格、命名规则等要符合规范。 (5)全局效率,指软件系统的整体效率。 (6)局部效率,指某个模块/子模块/函数的本身效率。 (7)个人表达方式/个人方便性,指个人编程习惯。 2.只引用属于自己的存贮空间。 3.防止引用已经释放的内存空间。 4.过程/函数中分配的内存,在过程/函数退出之前要释放。 5.过程/函数中申请的(为打开文件而使用的)文件句柄,在过程/函数退出前要关闭。 6.防止内存操作越界。 7.时刻注意表达式是否会上溢、下溢。 8.认真处理程序所能遇到的各种出错情况。 9.系统运行之初,要初始化有关变量及运行环境,防止未经初始化的变量被引用。 10.系统运行之初,要对加载到系统中的数据进行一致性检查。 11.严禁随意更改其它模块或系统的有关设置和配置。 12.不能随意改变与其它模块的接口。 13.充分了解系统的接口之后,再使用系统提供的功能。 14.要时刻注意易混淆的操作符。当编完程序后,应从头至尾检查一遍这些操作符。 15.不使用与硬件或操作系统关系很大的语句,而使用建议的标准语句。 16.建议:使用第三方提供的软件开发工具包或控件时,要注意以下几点: (1)充分了解应用接口、使用环境及使用时注意事项。 (2)不能过分相信其正确性。 (3)除非必要,不要使用不熟悉的第三方工具包与控件。
十、代码编译 1.编写代码时要注意随时保存,并定期备份,防止由于断电、硬盘损坏等原因造成 代码丢失。 2.同一项目组内,最好使用相同的编辑器,并使用相同的设置选项。 3.合理地设计软件系统目录,方便开发人员使用。 4.打开编译器的所有告警开关对程序进行编译。 5.在同一项目组或产品组中,要统一编译开关选项。 6.使用工具软件(如Visual SourceSafe)对代码版本进行维护。
十一、代码测试、维护 1.单元测试要求至少达到语句覆盖。 2.单元测试开始要跟踪每一条语句,并观察数据流及变量的变化。 3.清理、整理或优化后的代码要经过审查及测试。 4.代码版本升级要经过严格测试。
linux目录架构 / 根目录 /bin 常用的命令 binary file 的目錄 /boot 存放系统启动时必须读取的档案,包括核心 (kernel) 在内 /boot/grub/menu.lst GRUB设置 /boot/vmlinuz 内核 /boot/initrd 核心解壓縮所需 RAM Disk /dev 系统周边设备 /etc 系统相关设定文件 /etc/DIR_COLORS 设定颜色 /etc/HOSTNAME 设定用户的节点名 /etc/NETWORKING 只有YES标明网络存在 /etc/host.conf 文件说明用户的系统如何查询节点名 /etc/hosts 设定用户自已的IP与名字的对应表 /etc/hosts.allow 设置允许使用inetd的机器使用 /etc/hosts.deny 设置不允许使用inetd的机器使用 /etc/hosts.equiv 设置远端机不用密码 /etc/inetd.conf 设定系统网络守护进程inetd的配置 /etc/gateways 设定路由器 /etc/protocols 设定系统支持的协议 /etc/named.boot 设定本机为名字服务器的配置文件 /etc/sysconfig/network-scripts/ifcfg-eth0 设置IP /etc/resolv.conf 设置DNS /etc/X11 X Window的配置文件,xorg.conf 或 XF86Config 這兩個 X Server 的設定檔 /etc/fstab 记录开机要mount的文件系统 /etc/inittab 设定系统启动时init进程将把系统设置成什么样的runlevel /etc/issue 记录用户登录前显示的信息 /etc/group 设定用户的组名与相关信息 /etc/passwd 帐号信息 /etc/shadow 密码信息 /etc/sudoers 可以sudo命令的配置文件 /etc/securetty 设定哪些终端可以让root登录 /etc/login.defs 所有用户登录时的缺省配置 /etc/exports 设定NFS系统用的 /etc/init.d/ 所有服務的預設啟動 script 都是放在這裡的,例如要啟動或者關閉 /etc/xinetd.d/ 這就是所謂的 super daemon 管理的各項服務的設定檔目錄 /etc/modprobe.conf 内核模块额外参数设定 /etc/syslog.conf 日志设置文件 /home 使用者家目录 /lib 系统会使用到的函数库 /lib/modules kernel 的相关模块 /var/lib/rpm rpm套件安装处 /lost+found 系統不正常產生錯誤時,會將一些遺失的片段放置於此目錄下 /mnt 外设的挂载点 /media 与/mnt类似 /opt 主机额外安装的软件 /proc 虚拟目录,是内存的映射 /proc/version 内核版本 /proc/sys/kernel 系统内核功能 /root 系统管理员的家目录 /sbin 系统管理员才能执行的指令 /srv 一些服務啟動之後,這些服務所需要取用的資料目錄 /tmp 一般使用者或者是正在執行的程序暫時放置檔案的地方 /usr 最大的目录,存许应用程序和文件 /usr/X11R6: X-Window目录 /usr/src: Linux源代码 /usr/include:系统头文件 /usr/openwin 存放SUN的OpenWin /usr/man 在线使用手册 /usr/bin 使用者可執行的 binary file 的目錄 /usr/local/bin 使用者可執行的 binary file 的目錄 /usr/lib 系统会使用到的函数库 /usr/local/lib 系统会使用到的函数库 /usr/sbin 系统管理员才能执行的指令 /usr/local/sbin 系统管理员才能执行的指令 /var 日志文件 /var/log/secure 記錄登入系統存取資料的檔案,例如 pop3, ssh, telnet, ftp 等都會記錄在此檔案中 /var/log/wtmp 記錄登入者的訊息資料, last /var/log/messages 幾乎系統發生的錯誤訊息 /var/log/boot.log 記錄開機或者是一些服務啟動的時候,所顯示的啟動或關閉訊息 /var/log/maillog 紀錄郵件存取或往來( sendmail 與 pop3 )的使用者記錄 /var/log/cron 記錄 crontab 這個例行性服務的內容 /var/log/httpd, /var/log/news, /var/log/mysqld.log, /var/log/samba, /var/log/procmail.log: 分別是幾個不同的網路服務的記錄檔 一些常用的基本命令: uname -a 查看内核版本 ls -al 显示所有文件的属性 pwd 显示当前路径 cd - 返回上一次目录 cd ~ 返回主目录 date s 设置时间、日期 cal 显示日历 cal 2006 bc 计算器具 man & info 帮助手册 locale 显示当前字体 locale -a 所有可用字体 /etc/sysconfig/i18n设置文件 LANG=en 使用英文字体 sync 将数据同步写入硬盘 shutdonw -h now & half & poweroff 关机 reboot 重启 startx & init 5 进入图形介面 /work & ?work 向上、下查找文档内容 chgrp 改变档案群组 chgrp testing install.log chown 改变所属人 chown root:root install.log chmod 改变属性 chmod 777 install.log read=4 write=2 execute=1 cp 复制 cp filename rm 删除文件 rm -rf filename 强制删除文件 rmdir 删除文件夹 mv 移动 mv 123.txt 222.txt 重命名 mkdir 创建文件夹 touch 创建文件 更新当前时间 cat 由第一行开始显示 cat |more 分页 nl 在内容前加行号 more & less 一面一面翻动 head -n filename 显示第N行内容 tail -n filename 显示后N行内容 od 显示非纯文档 df -h 显示分区空间 du 显示目录或文件的大小 fdisk 分区设置 fdisk -l /dev/hda 显示硬盘分区状态 mkfs 建立各种文件系统 mkfs -t ext3 /dev/ram15 fsck 检查和修复LINUX档案 ln 硬链接 ln -s 软件链接 whereis 查找命令 locate 查找 find 查找 find / -name "***.***" which 查看工具 whoami 显示当前用户 gcc -v 查看GCC版本 chattr +i filename 禁止删除 chattr -i filename 取消禁止 lsattr 显示隐藏档属性 updatedb 更新资料库 mke2fs 格式化 mkfs -t ext3 dd if=/etc/passwd of=/tmp/passwd.bak 备份 mount 列出系统所有的分区 mount -t iso9660 /dev/cdrom /mnt/cdrom 挂载光盘 mount -t vfat /dev/fd0 /mnt/floppy 挂载软盘 mount -t vfat -o iocharset=utf8,umask=000 /dev/hda2 /mnt/hda2 挂载fat32分区 mount -t ntfs -o nls=utf8,umask=000 /dev/hda3 /mnt/hda3 挂载ntfs分区 Linux-NTFS Project: http://linux-ntfs.sourceforge.net/ umount /mnt/hda3 缷载 ifconfig 显示或设置网络设备 service network restart 重启网卡 ifdown eth0 关闭网卡 ifup eth0 开启网卡 clear 清屏 history 历史记录 !55 执行第55个指令 stty 设置终端 stty -a fdisk /mbr 删除GRUB at 僅進行一次的工作排程 crontab 循環執行的例行性命令 [e]编辑,[l]显示,[r]删除任务 & 后台运行程序 tar -zxvf 123.tar.gz & --------->后台运行 jobs 观看后台暂停的程序 jobs -l fg 将后台程序调到前台 fg n ------>n是数字,可以指定进行那个程序 bg 让工作在后台运行 kill 结束进程 kill -9 PID [9]强制结束,[15]正常结束,[l]列出可用的kill信号 ps aux 查看后台程序 top 查看后台程序 top -d 2 每两秒更新一次 top -d 2 -p10604 观看某个PID top -b -n 2 > /tmp/top.txt ----->將 top 的資訊進行 2 次,然後將結果輸出到 /tmp/top.txt pstree 以树状图显示程序 [A]以 ASCII 來連接, [u]列出PID, [p]列出帐号 killall 要刪除某個服務 killall -9 httpd free 显示内存状态 free -m -------->以M为单位显示 uptime 显示目前系统开机时间 netstat 显示网络状态 netstat -tulnp------>找出目前系統上已在監聽的網路連線及其 PID dmesg 显示开机信息 demsg | more nice 设置优先权 nice -n -5 vi & ----->用 root 給一個 nice 植為 -5 ,用於執行 vi renice 调整已存在优先权 runlevel 显示目前的runlevel depmod 分析可载入模块的相依性 lsmod 显示已载入系统的模块 modinfo 显示kernel模块的信息 insmod 载入模块 modprobe 自动处理可载入模块 rmmod 删除模块 chkconfig 检查,设置系统的各种服务 chkconfig --list ----->列出各项服务状态 ntsysv 设置系统的各种服务 cpio 备份文件
压缩命令: *.Z compress 程式壓縮的檔案; *.bz2 bzip2 程式壓縮的檔案; *.gz gzip 程式壓縮的檔案; *.tar tar 程式打包的資料,並沒有壓縮過; *.tar.gz tar 程式打包的檔案,其中並且經過 gzip 的壓縮 compress filename 压缩文件 加[-d]解压 uncompress gzip filename 压缩 加[-d]解压 zcat 123.gz 查看压缩文件内容 bzip2 -z filename 压缩 加[-d]解压 bzcat filename.bz2 查看压缩文件内容 tar -cvf /home/123.tar /etc 打包,不压缩 tar -xvf 123.tar 解开包 tar -zxvf /home/123.tar.gz 以gzip解压 tar -jxvf /home/123.tar.bz2 以bzip2解压 tar -ztvf /tmp/etc.tar.gz 查看tar内容 cpio -covB > [file|device] 份份 cpio -icduv < [file|device] 还原 vi一般用法 一般模式 编辑模式 指令模式 h 左 a,i,r,o,A,I,R,O :w 保存 j 下 进入编辑模式 :w! 强制保存 k 上 dd 删除光标当前行 :q! 不保存离开 l 右 ndd 删除n行 :wq! 保存后离开 0 移动到行首 yy 复制当前行 :e! 还原原始档 $ 移动到行尾 nyy 复制n行 :w filename 另存为 H 屏幕最上 p,P 粘贴 :set nu 设置行号 M 屏幕中央 u 撤消 :set nonu 取消行号 L 屏幕最下 [Ctrl]+r 重做上一个动作 ZZ 保存离开 G 档案最后一行 [ctrl]+z 暂停退出 :set nohlsearch 永久地关闭高亮显示 /work 向下搜索 :sp 同时打开两个文档 ?work 向上搜索 [Ctrl]+w 两个文档设换 gg 移动到档案第一行 :nohlsearch 暂时关闭高亮显示 认识SHELL alias 显示当前所有的命令别名 alias lm="ls -al" 命令别名 unalias lm 取消命令别名 type 类似which exprot 设置或显示环境变量 exprot PATH="$PATH":/sbin 添加/sbin入PATH路径 echo $PATH 显示PATH路径 bash 进入子程序 name=yang 设定变量 unset name 取消变量 echo $name 显示变量的内容 myname="$name its me" & myname='$name its me' 单引号时$name失去变量内容 ciw=/etc/sysconfig/network-scripts/ 设置路径 env 列出所有环境变量 echo $RANDOM 显示随意产生的数 set 设置SHELL PS1='[\u@\h \w \A #\#]\$ ' 提示字元的設定 [root@linux ~]# read [-pt] variable -----------读取键盘输入的变量 參數: -p :後面可以接提示字元! -t :後面可以接等待的『秒數!』 declare 声明 shell 变量 ulimit -a 显示所有限制资料 ls /tmp/yang && echo "exist" || echo "not exist" 意思是說,當 ls /tmp/yang 執行後,若正確,就執行echo "exist" ,若有問題,就執行echo "not exist" echo $PATH | cut -d ':' -f 5 以:为分隔符,读取第5段内容 export | cut -c 10-20 读取第10到20个字节的内容 last | grep 'root' 搜索有root的一行,加[-v]反向搜索 cat /etc/passwd | sort 排序显示 cat /etc/passwd | wc 显示『行、字数、字节数』 正规表示法 [root@test root]# grep [-acinv] '搜尋字串' filename 參數說明: -a :將 binary 檔案以 text 檔案的方式搜尋資料 -c :計算找到 '搜尋字串' 的次數 -i :忽略大小寫的不同,所以大小寫視為相同 -n :順便輸出行號 -v :反向選擇,亦即顯示出沒有 '搜尋字串' 內容的那一行! grep -n 'the' 123.txt 搜索the字符 -----------搜尋特定字串 grep -n 't[ea]st' 123.txt 搜索test或taste两个字符---------利用 [] 來搜尋集合字元 grep -n '[^g]oo' 123.txt 搜索前面不为g的oo-----------向選擇 [^] grep -n '[0-9]' 123.txt 搜索有0-9的数字 grep -n '^the' 123.txt 搜索以the为行首-----------行首搜索^ grep -n '^[^a-zA-Z]' 123.txt 搜索不以英文字母开头 grep -n '[a-z]$' 123.txt 搜索以a-z结尾的行---------- 行尾搜索$ grep -n 'g..d' 123.txt 搜索开头g结尾d字符----------任意一個字元 . grep -n 'ooo*' 123.txt 搜索至少有两个oo的字符---------重複字元 * sed 文本流编辑器 利用脚本命令来处理文本文件 awd 模式扫描和处理语言 nl 123.txt | sed '2,5d' 删除第二到第五行的内容 diff 比较文件的差异 cmp 比较两个文件是否有差异 patch 修补文件 pr 要打印的文件格式化
帐号管理 /etc/passwd 系统帐号信息 /etc/shadow 帐号密码信息 经MD5 32位加密 在密码栏前面加『 * 』『 ! 』禁止使用某帐号 /etc/group 系统群组信息 /etc/gshadow newgrp 改变登陆组 useradd & adduser 建立新用户 ---------> useradd -m test 自动建立用户的登入目录 useradd -m -g pgroup test --------->指定所属级 /etc/default/useradd 相关设定 /etc/login.defs UID/GID 有關的設定 passwd 更改密码 -----------> passwd test usermod 修改用户帐号 userdel 删除帐号 ----------->userdel -r test chsh 更换登陆系统时使用的SHELL [-l]显示可用的SHELL;[-s]修改自己的SHELL chfn 改变finger指令显示的信息 finger 查找并显示用户信息 id 显示用户的ID -----------> id test groupadd 添加组 groupmod 与usermod类似 groupdel 删除组 su test 更改用户 su - 进入root,且使用root的环境变量 sudo 以其他身份来执行指令 visudo 编辑/etc/sudoers 加入一行『 test ALL=(ALL) ALL 』 %wheel ALL = (ALL) ALL 系统里所有wheel群组的用户都可用sudo %wheel ALL = (ALL) NOPASSWD: ALL wheel群组所有用户都不用密码NOPASSWD User_Alias ADMPW = vbird, dmtsai, vbird1, vbird3 加入ADMPW组 ADMPW ALL = NOPASSWD: !/usr/bin/passwd, /usr/bin/passwd [A-Za-z]*, \ !/usr/bin/passwd root 可以更改使用者密码,但不能更改root密码 (在指令前面加入 ! 代表不可) PAM (Pluggable Authentication Modules, 嵌入式模組) who & w 看谁在线 last 最近登陆主机的信息 lastlog 最近登入的時間 读取 /var/log/lastlog talk 与其他用户交谈 write 发送信息 write test [ctrl]+d 发送 mesg 设置终端机的写入权限 mesg n 禁止接收 mesg y wall 向所有用户发送信息 wall this is q test mail 写mail /etc/default/useradd 家目录默认设置 quota 显示磁盘已使用的空间与限制 quota -guvs ----->秀出目前 root 自己的 quota 限制值 quota -vu 查询 quotacheck 检查磁盘的使用空间与限制 quotacheck -avug ----->將所有的在 /etc/mtab 內,含有 quota 支援的 partition 進行掃瞄 [-m] 强制扫描 quota一定要是独立的分区,要有quota.user和quota.group两件文件,在/etc/fstab添加一句: /dev/hda3 /home ext3 defaults,usrquota,grpquota 1 2 chmod 600 quota* 设置完成,重启生效 edquota 编辑用户或群组的quota [u]用户,[g]群组,[p]复制,[t]设置宽限期限 edquota -a yang edquota -p yang -u young ----->复制 quotaon 开启磁盘空间限制 quotaon -auvg -------->啟動所有的具有 quota 的 filesystem quotaoff 关闭磁盘空间限制 quotaoff -a -------->關閉了 quota 的限制 repquota -av 查閱系統內所有的具有 quota 的 filesystem 的限值狀態 Quota 從開始準備 filesystem 的支援到整個設定結束的主要的步驟大概是: 1、設定 partition 的 filesystem 支援 quota 參數: 由於 quota 必須要讓 partition 上面的 filesystem 支援才行,一般來說, 支援度最好的是 ext2/ext3 , 其他的 filesystem 類型鳥哥我是沒有試過啦! 啟動 filesystem 支援 quota 最簡單就是編輯 /etc/fstab , 使得準備要開放的 quota 磁碟可以支援 quota 囉; 2、建立 quota 記錄檔: 剛剛前面講過,整個 quota 進行磁碟限制值記錄的檔案是 aquota.user/aquota.group, 要建立這兩個檔案就必須要先利用 quotacheck 掃瞄才行喔! 3、編輯 quota 限制值資料: 再來就是使用 edquota 來編輯每個使用者或群組的可使用空間囉; 4、重新掃瞄與啟動 quota : 設定好 quota 之後,建議可以再進行一次 quotacheck ,然後再以 quotaon 來啟動吧!
开机流程简介 1、載入 BIOS 的硬體資訊,並取得第一個開機裝置的代號; 2、讀取第一個開機裝置的 MBR 的 boot Loader (亦即是 lilo, grub, spfdisk 等等) 的開機資訊; 3、載入 Kernel 作業系統核心資訊, Kernel 開始解壓縮,並且嘗試驅動所有硬體裝置; 4、Kernel 執行 init 程式並取得 run-level 資訊; 5、init 執行 /etc/rc.d/rc.sysinit 檔案; 6、啟動核心的外掛模組 (/etc/modprobe.conf); 7、init 執行 run-level 的各個批次檔( Scripts ); 8、init 執行 /etc/rc.d/rc.local 檔案; 9、執行 /bin/login 程式,並等待使用者登入; 10、登入之後開始以 Shell 控管主機。 在/etc/rc.d/rc3.d內,以S开头的为开机启动,以K开头的为关闭,接着的数字代表执行顺序 GRUB vga设定 彩度\解析度 640x480 800x600 1024x768 1280x1024 bit 256 769 771 773 775 8 bit 32768 784 787 790 793 15 bit 65536 785 788 791 794 16 bit 16.8M 786 789 792 795 32 bit
./configure 检查系统信息 ./configure --help | more 帮助信息 make clean 清除之前留下的文件 make 编译 make install 安装 rpm -q ----->查询是否安装 rpm -ql ------>查询该套件所有的目录 rpm -qi ----->查询套件的说明资料 rpm -qc[d] ----->设定档与说明档 rpm -ivh ---->安装 rpm -V -------->查看套件有否更动过 rpm -e ------>删除 rpm -Uvh ------->升级安装 --nodeps ----->强行安装 --test ----->测试安装
JavaScript,是世界上最流行的编程语言之一。事实上世界上的每一台个人电脑都安装并在频繁使用至少一个JavaScript解释器。JavaScript的流行完全是由于他在WWW脚本语言领域中的地位决定的。
Despite its popularity, few know that JavaScript is a very nice dynamic object-oriented general-purpose programming language. How can this be a secret? Why is this language so misunderstood?
尽管它很流行,但是很少有人知道JavaScript是一个非常棒的动态面向对象通用编程语言。这居然能成为一个秘密!这门语言为什么被误解如此之深?
The Name
名字
The Java- prefix suggests that JavaScript is somehow related to Java, that it is a subset or less capable version of Java. It seems that the name was intentionally selected to create confusion, and from confusion comes misunderstanding. JavaScript is not interpreted Java. Java is interpreted Java. JavaScript is a different language.
Java- 前缀很容易使人联想到Java,并认为它是Java的子集或简化版的Java。看起来最初给它选这个名字是别有用心的,是故意混淆概念、故意制造"误解"的。JavaScript不是解释执行的Java。Java是解释执行的Java。JavaScript是另外一种语言。
JavaScript has a syntactic similarity to Java, much as Java has to C. But it is no more a subset of Java than Java is a subset of C. It is better than Java in the applications that Java (fka Oak) was originally intended for.
JavaScript的语法和Java有相似之处,这就像Java的语法和C很相像一样。但是它不是Java的子集,就像Java不是C的子集一样。它在Java(Oak)最初打算进军的领域中比Java更好。
JavaScript was not developed at Sun Microsystems, the home of Java. JavaScript was developed at Netscape. It was originally called LiveScript, but that name wasn't confusing enough.
JavaScript不是Sun Microsystems的产品,Sun是Java的家。JavaScript是在Netscape被开发出来的。它最初叫LiveScript,嗯……还是这个名字好。
The -Script suffix suggests that it is not a real programming language, that a scripting language is less than a programming language. But it is really a matter of specialization. Compared to C, JavaScript trades performance for expressive power and dynamism.
-Script后缀让人认为他不是一门真正的编程语言,和一门"编程语言"还有相当的差距。但是这只是应用领域的问题。和C相比,JavaScript是牺牲了性能但换来了丰富的表现力和灵活的形态。
Lisp in C's Clothing
披着C皮的Lisp
JavaScript's C-like syntax, including curly braces and the clunky for statement, makes it appear to be an ordinary procedural language. This is misleading because JavaScript has more in common with functional languages like Lisp or Scheme than with C or Java. It has arrays instead of lists and objects instead of property lists. Functions are first class. It has closures. You get lambdas without having to balance all those parens.
JavaScript的类C语法,包括大括号和语句的形式 ,让它看起来像普通的面向过程编程语言。这是一种误解 ,因为JavaScript和函数式语言,比如 Lisp 或 Scheme,有更多的相似之处,而不是和C或Java。它使用数组而不是列表 ,使用对象而不是属性列表。函数是第一位的,它有闭包 (closures),另外你还可以使用lambda表达式。
Typecasting
类型转换
JavaScript was designed to run in Netscape Navigator. Its success there led to it becoming standard equipment in virtually all web browsers. This has resulted in typecasting. JavaScript is the George Reeves of programming languages. JavaScript is well suited to a large class of non-Web-related applications
JavaScript最初被设计成在Netscape Navigator中运行,它在Navigator中的成功引领它成为事实上所有web浏览器的标准装备。这就造就了"类型转换"。JavaScript是编程语言中的 George Reeves(超人),是大量非web程序的称职之选。
Moving Target
移动靶
The first versions of JavaScript were quite weak. They lacked exception handling, inner functions, and inheritance. In its present form, it is now a complete object-oriented programming language. But many opinions of the language are based on its immature forms.
JavaScript的最初几版非常弱,没有异常处理,没有内部函数和继承。现如今,它已经成为完全面向对象的编程语言。但是这门语言的许多思想是基于它不成熟的形式的。
The ECMA committee that has stewardship over the language is developing extensions which, while well intentioned, will aggravate one of the language's biggest problems: There are already too many versions. This creates confusion.
ECMA委员会,这门语言的管家,正在对它进行扩展,也在蓄意恶化它最大的问题:有太多的版本。这是混乱的根源。
Design Errors
设计上的错误
No programming language is perfect. JavaScript has its share of design errors, such as the overloading of + to mean both addition and concatenation with type coercion, and the error-prone with statement should be avoided. The reserved word policies are much too strict. Semicolon insertion was a huge mistake, as was the notation for literal regular expressions. These mistakes have led to programming errors, and called the design of the language as a whole into question. Fortunately, many of these problems can be mitigated with a good lint program.
没有什么编程语言是完美的。JavaScript也有它设计上的错误,比如重载的+号随着类型的不同既表示"相加"又表示"连接",和本该避免的有错误倾向的 with 语句。它的保留字策略过于严格。分号的插入是一个巨大的错误,比如作为字面正则表达式的符号时。这些失误已直接导致编程中的错误,也使这门语言的整体设计遭人质疑。还好,这些问题中有许多都可以在良好的 lint 程序中得以缓解。
The design of the language on the whole is quite sound. Surprisingly, the ECMAScript committee does not appear to be interested in correcting these problems. Perhaps they are more interested in making new ones.
这门语言的整体设计(上的问题)是相当明显的。奇怪的是ECMAScript委员会并没有对修正其中存在的问题表现出太大的兴趣,也许他们更热衷于制造新的问题。
Lousy Implementations
糟糕的实现
Some of the earlier implementations of JavaScript were quite buggy. This reflected badly on the language. Compounding that, those implementations were embedded in horribly buggy web browsers.
JavaScript的一些早期实现有许多bug,这反过来对语言本身产生了很坏的影响。更糟糕的是这些满是bug的实现是嵌入在满是bug的web浏览器中的。
Bad Books
糟糕的书
Nearly all of the books about JavaScript are quite awful. They contain errors, poor examples, and promote bad practices. Important features of the language are often explained poorly, or left out entirely. I have reviewed dozens of JavaScript books, and I can only recommend one: JavaScript: The Definitive Guide (4th Edition) by David Flanagan. (Attention authors: If you have written a good one, please send me a review copy.)
几乎所有的JavaScript书都是相当可怕的。它们包含错误,包含不好的例子,并鼓励不好的做法。JavaScript语言的一些重要特性它们要么没有解释清楚,要么根本就没有提及。我看过很多JavaScript的书,但我只能推荐一本:David Flanagan著的 JavaScript: The Definitive Guide (4th Edition) (《JavaScript权威指南 第四版》)。(作者们请注意:如果你们写出了好书请发给我一份副本,我给你们校对。)
Substandard Standard
“准标准”的标准
The official specification for the language is published by ECMA. The specification is of extremely poor quality. It is difficult to read and very difficult to understand. This has been a contributor to the Bad Book problem because authors have been unable to use the standard document to improve their own understanding of the language. ECMA and the TC39 committee should be deeply embarrassed.
ECMA公布的官方语言规范的质量极其的差。不仅难读而且极其难懂。它可为那些"糟糕的书"做出了不小的贡献,因为那些作者无法通过这个标准文档来更深地理解这门语言。ECMA和TC39应该为此感到非常尴尬。
Amateurs
业余者
Most of the people writing in JavaScript are not programmers. They lack the training and discipline to write good programs. JavaScript has so much expressive power that they are able to do useful things in it, anyway. This has given JavaScript a reputation of being strictly for the amateurs, that it is not suitable for professional programming. This is simply not the case.
使用JavaScript的人大多不是程序员,他们缺少写良好程序的培训和训练。JavaScript有非常强大的表现力,不管怎样他们也能使用它做有用的事情。这给了JavaScript一个”全然适合业余爱好者而不适合专业程序员“的名声。这很明显是一个错误。
Object-Oriented
面向对象
Is JavaScript object-oriented? It has objects which can contain data and methods that act upon that data. Objects can contain other objects. It does not have classes, but it does have constructors which do what classes do, including acting as containers for class variables and methods. It does not have class-oriented inheritance, but it does have prototype-oriented inheritance.
JavaScript是面向对象的吗?它有对象,它的对象可以包含数据以及对数据进行操作的方法,对象也可以包含其他的对象。它没有类,但是它有构造函数来做类的事情,包括声明类的变量和方法。它没有面向类的继承,但是他有面向原型的继承。
The two main ways of building up object systems are by inheritance (is-a) and by aggregation (has-a). JavaScript does both, but its dynamic nature allows it to excel at aggregation.
构建对象系统的两大主要方法是继承(is-a)和聚合(has-a)。这两者JavaScript都有,但是它的动态天性允许有比聚合更好的实现方式。
Some argue that JavaScript is not truly object oriented because it does not provide information hiding. That is, objects cannot have private variables and private methods: All members are public.
一些关于JavaScript不是真的面向对象的争论其理由是它没有提供信息隐藏。也就是说JavaScript的对象没有私有变量和私有方法:它的所有成员都是公开的。
But it turns out that JavaScript objects can have private variables and private methods. (Click here now to find out how.) Of course, few understand this because JavaScript is the world's most misunderstood programming language.
但是事实是JavaScript 的对象可以有私有变量和私有方法(点击这里来看如何实现)。当然,之所以很少有人知道这个是因为JavaScript是世界上误解最深的语言嘛。
Some argue that JavaScript is not truly object oriented because it does not provide inheritance. But it turns out that JavaScript supports not only classical inheritance, but other code reuse patterns as well.
另一些关于JavaScript不是真的面向对象的争论其理由是它没有提供继承。但是事实是JavaScript不但支持经典的继承,而且支持其他一些代码重用的模式。
觉得这篇文章很不错,转载过来与大家一起分享.
1. oncontextmenu="window.event.returnValue=false" 将彻底屏蔽鼠标右键 <table border oncontextmenu=return(false)><td>no</table> 可用于Table
2. <body onselectstart="return false"> 取消选取、防止复制
3. onpaste="return false" 不准粘贴
4. oncopy="return false;" oncut="return false;" 防止复制
5. <link rel="Shortcut Icon" href="favicon.ico"> IE地址栏前换成自己的图标
6. <link rel="Bookmark" href="favicon.ico"> 可以在收藏夹中显示出你的图标
7. <input style="ime-mode:disabled"> 关闭输入法
8. 永远都会带着框架 <script language="JavaScript"><!-- if (window == top)top.location.href = "frames.htm"; //frames.htm为框架网页 // --></script>
9. 防止被人frame <SCRIPT LANGUAGE=JAVASCRIPT><!-- if (top.location != self.location)top.location=self.location; // --></SCRIPT>
10. 网页将不能被另存为 <noscript><*** src="/*.html>";</***></noscript>
11. <input type=button value="/查看网页源代码 onclick="window.location = "view-source:"+ "http://www.pconline.com.cn""> 12.删除时确认 <a href=""javascript :if(confirm("确实要删除吗?"))location="boos.asp?&areyou=删除&page=1"">删除</a>
13. 取得控件的绝对位置 //Javascript <script language="Javascript"> function getIE(e){ var t=e.offsetTop; var l=e.offsetLeft; while(e=e.offsetParent){ t+=e.offsetTop; l+=e.offsetLeft; } alert("top="+t+"/nleft="+l); } </script> //VBScript <script language="VBScript"><!-- function getIE() dim t,l,a,b set a=document.all.img1 t=document.all.img1.offsetTop l=document.all.img1.offsetLeft while a.tagName<>"BODY" set a = a.offsetParent t=t+a.offsetTop l=l+a.offsetLeft wend msgbox "top="&t&chr(13)&"left="&l,64,"得到控件的位置" end function --></script>
14. 光标是停在文本框文字的最后 <script language="javascript"> function cc() { var e = event.srcElement; var r =e.createTextRange(); r.moveStart("character",e.value.length); r.collapse(true); r.select(); } </script> <input type=text name=text1 value="123" onfocus="cc()">
15. 判断上一页的来源 javascript : document.referrer
16. 最小化、最大化、关闭窗口 <object id=hh1 classid="clsid:ADB880A6-D8FF-11CF-9377-00AA003B7A11"> <param name="Command" value="Minimize"></object> <object id=hh2 classid="clsid:ADB880A6-D8FF-11CF-9377-00AA003B7A11"> <param name="Command" value="Maximize"></object> <OBJECT id=hh3 classid="clsid:adb880a6-d8ff-11cf-9377-00aa003b7a11"> <PARAM NAME="Command" value="/Close"></OBJECT> <input type=button value="/最小化 onclick=hh1.Click()> <input type=button value="/blog/最大化 onclick=hh2.Click()> <input type=button value=关闭 onclick=hh3.Click()> 本例适用于IE
17.屏蔽功能键Shift,Alt,Ctrl <script> function look(){ if(event.shiftKey) alert("禁止按Shift键!"); //可以换成ALT CTRL } document.onkeydown=look; </script>
18. 网页不会被缓存 <META HTTP-EQUIV="pragma" CONTENT="no-cache"> <META HTTP-EQUIV="Cache-Control" CONTENT="no-cache, must-revalidate"> <META HTTP-EQUIV="expires" CONTENT="Wed, 26 Feb 1997 08:21:57 GMT"> 或者<META HTTP-EQUIV="expires" CONTENT="0">
19.怎样让表单没有凹凸感? <input type=text style="""border:1 solid #000000"> 或 <input type=text style="border-left:none; border-right:none; border-top:none; border-bottom: 1 solid #000000"></textarea>
20.<div><span>&<layer>的区别? <div>(division)用来定义大段的页面元素,会产生转行 <span>用来定义同一行内的元素,跟<div>的唯一区别是不产生转行 <layer>是ns的标记,ie不支持,相当于<div>
21.让弹出窗口总是在最上面: <body onblur="this.focus();">
22.不要滚动条? 让竖条没有: <body style="overflow:scroll;overflow-y:hidden"> </body> 让横条没有: <body style="overflow:scroll;overflow-x:hidden"> </body> 两个都去掉?更简单了 <body scroll="no"> </body>
23.怎样去掉图片链接点击后,图片周围的虚线? <a href="#" onFocus="this.blur()"><img src="/logo.jpg" border=0></a>
24.电子邮件处理提交表单 <form name="form1" method="post" action=mailto:****@***.com enctype="text/plain"> <input type=submit> </form>
25.在打开的子窗口刷新父窗口的代码里如何写? window.opener.location.reload()
26.如何设定打开页面的大小 <body onload="top.resizeTo(300,200);"> 打开页面的位置<body onload="top.moveBy(300,200);">
27.在页面中如何加入不是满铺的背景图片,拉动页面时背景图不动 <STYLE> body {background-image:url(/logo.gif); background-repeat:no-repeat; background-position:center;background-attachment: fixed} </STYLE>
28. 检查一段字符串是否全由数字组成 <script language="Javascript"><!-- function checkNum(str){return str.match(//D/)==null} alert(checkNum("1232142141")) alert(checkNum("123214214a1")) // --></script>
29. 获得一个窗口的大小 document.body.clientWidth; document.body.clientHeight
30. 怎么判断是否是字符 if (/[^/x00-/xff]/g.test(s)) alert("含有汉字"); else alert("全是字符");
31.TEXTAREA自适应文字行数的多少 <textarea rows=1 name=s1 cols=27 onpropertychange ="this.style.posHeight=this.scrollHeight"> </textarea>
32. 日期减去天数等于第二个日期 <script language=Javascript> function cc(dd,dadd) { //可以加上错误处理 var a = new Date(dd) a = a.valueOf() a = a - dadd * 24 * 60 * 60 * 1000 a = new Date(a) alert(a.getFullYear() + "年" + (a.getMonth() + 1) + "月" + a.getDate() + "日") } cc("12/23/2002",2) </script>
33. 选择了哪一个Radio <HTML><script language="vbscript"> function checkme() for each ob in radio1 if ob.checked then window.alert ob.value next end function </script><BODY> <INPUT name="radio1" type="radio" value="/style" checked>Style <INPUT name="radio1" type="radio" value="/blog/barcode">Barcode <INPUT type="button" value="check" onclick="checkme()"> </BODY></HTML>
34.脚本永不出错 <SCRIPT LANGUAGE="JavaScript"> <!-- Hide function killErrors() { return true; } window.onerror = killErrors; // --> </SCRIPT>
35.ENTER键可以让光标移到下一个输入框 <input onkeydown="if(event.keyCode==13)event.keyCode=9">
36. 检测某个网站的链接速度: 把如下代码加入<body>区域中: <script language=Javascript> tim=1 setInterval("tim++",100) b=1 var autourl=new Array() autourl[1]=1000){this.resized=true;this.style.width=1000;}" align=absMiddle border=0>www.njcatv.net" autourl[2]="javacool.3322.net" autourl[3]=1000){this.resized=true;this.style.width=1000;}" align=absMiddle border=0>www.sina.com.cn" autourl[4]="www.nuaa.edu.cn" autourl[5]=1000){this.resized=true;this.style.width=1000;}" align=absMiddle border=0>www.cctv.com" function butt(){ ***("<form name=autof>") for(var i=1;i<autourl.length;i++) ***("<input type=text name=txt"+i+" size=10 value="/测试中……> =》<input type=text name=url"+i+" size=40> =》<input type=button value="/blog/GO onclick=window.open(this.form.url"+i+".value)><br>") ***("<input type=submit value=刷新></form>") } butt() function auto(url){ document.forms[0]["url"+b].value=url if(tim>200) {document.forms[0]["txt"+b].value="/链接超时"} else {document.forms[0]["txt"+b].value="/blog/时间"+tim/10+"秒"} b++ } function run(){for(var i=1;i<autourl.length;i++)***("<img src=http://"+autourl+"/"+Math.random()+" width=1 height=1 onerror=auto("http://"+autourl+"")>")} run()</script>
37. 各种样式的光标 auto :标准光标 default :标准箭头 hand :手形光标 wait :等待光标 text :I形光标 vertical-text :水平I形光标 no-drop :不可拖动光标 not-allowed :无效光标 help :?帮助光标 all-scroll :三角方向标 move :移动标 crosshair :十字标 e-resize n-resize nw-resize w-resize s-resize se-resize sw-resize
38.页面进入和退出的特效 进入页面<meta http-equiv="Page-Enter" content="revealTrans(duration=x, transition=y)"> 推出页面<meta http-equiv="Page-Exit" content="revealTrans(duration=x, transition=y)"> 这个是页面被载入和调出时的一些特效。duration表示特效的持续时间,以秒为单位。transition表示使用哪种特效,取值为1-23: 0 矩形缩小 1 矩形扩大 2 圆形缩小 3 圆形扩大 4 下到上刷新 5 上到下刷新 6 左到右刷新 7 右到左刷新 8 竖百叶窗 9 横百叶窗 10 错位横百叶窗 11 错位竖百叶窗 12 点扩散 13 左右到中间刷新 14 中间到左右刷新 15 中间到上下 16 上下到中间 17 右下到左上 18 右上到左下 19 左上到右下 20 左下到右上 21 横条 22 竖条 23 以上22种随机选择一种
39.在规定时间内跳转 <META http-equiv=V="REFRESH" content="5;URL=http://www.51js.com">
40.网页是否被检索 <meta name="ROBOTS" content="属性值"> 其中属性值有以下一些: 属性值为"all": 文件将被检索,且页上链接可被查询; 属性值为"none": 文件不被检索,而且不查询页上的链接; 属性值为"index": 文件将被检索; 属性值为"follow": 查询页上的链接; 属性值为"noindex": 文件不检索,但可被查询链接; 属性值为"nofollow": 文件不被检索,但可查询页上的链接。
41、email地址的分割 把如下代码加入<body>区域中 <a href="mailto:webmaster@sina.com">webmaster@sina.com</a>
42、流动边框效果的表格 把如下代码加入<body>区域中 <SCRIPT> l=Array(6,7,8,9,'a','b','b','c','d','e','f') Nx=5;Ny=35 t="<table border=0 cellspacing=0 cellpadding=0 height="+((Nx+2)*16)+"><tr>" for(x=Nx;x<Nx+Ny;x++) t+="<td width=16 id=a_mo"+x+"> </td>" t+="</tr><tr><td width=10 id=a_mo"+(Nx-1)+"> </td><td colspan="+(Ny-2)+" rowspan="+(Nx)+"> </td><td width=16 id=a_mo"+(Nx+Ny)+"></td></tr>" for(x=2;x<=Nx;x++) t+="<tr><td width=16 id=a_mo"+(Nx-x)+"> </td><td width=16 id=a_mo"+(Ny+Nx+x-1)+"> </td></tr>" t+="<tr>" for(x=Ny;x>0;x--) t+="<td width=16 id=a_mo"+(x+Nx*2+Ny-1)+"> </td>" ***(t+"</tr></table>") var N=Nx*2+Ny*2 function f1(y){ for(i=0;i<N;i++){ c=(i+y)%20;if(c>10)c=20-c document.all["a_mo"+(i)].bgColor=""""#0000"+l[c]+l[c]+"'"} y++ setTimeout('f1('+y+')','1')} f1(1) </SCRIPT>
43、JavaScript主页弹出窗口技巧 窗口中间弹出 <script> window.open("http://www.cctv.com","","width=400,height=240,top="+(screen.availHeight-240)/2+",left="+(screen.availWidth-400)/2); </script> ============ <html> <head> <script language="LiveScript"> function WinOpen() { msg=open("","DisplayWindow","toolbar=no,directories=no,menubar=no"); msg.***("<HEAD><TITLE>哈 罗!</TITLE></HEAD>"); msg.***("<CENTER><H1>酷 毙 了!</H1><h2>这 是<B>JavaScript</B>所 开 的 视 窗!</h2></CENTER>"); } </script> </head> <body> <form> <input type="button" name="Button1" value="Push me" onclick="WinOpen()"> </form> </body> </html> ============== 一、在下面的代码中,你只要单击打开一个窗口,即可链接到赛迪网。而当你想关闭时,只要单击一下即可关闭刚才打开的窗口。 代码如下: <SCRIPT language="JavaScript"> <!-- function openclk() { another=open('1000){this.resized=true;this.style.width=1000;}" align=absMiddle border=0>http://www.ccidnet.com','NewWindow'); } function closeclk() { another.close(); } //--> </SCRIPT> <FORM> <INPUT TYPE="BUTTON" NAME="open" value="/打开一个窗口" onClick="openclk()"> <BR> <INPUT TYPE="BUTTON" NAME="close" value="/blog/关闭这个窗口" onClick="closeclk()"> </FORM> 二、上面的代码也太静了,为何不来点动感呢?如果能给页面来个降落效果那该多好啊! 代码如下: <script> function drop(n) { if(self.moveBy){ self.moveBy (0,-900); for(i = n; i > 0; i--){ self.moveBy(0,3); } for(j = 8; j > 0; j--){ self.moveBy(0,j); self.moveBy(j,0); self.moveBy(0,-j); self.moveBy(-j,0); } } } </script> <body onLoad="drop(300)"> 三、讨厌很多网站总是按照默认窗口打开,如果你能随心所欲控制打开的窗口那该多好。 代码如下: <SCRIPT LANGUAGE="JavaScript"> <!-- Begin function popupPage(l, t, w, h) { var windowprops = "location=no,scrollbars=no,menubars=no,toolbars=no,resizable=yes" + ",left=" + l + ",top=" + t + ",width=" + w + ",height=" + h; var URL = "http://www.80cn.com"; popup = window.open(URL,"MenuPopup",windowprops); } // End --> </script> <table> <tr> <td> <form name=popupform> <pre> 打开页面的参数<br> 离开左边的距离: <input type=text name=left size=2 maxlength=4> pixels 离开右边的距离: <input type=text name=top size=2 maxlength=4> pixels 窗口的宽度: <input type=text name=width size=2 maxlength=4> pixels 窗口的高度: <input type=text name=height size=2 maxlength=4> pixels </pre> <center> <input type=button value="打开这个窗口!" onClick="popupPage(this.form.left.value, this.form.top.value, this.form.width.value, this.form.height.value)"> </center> </form> </td> </tr> </table>你只要在相对应的对话框中输入一个数值即可,将要打开的页面的窗口控制得很好。
44、页面的打开移动 把如下代码加入<body>区域中 <SCRIPT LANGUAGE="JavaScript"> <!-- Begin for (t = 2; t > 0; t--) { for (x = 20; x > 0; x--) { for (y = 10; y > 0; y--) { parent.moveBy(0,-x); } } for (x = 20; x > 0; x--) { for (y = 10; y > 0; y--) { parent.moveBy(0,x); } } for (x = 20; x > 0; x--) { for (y = 10; y > 0; y--) { parent.moveBy(x,0); } } for (x = 20; x > 0; x--) { for (y = 10; y > 0; y--) { parent.moveBy(-x,0); } } } //--> // End --> </script>
45、显示个人客户端机器的日期和时间 <script language="LiveScript"> <!-- Hiding today = new Date() ***("现 在 时 间 是: ",today.getHours(),":",today.getMinutes()) ***("<br>今 天 日 期 为: ", today.getMonth()+1,"/",today.getDate(),"/",today.getYear()); // end hiding contents --> </script>
46、自动的为你每次产生最後修改的日期了: <html> <body> This is a simple HTML- page. <br> Last changes: <script language="LiveScript"> <!-- hide script from old browsers ***(document.lastModified) // end hiding contents --> </script> </body> </html>
47、不能为空和邮件地址的约束: <html> <head> <script language="JavaScript"> <!-- Hide function test1(form) { if (form.text1.value == "") alert("您 没 写 上 任 何 东 西, 请 再 输 入 一 次 !") else { alert("嗨 "+form.text1.value+"! 您 已 输 入 完 成 !"); } } function test2(form) { if (form.text2.value == "" || form.text2.value.indexOf('@', 0) == -1) alert("这 不 是 正 确 的 e-mail address! 请 再 输 入 一 次 !"); else alert("您 已 输 入 完 成 !"); } // --> </script> </head> <body> <form name="first"> Enter your name:<br> <input type="text" name="text1"> <input type="button" name="button1" value="输 入 测 试" onClick="test1(this.form)"> <P> Enter your e-mail address:<br> <input type="text" name="text2"> <input type="button" name="button2" value="输 入 测 试" onClick="test2(this.form)"> </body>
48、跑马灯 <html> <head> <script language="JavaScript"> <!-- Hide var scrtxt="怎麽样 ! 很酷吧 ! 您也可以试试."+"Here goes your message the visitors to your page will "+"look at for hours in pure fascination..."; var lentxt=scrtxt.length; var width=100; var pos=1-width; function scroll() { pos++; var scroller=""; if (pos==lentxt) { pos=1-width; } if (pos<0) { for (var i=1; i<=Math.abs(pos); i++) { scroller=scroller+" ";} scroller=scroller+scrtxt.substring(0,width-i+1); } else { scroller=scroller+scrtxt.substring(pos,width+pos); } window.status = scroller; setTimeout("scroll()",150); } //--> </script> </head> <body onLoad="scroll();return true;"> 这里可显示您的网页 ! </body> </html>
49、在网页中用按钮来控制前页,后页和主页的显示。 <html> <body> <FORM NAME="buttonbar"> <INPUT TYPE="button" VALUE="Back" onClick="history.back()"> <INPUT TYPE="button" VALUE="JS- Home" onClick="location='script.html'"> <INPUT TYPE="button" VALUE="Next" onCLick="history.forward()"> </FORM> </body> </html> 50、查看某网址的源代码 把如下代码加入<body>区域中 <SCRIPT> function add() { var ress=document.forms[0].luxiaoqing.value window.location="view-source:"+ress; } </SCRIPT> 输入要查看源代码的URL地址: <FORM><input type="text" name="luxiaoqing" size=40 value="http://"></FORM> <FORM><br> <INPUT type="button" value="查看源代码" onClick=add()> </FORM>
51、title显示日期 把如下代码加入<body>区域中: <script language="JavaScript1.2"> <!--hide var isnMonth = new Array("1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月"); var isnDay = new Array("星期日","星期一","星期二","星期三","星期四","星期五","星期六","星期日"); today = new Date () ; Year=today.getYear(); Date=today.getDate(); if (document.all) document.title="今天是: "+Year+"年"+isnMonth[today.getMonth()]+Date+"日"+isnDay[today.getDay()] //--hide--> </script>
52、显示所有链接 把如下代码加入<body>区域中 <script language="JavaScript1.2"> <!-- function extractlinks(){ var links=document.all.tags("A") var total=links.length var win2=window.open("","","menubar,scrollbars,toolbar") win2.***("<font size='2'>一共有"+total+"个连接</font><br>") for (i=0;i<total;i++){ win2.***("<font size='2'>"+links[i].outerHTML+"</font><br>") } } //--> </script> <input type="button" onClick="extractlinks()" value="显示所有的连接">
53、回车键换行 把如下代码加入<body>区域中 <script type="text/javascript"> function handleEnter (field, event) { var keyCode = event.keyCode ? event.keyCode : event.which ? event.which : event.charCode; if (keyCode == 13) { var i; for (i = 0; i < field.form.elements.length; i++) if (field == field.form.elements[i]) break; i = (i + 1) % field.form.elements.length; field.form.elements[i].focus(); return false; } else return true; } </script> <form> <input type="text" onkeypress="return handleEnter(this, event)"><br> <input type="text" onkeypress="return handleEnter(this, event)"><br> <textarea>回车换行
54、确认后提交 把如下代码加入<body>区域中 <SCRIPT LANGUAGE="JavaScript"> <!-- function msg(){ if (confirm("你确认要提交嘛!")) document.lnman.submit() } //--> </SCRIPT> <form name="lnman" method="post" action=""> <p> <input type="text" name="textfield" value="确认后提交"> </p> <p> <input type="button" name="Submit" value="提交" onclick="msg();"> </p> </form>
55、改变表格的内容 把如下代码加入<body>区域中 <script> var arr=new Array() arr[0]="一一一一一"; arr[1]="二二二二二"; arr[2]="三三三三三"; </script> <select onchange="zz.cells[this.selectedIndex].innerHTML=arr[this.selectedIndex]"> <option value=a>改变第一格</option> <option value=a>改变第二格</option> <option value=a>改变第三格</option> </select> <table id=zz border=1> <tr height=20> <td width=150>第一格</td> <td width=150>第二格</td> <td width=150>第三格</td> </tr> </table>
webservice的工作原理
实际上,WebService的主要目标是跨平台的可互操作性。为了达到这一目标,WebService完全基于XML(可扩展标记语言)、XSD(XMLSchema)等独立于平台、独立于软件供应商的标准,是创建可互操作的、分布式应用程序的新平台。由此可以看出,在以下四种情况下,使用WebService会带来极大的好处。
优势一:跨防火墙的通信
如果应用程序有成千上万的用户,而且分布在世界各地,那么客户端和服务器之间的通信将是一个棘手的问题。因为客户端和服务器之间通常会有防火墙或者代理服务器。在这种情况下,使用DCOM就不是那么简单,通常也不便于把客户端程序发布到数量如此庞大的每一个用户手中。传统的做法是,选择用浏览器作为客户端,写下一大堆ASP页面,把应用程序的中间层暴露给最终用户。这样做的结果是开发难度大,程序很难维护。
举个例子,在应用程序里加入一个新页面,必须先建立好用户界面(Web页面),并在这个页面后面,包含相应商业逻辑的中间层组件,还要再建立至少一个ASP页面,用来接受用户输入的信息,调用中间层组件,把结果格式化为HTML形式,最后还要把“结果页”送回浏览器。要是客户端代码不再如此依赖于HTML表单,客户端的编程就简单多了。
如果中间层组件换成WebService的话,就可以从用户界面直接调用中间层组件,从而省掉建立ASP页面的那一步。要调用WebService,可以直接使用MicrosoftSOAPToolkit或.NET这样的SOAP客户端,也可以使用自己开发的SOAP客户端,然后把它和应用程序连接起来。不仅缩短了开发周期,还减少了代码复杂度,并能够增强应用程序的可维护性。同时,应用程序也不再需要在每次调用中间层组件时,都跳转到相应的“结果页”。
从经验来看,在一个用户界面和中间层有较多交互的应用程序中,使用WebService这种结构,可以节省花在用户界面编程上20%的开发时间。另外,这样一个由WebService组成的中间层,完全可以在应用程序集成或其它场合下重用。最后,通过WebService把应用程序的逻辑和数据“暴露”出来,还可以让其它平台上的客户重用这些应用程序。
优势二:应用程序集成
允许在不同平台上、以不同语言编写的各种程序以基于标准的方式相互通信。企业级的应用程序开发者都知道,企业里经常都要把用不同语言写成的、在不同平台上运行的各种程序集成起来,而这种集成将花费很大的开发力量。应用程序经常需要从运行在IBM主机上的程序中获取数据;或者把数据发送到主机或UNIX应用程序中去。即使在同一个平台上,不同软件厂商生产的各种软件也常常需要集成起来。通过WebService,应用程序可以用标准的方法把功能和数据“暴露”出来,供其它应用程序使用。
例如,有一个订单记录程序,用于从客户获得新订单,包括客户信息、发货地址、数量、价格和付款方式等内容;还有一个订单执行程序,用于实际货物发送的管理。这两个程序来自不同软件厂商。一份新订单进来之后,订单记录程序需要通知订单执行程序发送货物。通过在订单执行程序上面增加一层WebService,订单执行程序可以把“AddOrder”函数“暴露”出来。这样,每当有新订单到来时,订单登录程序就可以调用这个函数来发送货物了。
优势三:B2B的集成
用WebService集成应用程序,可以使公司内部的商务处理更加自动化。但当交易跨越供应商和客户、突破公司的界限时会怎么样呢?跨公司的商务交易集成通常叫做B2B集成。
WebService是B2B集成成功的关键。通过WebService,公司可以把关键的商务应用“暴露”给指定的供应商和客户。例如,把电子下单系统和电子发票系统“暴露”出来,客户就可以以电子的方式发送订单,供应商则可以以电子的方式发送原料采购发票。当然,这并不是一个新的概念,EDI(电子文档交换)早就是这样了。但是,WebService的实现要比EDI简单得多,而且WebService运行在Internet上,在世界任何地方都可轻易实现,其运行成本就相对较低。不过,WebService并不像EDI那样,是文档交换或B2B集成的完整解决方案。WebService只是B2B集成的一个关键部分,还需要许多其它的部分才能实现集成。
用WebService来实现B2B集成的最大好处在于可以轻易实现互操作性。只要把商务逻辑“暴露”出来,成为WebService,就可以让任何指定的合作伙伴调用这些商务逻辑,而不管他们的系统在什么平台上运行,使用什么开发语言。这样就大大减少了花在B2B集成上的时间和成本,让许多原本无法承受EDI的中小企业也能实现B2B集成。
优势四:软件和数据重用
软件重用是一个很大的主题,重用的形式很多,重用的程度有大有小。最基本的形式是源代码模块或者类一级的重用,另一种形式是二进制形式的组件重用。
用WebService集成各种应用中的功能,为用户提供一个统一的界面
当前,像表格控件或用户界面控件这样的可重用软件组件,在市场上都占有很大的份额。但这类软件的重用有一个很大的限制,就是重用仅限于代码,数据不能重用。原因在于,发布组件甚至源代码都比较容易,但要发布数据就没那么容易,除非是不会经常变化的静态数据。
WebService在允许重用代码的同时,可以重用代码背后的数据。使用WebService,再也不必像以前那样,要先从第三方购买、安装软件组件,再从应用程序中调用这些组件;只需要直接调用远端的WebService就可以了。举个例子,要在应用程序中确认用户输入的地址,只需把这个地址直接发送给相应的WebService,这个WebService就会帮你查阅街道地址、城市、省区和邮政编码等信息,确认这个地址是否在相应的邮政编码区域。WebService的提供商可以按时间或使用次数来对这项服务进行收费。这样的服务要通过组件重用来实现是不可能的,那样的话你必须下载并安装好包含街道地址、城市、省区和邮政编码等信息的数据库,而且这个数据库还是不能实时更新的。
另一种软件重用的情况是,把好几个应用程序的功能集成起来。例如,要建立一个局域网上的门户站点应用,让用户既可以查询联邦快递包裹,查看股市行情,又可以管理自己的日程安排,还可以在线购买电影票。现在Web上有很多应用程序供应商,都在其应用中实现了这些功能。一旦他们把这些功能都通过WebService“暴露”出来,就可以非常容易地把所有这些功能都集成到你的门户站点中,为用户提供一个统一的、友好的界面。
将来,许多应用程序都会利用WebService,把当前基于组件的应用程序结构扩展为组件/WebService的混合结构,可以在应用程序中使用第三方的WebService提供的功能,也可以把自己的应用程序功能通过WebService提供给别人。两种情况下,都可以重用代码和代码背后的数据。
从以上论述可以看出,WebService在通过Web进行互操作或远程调用的时候是最有用的。不过,也有一些情况,WebService根本不能带来任何好处。
短处一:单机应用程序
目前,企业和个人还使用着很多桌面应用程序。其中一些只需要与本机上的其它程序通信。在这种情况下,最好就不要用WebService,只要用本地的API就可以了。COM非常适合于在这种情况下工作,因为它既小又快。运行在同一台服务器上的服务器软件也是这样。最好直接用COM或其它本地的API来进行应用程序间的调用。当然WebService也能用在这些场合,但那样不仅消耗太大,而且不会带来任何好处。
短处二:局域网的同构应用程序
在许多应用中,所有的程序都是用VB或VC开发的,都在Windows平台下使用COM,都运行在同一个局域网上。例如,有两个服务器应用程序需要相互通信,或者有一个Win32或WinForm的客户程序要连接局域网上另一个服务器的程序。在这些程序里,使用DCOM会比SOAP/HTTP有效得多。与此相类似,如果一个.NET程序要连接到局域网上的另一个.NET程序,应该使用.NETremoting。有趣的是,在.NETremoting中,也可以指定使用SOAP/HTTP来进行WebService调用。不过最好还是直接通过TCP进行RPC调用,那样会有效得多。
总之,只要从应用程序结构的角度看,有别的方法比WebService更有效、更可行,那就不要用WebService。
将Web Service定义为:通过 SOAP 在 Web上提供的软件服务,使用 WSDL 文件进行说明,并通过 UDDI 进行注册。
Web Service架构:Web Service是独立的、模块化的应用,能够通过因特网来描述、发布、定位以及调用。在Web Service的体系架构中包括三个角色:服务提供者(Service Provider)、服务请求者(Service Requestor)、服务注册器(Service Registry)。角色间主要有三个操作:发布(Publish)、查找(Find)、绑定(Bind)。
下图清楚的描述了三种角色,以及角色之间的作用关系。
Web Service协议标准
1、简单对象访问协议(SOAP)
SOAP是Simple Object Access Protocol的缩写,是一种基于XML的不依赖传输协议的表示层协议,用来在分散或分布式的应用程序之间方便地以对象的形式交换数据。在SOAP的下层,可以是HTTP,也可以是SMTP/POP3,还可以是为一些应用而专门设计的特殊的通信协议。
SOAP包括三个主要部分:
SOAP封装结构:定义了一个整体框架,以表示消息中包含什么内容,谁来处理这些内容以及这些内容是可选的或是必需的。
SOAP编码规则:定义了用以交换应用程序定义的数据类型的实例的一系列机制。
SOAP RPC表示:定义了一个用来表示远程过程调用和应答的协定。
2、Web Service描述语言(WSDL)
WSDL是Web Service Description Language的缩写,该语言将网络服务定义成一个能交换消息的通信端点集,为分布式系统提供了帮助文档,同时也可作为自动实现应用间通信的解决方案。
3、统一描述、发现和集成协议(UDDI)
UDDI是一套基于Web的、分布式的、为Web Service提供的、信息注册中心的实现标准规范,同时也包含一组使企业能将自身提供的Web Service注册,以使别的企业能够发现的访问协议的实现标准。
通过xfire实现了webservice。下面详细介绍一下xfire。
XFire是一个免费的,开源的SOAP框架. 它不仅允许你轻松简易地实现这么一个环境.而且还提供了很多先进的特性.如果你的Web应用有一个Java类, 现在你希望这个类变成Web服务,用XFire完成这一工作你不必写一句代码.仅需操作一下部署描述器,你就会得到一个Web服务.
一、建立接口文件com.resoft.recis.ws.ReCISService
public interface ReCISService {
//请求系统设置信息
public AppInfo getAppInfo();
}
public class ReCISServiceImp implements ReCISService {
public com.resoft.recis.ws.AppInfo getAppInfo() {
// TODO Auto-generated method stub
return com.resoft.recis.ws.AppInfo.getAppInfo();
}
}
二、已存在类com.resoft.recis.ws. AppInfo
public class AppInfo {
double cardLeft;
/** default constructor */
public AppInfo() {
}
public double getCardLeft() {
return cardLeft;
}
public void setCardLeft(double cardLeft) {
this.cardLeft = cardLeft;
}
public static AppInfo getAppInfo() {
Session session = HibernateUtil.getSession();
com.resoft.recis.biz.AppInfo dbappinfo = (com.resoft.recis.biz.AppInfo) Util
.getHQLResult(session, "from AppInfo");
if (dbappinfo == null) {
return null;
}
com.resoft.recis.ws.AppInfo appinfo = new com.resoft.recis.ws.AppInfo();
appinfo.setOperid("");
appinfo.setOrgcode("");
appinfo.setCardHeight(dbappinfo.getCardHeight());
appinfo.setCardLeft(dbappinfo.getCardLeft());
appinfo.setCardTop(dbappinfo.getCardTop());
appinfo.setCardWidth(dbappinfo.getCardWidth());
HibernateUtil.closeSession();
return appinfo;
}
}
三、Web.xml应用的部署描述
<!— xfire的servlet配置文件 -->
<servlet>
<servlet-name>XFireServlet</servlet-name>
<display-name>XFire Servlet</display-name>
<servlet-class>
org.codehaus.xfire.transport.http.XFireConfigurableServlet
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>XFireServlet</servlet-name>
<url-pattern>/servlet/XFireServlet/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>XFireServlet</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
四、创建services.xml文件
XFire本身就是基于Servlet的应用,xfire使用services.xml文件来完成Web服务配置。这个文件位于src/META-INF/xfire目录下,
src\META-INF\xfire
下面是基本的配置条目,这个配置文件中配置了xfire的接口,实现与验印控件的交互。
<beans xmlns="http://xfire.codehaus.org/config/1.0">
<service>
<name>ReCISService</name>
<namespace>http://resoft</namespace>
<serviceClass>com.resoft.recis.ws.ReCISService</serviceClass> <implementationClass>com.resoft.recis.ws.ReCISServiceImp</implementat ionClass>
</service>
</beans>
services.xml文件中的具体内容如下:
<service>元素:
对Web服务的定义包含在<service>元素内。<service>元素下还有若干子元素。
<name>子元素:
可以提供任何有效的xml名字,这个名字会被客户端程序和服务器上的其他组件使用.例如,当服务器起来以后,你可以在浏览器上使用这个名称来查看WSDL.
<namespace>子元素:
任何有效地xml名称都可以, <namespace>将作为你服务器的唯一标识变量使用.
<serviceClass>子元素:
包含Java类名用来指明方法的签名.在这个例子中是ReCISService接口.如果Java类没有实现任何接口,那就填入类名.只需要这一个入口来将他们转换成Web服务.
<implementationClass>子元素:
记录实现接口的Java类名.这是一个可选元素.如果前一个元素<serviceClass>填入的是接口,那么此处就要填入相应的实现类名.
五、XFire和所有必要的库文件
访问XFire官方网站http://xfire.codehaus.org/ 下载xfire-distribution-1.2.5.zip并解压到本地文件夹中.参考xfire-distribution-1.2.5\xfire-1.2.5\manual\Dependency Guide.html中介绍拷贝相关jar包到WEB-INF\lib,xfire-distribution-1.2.5需要的jar包如下:
xfire-all-1.2.5.jar
activation-1.1.jar
commons-codec-1.3.jar
commons-httpclient-3.0.jar
commons-logging-1.0.4.jar
mail-1.4.jar
jaxen-1.1-beta-9.jar
jdom-1.0.jar
junit-3.8.1.jar
servlet-api-2.3.jar
spring-1.2.6.jar
stax-api-1.0.1.jar
wsdl4j-1.6.1.jar
wstx-asl-3.2.0.jar
xbean-2.2.0.jar
xbean-spring-2.8.jar
XmlSchema-1.1.jar
xfire-jsr181-api-1.0-M1.jar
六、通过URL验证Web服务有效性
首先,我们先来看看WSDL是否有效。在浏览器中输入URL地址为http://127.0.0.1/test/services/ReCISService?wsdl 注意URL中IP地址和端口号是否需要修改。如果输入了有效的URL,将会看到以<wsdl:definitions>为根结点的xml文件。这个文件叫做web服务的WSDL.如果你看到了这个文件,那么初步验证你的Web服务有效。
但是这个验证还不够。有时候情况会复杂一些,你可以看到WSDL,但是客户端却无法访问Web服务。因此要真正检验Web服务是否真的好使,就要用客户端程序对Web服务作一次真正的调用。
七、客户端验证Web服务有效性
建立下面测试类测试Web服务器的有效性。
public class TestWebservice
{
public static void main(String args[])
{
String serviceURL ="http://127.0.0.1/test/services/ReCISService";
Service serviceModel = new ObjectServiceFactory().create(ReCISService.class,null,"http://resoft",null);
XFireProxyFactory serviceFactory = new XFireProxyFactory();
try
{
ReCISService service = (ReCISService) serviceFactory.create(serviceModel, serviceURL);
Client client = Client.getInstance(service);
System.out.println("begin");
com.resoft.recis.ws.AppInfo ai=service.getAppInfo();
System.out.println(ai.getCardHeight());
System.out.println("end");
}
catch (MalformedURLException e)
{
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Web service到底是什么;在什么情况下你应该使用Web service。
分布式应用程序和浏览器
研究一下当前的应用程序开发,你会发现一个绝对的倾向:人们开始偏爱基于浏览器的瘦客户应用程序。这当然不是因为瘦客户能够提供更好的用户界面,而是因为它能够避免花在桌面应用程序发布上的高成本。发布桌面应用程序成本很高,一半是因为应用程序安装和配置的问题,另一半是因为客户和服务器之间通信的问题。
传统的Windows富客户应用程序使用DCOM来与服务器进行通信和调用远程对象。配置好DCOM使其在一个大型的网络中正常工作将是一个极富挑战性的工作,同时也是许多IT工程师的噩梦。事实上,许多IT工程师宁愿忍受浏览器所带来的功能限制,也不愿在局域网上去运行一个DCOM。在我看来,结果就是一个发布容易,但开发难度大而且用户界面极其受限的应用程序。极端的说,就是你花了更多的资金和时间,却开发出从用户看来功能更弱的应用程序。不信?问问你的会计师对新的基于浏览器的会计软件有什么想法:绝大多数商用程序用户希望使用更加友好的Windows用户界面。
关于客户端与服务器的通信问题,一个完美的解决方法是使用HTTP协议来通信。这是因为任何运行Web浏览器的机器都在使用HTTP协议。同时,当前许多防火墙也配置为只允许HTTP连接。
许多商用程序还面临另一个问题,那就是与其他程序的互操作性。如果所有的应用程序都是使用COM或.NET语言写的,并且都运行在Windows平台上,那就天下太平了。然而,事实上大多数商业数据仍然在大型主机上以非关系文件(VSAM)的形式存放,并由COBOL语言编写的大型机程序访问。而且,目前还有很多商用程序继续在使用C++、Java、Visual Basic和其他各种各样的语言编写。现在,除了最简单的程序之外,所有的应用程序都需要与运行在其他异构平台上的应用程序集成并进行数据交换。这样的任务通常都是由特殊的方法,如文件传输和分析,消息队列,还有仅适用于某些情况的的API,如IBM的"高级程序到程序交流(APPC)"等来完成的。在以前,没有一个应用程序通信标准,是独立于平台、组建模型和编程语言的。只有通过Web Service,客户端和服务器才能够自由的用HTTP进行通信,不论两个程序的平台和编程语言是什么。
什么是Web Service
对这个问题,我们至少有两种答案。从表面上看,Web service 就是一个应用程序,它向外界暴露出一个能够通过Web进行调用的API。这就是说,你能够用编程的方法通过Web来调用这个应用程序。我们把调用这个Web service 的应用程序叫做客户。例如,你想创建一个Web service ,它的作用是返回当前的天气情况。那么你可已建立一个ASP页面,它接受邮政编码作为查询字符串,然后返回一个由逗号隔开的字符串,包含了当前的气温和天气。要调用这个ASP页面,客户端需要发送下面的这个HTTP GET请求:
http://host.company.com/weather.asp?zipcode=20171
返回的数据就应该是这样:
21,晴
这个ASP页面就应该可以算作是Web service 了。因为它基于HTTP GET请求,暴露出了一个可以通过Web调用的API。当然,Web service 还有更多的东西。
下面是对Web service 更精确的解释: Web services是建立可互操作的分布式应用程序的新平台。作为一个Windows程序员,你可能已经用COM或DCOM建立过基于组件的分布式应用程序。COM是一个非常好的组件技术,但是我们也很容易举出COM并不能满足要求的情况。
Web service平台是一套标准,它定义了应用程序如何在Web上实现互操作性。你可以用任何你喜欢的语言,在任何你喜欢的平台上写Web service ,只要我们可以通过Web service标准对这些服务进行查询和访问。
新平台
Web service平台需要一套协议来实现分布式应用程序的创建。任何平台都有它的数据表示方法和类型系统。要实现互操作性,Web service平台必须提供一套标准的类型系统,用于沟通不同平台、编程语言和组件模型中的不同类型系统。在传统的分布式系统中,基于界面(interface)的平台提供了一些方法来描述界面、方法和参数(译注:如COM和COBAR中的IDL语言)。同样的,Web service平台也必须提供一种标准来描述Web service,让客户可以得到足够的信息来调用这个Web service。最后,我们还必须有一种方法来对这个Web service进行远程调用。这种方法实际是一种远程过程调用协议(RPC)。为了达到互操作性,这种RPC协议还必须与平台和编程语言无关。下面几个小节就简要介绍了组成Web service平台的这三个技术。
XML和XSD
可扩展的标记语言(XML)是Web service平台中表示数据的基本格式。除了易于建立和易于分析外,XML主要的优点在于它既是平台无关的,又是厂商无关的。无关性是比技术优越性更重要的:软件厂商是不会选择一个由竞争对手所发明的技术的。
XML解决了数据表示的问题,但它没有定义一套标准的数据类型,更没有说怎么去扩展这套数据类型。例如,整形数到底代表什么?16位,32位,还是64位?这些细节对实现互操作性都是很重要的。W3C制定的XML Schema(XSD)就是专门解决这个问题的一套标准。它定义了一套标准的数据类型,并给出了一种语言来扩展这套数据类型。Web service平台就是用XSD来作为其数据类型系统的。当你用某种语言(如VB.NET或C#)来构造一个Web service时,为了符合Web service标准,所有你使用的数据类型都必须被转换为XSD类型。你用的工具可能已经自动帮你完成了这个转换,但你很可能会根据你的需要修改一下转换过程。在第二章中,我们将深入XSD,学习怎样转换自定义的数据类型(例如类)到XSD的类型。
SOAP
Web service建好以后,你或者其他人就会去调用它。简单对象访问协议(SOAP)提供了标准的RPC方法来调用Web service。实际上,SOAP在这里有点用词不当:它意味着下面的Web service是以对象的方式表示的,但事实并不一定如此:你完全可以把你的Web service写成一系列的C函数,并仍然使用SOAP进行调用。SOAP规范定义了SOAP消息的格式,以及怎样通过HTTP协议来使用SOAP。SOAP也是基于XML和XSD的,XML是SOAP的数据编码方式。第三章我们会讨论SOAP,并结识SOAP消息的各种元素。
WSDL
你会怎样向别人介绍你的Web service有什么功能,以及每个函数调用时的参数呢?你可能会自己写一套文档,你甚至可能会口头上告诉需要使用你的Web service的人。这些非正式的方法至少都有一个严重的问题:当程序员坐到电脑前,想要使用你的Web service的时候,他们的工具(如Visual Studio)无法给他们提供任何帮助,因为这些工具根本就不了解你的Web
service。解决方法是:用机器能阅读的方式提供一个正式的描述文档。Web service描述语言(WSDL)就是这样一个基于XML的语言,用于描述Web service及其函数、参数和返回值。因为是基于XML的,所以WSDL既是机器可阅读的,又是人可阅读的,这将是一个很大的好处。一些最新的开发工具既能根据你的Web service生成WSDL文档,又能导入WSDL文档,生成调用相应Web service的代码。
对运营商来说,所谓电信数据业务一般是指承载于GSM、GRPS、WirelessLAN等通信网络,接入到基于IP(InternetProtocol)网络技术的各类数据设备与服务器,以Internet为资源基础提供内容与应用服务的各类新型业务的总称,例如:短消息(SMS)、无线应用协议(WAP)、多媒体消息(MMS)、电子邮件(E-mail)、空中接口(下载)服务器(OTAServer)等。从商业模式的角度来看,电信运营商利用自己成熟的通信网络和丰富的后端服务与计费系统,组成服务提供平台(Service Delivery Platform),为新闻、游戏、邮件、商务等各种Internet服务提供用户接入、管理、计费等基础设施支持,扩展了对自身终端用户的商业服务范围;与Internet内容与应用服务商实行收入分成,开启了新的营收渠道。长期以来,电信运营商掌握着三个技术制高点:通信渠道、用户数据库和营帐系统。围绕着这些制高点,运营商进行了长期的投入与建设,并且在语音等传统业务领域已经达到了很高的技术成熟度。然而,电信数据业务的开展为运营商的技术储备带来了新的需求和挑战,新的业务系统与管理平台大量涌现,彼此之间以及与旧有系统的整合迫在眉睫。独特的商业合作模式创造了独特的供应链管理(Supply-Chain Management)的需求,即合作服务提供商关系管理。据估计,电信行业传统业务中运营商需要管理的设备元素与终端用户数目的比例平均为1:10000,即一个设备元素平均被用于服务10000个用户。随着新业务的开展和数据网络设备及服务器的增加,该比例已经缩减至1:500,即一个设备元素平均被用于服务500个用户。很多数据业务灵活跨越多个通信渠道、用户和合作服务提供商,进一步增加了设备整合的复杂性。
基于上述原因,目前国内外成熟运营商的基础设施建设重点已经从个别关键设备转移到了端到端的设备整合,这种整合常常跨越大量合作伙伴的边界。面临这样的变化,传统的系统整合技术,如点对点的私有接口适配器、适用于企业内部使用的传统分布式对象构件中间件和消息中间件等,已经显得力不从心。电信互连互通和增值服务链的建设需要安全、灵活,有能力跨越合作伙伴IT管理域边界的新技术。
Web技术在广域网应用中的极大成功,XML(eXtendedMark-upLanguage)在电子商务和企业数据交换与整合中的普遍应用以及分布式对象和消息中间件架构在企业内部应用整合中的推广,从多方面启发了业界的智慧,于2001年推出了整合三者优势的WebService技术与面向服务架构(Service-Oriented Architecture,SOA),用以满足包括电信行业在内的各商务领域对新型整合技术与框架的需求。结合电信行业数据业务的背景,本文介绍了该技术的基本概念及其在系统整合中的应用。
一、基本概念
WebService的国际标准由因制定Web和XML技术标准而名满天下的W3C组织(WorldWideWeb Consortium)制定。目前,由 Web Services 架构组达成一致意见的Web Service的暂行定义为:Web Service是由URI(统一资源标识符)标识的软件应用程序,其接口和绑定可以通过XML构件进行定义、描述和发现,Web Service支持通过基于因特网的协议使用基于XML的消息与其它软件应用程序直接交互。
仔细阅读这个定义,我们可以看出WebService的用于软件应用程序之间交互的技术,具有以下基本特征:
通信层面上的Web特征:使用URI进行标识,并使用各种因特网协议进行通信。
表示层面上的XML特征:使用XML描述服务接口和绑定信息,通信消息格式使用XML。
架构层面上的分布式计算特征:服务可以被使用它的应用程序在网络上查找和发现。
从上个世纪90年代末开始,许多厂商已经自发的开始使用Web通信协议(HTTP)加XML消息的方法解决各种因特网上的服务整合的问题了。例如:基于位置服务中的LIF(LocationInteroperabilityForum)标准和爱立信、诺基亚、摩托罗拉等公司的实现都使用了HTTP承载XML消息的方式。各类电子商务标准普遍基于XML,并且在实现中使用HTTP协议进行传输。一个只有几页纸的因特网上远程过程调用标准XML-RPC则是这类技术的典范,该标准规范了基于XML的调用描述与数据表示,至今仍然在被一些公司应用。
业界早期零散的努力在W3C组织最终汇聚成为今天WebService标准的基础。而标准中的服务发现机制则具有些OMG(ObjectManagementGroup)组织制定的CORBA(Common Object Request Broker Architecture)的基于命名服务(Naming Service)和IDL(Interface Definition Language)描述的服务查找的影子。然而,目前Web Service技术和以CORBA为代表的传统分布式构件对象技术的一个显著不同在于:Web Service传递的是XML数据,而不是对象或对象引用。事实上,在广域网上不同的商家之间传递二进制对象和对象引用会导致服务与被服务方实现技术的紧耦合,是不合适、不现实的。因此,有人提出:Web Service也许更适合使用异步消息进行系统间对话,而不是现在流行的远程过程调用(Remote Procedure Call,RPC)模式。基于消息的Web Service被称为Message Web Service,基于RPC机制的Web Service为RPC Web Service。尽管Message Web Service从理论上说会更为灵活、高效,其编程模型却比较复杂,需要应用开发者具有较高的IT架构设计与程序编制的能力。因此,目前各个IT厂商支持的主流仍然是编程模型较为简单的RPC Web Service。此外,两类技术变种有着共同的技术基础,都采用面向服务架构,符合上述定义。
二、面向服务的应用架构
W3CWebService架构组建议了一个的面向服务的WebService架构,如图1所示。在这个架构中,核心是服务这个概念。服务被定义为执行某类商业任务(比如零件采购或书籍查询)的一组操作。在Web Service上下文中,可以使用标准的XML技术和Internet协议发布、查找和绑定服务。Web Service 架构定义了3个主要实体。
图1面向服务的WebService架构
服务提供者:负责使用WSDL描述和定义WebService的功能,在UDDI注册库(位于服务代理)中发布这些服务的信息,使得它们可以被服务请求者访问和调用。
服务代理:负责宣传服务提供者发布的WebService和允许服务请求者查找发布的WebService 定义。它的作用和电话本的黄页相同。
服务请求者:负责通过服务代理查找所需要的WebService后,下载描述WebService的WSDL文档,根据服务描述来绑定和调用服务提供者提供的Web Service。
WebService架构的这种三角形设计模式被称为面向服务的体系结构。它包括了下面3个标准操作。
发布:由服务提供者执行来宣传和注册一个服务的存在和功能,是服务提供者和服务代理之间的操作。
查找:由服务请求者执行来查找符合特定需求或技术特征的服务,是服务请求者和服务代理之间的操作。
绑定:由服务请求者执行来调用服务提供者提供的服务,是服务请求者和服务提供者之间的操作。
WebService是面向服务的架构(ServiceOrientedArchitecture, SOA)的一种实现。SOA是分布式计算领域中采用的一种主要体系结构。和CORBA和DCOM这样的分布式计算技术不同,Web Service是基于标准和松耦合的。首先,广泛接受的Internet标准(如XML、SOAP、HTTP等)提供了在各不同厂商解决方案之间的交互性。开发者就可以开发出平台独立、编程语言独立的Web Services,从而能够充分利用现有的软硬件资源和人力资源。其次,松耦合将分布计算中的参与者隔离开来,交互两边某一方的改动并不会影响到另一方。这两者的结合意味着公司可以实现某些Web services而不用对使用这些Web Services的客户端的知识有任何了解。
SOA的强大和灵活性将给电子商务带来巨大的好处。如果某企业将其IT基础设施抽象出来,将其业务功能以某种粒度的服务形式表示并发布出来,每种服务都清晰地表示其业务价值,那么,这些服务的顾客(可能在公司内部,也可能是公司的某个业务伙伴)就可以通过已发布的业务接口来使用这些服务,而不用考虑服务实现的具体技术。
三、WebService发展阶段
按照目前IT界较为公认的划分方法,WebService技术从产生到成熟可以分成三个阶段:
基础服务架构的完善;
安全与可靠性支持的完善;
跨域协同(Coordination)和快速服务链整合技术(Composition)的完善。
在第一阶段,WebService的发展重点在于服务通信、描述以及发现机制的标准化。在面向服务的架构下,具体的标准规范通信消息的SOAP(SimpleObjectAccess Protocol)协议,规范服务描述的WSDL语言,和用于服务注册与发现的UDDI(Universal Description, Discovery, and Integration)服务和ebXML(e-Business XML)标准。该阶段的主要工作目前已经完成。
目前,WebService的发展已经到了第二阶段,即消息级的WebService安全机制和WebService消息传输的可靠性机制的标准化。Web Service作为一种端到端的分布式技术,不同于以往的点对点的技术,传递的消息可能穿越各类信息服务中介,如:内容分类过滤的防火墙、商业导购中间商、专业计费服务提供商等。最终的服务,被服务方以及中介之间存在有限的商业信任,这意味着中介既需要看懂并处理部分消息内容,又无权看到与己无关的部分而传统的因特网点对点安全技术不能满足这样的需求。所谓消息级安全是对点对点安全技术的加强与扩充,目的在于满足端到端的通信安全需要。尽管实现效率还有待提高,目前在电子商务最具权威性的机构,OASIS(Organization for the Advancement of Structured Information Standards)组织中制定了 Web Service Security的发展框架,其核心的WS-Security标准也已经完成了第一版的工作。此外,大多数商业服务需要可靠的信息传输,它们共同的需求被抽取出来,就构成了对Web Service可靠性的需求。一些厂商试图给出这些需求在系统一级的解决方案,提出了一系列的标准化方案,整个工作正在迅速的进行之中。
此外,2002年7月IBM、微软和BEA共同提出了WebService跨域协同、事务和服务链整合技术的三个标准草案(WebServiceCoordination、Web Service Transaction、Business Process Execution Language for Web Service)标志着Web Service第三阶段研究与标准化工作也已经提上了日程。
四、WebService在电信增值业务平台的应用示例
尽管WebService的商业模式目前还处于发展过程中,但其中一些模式已经通过大量的实践得到了业界的承认,例如,企业之间的信息交换,信息门户和商业流程的整合。这些模式结合电信领域的特点,产生了一些特有的基于电信的WebService的商业模式。此处以WebService在电信增值业务平台的应用为示例,说明其在电信行业数据业务中的应用。
电信增值业务平台是增值业务价值链的技术支撑平台,管理运营商和ServiceProvider(SP)之间业务集成的商业关系。对于运营商而言,平台封装了底层的通信网络,向SP提供一个开放的安全的访问网络能力的标准接口集合。这个集合包括了网络功能实体、认证、基于内容的计费以及服务定购关系等。SP可以利用这个平台便捷地在这个平台上实现新的电信增值业务。ParlayGroup、3GPP和ETSI联合制定的Parlay/OSA[5]就是这样一个面向电信增值业务平台的电信规范。WebService在Parlay/OSA中得到了广泛的应用。如图1所示,采纳Parlay Web Service的电信增值业务平台体系结构。增值业务平台由电信运营商管理和维护,分为两个逻辑部分:框架和网络资源能力服务器。框架向SP提供两种类型的接口支持。其一是面向企业法人的电信服务定购关系的接口支持,如图2中②所示,包括了SP企业账户的管理、应用程序的管理、电信资源使用合同的管理。其二是向SP的电信增值业务的应用程序提供安全接入认证,电信资源查找、签署服务等级合约、获得电信服务实例入口和服务质量监控的接口支持,如图2中③所示。SP应用程序使用的电信资源是由网络资源能力服务器提供的,如图2中④所示。这里的电信资源包括话音、短信、位置、用户状态和计费等,它们可以通过各种不同的私有协议映射到运营商现有的网络设备和内部系统中。这些资源通过图2中①所示的接口注册到框架。从上可以看出,这种电信增值业务平台是一个典型的B2B模式(SP和运营商)中采用Web Service进行业务集成的应用示例。
此外,在OpenMobileAlliance(OMA)组织中的MobileWeb Service(MWS)工作组也在探讨如何采用标准的Web Service的技术在移动运营商的网络中部署并构建新的电信数据业务平台。目前的工作还处于草案阶段。鉴于Parlay在相同的领域中已经有了很多的标准和技术的积累,OMA MWS已经和Parlay签署了一个合作协议,用于协调双方的标准制定工作。
图2采纳ParlayWeb Service的电信增值业务平台体系结构
现在我将列举三种情况,在这三种情况下,你将会发现使用Web service会带来极大的好处。此后,我还会举出不应该使用Web service的一些情况。
跨越防火墙的通信
如果你的应用程序有成千上万的用户,而且他们都分布在世界各地,那么客户端和服务器之间的通信将是一个棘手的问题。那是因为客户端和服务器之间通常都会有防火墙或者代理服务器。在这种情况下,你想使用DCOM就不是那么简单了,而且,通常你也不愿意把你的客户端程序发布到如此庞大数量的每一个用户手中。于是,你最终选择了用浏览器作为客户端,写下一堆ASP页面,把应用程序的中间层暴露给最终用户。结果呢?运气好的话,只是开发难度大了一些,运气不好的话,就会得到一个根本无法维护的应用程序。
想象一下你应该怎么在你的应用程序里面加入一个新的页面:你必须先建立好用户界面(Web页面),以及在这个页面后面,包含相应商业逻辑的中间层组件。这还不够,你还要再建立至少一个ASP页面,用来接受用户输入的信息,调用中间层组件,把结果格式化为HTML形式,最后还要把"结果页"送回浏览器。要是客户端代码不再如此依赖于HTML表单,客户端的编程不就简单多了吗?还有,建立ASP页面的那一步可以省略掉吗?
当然。如果你的中间层组件是Web service的话,你完全可以从用户界面直接调用中间层组件,从而省掉建立ASP页面的那一步。要调用Web service,你可以直接使用Microsoft SOAP Toolkit或.NET这样的SOAP客户端,也可以使用你自己开发的SOAP客户端,然后把它和你的应用程序连接起来。这样做,不仅可以缩短开发周期,还可以减少代码的复杂度,并增强整个应用程序的可维护性。同时,你的应用程序也不再需要在每次调用中间层组件时,都跳转到相应的"结果页"了。
以我的经验来看,在一个用户界面和中间层有较多交互的应用程序中,使用Web service这种结构,可以轻松的节省花在用户界面编程上的20%的开发时间。这样做还有另一个好处,就是你将得到一个由Web service组成的中间层,这一层是完全可以在应用程序集成或其他场合下被重用的。最后,通过Web service把你的应用程序的逻辑和数据暴露出来,还可以让其它平台上的客户重用你的应用程序。
应用程序集成
企业级的应用程序开发者都知道,企业里经常都要把用不同语言写成的在不同平台上运行的各种程序集成起来,而这种集成将花费很大的开发的力量。你的应用程序经常都需要从运行在古老的IBM主机上的程序中获取数据;或者再把数据发送到主机或UNIX应用程序中去。即使是在同一个平台上,不同的软件厂商生产的各种软件也常常需要集成起来。通过Web service,应用程序可以用标准的方法把功能和数据暴露出来,供其它的应用程序使用。
例如,你有一个订单登录程序,用于登录从客户来的新订单,包括客户信息、发货地址、数量、价格和付款方式等信息。同时,你还有一个订单执行程序,用于实际货物发送的管理。这两个程序是来自不同软件厂商的。一份新订单进来之后,订单登录程序需要通知订单执行程序发送货物。通过在订单执行程序上面增加一层Web service,订单执行程序可以把"AddOrder"函数暴露出来。这样,每当有新订单到来时,订单登录程序就可以调用这个函数来发送货物了。进而通过Web service集成应用程序
B2B的集成
用Web service集成应用程序,可以使你公司内部的商务处理更加自动化。但当交易跨越了你的供应商和客户,突破了公司的界线时又会怎么样呢?跨公司的商务交易集成通常叫做B2B集成。
Web service是B2B集成成功的关键。通过Web service,你的公司可以把关键的商务应用暴露给指定的供应商和客户。例如,把你的电子下单系统和电子发票系统暴露出来,你的客户就可以以电子的方式向你发送购货订单,而你的供应商则可以以电子的方式把原料采购的发票发送给你。当然,这并不是一个新的概念:电子文档交换(EDI)早就是这样了。Web service和EDI之间的主要区别在于,Web service的实现要比EDI简单得多,而且Web service是运行在Internet上的,在世界任何地方都可轻易实现,这样其运行成本就相对较低。不过,Web service并不像EDI那样,是文档交换或B2B集成的一套完整的解决方案。Web service只是B2B集成的一个关键部分,还需要许多其它的部分才能完成这个集成。
用Web service来实现B2B集成的最大好处在于可以轻易实现互操作性。只要把你的商务逻辑暴露出来,成为Web service,你就可以让任何指定的合作伙伴轻松的调用你的商务逻辑,而不管他们的系统在什么平台上运行,使用的是什么开发语言。这样就大大减少了花在B2B集成的上的时间和成本。这样的低成本让许多原本无法承受EDI的投资成本的中小企业也能实现B2B集成。
软件重用
软件重用是一个很大的主题,它有很多的形式和程度。最基本的形式是源代码模块或者类一级的重用。另一种形式是二进制形式的组件重用。当前,像表格控件或用户界面控件这样的可重用软件组件在市场上都占有很大的份额。但这类软件的重用都有一个很严重的限制:重用仅限于代码,而数据不能被重用。原因在于你可以很轻易的发布组件甚至源代码,但要发布数据就没那么容易了,除非那些数据都是不会经常变化的静态数据。
而Web service允许你在重用代码的同时,重用代码后面的数据。使用Web service,你不再像以前那样,要先从第三方购买、安装软件组件,再从你的应用程序中调用这些组件。你只需要直接调用远端的Web service就可以了。举个例子,你想在你的应用程序中确认用户输入的邮件地址,那么,你只需把这个地址直接发送给相应的Web service,这个Web service 就会帮你查阅街道地址、城市、省区和邮政编码等信息,确认这个地址的确在相应的邮政编码区域。Web service 的提供商可以按时间或使用次数来对这项服务进行收费。这样的服务要通过组件重用来实现是不现实的,因为那样的话你必须下载并安装好包含街道地址、城市、省区和邮政编码等信息的数据库,而且这个数据库还是不能实时更新的。
另一种软件重用的情况是把好几个应用程序的功能集成起来。例如,你想要建立一个局域网上的门户站点应用,让用户既可以查询他们的联邦快递包裹,察看股市行情,又可以管理他们的日程安排,还可以在线购买电影票。现在Web上有很多应用程序供应商,都在其应用中实现了上面的这些功能。一旦他们把这些功能都通过Web service 暴露出来,你就可以非常轻易地把所有这些功能都集成到你的门户站点中,为用户提供一个统一的、友好的界面。
用Web service来集成各种应用中的功能,为用户提供一个统一的界面
许多应用程序都会利用Web service,把当前基于组件的应用程序结构扩展为组件和Web service 的混合结构。你也可以在应用程序中使用第三方的Web service 提供的功能。你还可以把你自己的应用程序的功能通过Web service 提供给别人。所有这些情况下,你都可以重用代码和代码后面的数据。总之,Web service 将是软件重用的一种非常有力的形式。
什么时候不应该使用Web Service
一个对Web service的完整介绍还应该包括什么时候不该用Web service。经过前面的介绍,我们知道了Web service 在通过Web进行互操作或远程调用的时候是最有用的。不过,还有许多情况,Web service根本不能给你带来任何好处。
单机应用程序
目前,我们还有很多桌面应用程序是供商用和个人使用的。其中一些只需要与运行在本机上的其他程序通信。在这种情况下,我们最好就不要再用Web service ,只要用本地的API就可以了。COM非常适合于在这种情况下工作,因为它既小又快。运行在一台服务器上的服务器软件也是这样:最好直接用COM或其他本地的API来进行应用程序间的调用。当然Web service 也能用在这些情况下,但那样不仅消耗太大,而且不会给你带来任何好处。
局域网上的同构应用程序
在许多应用中,你所有的程序都是用VB或VC开发的,都在Windows平台下使用COM,都运行在同一个局域网上。例如,你有两个服务器应用程序需要相互通信,或者你有一个Win32或WinForm的客户程序要连接到局域网上的另一个服务器程序。在这些程序里使用DCOM会比SOAP/HTTP有效的多。类似的,如果你的一个.NET程序要连接到LAN上的另一个.NET程序,那么你应该使用.NET remoting。有趣的是,在.NET remoting中,你也可以指定使用SOAP/HTTP来进行Web service 调用。不过最好还是直接通过TCP进行RPC调用,那样会有效得多。总之,只要你从应用程序结构的角度看来,有别的方法比Web service 更有效,更可行,那就不要再用Web service。
总结
Web service是创建可互操作的分布式应用程序的新平台。Web service 的主要目标是跨平台的可互操作性。为了达到这一目标,Web service 是完全基于XML、XSD等独立于平台、独立于软件供应商的标准的。
Web service在应用程序跨平台和跨网络进行通信的时候是非常有用的。Web service适用于应用程序集成、B2B集成、代码和数据重用,以及通过Web进行客户端和服务器的通信的场合。
当然,Web service也不是万能的,你不能到处滥用Web service。在有些情况下,Web service 会降低应用程序的性能,而不会带来任何好处。例如,一台机器或一个局域网里面运行的同构应用程序就不应该用Web service 进行通信。
今天是感恩节,差点又要在公司加班了。好在Web Service程序并不是特别难搞,下午终于在eclipse下调通过了,正确产生了服务器端和客户端的Java代码,apache的东西的确很不错。
说道Web Service的程序开发八个月前我加班调试公司和中国电信的商务领航系统的接口的时候,用的就是Web Service,Web Service有很多优点,使用Web Service可以在不同编程语言间实现数据交换,而我那时对Web Service也不熟,就由同事帮我生成了一大堆Web Service的框架代码,我则只单独开发业务代码。
这次的另外一个项目也要用Web Service了,不过人手也少了,没有人帮做Web Service了,只好自己动手。
好在开发前,有个同事先给我们不熟悉Web Service的程序员进行了一些培训,我才知道原来以前的Web Service都是可以自动生成代码的,而且也不难,试了一个下午客户端和服务器端的Web Service代码就都调试通过了,真不错。
为了更多喜爱开发的程序员也能迅速了解Web Service的开发,我这里整理了一些通过Axis开发Web Service的一些要点,希望能让不熟悉Web Service的开发人员能够迅速掌握Web Service。
一、Axis环境的安装
1、安装环境 J2SE SDK 1.4,Tomcat 5.0,eclipse 3.2。
2、到 http://xml.apache.org 网站下载Axis安装包。
3、将Axis相关包文件放在WEB-INF\lib目录下。
4、Axis可选的包:activation.jar; mail.jar; xmlsec-1.4.Beta1.jar拷贝到WEB-INF目录下,生成客户端时候需要使用。
Axis支持三种web service的部署和开发,分别为:
1、Dynamic Invocation Interface (DII)
2、Dynamic Proxy方式
3、Stubs方式
前两种方式我就不介绍了,同事告诉我他们自己都不使用前两种方式,他们建议我们使用Stubs方式,因此我就主要就介绍一下第三种方式。注意,我自己的Java源代码是放在D:\workspace\test\目录下,Axis相关包文件放在D:\workspace\test\WEB-INF目录下。
二、编写wsdd发布web服务,编写stub client访问web服务
1、编写服务端程序server,SayHello.java,编译server.SayHello.java
package server; public class SayHello { public String getName(String name) { return "hello "+name; } }
2、编写wsdd文件
deploy.wsdd文件内容如下:
<deployment xmlns="http://xml.apache.org/axis/wsdd/" xmlns:java="http://xml.apache.org/axis/wsdd/providers/java"> <service name="SayHello" provider="java:RPC"> <parameter name="className" value="server.SayHello.getName"/> <parameter name="allowedMethods" value="*"/> </service> </deployment>
3、发布服务:
编辑一个deploy.bat,Axis_Lib为axis.jar路径。内容如下:
set Axis_Lib=D:\workspace\test\WEB-INF\lib set Java_Cmd=java -Djava.ext.dirs=%Axis_Lib% set Axis_Servlet=http://localhost:8080/test/servlet/AxisServlet %Java_Cmd% org.apache.axis.client.AdminClient -l%Axis_Servlet% deploy.wsdd
执行这个批处理文件,这时候,如果提示成功的话,访问http://localhost:8080/test/services 就会显示服务列表。
4、生成客户端client stub文件
在浏览器上访问服务器端的服务,可以下载到WSDL文件,通过Axis的相关工具,可以自动从WSDL文件中生成Web Service的客户端代码。
编写一个WSDL2Java.bat文件,其内容如下:
set Axis_Lib=D:\workspace\test\WEB-INF\lib set Java_Cmd=java -Djava.ext.dirs=%Axis_Lib% set Output_Path=D:\workspace\test\src set Package=server.SayHello %Java_Cmd% org.apache.axis.wsdl.WSDL2Java -o%Output_Path% -p%Package% SayHello.wsdl
执行这个批处理文件就可以生成client stub.
生成的stub client文件列表为:SayHello.java,SayHelloService.java,SayHelloServiceLocator.java,SayHelloSoapBindingStub.java .
5、编写客户端程序,编译并执行
下面是一段junit测试客户端代码。
import java.net.URL; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite;
public class TestWSClient extends TestCase {
public TestWSClient(String string) { super(string); }
public void SayHelloClient() throws Exception {
SayHelloService service = new SayHelloServiceLocator(); SayHello_PortType client = service.getSayHello() ; String retValue = client.getName("clientname"); System.out.println(retValue);
}
public static Test suite() { TestSuite suite = new TestSuite(); suite.addTest(new TestWSClient("SayHelloClient")); return suite; } }
至此,整个服务器端和客户端的Web Service框架代码就完成了,剩下的就是在里面加入你的业务代码了,怎么样,Web Service并不难开发吧。
虽然人们通过跳槽来寻求职位和收入的快速提升,但也不是每个人都可以通过跳槽达到这些目的。据调查,以下这几个因素决定了人们的收入差别:
一、学历
收入的差别是随着学历的增长而增高,据调查,每多接受一年的教育,平均年薪就会增加8.3%(MBA除外),拥有较高的教育程度,良好的实际工作能力的人通常会获得比较优厚薪酬的工作。
二、经验
随着年龄和工作经验的增长,薪资水平也会递增。工作6年以上者年薪均值达到了4.5万元以上,是工作1年以下者的2倍。也就是说,薪酬与经验成正比,经验多、工作时间长者自然获薪酬也多。《财经》杂志进行过一项调查,其中销售人员的调查结果是:有2年经验的销售部主管年总薪金平均是3.27万元,而有13年经验的平均达到7.18万元。
三、年龄
国家统计局城市社会经济调查总队在北京、上海、浙江等10个省市对9956户城市高收入家庭进行了问卷调查。在我国,目前25-35岁年轻人的收入高于其他各年龄组,占城市高收入群体的37%.说明随着社会的变化发展,英语、电脑已越来越成为基本工具而不是技能,从业者(尤其是高级管理人员)掌握了较多新知识,具备较强的知识更新能力,就能在人才竞争中占据有利地位。因此,30-40岁的人在中高收入人群中的比重将迅速扩大。
四、行业
一项对京、沪、穗、深四城市白领年薪的调查显示,北京地区收入最高的是计算机行业,白领平均年薪为5万元;上海、广州均是“律师、会计师”行业高居榜首,平均年薪分别为5.42万元和5万元;在深圳,薪水最高的是“教育、文化、科研、医疗”行业,平均年薪高达7.02万元。
五、英语
虽然社会上对英语等级考试还有些质疑,但职场中,英语无疑是添薪加码的一大“法宝”。调查显示,外语能力越高,其薪资的竞争力也就越强。外语能力“熟练”者平均年薪比“中等”者年薪多出近16000元。即使与去年下半年相比,外语能力熟练者的平均薪资也有了近2000元的升幅,而外语能力一般者薪资升幅仅为300元。
六、个人整体素质
一项针对高收入外企白领的调查显示:高学历并不完全等同于高收入,优秀个人素质才是获得高薪的关键因素。目前高薪收入者大多具有良好的人际关系处理能力,敬业精神和不断学习的能力等基本素质。
七、成功跳槽
具备了以上素质,无论是在原单位还是成功跳到另一家新单位,都会拥有高于一般水平的薪资,而成功地跳槽则会加速薪酬的提升速度。
了解了以上信息,你就会理解为什么有的人不但跳得不理想,而且越跳越低的原因了。反过来,具备综上所述各种优势的人才也是企业们想方设法要留下的骨干力量,面对越来越激烈的人才竞争,企业也在挖空心思地维护着自己的人才领地,用各种方法留住人才。
讲理法:“老板,我干活,你领功拿赏。功我不要了,钱总得分我一些吧。” 对比法:“老板,再给我一万,我开的还是小丰田,那能和您的凯迪拉克比。” 拍马屁法:“老板,你的马屁好大噢。能不能让我拍一下。” 同情法:“老板,我上有老,下有小,中间还有个好吃懒做爱花钱的老公/老婆。” 输球法:常陪老板打高尔夫。每场必输。(此法源出于国内的输棋、输牌法)
Blackmail法:“老板,秘书xx小姐取笑我。说我一年挣的还不够你俩假装开会用公款到欧洲浪漫一星期的开销。 分红法:“老板,你长我二万元,我分你一万。” 入股法:“老板,我在研制永动机。快做成了,只是还差十万元。你先捐给我,以后你做股东” 暗示法:在老板面前大声念关于员工枪杀上司的报导。然后叹道:“可怜的人,薪水长得不够,才干出这种事来”
拂袖法:“不长钱,我走人”(此为上计)
如果你觉得自己的能力、业绩足以超过别人……总之你有把握让老板知道你值得加薪,那么你就不妨大胆地把你的要求提出来。
对自己作正确的评估
老板给员工加薪,意味着他自己要因此承担部分损失。当你打定主意准备向老板提出加薪要求的时候,一定得先给自己作一番正确的评估,即你在公司的资历怎样,你在老板心中的分量重不重,你最近出色地完成了哪些项目,这些项目为公司带来了多大的利润,你认为你未来还会为公司作出哪些贡献,你的离去是否会为公司带来某种损失……总之对自己有一个正确的评估,你就能知彼知己,有的放矢,既不会让老板为难,也能让大家知道你是否真正“薪有所值”。
选择适当的时机
当老板沉浸在成功的喜悦中,或是他的家人有什么喜事而使他轻松愉快的时候,你向他提出适当的要求他就比较容易接受。
从你自身来说,由于你的努力,公司近期业绩增长,或者你刚刚完成了某个大项目为公司增了光,这个时候,你向老板提出加薪要求,他也会慎重考虑一番。再者就是你看到同行业的许多员工都不同程度地加了薪,老板心里也有数,正在等待观望中,你适时地捅破这层纸,他也会欣然接受,顺水推舟。
善开“金”口几招式
向老板提加薪要求其实是一招险棋,弄不好就会因此而被“扫地出门”,或者即使没赶你出去,今后也会对你“另眼相看”。所以,善开“金”口是既不让老板对你反感又能让你腰包鼓鼓的前提。托人传话
作为一般员工,你也许不会经常直接和老板打交道,但部门经理会对你了解得更多一些,而部门经理则是老板经常要召集开会的人之一。除此之外,老板身边也有比较亲近的人,通过他们转达你的加薪要求有时比你直接开口效果更好。当然这里你得把握好一个“度”,即能替你传话的人一定是了解你、理解你、同情你的人,这样他在传话的过程中就能把话说得婉转些、圆满些,即使遭到拒绝,面子上也不至于太尴尬,因为你毕竟没和老板“正面交锋”。
适时“提醒”
记得五年前,我在南方一家公司打工,由于初来乍到,不懂规矩,每到发工资时总爱向别人打听:“哎,这个月你拿了多少?”谁知他们一个个都讳莫如深,三缄其口。后来我才明白个中奥妙,因为每个员工的工资是不一样的。但在一个偶然的机会里,我还是发现我的工资连续好几个月比与我做同一样事的同事少了好几百块钱。于是我趁向老板送材料的机会向他作了一番“提醒”:“老板,实在是不好意思,有一件事我一直没弄清楚,我发现这几个月我的工资比我的同事少了好几百块钱,是不是我的试用期已过而正式聘用的相关手续还没有办妥(其实我知道人事部门已经给我办好了手续)”当时老板并没有什么特别的反应,而是很认真地答应替我过问一下。第二天,他正式通知我说,真是不好意思,其实你的工资早几个月就应该加上去了,只是财务上一时没办好手续,以后有什么事如果我忘了可以提醒我一下,不要有什么顾虑,按劳分配嘛。
假意辞职
公司真的离不开你吗?你这一走马上就有单位愿意接收你吗?新的公司薪水就一定比现在多吗?这些问题在你假意辞职前一定得吃准了,否则“偷鸡不成反蚀一把米”,那可是你自找的。
小王是公司里的业务骨干,同他一块出来打拼的一个同学在另一家公司干得有声有色,而且月薪比他多了近千元。他力邀小王加盟他们公司,并说他们老板已经给他留好了位置,承诺月薪一定比原单位多一千元。小王考虑到自己老板平时对他不薄,工作也干得很顺心,只要老板给他加个五六百元,他就不想离开原公司。但薪水毕竟是个诱惑,不提出来也不行。于是他找了机会把同学的意思向老板说了,并说如果老板有接替他的合适人选,他才会考虑离开,如果暂时还没有合适人选,他宁愿不要那份薪水继续留在公司干。老板感动之余自然明白了小王的心思。过了一个月,小王的工资袋里就多了800元钱。
直言不讳
一个人因为暗恋另外一个人却不敢当面对他说,结果人家最终投入了别人的怀抱。这种叫人后悔不已的事在职场上也时有发生。如果你觉得自己的付出与得到的回报不相符,如果你认为你的潜力足以压过你身边的平庸之辈,那么你就不妨把你的加薪要求直接向老板提出来。你不愿提或不敢提,知情人反而会觉得你这人缺乏激情,不思进取。要知道,精明的老板有时宁愿给一个敢为天下先的“激进分子”加一千块钱,也不愿给10个按部就班的平庸之辈人均加一百块钱。第一个吃螃蟹的人往往是创造财富最多的人。
尴尬一:辛辛苦苦小学六年勤勤恳恳初中三年废寝忘食高中三年,眼看要走进考场却赶上国家扩招,任他猫猫狗狗也都能混个大学文凭,现在大学文凭算什么葱啊!(正好混了个) 尴尬二:稀里糊涂大学混了四年,使尽浑身解数拿到英语四级、计算机三级证,毕业证、学位证二证在手却怎么也找不到如意的工作,有的连工作都找不到??刚毕业就失业。 (混了四年拿了几个证,现在的工作的感觉就是被骗了,谁叫我们都是“第一次”啊,现在的大学生值几个钱啊) 尴尬三:千辛万苦进了外商独资企业当白领,还是世界五百强,才发现原来中国现在遍地是外企,五百强有499家都在中国有分号。干白领的活承受巨大压力天天加班挣得比民工又多不了多少,稍微发点牢骚就有老外拍桌子:你他妈什么玩意儿,上午把你fire下午我就能找一个!(幸运没进掉外企) 尴尬四:福利分房早已成为昨日黄花,住房公积金少得可怜,又赶上无耻之徒畜牲一样遍地炒房,辛辛苦苦工作了一年,才发现如果不吃不喝睡大街衣麻袋一年攒的钱才能买四五平米住房,贷款住进新房一点都开心不起来??要换贰拾年的贷款啊!(没敢想买房,只想把房租交上) 尴尬五:小时候教育要做个诚实的孩子,中学大学又普及诚信教育,工作后却不得不抽假烟、喝假酒、说假话,上了拿假文凭人的当,在假发票上签了字,最糟心的是??花钱叫了个小姐,一摸身上全是假的。(虽然假话到是不说,但假酒喝了不少,抽烟那叫人在江湖身不由己;倒是没叫过小姐,听到这两个字都起鸡皮疙瘩) 尴尬六:他们说计划经济的教育已经跟不上时代,他们说要普及素质教育,结果我们什么都得学,什么都刚摸到皮毛却连皮毛都不知道。一旦参加工作发现原来在学校里什么都没有学到,得花大把大把的钱去上这个班去考那个证。班上完了,证也考到了,发现自己还是一个二百五;(越来越觉得自己真是一个二百五) 尴尬七:电子信息产业高速发展,网上信息如潮如涌,不论是垃圾还是精华都让人疲惫不堪,没手机没电脑人家会觉得你生于陆拾年代,有人天天打游戏有人天天上网也有人天天在网上钓鱼??美人鱼出现的几率小于万分之一。(出现美人鱼,是人家的) 尴尬八:从小学完雷锋学赖宁,接着在学李素丽、孔繁森,之后还有济南交警还有抗洪英雄还有在异国他乡被炸死的记者还有……现在要学杨利伟??说一套做一套,表面文章做足了接着自私自利。(看透了政府,就是蒙着老百姓玩,大死也不做公务员) 尴尬九:闯荡社会若干年发现一事无成一钱未赚一权未某,必不得已重新拾起书本泡在这个考前冲刺那个精华笔记那个制胜宝典那个某某密题中,希望能够再去学校混个更高一点的文凭出来好混日子;(回想起来在学校的日子叫爽啊,可惜没有珍惜,多希望上天再给一次机会,目前有考研的打算) 尴尬十:美好的生活属于谁呢?二十年前,“属于我,属于你,属于八十年代的新一辈“,十五年前“太阳是我们的,太阳是我们的,月亮……”,十年前“让我们期待明 天会更好!”,八年前“不经历风雨,则么能见彩虹,没有人能随随便便成功”,现在“我闭上眼睛就成天黑”。1990S初生牛犊不怕虎,谁都没把八十年出生的人放在眼里。
中新网8月7日电 美国《财富》(Fortune)杂志6日证实,墨西哥电信巨子卡洛斯·斯利姆·埃卢以590亿美元资产,取代微软创始人比尔·盖茨成为新的世界首富。但埃卢对此反应平静,称“并不在乎世界首富的头衔“。
追踪世界顶尖公司业绩的《财富》表示,根据埃卢旗下公司在股票交易所的市场价值,他的资产净值在今年增加120亿美元。《财富》杂志在67岁的埃卢简介中称,依照他7月底公开持有的股票价值,他的资产已达590亿美元。
该杂志称,之前长期占据世界首富宝座的微软创始人盖茨资产净值估计有580亿美元。埃卢此前在接受媒体采访时说,“无论我的财富排名第2位,第20位,或是2000位,这都不重要。”
在全球富豪中,身为黎巴嫩移民之子的埃卢创造了一个神话,曾经创下最近10年全球个人资产增值速度最快的纪录。美国《福布斯》杂志曾于今年4月11日公布的最新一期全球个人财富排行榜显示,那时排名第三的埃卢身家超过美国伯克希尔·哈撒韦公司董事长沃伦·巴菲特,跃至财富榜第二位。
这是一张椅子的图片,但是,回复后,把它保存到某个目录下,如果你的系统是xp的话, 查看方式选择缩略图或者幻灯片方式,看到的小图 却变成一个机器女人坐着的图案,据说这是清华学子发现的xp漏洞, 真是百思不得其解,到底是怎么一回事啊!!!!!
本人是试过了·····真的·····
要轻松流畅上网你是否注意到你的电脑系统磁盘的可用空间正在一天天在减少呢?是不是像老去的猴王一样动作一天比一天迟缓呢?
没错!在Windows在安装和使用过程中都会产生相当多的垃圾文件,包括临时文件(如:*.tmp、*._mp)日志文件(*.log)、临时帮助文件(*.gid)、磁盘检查文件(*.chk)、临时备份文件(如:*.old、*.bak)以及其他临时文件。特别是如果一段时间不清理IE的临时文件夹“Temporary Internet Files”,其中的缓存文件有时会占用上百MB的磁盘空间。这些LJ文件不仅仅浪费了宝贵的磁盘空间,严重时还会使系统运行慢如蜗牛。这点相信你肯定忍受不了吧!所以应及时清理系统的LJ文件的淤塞,保持系统的“苗条”身材,轻松流畅上网!朋友来吧,现在就让我们一起来快速清除系统垃圾吧!!下面是步骤很简单就两步!
在电脑屏幕的左下角按“开始→程序→附件→记事本”,把下面的文字复制进去(黑色部分),点“另存为”,路径选“桌面”,保存类型为“所有文件”,文件名为“清除系统LJ.bat”,就完成了。记住后缀名一定要是.bat,ok!你的垃圾清除器就这样制作成功了! 双击它就能很快地清理垃圾文件,大约一分钟不到。
======就是下面的文字(这行不用复制)=============================
@echo off echo 正在清除系统垃圾文件,请稍等...... del /f /s /q %systemdrive%\*.tmp del /f /s /q %systemdrive%\*._mp del /f /s /q %systemdrive%\*.log del /f /s /q %systemdrive%\*.gid del /f /s /q %systemdrive%\*.chk del /f /s /q %systemdrive%\*.old del /f /s /q %systemdrive%\recycled\*.* del /f /s /q %windir%\*.bak del /f /s /q %windir%\prefetch\*.* rd /s /q %windir%\temp & md %windir%\temp del /f /q %userprofile%\cookies\*.* del /f /q %userprofile%\recent\*.* del /f /s /q "%userprofile%\Local Settings\Temporary Internet Files\*.*" del /f /s /q "%userprofile%\Local Settings\Temp\*.*" del /f /s /q "%userprofile%\recent\*.*" echo 清除系统LJ完成! echo. & pause
=====到这里为止(这行不用复制)============================================== 以后只要双击运行该文件,当屏幕提示“清除系统LJ完成!就还你一个“苗条”的系统了!!到时候再看看你的电脑,是不是急速如飞呢?可别忘了回帖喔!
注:LJ就是垃圾的意思!这招比那些所谓的优化大师好用!最重要的是无论在公司默认的系统环境还是在自己家中的电脑都不会破坏系统文件
安装
Add jcaptcha-all.jar (provided in bin-distribution) and ehcache.jar (not provided see ehcache site) to your application class path, ie in you WEB-INF/lib folder. 实例一个jcaptcha服务,注意,必须是单例模式的
import com.octo.captcha.service.image.ImageCaptchaService; import com.octo.captcha.service.image.DefaultManageableImageCaptchaService;
public class CaptchaServiceSingleton { private static ImageCaptchaService instance = new DefaultManageableImageCaptchaService(); public static ImageCaptchaService getInstance(){ return instance; } }
注:以上是默认的一个实现,下面是其他更多的实现
- SimpleListSoundCaptchaEngine //还可以用声音,真爽哦
- SpellerSoundCaptchaEngine
- SpellerSoundCaptchaEngine
- DefaultGimpyEngineCaptcha
- BaffleListGimpyEngineCaptcha
- BasicListGimpyEngineCaptcha
- DeformedBaffleListGimpyEngineCaptcha
- DoubleRandomListGimpyEngineCaptcha
- SimpleListImageCaptchaEngineCaptcha
- SimpleFishEyeEngineCaptcha
具体请参考 官方说明编写一个产生图片的servlet
import com.octo.captcha.service.CaptchaServiceException; import com.sun.image.codec.jpeg.JPEGCodec; import com.sun.image.codec.jpeg.JPEGImageEncoder;
import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.awt.image.BufferedImage; import java.io.ByteArrayOutputStream; import java.io.IOException;
public class ImageCaptchaServlet extends HttpServlet {
public void init(ServletConfig servletConfig) throws ServletException {
super.init(servletConfig);
}
protected void doGet(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws ServletException, IOException { byte[] captchaChallengeAsJpeg = null; // the output stream to render the captcha image as jpeg into ByteArrayOutputStream jpegOutputStream = new ByteArrayOutputStream(); try { // get the session id that will identify the generated captcha. //the same id must be used to validate the response, the session id is a good candidate! String captchaId = httpServletRequest.getSession().getId(); // call the ImageCaptchaService getChallenge method BufferedImage challenge = CaptchaServiceSingleton.getInstance().getImageChallengeForID(captchaId, httpServletRequest.getLocale()); // a jpeg encoder JPEGImageEncoder jpegEncoder = JPEGCodec.createJPEGEncoder(jpegOutputStream); jpegEncoder.encode(challenge); } catch (IllegalArgumentException e) { httpServletResponse.sendError(HttpServletResponse.SC_NOT_FOUND); return; } catch (CaptchaServiceException e) { httpServletResponse.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); return; }
captchaChallengeAsJpeg = jpegOutputStream.toByteArray();
// flush it in the response httpServletResponse.setHeader("Cache-Control", "no-store"); httpServletResponse.setHeader("Pragma", "no-cache"); httpServletResponse.setDateHeader("Expires", 0); httpServletResponse.setContentType("image/jpeg"); ServletOutputStream responseOutputStream = httpServletResponse.getOutputStream(); responseOutputStream.write(captchaChallengeAsJpeg); responseOutputStream.flush(); responseOutputStream.close(); } }
为servlet修改web.xml配置文件
<servlet> <servlet-name>jcaptcha</servlet-name> <servlet-class>ImageCaptchaServlet</servlet-class> <load-on-startup>0</load-on-startup> </servlet>
<servlet-mapping> <servlet-name>jcaptcha</servlet-name> <url-pattern>/jcaptcha</url-pattern> </servlet-mapping>
编写你的客户端的展示
<img src="jcaptcha"> <input type='text' name='j_captcha_response' value=''>
上面的src="jcaptcha" 就是调用了上面的servlet,text里是用户填写的确认验证码 后台逻辑验证
Boolean isResponseCorrect =Boolean.FALSE; //remenber that we need an id to validate! String captchaId = httpServletRequest.getSession().getId(); //retrieve the response String response = httpServletRequest.getParameter("j_captcha_response"); // Call the Service method try { isResponseCorrect = CaptchaServiceSingleton.getInstance().validateResponseForID(captchaId, response); } catch (CaptchaServiceException e) { //should not happen, may be thrown if the id is not valid }
OK,大功告成了.
在java中使用awt在服务器上处理图片的时候发现有错: 第一遍执行 500 Servlet Exception java.lang.InternalError: Can't connect to X11 window server using ':0.0' as the value of the DISPLAY variable. at sun.awt.X11GraphicsEnvironment.initDisplay(Native Method) at sun.awt.X11GraphicsEnvironment.<clinit>(X11GraphicsEnvironment.java:134) at java.lang.Class.forName0(Native Method) at java.lang.Class.forName(Class.java:141) at java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment(GraphicsEnvironment.java:62) at java.awt.image.BufferedImage.createGraphics(BufferedImage.java:1041) at com.lodesoft.ipniii.club.tool.AlbumTool.createSmallThumb(AlbumTool.java:793) at com.lodesoft.ipniii.club.test.action.UpdateAllPhotoAction.perform(UpdateAllPhotoAction.java:82) at org.apache.struts.action.Action.execute(Action.java:420) at org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:484) at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:274) at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1482) at org.apache.struts.action.ActionServlet.doGet(ActionServlet.java:507) at javax.servlet.http.HttpServlet.service(HttpServlet.java:126) at javax.servlet.http.HttpServlet.service(HttpServlet.java:103) at com.caucho.server.dispatch.ServletFilterChain.doFilter(ServletFilterChain.java:113) at com.caucho.server.cache.CacheFilterChain.doFilter(CacheFilterChain.java:211) at com.caucho.server.webapp.WebAppFilterChain.doFilter(WebAppFilterChain.java:177) at com.caucho.server.dispatch.ServletInvocation.service(ServletInvocation.java:221) at com.caucho.server.http.HttpRequest.handleRequest(HttpRequest.java:262) at com.caucho.server.port.TcpConnection.run(TcpConnection.java:315) at com.caucho.util.ThreadPool.runTasks(ThreadPool.java:353) at com.caucho.util.ThreadPool.run(ThreadPool.java:302) at java.lang.Thread.run(Thread.java:534)
-------------------------------------------------------------------------------- Resin-3.0.6 (built Tue, 20 Jan 2004 09:46:57 PST) 然后刷新这个页面 500 Servlet Exception java.lang.NoClassDefFoundError at java.lang.Class.forName0(Native Method) at java.lang.Class.forName(Class.java:141) at java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment(GraphicsEnvironment.java:62) at java.awt.image.BufferedImage.createGraphics(BufferedImage.java:1041) at com.lodesoft.ipniii.club.tool.AlbumTool.createSmallThumb(AlbumTool.java:793) at com.lodesoft.ipniii.club.test.action.UpdateAllPhotoAction.perform(UpdateAllPhotoAction.java:82) at org.apache.struts.action.Action.execute(Action.java:420) at org.apache.struts.action.RequestProcessor.processActionPerform(RequestProcessor.java:484) at org.apache.struts.action.RequestProcessor.process(RequestProcessor.java:274) at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1482) at org.apache.struts.action.ActionServlet.doGet(ActionServlet.java:507) at javax.servlet.http.HttpServlet.service(HttpServlet.java:126) at javax.servlet.http.HttpServlet.service(HttpServlet.java:103) at com.caucho.server.dispatch.ServletFilterChain.doFilter(ServletFilterChain.java:113) at com.caucho.server.cache.CacheFilterChain.doFilter(CacheFilterChain.java:211) at com.caucho.server.webapp.WebAppFilterChain.doFilter(WebAppFilterChain.java:177) at com.caucho.server.dispatch.ServletInvocation.service(ServletInvocation.java:221) at com.caucho.server.http.HttpRequest.handleRequest(HttpRequest.java:262) at com.caucho.server.port.TcpConnection.run(TcpConnection.java:315) at com.caucho.util.ThreadPool.runTasks(ThreadPool.java:353) at com.caucho.util.ThreadPool.run(ThreadPool.java:302) at java.lang.Thread.run(Thread.java:534)
-------------------------------------------------------------------------------- Resin-3.0.6 (built Tue, 20 Jan 2004 09:46:57 PST) 我们的服务器上没有安装xwindows,但是安装了XFree86的相关包。web server用的是 Resin 306 ,现在找到了解决方法。 1:安装XFree86-Xvfb-4.3.0-2.i386.rpm。如果什么XFree86的相关包都没有,那就要弄来装一装了。起码的libs是要有的。 2:使用两个命令: ------------------------------------ Xvfb :0 -screen 0 800x600x16 & 启动Xwindows的虚拟设备 export DISPLAY=localhost:0.0 配置本地环境 ------------------------------------ 运行顺序先后没有太大的关系。 注意的是 Xvfb :0 -screen 0 中的两个0的参数和后面 DISPLAY=localhost:0.0 中的两个0是对应的。Xvfb实现的应该是后台虚拟拟图形界面环境。 3:可以把这两个命令做成启动就运行的脚本,也可以在启动Resin的时候调用起来,我用的后者 修改resin ./bin 目录下的httpd.sh 在JAVA_HOME 配置项前加入 Xvfb :0 -screen 0 800x600x16 & export DISPLAY=localhost:0.0 4:其实没有什么第四,因为这样就可以啦。 200408220127 :今天来增加一条,如果安装liunx的时候没有选择安装任何xwindows的组件,那么从linux安装盘上去取Xvfb的包安装是不会成功的,因为还需要一大堆依赖的包,而我就因为找不到这些包,不能加快进度而加班到昨天早上4点多。庆幸的是我找到了一个好办法去解决(不然可能要拖到5,6点才能结束),我在XFree86的官方站点上 http://XFree86.org 找到了一个Xvfb的tag下载,下来后解压出来就可以用了,哈哈哈哈。要注意的是要去找版本对应的tag包,比如RedHat 9对应的是XFree86 4.3.0 的版本,就去它的FTP下载相应版本的包,取下来后解压出bin目录,运行其中Xvfb就可以,记得加参数哦!
碰到文件乱码,google了一下,发现这篇文章还不赖
摘录如下: 之前,写过一个Download.jsp文件,可以解决下载文件乱码问题(诸如:DOC,XSL文件等等). 后来发现,遇到中文名的文件的时候,文件下载将会报错~~~~ 今天,通过改写原Download.jsp文件已经彻底解决了这个问题~ 现在,把一整套的文件上传下载的方法给贴出来~~~以便大家借鉴!~!~!~!~! 作者:古埃及法老 download.jsp文件---------------------------------------------------------
<% java.io.BufferedInputStream bis=null; java.io.BufferedOutputStream bos=null; try{ String filename=request.getParameter("filename"); filename=new String(filename.getBytes("iso8859-1"),"gb2312"); response.setContentType("application/x-msdownload"); response.setHeader("Content-disposition","attachment; filename="+new String(filename.getBytes("gb2312"),"iso8859-1")); bis =new java.io.BufferedInputStream(new java.io.FileInputStream(config.getServletContext().getRealPath("files/" + filename))); bos=new java.io.BufferedOutputStream(response.getOutputStream()); byte[] buff = new byte[2048]; int bytesRead; while(-1 != (bytesRead = bis.read(buff, 0, buff.length))) { bos.write(buff,0,bytesRead); } } catch(Exception e){ e.printStackTrace(); } finally { if (bis != null)bis.close(); if (bos != null)bos.close(); } %>
注意,关键就是 setHeader里的filename需要重新编码,格式是ISO-8859-1就OK了
以下是我自己项目中用到的代码片断,供参考:
list.jsp: 显示附件名称的页面
<tr> <td height="25" class="tdcor">附 件 </td> <td colspan="3" height=50> <% if (null != publish.getAttatchFilename() && publish.getAttatchFilename().length() > 0) { %> <a href="publish_do.jsp?method=download&fileName= <%=URLEncoder.encode(publish.getAttatchFilename(),"GBK")%>"> <%=URLDecoder.decode(publish.getAttatchFilename(),"GBK")%></a> <% } %> </td> </tr>
download.jsp:下载页面
else if (null != method && method.equals("download")) {//下载附件
String fileName = request.getParameter("fileName"); File file = new File(Constants.PUBLISH_FILE_PATH + "/" + URLDecoder.decode(fileName,"GBK")); response.reset(); response.setContentType("application/octet-stream; charset=GBK"); response.addHeader("Content-Disposition", "attachment; filename=" + CourseDetailBusiness.transfer(URLDecoder.decode(fileName,"GBK"),"GBK","ISO-8859-1")); response.setContentLength((int) file.length());
byte[] buffer = new byte[4096]; BufferedOutputStream output = null; BufferedInputStream input = null;
// 写缓冲区: try { output = new BufferedOutputStream(response.getOutputStream()); input = new BufferedInputStream(new FileInputStream(file));
int n = (-1); while ((n = input.read(buffer, 0, 4096)) > -1) { output.write(buffer, 0, n); } response.flushBuffer(); } catch (Exception e) { } // maybe user cancelled download finally { if (input != null) input.close(); if (output != null) output.close(); }
说明: 1。文件名在数据库中保存的编码为URLEncode 2.在list.jsp显示的时候多了一次encode,不知为什么,不encode一次还不行,实际上是第二次编码了
我现在的编程方法,不再是以前的整块应用,和C/S应用的两层架构,现在流行的编程方式是三层架构,就是表示层,商业逻辑,还有数据库都相互独立。 远程方法调用正是基于三层架构设计的中间层。远程方法调用的原理是桩和骨架结构。主要有三层,分别是桩/骨架层,远程引用层,还有传输层。 要完成一个简单的RMI应用要分为以下几个简单的步骤: 1。定义远程接口 2。定义和实现RMI服务器类 3。定义和实现客户端类 4。编译以上的源码 5。生成桩/骨架 6。创建安全策略 7。启动RMI注册表 8。启动服务器 9。启动客户端 我们来做一个例子,在服务器上有一个连接数据库,插入值的方法,我们在客户端要使用这个方法,来真正的插入一个值! 第一步:先编写一个接口AccountServer.java,这个接口要继承Remote接口,并且提供一个远程方法insertDetails(),这个方法要抛出RemoteException异常,代码如下:
import java.rmi.Remote; import java.rmi.RemoteException;
public interface AccountServer extends Remote { public String insertDetails(String firstName, String lastName, String phone, String income, String accountType) throws RemoteException; }
第二步:实现远程对象类,就是RMI服务器,AccountServerImpl.java,这个类要继承UnicastRemoteObject类,并且要实现自己写的远程接口类AccountServer,首先要定义远程对象构造器,然后就是要实现远程接口中的方法,这个方法来连接mysql数据库,并且插入值.然后我们main方法中,设置安全管理程序,然后创建远程对象,接着注册远程对象.代码如下:
import java.rmi.Naming; import java.rmi.RMISecurityManager; import java.rmi.RemoteException; import java.rmi.server.UnicastRemoteObject; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement;
public class AccountServerImpl extends UnicastRemoteObject implements AccountServer { private Connection con;
public AccountServerImpl() throws RemoteException { super(); }
public String insertDetails(String firstName, String lastName, String phone, String income, String accountType) throws RemoteException { int rowsAffected = 0; String sReturn = "fail"; try { Class.forName("com.mysql.jdbc.Driver"); con = DriverManager .getConnection( "jdbc:mysql://127.0.0.1/jsptest?useUnicode=true&characterEncoding=GBK", "root", ""); PreparedStatement ps = con .prepareStatement("insert into User_info values(?,?,?,?,?)"); ps.setString(1, "firstName"); ps.setString(2, "lastName"); ps.setString(3, "phone"); ps.setString(4, "income"); ps.setString(5, "accountType");
rowsAffected = ps.executeUpdate();
if (rowsAffected > 0) { sReturn = "success"; }
} catch (Exception e) { e.printStackTrace(); } return sReturn; }
public static void main(String[] args) { //设置安全管理程序 System.setSecurityManager(new RMISecurityManager());
try { //创建远程对象 AccountServerImpl as = new AccountServerImpl(); //注册远程对象 Naming.rebind("AccountServer", as); System.out.println("RMI服务器启动成功"); } catch (RemoteException e) { e.printStackTrace(); } catch (Exception e1) { e1.printStackTrace(); } }
} 第三步:编写客户端代码,Client.java 这个代码中有两个重要的任务,就是得到远程对象的应用,然后调用远程对象,其余的都是界面部分,就不再讲解,代码如下:
import java.awt.Container; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.rmi.Naming;
import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JTextField;
public class Client { public static void main(String[] args) { ClientFrame frame = new ClientFrame(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.show(); } }
class ClientFrame extends JFrame { public ClientFrame() { setTitle("客户端"); setSize(200, 220);
Container con = getContentPane(); ClientPanel panel = new ClientPanel(); con.add(panel); } }
class ClientPanel extends JPanel { private JLabel lfirst, llast, lphone, lincome, ltype;
private JTextField ffirst, flast, fphone, fincome, ftype;
private JButton submit;
public ClientPanel() { lfirst = new JLabel(" 姓:"); llast = new JLabel(" 名:"); lphone = new JLabel("电话:"); lincome = new JLabel("来自:"); ltype = new JLabel("类型:");
ffirst = new JTextField(10); flast = new JTextField(10); fphone = new JTextField(10); fincome = new JTextField(10); ftype = new JTextField(10);
submit = new JButton(" 提 交 "); submit.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { try { //得到远程对象 AccountServer as = (AccountServer) Naming .lookup("rmi://localhost/AccountServer"); String firstName = ffirst.getText(); String lastName = flast.getText(); String phone = fphone.getText(); String income = fincome.getText(); String accountType = ftype.getText(); //调用远程方法 String str = as.insertDetails(firstName, lastName, phone, income, accountType); if ("fail".equals(str)) { JOptionPane.showMessageDialog(null, "插入失败"); } else { JOptionPane.showMessageDialog(null, "插入成功"); }
} catch (Exception e2) { e2.printStackTrace(); } } });
add(lfirst); add(ffirst); add(llast); add(flast); add(lphone); add(fphone); add(lincome); add(fincome); add(ltype); add(ftype); add(submit); } }
第四步:在Dos下,进入代码所在目录,使用javac *.java 来编译所有代码 第五步:在class文件所在目录使用 rmic AccountServerImpl来生成桩和骨架(AccountServerImpl_Skel.class和AccountServerImpl.Stub.class) 第六步:用policytool工具来创建安全策略文件,放开所有的权限,保存.java.policy文件在C:\Documents and Settings\Administrator文件夹下 第七步:使用start rmiregistry命令来启动注册表,默认使用1099端口,我们不需要改变 第八步:java -Djava.rmi.server.codebase=file:/e:/aa/ -classpath .;%CLASSPATH% AccountServerImpl来启动服务器,注意由于服务器中要使用Mysql数据库,所有我们引入使用数据库的jar包,将mysql的jar包添加的CLASSPATH,就OK呢 第九步:使用java Client来启动客户端,和得到图形界面的客户端,填入数据,点击提交,数据就会添加进入数据库
附: 数据库名称:jsptest 表名:user_info 表结构: CREATE TABLE user_info ( firstName varchar(50) NOT NULL default '', lastName varchar(50) NOT NULL default '', phone varchar(20) NOT NULL default '', income varchar(30) NOT NULL default '', accountType varchar(50) NOT NULL default '', PRIMARY KEY (firstName) )
一 .RMI概述
RMI(Remote Method Invocation) RMI是分布式对象软件包,它简化了在多台计算机上的JAVA应用之间的通信。必须在jdk1.1以上
RMI用到的类 java.rmi.Remote 所有可以被远程调用的对象都必须实现该接口 java.rmi.server.UnicastRemoteObject 所有可以被远程调用的对象都必须扩展该类
什么是RMI 远程方法调用是一种计算机之间对象互相调用对方函数,启动对方进程的一种机制, 使用这种机制,某一台计算机上的对象在调用另外一台计算机上的方法时,使用的程 序语法规则和在本地机上对象间的方法调用的语法规则一样。
优点 这种机制给分布计算的系统设计、编程都带来了极大的方便。 只要按照RMI规则设计程序,可以不必再过问在RMI之下的网络细节了,如:TCP和Socket等等。 任意两台计算机之间的通讯完全由RMI负责。调用远程计算机上的对象就像本地对象一样方便。
1、面向对象: RMI可将完整的对象作为参数和返回值进行传递,而不仅仅是预定义的数据类型。 也就是说,可以将类似Java哈西表这样的复杂类型作为一个参数进行传递。
2、可移动属性: RMI可将属性从客户机移动到服务器,或者从服务器移动到客户机。
3、设计方式: 对象传递功能使您可以在分布式计算中充分利用面向对象技术的强大功能,如二层和三层结构系统。 如果用户能够传递属性,那么就可以在自己的解决方案中使用面向对象的设计方式。 所有面向对象的设计方式无不依靠不同的属性来发挥功能,如果不能传递完整的对象——包括实现和类型 ——就会失去设计方式上所提供的优点。
4、安全性: RMI使用Java内置的安全机制保证下载执行程序时用户系统的安全。 RMI使用专门为保护系统免遭恶意小程序侵害而设计的安全管理程序。 5、便于编写和使用 RMI使得Java远程服务程序和访问这些服务程序的Java客户程序的编写工作变得轻松、简单。 远程接口实际上就是Java接口。 为了实现RMI的功能必须创建远程对象任何可以被远程调用的对象必须实现远程接口。但远程 接口本身并不包含任何方法。因而需要创建一个新的接口来扩展远程接口。 新接口将包含所有可以远程调用的方法。远程对象必须实现这个新接口,由于新的接口扩展了 远程接口,实现了新接口,就满足了远程对象对实现远程接口的要求,所实现的每个对象都将 作为远程对象引用。
个人总结: RMI说白了,就是提供了一种远程的方法调用。这种调用简单方便,可以传递复杂java对象。现在流行的j2ee中的EJB的底层实现技术就是RMI,EJB的调用就是经过封装的,更高级的RMI调用。
下面我们就来写一个RMI的程序:
一.创建RMI程序的6个步骤: 1、定义一个远程接口的接口,该接口中的每一个方法必须声明它将产生一个RemoteException异常。 2、定义一个实现该接口的类。 3、使用RMIC程序生成远程实现所需的残根和框架。 4、创建一个服务器,用于发布2中写好的类。 5. 创建一个客户程序进行RMI调用。 6、启动rmiRegistry并运行自己的远程服务器和客户程序。
二. 程序详细说明
1.定义一个远程接口的接口,该接口中的每一个方法必须声明它将产生一个RemoteException异常。
import java.rmi.Remote; import java.rmi.RemoteException; public interface I_Hello extends java.rmi.Remote //需要从Remote继承 { public String SayHello() throws RemoteException; //需要抛出remote异常 }
上面例子我们定义一个返回字符串的远程方法 SayHello(),这个远程接口 I_Hello必须是public的,它必须从java.rmi.Remote继承而来,接口中的每一个方法都必须抛出远程异常java.rmi.RemoteException。
抛出这个异常的原因 由于任何远程方法调用实际上要进行许多低级网络操作,因此网络错误可能在调用过程中随时发生。 因此,所有的RMI操作都应放到try-catch块中。 2、定义一个实现该接口的类。
import java.io.PrintStream; import java.rmi.*; import java.rmi.server.UnicastRemoteObject;
public class Hello extends UnicastRemoteObject //必须从UnicastRemoteObject 继承 implements I_Hello { public Hello() throws RemoteException //需要一个抛出Remote异常的默认初始化方法 { }
public String SayHello() //这个是实现I_Hello接口的方法 { return "Hello world !!"; } }
实现接口的类必须继承UnicastRemoteObject类。 扩展java.rmi.server.UnicastRemoteObject UnicastRemoteObject顾名思义,是让客户机与服务器对象实例建立一对一的连接。
3、使用RMIC程序生成远程实现所需的残根Stub 和 框架。 2中的Hello 编译好以后,我们就可以用RMIC命令来生成残根Stub 在Dos窗口里,到Hello.class 所在目录,运行以下命令: rmic Hello 命令执行完以后,将会在当前目录生成一个 Hello_Stub.class 这个就是我们远程调用时需要的类
参考: 在RMI中,客户机上生成的调动调用参数和反调动返回值的代码称为残根。有的书上称这部分代码为“主干”。 服务器上生成的反调动调用参数和进行实际方法调用调动返回值的代码称为框架。 生成残根和框架的工具 Rmic命令行工具(RMI Compiler) 格式: Rmic classname
4、创建一个服务器,用于发布2中写好的类。
import java.rmi.*; public class RMI_Server { public static void main(String[] args) { try { Hello hello = new Hello(); //实例化要发布的类 Naming.rebind("RMI_Hello", hello); //绑定RMI名称 进行发布 System.out.println("=== Hello server Ready === "); } catch(Exception exception) { exception.printStackTrace(); } } }
5. 创建一个客户程序进行RMI调用。
import java.rmi.*; public class RMI_Client { public static void main(String[] args) { try { I_Hello hello = (I_Hello) Naming.lookup("RMI_Hello"); //通过RMI名称查找远程对象 System.out.println(hello.SayHello()); //调用远程对象的方法 } catch (Exception e) { e.printStackTrace(); } }
}
Naming.lookup("RMI_Hello") 其中的参数“RMI_Hello”只是针对本机的RMI查找,如果是异地的RMI调用请参照 rmi://127.0.0.1:1099/RMI_Hello 端口1099是默认的RMI端口,如果你启动 rmiregistry 的时候(见第6点)没有指定特殊的端口号,默认就是1099
到此我们所有的代码编写都完成了,不过不要急着去运行,请跟随第6点去运行,因为rmi 调用还会遇到一些特别的情况,偶花了牛劲,才找到原因的,许多刚用RMI的人,常常被这些问题搞得吐血
6、启动rmiRegistry并运行自己的远程服务器和客户程序。 1)服务器的运行 先在DOS下运行 rmiregistry 这个命令是开启RMI的注册服务,开启以后我们的server程序才能调用rebing方法发布我们的类
然后,运行我们的server程序 RMI_Server 这里是最容易出错的,参见下面注意事项。 注意: 如果提示找不到Stub类,这个需要用下面的命令来运行 java.exe -Djava.rmi.server.codebase=file:/E:\MIS_Interface\momo\TestEasy\classes/ RMI_Server
蓝字部分指定了stub类的路径。
有人会问,我已经把stub 通过-classpath 加到类路径里面了,为什么还没有提示这个错误呢?原因是这样的:这里提示的找不到stub类,不是由你写的RMI_Server这个程序引起的,是由rmi注册服务器报告的异常,也就是我们前面启动的 rmiregistry ,因为你写的RMI_Server 要求RMI注册服务器注册一个新的类,自然RMI服务器必须知道你的类放在哪里,所以我们通过 -Djava.rmi.server.codebase 这个运行参数来指定 你也可以通过修改操作系统的classpath 环境变量来指定stub的位置,只不过太麻烦
2) 客户端的运行 直接运行RMI_Client 即可 注意 把 Stub 和 接口 I_Hello 加到类路径里 通常第一次运行客户端都会报一个错误: Access XXXX 不记得具体的了,反正就是“访问权限限制”,这是因为RMI的服务需要授权,外部程序才能访问,所以我们要改动 jre的安全配置文件,来开放权限, 具体如下:
打开你的jdk目录下的这个文件 C:\Program Files\Java\jdk1.5.0_04\jre\lib\security\java.policy 在文件最后加入下面代码: grant { permission java.net.SocketPermission "*:1024-65535", "connect,accept"; permission java.net.SocketPermission "*:80","connect"; }; 此代码,开放了端口的connect访问权限
注意 你应该修改服务器那台机子的安全配置文件,也就是你运行 rmiregistry 和 RMI_Server的机子 另外,很多人修改完以后,仍然报这个错误,多数情况是由于你没有修改到正确的jdk 下的文件,而是修改到其他jdk的文件, 我们安装oracle , Weblogic等等软件的时候都会自带一个 jdk,他们会自动在操作系统的环境变量里面加入jdk的路径,所以,你先要确定你运行服务器端程序是用哪个jdk,再修改这个jdk下的配置文件,确定当前jdk的路径很简单 开始 -》运行-》rmiregistry 看看这个DOS窗口标题的路径,就是你当前系统默认jdk的路径了
客户端正常运行以后,就会出现以下结果: Hello world !!
这些字符是通过RMI调用远程服务器的类返回的结果
摘要 Java Servlet 编程可以很方便地将 HTML 文件发送到客户端 Web 浏览器。然而许多站点还允许访问非 HTML 格式的文档,包括 Adobe PDF、Microsoft Word 和 Micorsoft Excel 等。事实上这些非 HTML 格式只要能用 MIME 类型表示,就可以利用 servlet 来发送。本文将以 PDF 和 Microsoft Word 文件为例,向你介绍如何使用 servlet 传送非 HTML 格式文件,以及与防火墙交互的方法。 你只要将文件写到 servlet 的输出流中,就可以利用 servlet 在浏览器中打开一个文件。尽管这看起来非常简单,在打开非 HTML 格式文档(比如二进制数据或多媒体文件)的时候,仍要注意一些要点。 首先从获得 servlet 的输出流开始: ServletOutputStream out = res.getOutputStream(); 互联网上使用 MIME (multipurpos Internet mail extension 多目的互联网邮件扩展协议)来传送混合格式、多媒体和二进制数据文件。如果要在 servlet 的 response 对象中打开某个文档,就必须设置该文档的 MIME 类型。下面这个例子中我们将打开 PDF 文档。 MIME 类型 Web 浏览器使用 MIME 类型来识别非 HTML 文档,并决定如何显示该文档内的数据。将插件 (plug-in) 与 MIME 类型结合使用,则当 Web 浏览器下载 MIME 类型指示的文档时,就能够启动相应插件处理此文档。某些 MIME 类型还可以与外部程序结合使用,浏览器下载文档后会启动相应的外部程序。 MIME 类型非常有用。它们允许 Web 浏览器处理不同格式的文档,却不需要事先嵌入相关知识。Java Servlets 可以使用 MIME 类型来向浏览器传送非 HTML 文件,比如 Adobe PDF 和 Micorsoft Word。使用正确的 MIME 类型能够保证这些非 HTML 文件被正确的插件或外部程序显示。本文末的资料部分提供了一些网址,指向一些已定义 MIME 类型列表和关于 MIME 类型的文章。 PDF 文件的 MIME 类型是 "application/pdf"。要用 servlet 来打开一个 PDF 文档,需要将 response 对象中 header 的 content 类型设置成 "application/pdf": // MIME type for pdf doc res.setContentType( "application/pdf" ); 若要打开一个 Microsoft Word 文档,你就要将 response 对象的 content 类型设置成 "application/msword": // MIME type for MSWord doc res.setContentType( "application/msword" ); 如果是一个 Excel 文档,则使用 MIME 类型 "application/vnd.ms-excel"。其中 vnd 表示该应用程序的制造者,必须将它包含在 MIME 类型里才能够打开该类型文档。 有时候浏览器不能识别文档的 MIME 类型。通常这是由于没有安装这些文档需要的插件而导致的。这种情况下,浏览器会弹出一个对话框,询问用户是否需要打开该文件或是将它保存到本地磁盘上。 Content disposition 一种叫做 content-disposition 的 HTTP response header 允许 servlet 指定文档表示的信息。使用这种 header ,你就可以将文档指定成单独打开(而不是在浏览器中打开),还可以根据用户的操作来显示。如果用户要保存文档,你还可以为该文档建议一个文件名。这个建议名称会出现在 Save As 对话框的“文件名”栏中。如果没有指定,则对话框中就会出现 servlet 的名字。更多关于 content-disposition header 的信息,可以参阅资料。 在 servlet 中,你需要将 header 设置成下面这样: res.setHeader("Content-disposition", "attachment; filename=" + "Example.pdf" ); // attachment - since we don´t want to open // it in the browser, but // with Adobe Acrobat, and set the // default file name to use. 如果你要打开的是 Microsoft Word 文件,你可以设成: res.setHeader("Content-disposition", "attachment; filename" + "Example.doc" ); 封装非 HTML 文档 完成上述工作后,剩下的就非常简单了。你需要根据待传送文件的名字,创建一个 java.net.URL 对象。交给 URL 构造器的字符串必须是指向该文件的一个有效 URL 地址。在这个例子中,我要打开 Adobe employment 格式的文档: String fileURL = "http://www.adobe.com/aboutadobe/careeropp/pdfs/adobeapp.pdf;" 你的 URL 字符串也可以类似于 http://www.gr.com/pub/somefile.doc 或 http://www.gr.com/pub/somefile.xls。但必须确保待传送文件类型与先前在 HTTP response 对象中设置的 MIME 类型一致。 URL url = new URL ( fileURL ); 防火墙 如果需要通过防火墙,最后一件要考虑的事情就是你的 URL 链接。首先应当搜集所用代理服务器的相关信息,例如主机名称和端口号等。更多关于如何通过防火墙建立链接的信息,可以参看下面的资料部分。 如果使用的是 Java 2,你应该从 URL 对象类中创建一个 URLConnection 对象,并设置下列系统属性: URLConnection conn = url.openConnection(); // Use the username and password you use to // connect to the outside world // if your proxy server requires authentication. String authentication = "Basic " + new sun.misc.BASE64Encoder().encode("username:password".getBytes()); System.getProperties().put("proxySet", "true"); System.getProperties().put("proxyHost", PROXY_HOST); // your proxy host System.getProperties().put("proxyPort", PROXY_PORT); // your proxy port conn.setRequestProperty("Proxy-Authorization", authentication); 如果你使用的是 JDK 1.1,则不能设置这些系统属性。这种情况下,你可以根据所用代理服务器的信息创建 java.net.URL 对象: url = new URL("http", PROXY_HOST, Integer.parseInt(PROXY_PORT), fileURL ); // assumes authentication is not required 深入工作 开始阅读你传送的文档之前,首先要从 URLConnection (或 URL) 对象中获得输入流 InputStream。在这个例子中,用 BufferedInputStream 将 InputStream 封装起来。 如果你采用 URLConnection,可以尝试如下代码: BufferedInputStream bis = new BufferedInputStream(conn.getInputStream()); 如果你使用 URL,则可用下列代码: BufferedInputStream bis = new BufferedInputStream(url.openStream()); 一旦你完成上述操作,就只要简单地将 InputStream 中的字节,写入到 servlet 的输出流 OutputStream 中: BufferedOutputStream bos = new BufferedOutputStream(out); byte[] buff = new byte[2048]; int bytesRead; // Simple read/write loop. while(-1 != (bytesRead = bis.read(buff, 0, buff.length))) { bos.write(buff, 0, bytesRead); } 在最后的代码块中,关闭这些流。 这个例子是利用 doPost 来实现的(doPost 是 HttpServlet 子类的一个方法): public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { ServletOutputStream out = res.getOutputStream (); //--------------------------------------------------------------- // Set the output data´s mime type //--------------------------------------------------------------- res.setContentType( "application/pdf" ); // MIME type for pdf doc //--------------------------------------------------------------- // create an input stream from fileURL //--------------------------------------------------------------- String fileURL = "http://www.adobe.com/aboutadobe/careeropp/pdfs/adobeapp.pdf"; //------------------------------------------------------------ // Content-disposition header - don´t open in browser and // set the "Save As..." filename. // *There is reportedly a bug in IE4.0 which ignores this... //------------------------------------------------------------ res.setHeader("Content-disposition", "attachment; filename=" += "Example.pdf" ); //----------------------------------------------------------------- // PROXY_HOST and PROXY_PORT should be your proxy host and port // that will let you go through the firewall without authentication. // Otherwise set the system properties and use URLConnection.getInputStream(). //----------------------------------------------------------------- BufferedInputStream bis = null; BufferedOutputStream bos = null; try { URL url = new URL( "http", PROXY_HOST, Integer.parseInt(PROXY_PORT), fileURL ); // Use Buffered Stream for reading/writing. bis = new BufferedInputStream(url.openStream()); bos = new BufferedOutputStream(out); byte[] buff = new byte[2048]; int bytesRead; // Simple read/write loop. while(-1 != (bytesRead = bis.read(buff, 0, buff.length))) { bos.write(buff, 0, bytesRead); } } catch(final MalformedURLException e) { System.out.println ( "MalformedURLException." ); throw e; } catch(final IOException e) { System.out.println ( "IOException." ); throw e; } finally { if (bis != null) bis.close(); if (bos != null) bos.close(); } } 结论 正如你所读到的,用 servlet 来打开非 html 文档相当简单。即使是要通过防火墙也是如此。只要设置了正确的 MIME 类型,就可以使用同样的代码来打开图片或其他多媒体文件。当今的互联网上包含了大量信息,其中许多数据被存储为非 HTML 格式。使用 servlet 能够克服 HTML 的限制,简单方便地向用户传送这些非 HTML 格式的信息
下面是DLOG4J生成随即验证码的代码:
package dlog4j;
import java.io.IOException;
import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession;
import dlog4j.util.image.RandomImageGenerator;
/** * 用于产生注册用户时的随即图片以防止非法攻击 * @author Liudong */ public class RandomImageServlet extends HttpServlet {
public final static String RANDOM_LOGIN_KEY = "RANDOM_LOGIN_KEY";
public void init() throws ServletException { System.setProperty("java.awt.headless","true"); } public static String getRandomLoginKey(HttpServletRequest req) { return (String)req.getSession().getAttribute(RANDOM_LOGIN_KEY); } protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { HttpSession ssn = req.getSession(); if(ssn!=null) { String randomString = RandomImageGenerator.random(); ssn.setAttribute(RANDOM_LOGIN_KEY,randomString); res.setContentType("image/jpeg"); RandomImageGenerator.render(randomString,res.getOutputStream()); } } }
这段代码在Linux下工作是没问题的,但是生成图片的时候会抛出类没定义的异常,除非JDK是1.5版本。如果JDK为1.4的话,那只能给应用服务器的启动加上参数-Djava.awt.headless=true,具体每个应用服务器如何加此参数请参照不同服务器的文档。Tomcat可以通过修改startup.sh来添加这个参数。
在网上看过很多对该问题的描述,都没有什么有效的解决办法。
在这将着重介绍一下Windows系统的Svchost.exe和Explorer.exe两种进程,作为Windows系统中两种重要的进程,下面我们就来看看他们的特点以及在各个操作系统中的应用。
Explorer
在Windows系列的操作系统中,运行时都会启动一个名为Explorer.exe的进程。这个进程主要负责显示系统桌面上的图标以及任务栏,它在不同的系统中有不同的妙用。
Explorer在Windows 9x中的应用
在Windows 9x中,这个进程是运行系统时所必需的。如果用“结束任务”的方法来结束Explorer.exe进程,系统就会刷新桌面,并更新注册表。所以,我们也可以利用此方法来快速更新注册表。方法如下:
按下Ctrl+Alt+Del组合键,出现“结束任务”对话框。在该对话框中选择“Explorer”选项,然后单击“结束任务”按钮,将出现“关闭Windows”对话框。单击“否”按钮,系统过一会儿将出现另一个对话框,告诉你该程序没有响应,询问是否结束任务。单击“结束任务”按钮,则更新注册表并返回Windows 9x系统环境中。这比起烦琐的重新启动过程要方便多了?
Explorer在Windows 2000/XP中的应用
在Windows 2000/XP和其他Windows NT内核的系统中,Explorer.exe进程并不是系统运行时所必需的,所以可以用任务管理器来结束它,并不影响系统的正常工作。打开你需要运行的程序,如记事本。然后右击任务栏,选择“任务管理器”,选中“进程”选项卡,在窗口中选择
Explorer.exe进程,单击“结束进程”按钮,,接下来桌面上除了壁纸(活动桌面Active Desktop的壁纸除外),所有图标和任务栏都消失了。此时你仍可以像平常一样操作一切软件。
如果你想运行其他软件,但此时桌面上空无一物,怎么办?别着急,下面有两种可以巧妙地打开其他软件:
第一种方法:按下Ctrl+Alt+Del组合键,出现“Windows安全”对话框,单击“任务管理器”按钮(或是直接按下Ctrl+Shift+Esc组合键),在任务管理器窗口中选中“应用程序”选项卡,单击“新任务”,在弹出的“创建新任务”的对话框中,输入你想要打开的软件的路径和名称即可。
你还可以在正在运行的软件上,选择“文件→打开”,在“打开”对话框中,点击“文件类型”下拉列表,选择“所有文件”,再浏览到你想打开的软件,右击它,在快捷菜单中选择“打开”命令,就可以启动你需要的软件了。注意,此时不能够通过单击“打开”按钮来打开软件,此种方法适用于大多数软件,Office系列除外。
通过结束Explorer.exe进程,还可以减少4520KB左右的系统已使用内存,无疑会加快系统的运行速度,为资源紧张的用户腾出了宝贵的空间。
Svchost.exe
Svchost.exe是NT核心系统的非常重要的进程,对于2000、XP来说,不可或缺。很多病毒、木马也会调用它。所以,深入了解这个程序,是玩电脑的必修课之一。
大家对Windows操作系统一定不陌生,但你是否注意到系统中“Svchost.exe”这个文件呢?细心的朋友会发现Windows中存在多个 “Svchost”进程(通过“ctrl+alt+del”键打开任务管理器,这里的“进程”标签中就可看到了),为什么会这样呢?下面就来揭开它神秘的面纱。
在基于NT内核的Windows操作系统家族中,不同版本的Windows系统,存在不同数量的“Svchost”进程,用户使用“任务管理器”可查看其进程数目。一般来说,Win 2000有两个Svchost进程,Win XP中则有四个或四个以上的Svchost进程(以后看到系统中有多个这种进程,千万别立即判定系统有病毒了哟),而Win 2003 server中则更多。这些Svchost进程提供很多系统服务,如:rpcss服务(remote procedure call)、dmserver服务(logical disk manager)、dhcp服务(dhcp clieNT)等
如果要了解每个Svchost进程到底提供了多少系统服务,可以在Win 2000的命令提示符窗口中输入“tlist -s”命令来查看,该命令是Win 2000 support tools提供的。在Win XP则使用“tasklist /svc”命令。
Svchost中可以包含多个服务
Windows系统进程分为独立进程和共享进程两种,“Svchost.exe”文件存在于“%systemroot% system32”目录下,它属于共享进程。随着Windows系统服务不断增多,为了节省系统资源,微软把很多服务做成共享方式,交由 Svchost.exe进程来启动。
但Svchost进程只作为服务宿主,并不能实现任何服务功能,即它只能提供条件让其他服务在这里被启动,而它自己却不能给用户提供任何服务。那这些服务是如何实现的呢?
原来这些系统服务是以动态链接库(dll)形式实现的,它们把可执行程序指向 Svchost,由Svchost调用相应服务的动态链接库来启动服务。那Svchost又怎么知道某个系统服务该调用哪个动态链接库呢?这是通过系统服务在注册表中设置的参数来实现。
从启动参数中可见服务是靠Svchost来启动的。
因为Svchost进程启动各种服务,所以病毒、木马也想尽办法来利用它,企图利用它的特性来迷惑用户,达到感染、入侵、破坏的目的(如冲击波变种病毒“w32.welchia.worm”)。但Windows系统存在多个Svchost进程是很正常的,在受感染的机器中到底哪个是病毒进程呢?这里仅举一例来说明。
假设Windows XP系统被“w32.welchia.worm”感染了。正常的Svchost文件存在于“c:\Windows\system32”目录下,如果发现该文件出现在其他目录下就要小心了。“w32.welchia.worm”病毒存在于“c:\Windows\system32Win s”目录中,因此使用进程管理器查看Svchost进程的执行文件路径就很容易发现系统是否感染了病毒。
Windows系统自带的任务管理器不能够查看进程的路径,可以使用第三方进程管理软件,如“Windows优化大师”进程管理器,通过这些工具就可很容易地查看到所有的Svchost进程的执行文件路径,一旦发现其执行路径为不平常的位置就应该马上进行检测和处理。
印度软件巨头印孚瑟斯技术公司(Infosys)董事长纳拉亚纳·穆尔蒂日前表示,他认为印度软件业领先中国20年。
印度报业托拉斯援引穆尔蒂的话说,中国的制造业享誉世界,但软件业落后于印度。但他同时强调,印度软件公司不能低估中国同行的发展潜力。
在分析印度软件业迅速发展的原因时,穆尔蒂认为,印度软件人才工作勤奋,软件公司更加了解顾客的需求,同时在运营方面更加优秀。
穆尔蒂指出,印度软件业发展了先进的销售体系、销售流程和销售方法,并且高度重视产品质量。与此同时,他认为印度应该在软件业方面进一步加强其优势。
印度目前已经成为全球软件研发基地之一和IT服务外包主要目的地。据统计,目前印度公司参与的IT服务合同约占全球IT服务合同总金额的7%。这其中,塔塔咨询公司、印孚瑟斯技术有限公司和维普罗公司等大型企业扮演了重要角色。
网站中有哪些关键技巧?有哪些陷阱?在这里,世界上一流的网站设计专家,让你共享他们的秘密,告诉你:使网站赋予情趣的诀窍、应该避免做什么、应使用什么工具软件以及他们喜爱和厌恶的网站。
01明确内容
如果你想成为一个网站设计者,并正想建一个网站的话,首先应该考虑网站的内容,包括网站功能和你的用户需要什么。你的整个设计都应该围绕这些方面来进行。
02抓住用户
如果用户不能够迅速地进入你的网站,或操作不便捷,网站设计就是失败的。不要让用户失望而转向你的对手的网站。Ailiss.com
03优化内容
内容是核心。大约在两年以前,企业网站就像一本广告册子,更槽糕的是,网站使用了大量的图片,似乎要几个世纪才能下载完。Chanels网站(www.channels.co.uk)在设计的某些方面是成功的,但是内容太贪乏,并且要花很长时间才能找到所要的东西,因此不能算是一个成功的网站。
04快速下载
没有什么比要花很长时间下载页面更槽糕的了。作为一条经验,一个标准的网页应不大于60K,通过56K调制解调器加载花30秒的时间。有的设计者说网页加载应在15秒内。
05网站升级
时刻注意网站的运行状况。性能很好的主机随着访问人数的增加,可能会运行缓慢。但是,如果你不想失去访问者的话,一定要仔细计划好你的升级计划。Ailiss.com
06坚持基本原则
即使你不懂HTML语言,你只需购买一个有版权的所见即所得的网页设计工具,如AdobePageMill或MicrosoftFrontPageExpress,就可以创建一个看起来很合理的网站。但是,在设计时,这些软件包虽然不需要HTML,却使网站速度下降。为了成功地设计网站,你必须理解HTML是如何工作的。大多数的网站设计者建议网络新手应从有关HTML的书中去寻找答案,用Notepad制作网页。
07学习HTML
用HTML设计网站,可以控制设计的整个过程。但是,如果你仅仅是网站设计的新手,你应该寻找一个允许修改HTML的软件包。HomeSite4是一个很好的Web设计工具。在设计过程中,HomeSite4能帮助你学习HTML。它还允许你切换到所见即所得的模式,以便你在把网站发送到Web之前,预览你的网站。
08用笔画一个网站的框架
圣人云:笔比剑更强大。在用计算机之前,用笔画一个网站的框架,显示出所有网页的相互关系。计划好你的用户如何以最少的时间浏览你的网站。
09“在计算机上永远也找不到好的方案”。——专家忠告
10网站地图
许多设计者把他们的网站地图放在网站上,这种做法,却是弊大于利。绝大部分的访问者上网是寻找一些特别的信息,他们对于你的网站是如何工作的,并没有兴趣。如果你觉得你的网站需要地图,那很可能是需要改进你的导航和工具条
11“睁大你的眼睛,留意所有的事情。对最不相关的东西的观察可以得到最好的灵感。观察一个站点的结构和设计。理解站点结构的关键元素,确保你的设计是围绕站点浏览进行的。”——专家忠告
12点击规则
听说过3次点击规则吗?对于小型网站,在你的主页上,没有任何一条信息,需要点击次数超过3次的。对于大型网站,使用导航和工具条来改善操作。
13特殊字体的应用
虽然你可以在你的HTML中使用特殊的字体,但是,你不可能预测你的访问者在他们的计算机上将看到什么。在你的计算机里看起来相当好的页面,在另一个不同的平台上看起来可能非常糟糕。一些网站设计员喜欢使用来定义特性,这虽然允许你使用特殊的字体,但是仍需要一些变通的方法,以免你所选择的字体在访问者的计算机上不能显示。级联风格表CSS有助于解决这些问题,但是只有最新版的浏览器才支持CSS。
14“使用切合实际的简便的命名规则。”——专家忠告
15检查错别字
好的拼写是人们一生中重要的技能。但是遗憾的是,许多设计者都缺少这种技能。确保你拼写正确,并且格外注意平常容易误写的错别字。Ailiss.com
16避免长文本页面
在一个站点上有许多只有文本的页面,是令人乏味的,且也浪费Web的潜力。如果你有大量的基于文本的文档,应当以AdobeAcrobat格式的文件形式来放置,以便你的访问者能离线阅读。
17不要使用卷滚条人们厌恶在网上使用卷滚条。Trouble网站(www.Trouble.co.uk)是一个典型的设计很差的网站。它基于一个浮动的架构,为了阅读所有的文本,浏览者不得不使用卷滚条。
18专家最喜爱的Web设计工具
1.AdobePhotoshop
2.MacromediaFlash
3.AdobeIllustrator
4.AdobeImageRead
5.Dreamweaver
6.MacromediaFireworks
7.AllaireHomesites
8.MicrosoftNotepad
9.MacromediaDirector
10.lightwave
11.MacromediaFreehand
12.其它:AdobeAcrobatExchange,AllaireColdFusion,BBEdit,HTMLValidator等。
19网站介绍
你应当有一个很清晰的网站介绍,告诉访问者你的网站能够提供些什么,以便访问者能找到想要的东西。但是,许多设计者都没有这样做。有效的导航条和搜索工具使人们很容易找到有用的信息,这对访问者很重要。告诉访问者你所提供的正是他们想要的信息。
20“网站一旦发布,网站设计的优点和缺陷全都公布于世。没有什么方法使你能够比从自己的错误、倾听其他人的建议和用户反馈意见中学到更多的东西。”——专家忠告
21闪烁让人头痛
通过使用标识可以吸引访问者对你的主页特殊部分的注意,但这也让你的访问者头痛。如果你想使访问者再次光顾你的网站,就少用此方法。
22背景颜色
背景颜色也会产生一些问题,可能会使网页难于阅读。你应当坚持使用白色的背景和黑色的文本,另外还应当坚持使用通用字体。Ailiss.com
23向前和向后按钮
应当避免强迫用户使用向前和向后按钮。你的设计应当使用户能够很快地找到他们所要的东西。绝大多数好的站点在每一页同样的位置上都有相同的导航条,使浏览者能够从每一页上访问网站的任何部分。
24“坚持你的信念。严格遵守各种规则。避免想当然。绝不停止学习。”——专家忠告
25点击记数器
不要轻易考虑在你的网站上放置一个醒目的点击记数器。你设计网站是为了给访问者提供服务,而不是推销你自己认为重要的东西。大多数浏览者认为计数器毫无意义,它们很容易被做假,浏览者也不想看广告。如果你显示你的网站是多么受欢迎,你最好提供一个链接,显示访问日志。
26不要用框架
与记数器一样,框架在网页上越来越流行。在大多数网站上,在屏幕的左边有一个框架。但是设计者立刻就发现,在使用框架时产生了许多的问题。使用框架时如果没有17英寸的显示屏几乎不可能显示整个网站。框架也使得网站内个人主页不能够成为书签。也许更重要的是,搜索引擎常常被框架混淆,从而不能列出你的网站。
27去掉图像
在浏览器中即使去掉了图像功能,也要保证访问者能够在你的网站上获得满意的效果。对于那些使用ISDN连接并且关掉了图像功能的访问者,还能获得好的网页加载性能。可以通过在网页底部提供另外的链接和使用替代文字,而不是图像来满足访问者的需要。
28重复使用图像
一些网站由于使用大量不重复的图像而错过了使用更好的技巧的机会。在创建商标时,在网页上多次使用同样的图像是一个好的方法,并且一旦它们被装入,以后重新载入就会很快。
29避免使用过大的图像
不要使用横跨整个屏幕的图像。避免访问者向右滚动屏幕。占75%的屏幕宽度是一个好的建议。Ailiss.com
30“避免使用炫耀的技巧。”——专家忠告
31选择使用Flash动画
许多使用比较慢的计算机的访问者发现动画图标很容易耗尽系统资源,使网站的操作变得很困难,因此,应该给用户一个跳过使用Flash动画的选择。
32尽量少使用Flash插件
虽然许多Web设计者认为Flash功能很强大,并且Netscape5.0将支持Flash,在使用时不必再下载任何插件。但是,最好还是取消使用Flash做各接口的想法。
33让用户先预览小图像
如果不得不放置大的图像在网站上,就最好使用Thumbnails软件,把图像的缩小版本的预览效果显示出来,这样用户就不必浪费金钱和时间去下载他们根本不想看的大图像。
34动画与内容应有机结合
确保动画和内容有关联。它们应和网页浑然一体,而不是干巴巴的。动画并不只是MacromediaDirector等制作的东西的简单堆积。Ailiss.com
35慎用声音
声音的运用也应得到警惕。内联声音是网页设计者的另一个禁地。因为过多地使用声音会使下载速度很慢,同时并没有带给浏览者多少好处。首次听到鼠标发出声音可能会很有趣,但是多次以后肯定会很烦人。使用声音前,应该仔细考虑声音将会给你带来什么。
36少用Java和AxtiveX
在网页上应尽量少使用Java和AxtiveX。因为并不是每一种浏览器都需要使用它,只有那些Netscape和Explorer的早期版本的使用者才需要它。另外Mac在处理Java时也存在问题,过分地使用Java,会使Mac崩溃。
37设计成功的网站
www.bmw.co.uk——内容和关联性很好 Ailiss.com
www.yugop.com——图形下载很快
www.comicrelief.org.uk——设计简单明了
www.dreamcast-europe.comwww.newsunlimited.co.ukwww.newbeetle.comwww.swoon.comwww.viaduct.co.uk
38慎用插件
在Web设计中,如果依赖于一些特别的插件,会减少网站的吸引力。如果访问者没有所要求的插件,将不得不到其它站点去下载,这样访问者有可能就不会返回了。
39使用著名的插件
如果网站上有声音或视频,要保证使用者通过使用某个知名的插件,能够听到或看到。许多站点使用QuickTime、RealPlay和Shockwave插件。因为,许多访问者并不愿意浪费很多时间和金钱去下载可能仅使用一次的插件。
40使用先进技术
跟上新的技术。Web技术的进步绝不会停止,所以应花一些时间来研究新产品和开发技术。
41自己创建图像和声音
使用你自己创建的或从某个商业网站上下载的图像和声音。在制作商业网站时,应该花足够的资金来创建图形,以增强公司的宣传。Ailiss.com
42“无论是游戏、图像、动画还是电影,想想你喜欢的设计是怎样的,这将激发你的创作灵感,使你创作出新的和更好的网站。”——专家忠告
43平台的兼容性
要为用户着想,必须最少在一台PC和一台Mac机上测试你的网站,看看兼容性如何。
44用软件分析工具找错
使用软件分析工具检查HTML。软件分析工具DoctorHTML能够帮助检查HTML中的任何问题。如果你有许多网页需要检查,可选用软件分析工具。在网址www.weblint.org/validation.html中,你能够找到更多有效的HTML工具。
45避免错误链接
网站中可能与其它一些有用的站点作了链接。但是,如果在你的网页上有链接,一定要经常检查它们,保证链接有效。链接的网站可能很多,但不要链接到与你的内容无关的网站上。
46给观众成熟的东西
如果网站没有完成,就不要发送到Web上。所有好的网站都是在幕后完成之后再发布的。
47在搜索引擎上登记网站
任何一个人发现你的网站的机会都很少,除非你把你的网站在主要的搜索引擎上进行登记。Ailiss.com
48设计一个留言板
浏览者愿意把时间花在好的网站上,所以最好有一个留言本,这能激励访问者再次回到你的网站,还有助于扩充网站内容。
49测试网站
在你的网站正式发布之前,必须进行有用的测试。在设计网站时要使用最新的软件,但是不要忘了人们并不会使用最新的浏览器,所以要照顾到以前的浏览器。在上载网站时还要测试所有的链接和导航工具条。
50“尽你所能反复测试所设计的网站,直到你不能发现新的东西为止。”——专家忠告
51演示即将发布的网站
在网站正式运行之前,让人演示它。演示中人们会告诉你所设计的网站是否容易使用。Ailiss.com
52动画点缀
网页上的动画最多只用一个
53“倾斜的按钮看起来不会太好,最好不要使用。”——专家忠告
54内容组织
在开始创建新的网页前,仔细考虑网站内容的组织。决定好想让访问者浏览的内容,然后设计导航系统。
55“空白万岁”
注意留空白。不要用图像、文本和不必要的动画GIFs来充斥网页,即使有足够的空间,在设计时也应该避免使用。
56“利用空白去吸引注意力。为了吸引眼球,Web设计者使用各种方法,比如:闪烁、旋转等,但是利用空白会吸引更多的注意力。”——专家忠告
57图像压缩
为了保持小的图像,可以使用类似GIF向导的程序,它能自动对图像进行压缩。先声明图像的大小,在图像显示之前最好能详细说明图像大小属性,可以在IMG标签中保存这个属性。这可以使网页显得很流畅,因为浏览器可以在图像被下载之前在屏幕上显示整个网页。
58设计失败的网站
www.boo.com——在它上面找一件T恤衫要花一个小时www.miniheroes.co.uk——不吸引人,主页太雷赘 Ailiss.com
www.saturn.com.——设计太差
www.e13.com.——没有新意
www.song.com.——导航不知所云
59图像大小属性,可以在IMG标签中保存这个属性。这可以使网页显得很流畅,因为浏览器可以在图像被下载之前在屏幕上显示整个网页。Ailiss.com
60用户注册
如果能知道谁浏览了网站以及是怎样浏览网站的,那么就能得到大量有用的信息。但是,要求访问者在浏览网站之前进行注册,这样做是要冒风险的,因为这将赶走一批不愿意注册的人。获得信息的另一种方法是进行有奖竞猜或金钱奖励,让用户能主动填一些信息反馈表。
61使网站具有交互功能
在网站上提供一些回答问题的工具,使得访问者能从网站上获得交互的信息。Ailiss.com
62图片更新
尽可能经常更换网站上的图片,人们更愿意点击的是图片而不是文本。
63在网站上提供游戏
游戏是很好的交互工具,它是使访问者能再次光顾网站的好方法。
64挑选工具软件
仔细选择Web设计工具。保证使用自己最想要的、自我感觉最好的软件。
65使用最新版本的软件
尽量使用Web设计软件的最新版本,还应当能被授权进行免费或便宜的升级。
现在中国所有招聘网站都是以人事经理为中心,因为他们是给钱的一方,较少从求职者角度考虑,如果我们从求职者立场或者中立立场来看中国招聘网站的生意模式及运作流程,将这个求职者并不知晓的事情公布出来,你就会更好清醒认识招聘网站,也更好的实际的利用人才网站求职: 1、 人才网站与企业人事经理的生意模式对求职者影响: 人才网站的行规是企业人事经理支付600元,可以在一个月内发布一定的职位让求职者投递简历,可以搜索查看人才网站简历库的简历,还可以下载一定数量的简历主动与求职者联系。而大企业及知名公司一般都是购买1年的招聘服务。问题就出来了:如果这个职位1到2周企业招到人了,但他购买的是1个月的服务,所以企业的职位还是挂在网上,而且人才网站竞争激烈,一般都会赠送1个月服务。所以一般职位至少1个月挂在人才网站是无效的,是浪费求职者查看与投递简历时间的。 大公司最不可靠,他们用网络、报纸、现场,1年的大大banner永远挂在人才网站上,他们并不需要人,只是为了广告宣传。 所以人才网站50%以上的职位都是过期的、无效的、不招人或招满人的,所有求职者抱怨我投了那么多简历为什么反馈率那么低,反馈率低是非常正常的。 另外51job网站的反馈率是最低的,这也是行业秘密:因为51Job的资源80%是以报纸招聘为主,报纸招聘效率高,但网站上的职位都是在报纸上刊登过后作为免费与补充服务,所以很多HR只会看报纸上来的简历,网站来的简历基本不看,在加上51job简历投递量实在太大,那些懒惰的HR才懒得一封一封的看,只会用搜索关键字来看,如本科+3年工作经验+主管等,其他不符合条件的看都不看一眼。所以你知道为什么一直没有公司找你面试,不是你不行,而是HR都不看你发的简历。下面第二部分告诉你如何被他们搜索到。 现在你知道网络招聘的反馈率为什么那么低了吧。不信你用自动回复邮件形式发送中国3大招聘网站职位HR的邮箱,看看有多少HR看了你的简历,一个工作论坛的网友说,他试着发了100个HR邮箱简历,可以通过自动回复的反馈率统计,可以看到50%HR不看简历就直接删除,30%根本就不打开邮件,只有20%打开邮箱,还有10%可能已经找到人的。他的分析说即使是中国前3名招聘网站以严格标准来看也只有10%职位是真正要急迫招人的。 二、既然知道一些潜规则,那我们也迎合一些这些规则,告诉你一些网络求职的小秘密 (1)采用行业招聘网站求职。因为行业招聘网站是按行业发布职位信息的,所以专业和工作经历比较对口。比如你要找物业管理类的工作,你到万行工作网 www.114job.com.cn的物业管理招聘频道上去注册简历就比较好,因为那里全部都是物业管理类的企业在招聘;如果你要找外贸的工作,你就可以万行工作网的外贸招聘频道去找,肯定有大量的外贸工作机会。其它的就不在列举。在目前的情况下,几乎每个行业的人才在万行工作网上都能找到自己的频道。 (2)简历要与大公司沾边 当人事经理搜索招聘网站简历库简历时,一般会以关键字“知名企业名称+职位名称”,比如消费品行业可能喜欢可口可乐及宝洁的人,人事经理会这样搜索,例如:“可口可乐+销售经理”,系统会搜索到简历中出现以上关键字的求职者,如果你的简历里出现知名企业名称的字样,就可以被搜索到,例如:“我在xx矿泉水公司工作,成功地令竞争对手——可口可乐旗下的天与地矿泉水在当地的市场份额减少……”:“我在可口可乐的广州白云区经销商工作”等。又提高了人事经理浏览简历的机会! (3) 经常刷新简历 当人事经理搜索简历库的简历时,符合条件的简历是按刷新的时间顺序排列,而一般只会看前面一两页。很多求职者其实并不知道刷新简历可以获得更多求职机会。因此每次登陆,最好都刷新简历,刷新以后,就能排在前面,更容易被人事经理找到! (4) 不要只应聘最近三天的职位 一般求职者认为刚刚发布的最新的招聘信息肯定是成功率最大的,其实不然。因为很多企业人事经理没有及时的登陆刷新刊登的职位,所以求职者在搜索职位时刚刷新的职位会排在前面,这些职位应聘的人多,竞争大,相反,一些职位已经是半个月甚至两个月的,应聘的人少,成功率反而高。 (5) 让你的邮件永远在最前面 你要知道每天人事经理看求职者邮箱,他们其实是很懒的,100多页简历邮件他们最多只看前5页!你现在应该知道为什么你的求职简历永远没有回应! 所以发邮件到企业指定的邮箱时,怎样才能让你的邮件永远排在最前面,让人事经理每次打开邮箱都首先看到你的邮件?只要在发邮件前,把电脑系统的日期改为一个将来的日期,如2008年,因为大多邮箱都是默认把邮件按日期排序,所以你的邮件起码要到2008年以后才会被排在后面! (如果你求职成功,要向我请客耶!) (6) 新颖的邮件标题 人事经理每天收到大量的求职电子邮件,求职者一般会按企业要求把邮件题目写成:应聘xx职位,怎样才能吸引人事经理的眼球,让他先打开自己的邮件?可以在邮件题目上做文章。一天人事经理收到几百封邮件,只有标题新颖的才有机会被打开。 例子:我的一个女性朋友发了100多封邮件求职都没有任何反应,因为应聘做文员的太多了,而我这个朋友做过空姐,我将她的邮件标题改为“空姐来广州找工作”,引起绝大部分男人事经理想入非非,结果三天之内有30多个男人事经理通知面试,3个月找不到工作的她而变成3天找到上十份工作。你现在知道邮件标题的重要性了吧。 (7) 简历最好放靓照 对于人事经理来说,每天需要浏览大量简历,如果同等的条件,一般会先通知有照片的求职者来面试,因为通过照片,人事经理对应聘者又多了几分了解。如果是美女,被通知的可能性就更大。我作为人事经理,曾经招聘一个人事主管,收到300多封简历,我找出前30份有相片的前5份,通知了最漂亮相片的2个女孩,就定下了其中的一个。对于一般职位如文职人员之类,中国人的传统还是以貌取人,你即使不漂亮,也照一个艺术照,就增多了面试机会(与其等死,还不如放手一搏),毕竟很现实的是,简历的目的就是有面试的机会,其他就要靠实力与运气了。 (8)求职信“骂”对方公司往往会带来意想不到的效果 一般人认为在求职信中称赞对方公司会引起好感,其实不然。如果先指出这家公司的缺点,往往会引起关注,语不惊人死不休呢,我作为人事经理,我只会对指出我们缺点的求职者有好感,对恭维我们公司的求职者一般会放在一边。即使你不知道对方公司缺点,你随便写一些永远不会错的:“我认为贵司创新不够,市场表现过于常规化;我以消费者心态观察贵司,发现贵司客户服务还有许多待改进的地方;我发现贵司品牌形象还有可能做的更好……”如闻其详,可面谈。可勾引相关公司面试。只要有面试机会,其他再说。(简历有机会面试目的是一切,手段是无所谓的)。 (9)自己要学会让简历与职位匹配 2个观念都是有效的:一是不要太在乎对方职位要求的描述,很多职位描述只是写写,连经理都不知道要招什么样的人,如果你看到对方职位要求本科,你是专科就不敢投递简历,那就失去机会了。如果你看到对方要求有5年经验,你只有3年经验,你也不敢投,那完全没有必要。因为人事经理们对职位的描述只是例行公事随便谢谢而已,你千万不要当真! 另外一个匹配观念就是他的职位如何描述,你就改变你的简历换一个说法匹配,如他说要求领导能力强,你的简历也说具有领导才能,他要沟通能力一流,你的简历也说我最擅长沟通。你的简历表面匹配度最高,也可以多增加机会。你可将简历改成为他职位描述完全量身定做的简历。 其实求职者有更多的面试机会,不但可以增加成功求职机会,还可以增加自己的信心,工资越叫越高还可以积累面试经验。很多优秀的求职者网上发了很多简历没有回应,以为自己不行没有竞争力,只好自动降价,实为可惜! 特别是中国最大的招聘网站51job的简历投递反馈率是同行业最低的,因为它主要资源80%投入报纸,报纸招聘完甚至录取完毕后将职位入库,只是将职位作为一个摆设放到网站。 要知道现在网络求职的成功率一般2个月是发1000份简历,有8份面试,2份成功,一个是你不想去的,可能一个是你相对满意的。所以网络求职的朋友千万不要对自己失去信心。
Q: Can you sell yourself in two minutes? Go for it. (你能在两分钟內自我推荐吗?大胆试试吧!) A: With my qualifications and experience, I feel I am hardworking,responsible and diligent in any project I undertake. Your organization could benefit from my analytical and interpersonal skills.(依我的资格和经验,我觉得我对所从事的每一个项目都很努力、负责、勤勉。我的分析能力和与人相处的技巧,对贵单位必有价值。)
Q:Give me a summary of your current job description. (对你目前的工作,能否做个概括的说明。) A:I have been working as a computer programmer for five years. To be specific, I do system analysis, trouble shooting and provide software support. (我干了五年的电脑程序员。具体地说,我做系统分析,解决问题以及软件供应方面的支持。)
Q:Why did you leave your last job?(你为什么离职呢?) A: Well, I am hoping to get an offer of a better position. If opportunity knocks, I will take it.(我希望能获得一份更好的工作,如果机会来临,我会抓 住。) A:I feel I have reached the "glass ceiling" in my current job. / I feel there is no opportunity for advancement. (我觉得目前的工作,已经达到顶峰,即沒有升迁机会。)
Q:How do you rate yourself as a professional?(你如何评估自己是位专业人员呢?) A: With my strong academic background, I am capable and competent. (凭借我良好的学术背景,我可以胜任自己的工作,而且我认为自己很有竞争力。) A:With my teaching experience, I am confident that I can relate to students very well. (依我的教学经验,我相信能与学生相处的很好。)
Q: What contribution did you make to your current (previous) organization?(你对目前/从前的工作单位有何贡献?) A: I have finished three new projects, and I am sure I can apply my experience to this position. (我已经完成三个新项目,我相信我能将我的经验用在这份工作上。)
Q:What do you think you are worth to us?(你怎么认为你对我们有价值呢?) A:I feel I can make some positive contributions to your company in the future. (我觉得我对贵公司能做些积极性的贡献。)
Q:What make you think you would be a success in this position? (你如何知道你能胜任这份工作?) A:My graduate school training combined with my internship should qualify me for this particular job. I am sure I will be successful. (我在研究所的训练,加上实习工作,使我适合这份工作。我相信我能成功。)
Q:Are you a multi-tasked individual?(你是一位可以同时承担数项工作的人吗?)or Do you work well under stress or pressure?(你能承受工作上的压力吗?) A:Yes, I think so. A:The trait is needed in my current(or previous) position and I know I can handle it well. (这种特点就是我目前(先前)工作所需要的,我知道我能应付自如。)
Q:What is your strongest trait(s)?(你个性上最大的特点是什么?) A:Helpfulness and caring.(乐于助人和关心他人。) A:Adaptability and sense of humor.(适应能力和幽默感。) A:Cheerfulness and friendliness.(乐观和友爱。)
Q: How would your friends or colleagues describe you?(你的朋友或同事怎样形容你?) A: (pause a few seconds) (稍等几秒钟再答,表示慎重考虑。) They say Mr. Chen is an honest, hardworking and responsible man who deeply cares for his family and friends. (他们说陈先生是位诚实、工作努力,负责任的人,他对家庭和朋友都很关心。) A:They say Mr. Chen is a friendly, sensitive, caring and determined person.(他们说陈先生是位很友好、敏感、关心他人和有决心的人。)
Q:What personality traits do you admire?(你欣赏哪种性格的人?) A: (I admire a person who is)honest, flexible and easy-going. (诚实、不死板而且容易相处的人。) A: (I like) people who possess the "can do" spirit. (有"实际行动"的人。)
Q:What leadership qualities did you develop as an administrative personnel?(作为行政人员,你有什么样的领导才能?) A:I feel that learning how to motivate people and to work together as a team will be the major goal of my leadership. (我觉得学习如何把人们的积极性调动起来,以及如何配合协同的团队精神,是我行政工作的主要目标。) A:I have refined my management style by using an open-door policy. (我以开放式的政策,改进我的行政管理方式。)
Q:How do you normally handle criticism?(你通常如何处理別人的批评?) A:Silence is golden. Just don’t say anything; otherwise the situation could become worse. I do, however, accept constructive criticism. (沈默是金。不必说什么,否则情况更糟,不过我会接受建设性的批评。) A:When we cool off, we will discuss it later. (我会等大家冷靜下来再讨论 。)
Q: What do you find frustrating in a work situation?(在工作中,什么事令你不高兴?) A: Sometimes, the narrow-minded people make me frustrated. (胸襟狭窄的人,有时使我泄气。) A:Minds that are not receptive to new ideas. (不能接受新思想的那些取。)
Q:How do you handle your conflict with your colleagues in your work? (你如何处理与同事在工作中的意见不和?) A:I will try to present my ideas in a more clear and civilized manner in order to get my points across. (我要以更清楚文明的方式,提出我的看法,使对方了解我的观点。)
Q:How do you handle your failure?(你怎样对待自己的失敗?) A: None of us was born "perfect". I am sure I will be given a second chance to correct my mistake. (我们大家生来都不是十全十美的,我相信我有第二个机会改正我的错误。)
Q:What provide you with a sense of accomplishment. (什么会让你有成就感?) A:Doing my best job for your company. (为贵公司竭力效劳。) A:Finishing a project to the best of my ability. (尽我所能,完成一个项目。)
Q:If you had a lot of money to donate, where would you donate it to?Why?(假如你有很多钱可以捐赠,你会捐给什么单位?为什么?) A:I would donate it to the medical research because I want to do something to help others. (我会捐给医药研究,因为我要为他人做点事。) A:I prefer to donate it to educational institutions. (我乐意捐给教育机构。)
Q:What is most important in your life right now?(眼下你生活中最重要的是什么?) A:To get a job in my field is most important to me. (对我来说,能在这个领域找到工作是最重要的。) A:To secure employment hopefully with your company. (希望能在贵公司任职对我说最重要。)
Q:What current issues concern you the most?(目前什么事是你最关心的?) A:The general state of our economy and the impact of China’ entry to WTO onour industry. (目前中国经济的总体情況以及中国入世对我们行业的影响。)
Q: How long would you like to stay with this company?(你会在本公司服务多久呢?) A: I will stay as long as I can continue to learn and to grow in my field.(只要我能在我的行业力继续学习和长进,我就会留在这里。)
Q:Could you project what you would like to be doing five years from now?(你能预料五年后你会做什么吗?) A:As I have some administrative experience in my last job, I may use my organizational and planning skills in the future. (我在上一个工作中积累了一些行政经验,我将来也许要运用我组织和计划上的经验 和技巧。) A:I hope to demonstrate my ability and talents in my field adequately.(我希望能充分展示我在这个行业的能力和智慧。) A:Perhaps, an opportunity at a management position would be exciting.(也许有机会,我将会从事管理工作。) 如果不愿正面回答,也可以说:It would be premature for me to predict this. (现在对此问题的预测,尚嫌过早。) 甚至还可以打趣的说:Hypothetically speaking, I might be able to do your current job as adirector.(或 CEO 或 president)((说不定,我也能做你现在主任的工作呢!)
Q: What range of pay-scale are you interested in?(你喜欢那一种薪水层次标准?) A: Money is important, but the responsibility that goes along with this job is what interests me the most. (薪水固然重要,但这工作伴随而来的责任更吸引我。) A: 假如你有家眷,可以说: To be frank and open with you, I like this job, but I have a family to support. (坦白地说,我喜欢这份工作,不过我必须要负担我的家庭。)
Other Tips (其它建议) Know something about the organization you are applying to. (了解一些你申请工作单位的情况) Dress properly. Don’t shake hand with the interviewer until he/she extendshis/her hand. (穿着要得体,人家伸手时才握手。) Don’t sit down until invited to do so by the interviewer. (人家未请,先別坐下。) Make eye-contact with the interviewer during the interview. (面试时,眼睛要看着对方。)Listen actively and stay calm. (注意听,保持冷静。) If invited to a meal, be especially careful about your table manners. (被邀吃饭时,要特別注意餐桌礼节。) Don’t talk with your mouth full. (嘴里有食物,不可开口说话) Don’t make much noise while you eat. (吃东西不要出声音) Don’t blow your nose or use the toothpick at table. (不要拧鼻涕或用牙签剔牙) Don’t appear to be pushy or overly anxious to get a job.(不必过分表现急着要工作) Be honest but not too modest.(要诚实,但不必太谦虚) Don’t put yourself down or cut yourself up. (不可妄自菲薄或自贬) Try to avoid discussing politics or religion with your interviewer. (避免 与面试人谈政治或宗教)
献个自己的清明节哀悼书 文/微尘
不管你从事什么行业的工作,千万别从事计算机软件行业的开发工作。我发誓,今生我入错行,来世我做猪做狗,不做程序员!
软件开发行业的的特点决定的开发人员痛苦的一生,有如下原因:
1、我即将设计的东西用户无法看到或者想象到 比如建筑行业吧,你要盖房子,没问题开放单位会请人设计效果图,或者画出标准图纸,包括用的钢筋、水泥、瓷砖等等所有材料都可以标上要求。 再说抽象点的广告设计,广告设计基本上可以做出过样板或者效果图,即使错了修正起来也是容易。最主要是美术东西是可以描述的。
不管从事哪个行业,你能做的东西别人大概都有个粗略的概念,但软件就没有,你做出来的东西可*作性如何,你做出来的东西美感效果如何,这都关系到双方的责任界定问题。
2、我即将设计的东西是否是客户所描述的东西 软件东西涉及到从外观表现到内在的逻辑,外观表现还好,客户说不好看,我就改一改,可要命的是有些开发工具无法实现,那就只能跳楼,比如说人家说要IE那种性感美,可你设计出来的传统美,更糟糕的是你的开发平台无法实现那种骨美,这个时候你就抱着你的软件哭吧。
逻辑的东西更不提,很多时候客户要什么都描述不清楚,或者就是描述错误。好了你的需求分析做出来,他们也签字了。可最后东西出来,经过运行测试,人家说你理解错啦!怎么办,跟他争吗?有意义吗?欲哭无泪,欲死不能!到了这个程度只能自己骂自己笨,不清楚中国话是可以进行多种理解的吗?也只能怪自己没有具备神通看出客户的内心。
以上所说的,还是正常错误,不是故意整你,如果你碰到故意整你的客户,那么不上吊都要自杀的了。
3、特别是制度化的软件犹如地狱 如果是开发什么杀毒软件啊,应用、工具软件等好办。无法就是象WINDOWS那么傻瓜式,后面的版本升级也不用花太多的精力,请几个美工或者找个论坛征求下意见,就可以:我变我变,七十二变不够可以八十一变。 可如果你是帮客户进行制度化软件的实施,特别是用产品包软件去帮客户进行制度化实施。不掉层皮也要抽点筋还不知道能否顺利结束。一般销售人员可以天花乱坠地吹或者跟客户做演示,这也是每办法的办法,谁让他们是业务员,业务人员的目标就是业绩、提成,业绩提成。而开发人员往往也是最讨厌业务人员了。因为牛是你吹的,可责任是我付的!这就好比中国教育部有句话:书记领导下校长负责制。书记可以领导,错了,该杯黑锅的时候由校长抗着!这是怎么样的天理啊!话说多了,业务人员错了有钱拿,错得越多签单越快,开发人员就死得越早。
制度化的东西是最不好弄,没有理由,没有建设性,人家就是如此的制度,你不能提建议要求该制度,完全一种强奸的感觉。就是你当孙子去!为了那几文钱!
4、人家是越老越值钱,我们是越老越贬值 除了卖色、唱、身等行业有这个特点外,看来也就开发行业有这个特点。
你年轻,你有本钱,没问题,三天不睡觉,白天睡觉晚上干活,你牛!到了你30岁,你就知道死字是如何写的了。
还有就是不知道是哪些傻瓜,天天弄出什么新技术,关键技术,你跟不跟?不跟,那么不如提前退休回家种番薯还好了。跟吧,你能跟多久,到你结婚的时候看着老婆在睡觉你却在愁眉苦脸啃那烂书;等你孩子出生了,你孩子要换尿片的时候,你能说等等我在看书呢?
5、人家要钱有钱,要面子有面子,我却灰头灰脸 各个行业都有爆发户,惟独开发人员无法爆发!为什么呢,你就靠那么点小工资能做什么?人家企业部门经理月薪都是几十K算,我们的计量单位还是元,更别说那些总经理了,看着他们的收入,我数都不会数,一个字,晕;二个字,真晕。
当你的孩子在同学中说,我爸爸是程序员,意味着怎么呢?A、那么老了还做程序员啊 B、就是编编程序的 C、顶多是个工匠(就是修理修理的那种) 。
综合上所述: A、我下定决心,排除万难,不管做什么,不做程序员! B、我请求上天,如果要让我当程序员,那么就让我去做畜生好了! C、为了我的孩子,我要发奋图强,我要翻身!
|
|
|
| 日 | 一 | 二 | 三 | 四 | 五 | 六 |
---|
29 | 30 | 31 | 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 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
|
公告
导航
统计
- 随笔: 63
- 文章: 0
- 评论: 27
- 引用: 0
常用链接
留言簿(2)
随笔分类
随笔档案
搜索
最新评论
阅读排行榜
评论排行榜
|
|