This page looks plain and unstyled because you're using a non-standard compliant browser. To see it in its best form, please upgrade to a browser that supports web standards. It's free and painless.

毛泽西

首页 | 资源中心 | 管理控制台

出口香烟

silver6 | 20 六月, 2009 08:24


FC 4下安装ORACLE 9i 的全过程

silver6 | 31 十二月, 2007 01:17

FC 4下安装ORACLE 9i 的全过程

以前在Windows XP下安装过Oracle9i,但是装完了发现它自带的Apache Server跟我原来安装的Apache出现了冲突,使我感到很不爽,于是就把它给卸了。最近又要使用Oracle了,所以又得重新安装,于是决定在 Linux底下文字安装Oracle9i。在安装过程中还使出现了很多的问题,浪费了两天的时间。终于,经过查阅了一些资料,在网友们的帮助下终于安装成功了。为了防止遗忘,马上把安装过程写下来,给大家分享,希望能为以后需要安装的朋友节省点时间。 "X$a~SS~{]
安装环境: , s6? g i
Fedora core 4 FwDQ.&
Oracle9i release 2 &nAFR6;@
;MguBZcR
安装前的准备: $|)Rr;6[:
安装前需要下载如下软件: "dN*%"
ship_9204_linux_disk1.cpio.gz ba;c8h+N?
ship_9204_linux_disk2.cpio.gz ^y_9&XS]e*
ship_9204_linux_disk3.cpio.gz #tk"P+J4
下载地址: +FMm,3v
http://www.oracle.com/technology/software/products/oracle9i/index.html [UoP~=
}fsN=rl^a
p3006854_9204_LINUX.zip(Red Enterprise Linux3的补丁,不过也可以用于 Fedora) X*O3MU
下载地址: zEH`h5nv
http://www.idevelopment.info/data/Oracle/DBA_tips/Linux/FedoraCore2_RPMS r|r(BdL0
/p3006854_9204_LINUX.zip C^,@MK
-Lr*yTH;
开始安装 #D@%5YQj
a. 新建目录 $mkdir /mnt/oracle XhDo/O
b. 将安装文件拷贝到新建的目录下 `k/0fu;m.
/W0p%
c. 解压文件: $gunzip ship_9204_linux_disk1.cpio.gz W4RWt-i
}wvLcv
释放文件:cpio -idmv < ship_9204_linux_disk1.cpio !9y*G`V`
:X;,W d'
可以看到在生成了目录 /mnt/oracle/Disk1 ++oxAM
q` yoj!w
接着上面的步骤生成了Disk2 和 Disk3。 "n?dd`|0{
K o%DZA
解压补丁文件 $ unzip p3006854_9204_LINUX.zip <{: Zix
:;emR0tl
生成了目录 /mnt/oracle/3006854 [B:-$=
`dw>ex
d. 创建安装Oracle所需要的用户以及组 Krf #oC
X0`/q
1)以root用户登录或者是:su - root hTY{|B'I^
2) Oracle不能已root安装,所以要建立一个oracle用户,建立oracle 用户和密码: c+ C*2|}3N
# groupadd oinstall (在安装oracle时会提示输入UNIX Group name:oinstall) b@_Asrb
# groupadd dba "K]!=K'
# useradd -g oinstall -G dba oracle PxLJ-B?Z]
# passwd oracle (注意:此不能忘记,如果没有建立密码,可能下次无法用oracle登陆) >[&G)X0
# groupadd apache OBoC`',^
# useradd –gapache –G oinstall apache z-=cCJ:%
# passwd apache IQNrd^`
Rb% ;W
3)b) 准备文件目录: TX!P'd8B)
# mkdir -p /opt/ora9/product/9.2 zsD |?E
# mkdir /var/opt/oracle Jr0iJ,S
# chown oracle.dba /var/opt/oracle AomXxok<
# chown -R oracle.dba /opt/ora9 "ir{2.K?
C3!*'
4)设置内核参数,调节信号灯及共享内存 2,S{y5 KX
修改 /etc/sysctl.conf 这个文件,加入以下的语句: J!qD'd
kernel.shmmax = 2147483648 (机器内存2G,如果你的没这么大可相应设置小些,我的是512M的,所以改成相应的内存就可以了) w~+eo5/
kernel.shmmni = 4096 Q, ^r
kernel.shmall = 2097152 {C-c^cfK/x
kernel.sem = 250 32000 100 128 _zFY_]Y"
fs.file-max = 65536 t>2t z-!
net.ipv4.ip_local_port_range = 1024 65000 Y<D ,
#!2#]-
5)执行sysctl以反映修改 6:.4e7iV
# sysctl –p pbAc2K "J
FyEq6) 
6)设置oracle对文件的要求 &W]U]Sl[pC
编辑文件:/etc/security/limits.conf 加入以下语句: 4I"~l^P
oracle    soft nofile    65536 /]+mO/]>
oracle    hard    nofile 65536 bb3IAy's
oracle    soft nproc    16384 #NP*kZtV
oracle    hard    nproc    16384 pQ6JN?
5Wn4O6k
7)以root身份设置系统环境 oaK1TnzW7
%y2EJ~hn|
#export ORACLE_BASE=/opt/ora9 )j63vjH7
#export ORACLE_HOME=/opt/ora9/product/9.2 WlN#!7 
%sQ~xu ?u
Hqu8pqE
8)确定使用正确的编译器 (这一步我用过了,反而出现了问题,导致gcc找不到,所以建议不要使用;如果后面运行sh脚本时出问题了再回来做此步) >)Hrl%:
#mv /usr/bin/gcc /usr/bin/gcc323 --如果没有gcc这个文件,请不要执行此命令 gRfx5D"
#mv /usr/bin/g++296 /usr/bin/g++ --如果没有gcc这个文件,请不要执行此命令 g&90gzH
#ln –s /usr/bin/gcc296 /usr/bin/gcc P(r"Gvl5
#ln –s /usr/bin/g++296 /usr/bin/g++ `=~|5<K}
3aPxpjD
9)打开一个新的终端,以Oracle用户登陆,然后修改./bash_profile文件 `(*DiLNFZ
L]Im!.6
$ vi /home/oracle/.bash_profile nP#&pky
ut #wa,
添加以下的内容: y'w0,bUtw
)YFfwt
export DISPLAY=”127.0.0.1:0.0” (我这里虽然设了,但是安装开始时还是显示无法连接X Server,查资料后知道可能是JDK版本的问题, Eb{0Mh{
这里可以不加此行,下面自有解决方案) G>^#xYaF>
export ORACLE_BASE=/opt/ora9 _7dGQ!5LU
export ORACLE_HOME=/opt/ora9/product/9.2 _`oCgIxW
export PATH=$ORACLE_HOME/bin:$ORACLE_HOME/Apache/Apache/bin:$PATH HWy<~Xh=u
export ORACLE_OWNER=oracle Xs/<(
export ORACLE_SID=ora9i (数据库全局变量名) l 3 N]w x
export ORACLE_TERM=xterm (xterm窗口模式 vt100 终端调试模式) ?n M
export LD_ASSUME_KERNEL=2.4.1 (这一步非常重要,不能用实际的内核为2.4.22) export THREADS_FLAG=native ?0@I#36t
export LD_LIBRARY_PATH=/opt/ora9/product/9.2/lib:$LD_LIBRARY_PATH gn3t}^.Bm
export PATH=/opt/ora9/product/9.2/bin:$PATH vBX S p8
export NLS_LANG=AMERICAN (设置语言AMERICAN英文) #V4vS
export ORA_NLS33=$ORACLE_HOME/ocommon/nls/admin/data {hN[F6-
保存后退出. 执行: source .bash_profile 查看 set | more xjJ9R
然后。退出登录,再次进入,这时候oracle的环境就已经生效了.注:一定要推出后重登陆,否则不会生效! Lb{gf JV
T!Y+b~WCLx
注意,如果内核参数设置过高,即设置为实际内核 export LD_ASSUME_KERNEL=2.4.22就会出现以下错误:/ i(nEXBMNu1
./-<>
opt/oracle/jre/1.1.8/bin/../lib/i686/green_threads/libzip.so: symbol errno, version GLIBC_2.0 not defined in file libc.so.6 with link time reference (libzip.so) Unable to initialize threads: cannot find class java/lang/Thread         Could not create Java VM ]Hq$ aAX{U
xb t|?6$u
造成不能安装 OEM,net configure 等组件 G }750
tzj0 kG%;
10)安装补丁 *,P9/4'
ifRb/! E=>
$ cd /home/ora9i /3006854 9Ve<zWYA
RjE;.1;i'
$ chmod +x rhe13_pre_install.sh c5::8ggs
$ sh rhe13_pre_install.sh yo1Antr1
Applying patch... L0v" 2x%O
Patch successfully applied T}w'S
0]*!4J}Ljv
这里很重要,一定要成功,否则就无法安装,会出现下面的错误。如果执行时报错:gcc找不到,则进行上面设置编译器的步骤。我设了反而出错了! :( dn)vSVk%qY
注意:如果没有安装补丁,安装时会出现如下的错误信息: A9AUr|p9
)',gOs< WW
Initializing Java Virtual Machine from /tmp/OraInstall2005-01-18_06-01-55PM/jre/bin/java. Please wait... Z az}?*>s
Error occurred during initialization of VM ,|h(7N,
Unable to load native library: /tmp/OraInstall2005-01-18_06-01-55PM/jre/lib/i386/libjava.so: symbol __libc_wait, version GLIBC_2.0 not defined in file libc.so.6 with link time reference yQe:k"8<
B]E~u4P
11) 以oracle用户安装Oracle L1Tm4A;
rV=$R K
$ cd /mnt/oracle/Disk1 BoNQcX
BE]>f
$./runInstaller ~_%aL
Initializing Java Virtual Machine from /tmp/OraInstall2005-11-09_07-21-54PM/jre/bin/java. Please wait... 9stR6zk8
如果以上步骤设置了DISPLAY的环境变量,而且安装界面也已出现,那么祝贺你,你安装Oracle9i已基本不会有问题了。但是我设置了以后就出现了如下的错误,导致无法继续安装: " )>CnX
Exception in thread "main" java.lang.InternalError: Can''t connect to X11 window server using ''127.0.0.1:0.0'' as the value of the DISPLAY variable. +j~vk,
at sun.awt.X11GraphicsEnvironment.initDisplay(Native Method) nVt)+y5
at sun.awt.X11GraphicsEnvironment.(X11GraphicsEnvironment.java:59) Hmj'FbL3
at java.lang.Class.forName0(Native Method) >!}6-w
at java.lang.Class.forName(Class.java:120) &GWHA ?w
at java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment(GraphicsEnvironment.java:58) f9T4p;
at java.awt.Window.(Window.java:188) Ii:}ZOKD
at java.awt.Frame.(Frame.java:315) 6aDuUe
at java.awt.Frame.(Frame.java:262) 4##w'+u
at oracle.sysman.oii.oiic.OiicInstaller.main(OiicInstaller.java:593) OW6wLEt#
f1VeSdu
我在网上查了一下,原因可能是由于JDK的版本过老,在使用AWT时的一个属性出了问题。可以使用如下方法解决: 24_$gG
如果你设置了环境变量DISPLAY,请先到/home/oracle/.bash_profile中把DISPLAY删掉,然后打开一个新的终端(注:必须是图形界面下的Koncole,如果在文字界面下将不成功),以root登陆,输入如下命令: 7 =@_j" 
#xhost + R^QKEyCn
如果成功,会输出其他用户可以连接此窗口的结果。 [<TH>y.='
然后在另外一个终端中以oracle登陆,执行命令: "8/sY<&5
$./runInstaller t89@|o"i
网上几乎所有的文章都是使用设置环境变量DISPLAY的方法来安装了,但是这里就是不行,这也是困扰我很久的主要问题! 好了,你现在应该能看到安装的界面了吧! ?AsaKF(Wk
可是界面上怎么都是“方框”的乱码呢?呵呵,那是因为语言、字体设置的问题,退出安装,先设置一下环境变量: oo'<W)
$ export LC_ALL=C -i|m(0g
$ ./runInstaller Xh5n-ig
这下好了吧,现在可以方便的进行安装了,应该不会再出现什么问题了! w}j|1 jGo
在安装过程中需要以root来执行两次sh脚本,根据它的提示做就可以了。 S Q]'QdYC
[OWD,*mk
12) 终于安装成功了,现在可以建立你的数据库了

安装Linux 的硬盘分区

silver6 | 31 十二月, 2007 01:14

安装Linux 的硬盘分区

为了安装L i n u x ,你必须为它准备硬盘空间。这个硬盘空间必须和你的计算机上安装的其他操作系统(如Wi n d o w s ,O S / 2 或着其他版本的L i n u x )所使用的硬盘空间分开。这项工作就是我们马上要进行的硬盘分区。
  1. Linux 硬盘分区的基础知识

  一个硬盘可以分割成不同的分区。访问每个分区就像访问不同的硬盘。每个分区甚至可
以有一个类型用来表明这个分区中信息是如何存储的。例如,D O S 、O S / 2 和L i n u x 使用不同的硬盘分区类型。你可以这样处理你的L i n u x 分区:

  1) 可以将L i n u x 安装在一个或多个类型“ Linux Native "的硬盘分区,通常称为"L i n u x原始分区"。同时还需要一个类型为"Linux Swap "的分区,也叫做"L i n u x 交换分区"。

  2) Linux 对分区的最小要求是:一个"Linux Native "加一个"Linux Swap "分区。要特别注意的是,L i n u x 一定不可以安装在D O S / Wi n d o w s 的分区内!

  3) 即使你将L i n u x 安装在一个专门的硬盘,或者一不安装其他操作系统的计算机上,你仍需要为L i n u x 创建分区。相对而言,这种情况非常简单,因为不必为硬盘的其他分区操心。

  对于网站建设者而言,我们推荐采用这种方法,你甚至可以不要D O S / Wi n d o w s ,因为在你的网站对外发布(供外界访问)的时候,你只能使用L i n u x 系统,而且,一般网站总是处于"发布"的状态,你将几乎没有机会运行你的D O S / Wi n d o w s 。

  4) 对于一般用户,另一种更普遍的情况是:将L i n u x 安装在已经含有其他操作系统的硬盘上。这种情况就有一点复杂,因为一个错误就可以毁了你现有的分区,更不用说它含有的数据!

  L i n u x 通过字母和数字的组合来标识硬盘分区,如果你习惯于使用类似"C 盘/ D 盘"来标识硬盘分区的话,可能会搞混。L i n u x 的命名设计比其他操作系统更灵活,能表达更多的信息。

  归纳如下:

  1) 分区名的前两个字母表明分区所在设备的类型。你将通常看到h d (指I D E 硬盘),或s d(指S C S I 硬盘)。

  2) 第三个字母表明分区所在的设备号。例如:/ d e v / h a d (第一个I D E 硬盘)或/ d e v / s d b(第二个S C S I 硬盘)。

  3) 最后的数字代表分区。前四个分区(主分区或扩展分区)用数字1 到4 表示。逻辑分区
从5 开始。例如,/ d e v / h d a 3 第一个I D E 硬盘上的第三个主分区或扩展分区; / d e v / s d b 6 是第二个S C S I 硬盘上的第二个逻辑分区。

  在重新对你的硬盘分区时,可能遇到三种情况,一般而言,对它们的处理方法分别应该是这样的:

  1) 有未分区的空闲空间。在这种情况下,已定义的分区未占有整个硬盘空间,也就是说空闲空间不属于任何已定义的分区。仔细想一下,一个未用的硬盘也属于这种情况,不同的只是所有的空间都不属于任何已定义的分区。这时,只须简单地从未用的空间创建所需的分区。

  2 )有未用的分区。你可能已经将硬盘分成诸如C 、D 、E 这样的D O S 分区,但是有一个分区现在没有使用,或是已经被清空,你或许希望将L i n u x 安装在这里。如果你属于这种情况,可以使用这个未使用的分区。这时,先得删除这个分区,然后再在这个空间创建合适的L i n u x分区。

  3) 在已有分区中有空闲空间。如果你已经将硬盘分区,并且没有一个完全空闲的分区,以下就是你应该看的了。这是最常见的情况。不幸的是,这也是最难对付的情况。虽然你有足够的空间,但却属于已用的分区。除了加一个硬盘外(这时你只需要考虑你的银子,其他就好办了),还有两种选择:

  a. 破坏性的重新分区。首先删除一个大的分区,然后创建几个小的分区。被删除的那个大的分区中的所有数据将被破坏。这就是说必须做一次完全的备份。为安全起见,做两套备份,使用校验(如果你的备份软件有此功能),在删除分区之前试着读一下你备份的数据。这将是一件麻烦的工作,但为了保护你以前的工作,还是十分必要的。注意一点,如果你删除的分区含有操作系统,还得重装操作系统。在创建了小的分区之后,可以重装软件,恢复数据,然后继续安装L i n u x 。

  b. 非破坏性的重新分区。这里,你可以运行一个提供这种功能的应用程序。这个程序可以将大分区变小而不丢失分区中的文件。很多人发现这种方法是可靠而没有麻烦的。那么你该用什么软件呢? 市场上有好几种磁盘管理的软件产品,就笔者看来,它们在功能和可靠性方面大同小异,例如Partition Magic 就是一个口碑不错的分区软件。Red Hat Linux 也为I n t e l 系统提供了一个这样的软件:在Linux/Intel CD-ROM 上d o s u t i l s 目录中的f i p s 。

  2. Linux 硬盘分区的实际操作
  尽管可以根据我们已经提到的分区原则,将L i n u x 装在一个单一的大分区中,但更好的主意是将它分开。综合了单一分区的简单性和多分区的灵活性,我们推荐以下配置。请注意:

  如果你想安装L i n u x 的所有软件包的话,必须使用这里指出的较大的分区尺寸。事实上,你可能会加大我们推荐的尺寸,以使将来升级时不必重新分区。

  1) 一个交换(s w a p )分区。交换分区用来支持虚拟内存。如果你的计算机内存小于 1 6 M B ,必须创建交换分区。即使你有更多的内存,仍然推荐使用交换分区。交换分区的最小尺寸是你的内存的大小,或1 6 M B (两者取大)。交换分区最大可以达到1 2 7 M B ,所以创建更大的交换分区是浪费空间。注意,可以创建和使用一个以上的交换分区(尽管这通常安装在大的服务器上)。

  2) 一个根(r o o t )分区。根分区是"/"(根目录)所在地(注意不是/ r o o t )。它只需要启动系统所须的文件和系统配置文件。对于大多数系统,5 0 M B 到1 0 0 M B 的根分区可以工作得很好。

  3) 一个/usr 分区。/ u s r 是L i n u x 系统的许多软件所在的地方。根据你交换安装的包的数量,这个分区应该在3 0 0 M B 到7 0 0 M B 之间。如果可能,将最大的空间用于/ u s r 分区。任何你以后将要安装的基于R P M 的包都会使用比其他分区更多的/ u s r 空间。

  4) 一个/ h o m e 分区。这是用户的h o m e 目录所在地; 它的大小取决于你的Linux 系统有多少用户,以及这些用户将存放多少数据。如果系统将用作E - m a i l 服务的话,为每一位用户预留5 M B 左右的空间,如果将提供个人主页存放空间的话,则应至少为每位用户预留2 0 M B 空间。

  对于网站建设者,还有一点需要注意的是,你的We b 服务和匿名F t p (/ h o m e / f t p )服务器的内容也在这里!

  另外,你的环境可能会要求你创建一个和多个以下的分区:

  1) 一个/usr/local 分区。一般/ u s r / l o c a l 用来存放与其余L i n u x 系统不同的软件,如不是R P M 包的软件。它的尺寸取决于你准备存放的这些软件的数量。

  2) 一个/usr/src 分区。在一个L i n u x 系统中,/ u s r / s r c 通常存放两样东西:
  L i n u x 内核源程序。内核的所有源程序都放在这里,新的内核也在这里创建。目前,内核源程序大概有3 0 M B 。记住,你可能需要更多的空间来创建内核,或者保存几个不同版本的内核。

  R P M 包的源程序。如果安装了包的源程序,文件将存放在这里。注意,除非特别指定,

  创建包也将使用在这里的一个'创建目录'。

  同样,这个分区的尺寸也取决于你将在这里安装的软件的数量。

  3) 一个/ t m p 分区。就像它的名字,/ t m p 分区用来存放临时文件。对于一个大型的,多用户的系统或者网络服务器,专门创建一个/ t m p 分区是一个好主意。对于一个单用户的工作站,就不必专门创建一个/ t m p 分区了。

  4) 一个/var 分区。你的L i n u x 系统将把日志写在/ v a r / l o g 。打印队列的文件通常写在/ v a r / s p o o l 。这只是两个写在/ v a r 的例子。除非特别配置,/ v a r 将是根文件系统的一部分,通常不占很多空间。如果你的系统有很多打印、邮件、或者日志,可以考虑专门创建一个/ v a r 分区。

  一般来讲,只有多用户或者服务器才需要专门的/ v a r 分区。

  5) 一个/boot 分区。这里提到的分区多数是针对大的系统,这个分区则对空间很少的小的系统很有用。在上文中,我们讨论了标准P C 的B I O S 的一些限制,以及这些限制如何影响L I L O 的启动。所有L I L O 启动时需要的文件都在/ b o o t 目录。因此最好的办法就是专门为根文件分一个区,大小至多6 4 M B ,最好首先分这个区,然后再分/ u s r 等等。

C语言面试题大汇总之华为面试题

silver6 | 01 二月, 2007 15:57

1、局部变量能否和全局变量重名?   答:能,局部会屏蔽全局。要用全局变量,需要使用"::"   局部变量可以与全局变量同名,在函数内引用这个变量时,会用到同名的局部变量,而不会用到全局变量。对于有些编译器而言,在同一个函数内可以定义多个同名的局部变量,比如在两个循环体内都定义一个同名的局部变量,而那个局部变量的作用域就在那个循环体内。   

2、如何引用一个已经定义过的全局变量?   答:extern   可以用引用头文件的方式,也可以用extern关键字,如果用引用头文件方式来引用某个在头文件中声明的全局变理,假定你将那个变写错了,那么在编译期间会报错,如果你用extern方式引用时,假定你犯了同样的错误,那么在编译期间不会报错,而在连接期间报错。   

3、全局变量可不可以定义在可被多个.C文件包含的头文件中?为什么?   答:可以,在不同的C文件中以static形式来声明同名全局变量。   可以在不同的C文件中声明同名的全局变量,前提是其中只能有一个C文件中对此变量赋初值,此时连接不会出错   

4、语句for( ;1 ;)有什么问题?它是什么意思?   答:和while(1)相同。   

5、do……while和while……do有什么区别?   答:前一个循环一遍再判断,后一个判断以后再循环   

6、请写出下列代码的输出内容   

#include   

main()   

{    

int a,b,c,d;

   a=10;  

  b=a++;  

  c=++a;   

 d=10*a++;  

  printf("b,c,d:%d,%d,%d",b,c,d);  

  return 0;  

 }   

答:10,12,120   

7、static全局变量与普通的全局变量有什么区别?static局部变量和普通局部变量有什么区别?static函数与普通函数有什么区别?   全局变量(外部变量)的说明之前再冠以static 就构成了静态的全局变量。全局变量本身就是静态存储方式, 静态全局变量当然也是静态存储方式。 这两者在存储方式上并无不同。这两者的区别虽在于非静态全局变量的作用域是整个源程序, 当一个源程序由多个源文件组成时,非静态的全局变量在各个源文件中都是有效的。 而静态全局变量则限制了其作用域, 即只在定义该变量的源文件内有效, 在同一源程序的其它源文件中不能使用它。由于静态全局变量的作用域局限于一个源文件内,只能为该源文件内的函数公用, 因此可以避免在其它源文件中引起错误。   从以上分析可以看出, 把局部变量改变为静态变量后是改变了它的存储方式即改变了它的生存期。把全局变量改变为静态变量后是改变了它的作用域, 限制了它的使用范围。   static函数与普通函数作用域不同。仅在本文件。只在当前源文件中使用的函数应该说明为内部函数(static),内部函数应该在当前源文件中说明和定义。对于可在当前源文件以外使用的函数,应该在一个头文件中说明,要使用这些函数的源文件要包含这个头文件   static全局变量与普通的全局变量有什么区别:static全局变量只初使化一次,防止在其他文件单元中被引用;   static局部变量和普通局部变量有什么区别:static局部变量只被初始化一次,下一次依据上一次结果值;   static函数与普通函数有什么区别:static函数在内存中只有一份,普通函数在每个被调用中维持一份拷贝   

8、程序的局部变量存在于(堆栈)中,全局变量存在于(静态区 )中,动态申请数据存在于( 堆)中。   

9、设有以下说明和定义:  

 typedef union

{

long i; int k[5]; char c;} DATE;  

 struct data { int cat; DATE cow; double dog;} too;  

 DATE max;   

则语句 printf("%d",sizeof(struct date)+sizeof(max));的执行结果是:___52____   

答:DATE是一个union, 变量公用空间. 里面最大的变量类型是int[5], 占用20个字节. 所以它的大小是20 data是一个struct, 每个变量分开占用空间. 依次为int4 + DATE20 + double8 = 32. 所以结果是 20 + 32 = 52.   当然...在某些16位编辑器下, int可能是2字节,那么结果是 int2 + DATE10 + double8 = 20   

10、队列和栈有什么区别?      队列先进先出,栈后进先出   

11、写出下列代码的输出内容   

#include   

int inc(int a)    {     return(++a);    }    int multi(int*a,int*b,int*c)    {     return(*c=*a**b);    }    typedef int(FUNC1)(int in);    typedef int(FUNC2) (int*,int*,int*);    void show(FUNC2 fun,int arg1, int*arg2)    {     INCp=&inc;     int temp =p(arg1);     fun(&temp,&arg1, arg2);     printf("%dn",*arg2);    }    main()    {     int a;     show(multi,10,&a);     return 0;    }   答:110   

12、请找出下面代码中的所以错误   

说明:以下代码是把一个字符串倒序,如“abcd”倒序后变为“dcba”   

#include"string.h"   

main()   

{   

char*src="hello,world";   

char* dest=NULL;   

int len=strlen(src);   

dest=(char*)malloc(len);   

char* d=dest;   

char* s=src[len];   

while(len--!=0)   

d++=s--;   

printf("%s",dest);   

return 0;   

}   

答:   

方法1:   

int main()   

{   

 char* src = "hello,world";   

 int len = strlen(src);   

 char* dest = (char*)malloc(len+1);//要为分配一个空间    char* d = dest;   

 char* s = &src[len-1];//指向最后一个字符   

 while( len-- != 0 )   

 *d++=*s--;   

 *d = 0;//尾部要加   

 printf("%sn",dest);    

free(dest);// 使用完,应当释放空间,以免造成内存汇泄露    return 0;  

 }

方法2:   

#include <stdio.h>

#include <string.h>

main()

{

char str[]="hello,world";

int len=strlen(str);

char t;

for(int i=0; i<len/2; i++)

{

t=str[i];

str[i]=str[len-i-1]; str[len-i-1]=t;

}

printf("%s",str);

return 0;

}

13.对于一个频繁使用的短小函数,在C语言中应用什么实现,在C++中应用什么实现?   c用宏定义,c++用inline   

14.直接链接两个信令点的一组链路称作什么?   PPP点到点连接     

6.接入网用的是什么接口?

V5接口    

16.voip都用了那些协议?  H.323协议簇、SIP协议、Skype协议、H.248MGCP协议 

17.软件测试都有那些种类?   黑盒:针对系统功能的测试   白合:测试函数功能,各函数接口   

18.确定模块的功能和模块的接口是在软件设计的那个队段完成的?   概要设计阶段   

19.  

enum string

{

x1,

x2,

x3=10,

x4,

x5,

}x;

x= 0x8010050x8010f4 ;

  20.   

unsigned char *p1;

unsigned long *p2;

p1=(unsigned char *)0x801000;

p2=(unsigned long *)0x810000;

请问p1+5= ;

p2+5= ;

选择题:   

21.Ethternet链接到Internet用到以下那个协议?   A.HDLC;B.ARP;C.UDP;D.TCP;E.ID    

22.属于网络层协议的是:      A.TCP;B.IP;C.ICMP;D.X.25   23.Windows消息调度机制是:   A.指令队列;B.指令堆栈;C.消息队列;D.消息堆栈;   

24.    unsigned short hash(unsigned short key)

{

return (key>>)%256

}

请问hash(16),hash(256)的值分别是:

A.1.16;B.8.32;C.4.16;D.1.32

找错题:   

25.请问下面程序有什么错误?   

int a[60][250][1000],i,j,k;   

for(k=0;kMax_GT_Length)    

{     return GT_Length_ERROR;  

 }    ....... }   

问答题:    29.IP Phone的原理是什么?   IPV6  

  30.TCP/IP通信建立的过程怎样,端口有什么作用?   三次握手,确定是哪个应用程序使用该协议   

31.1号信令和7号信令有什么区别,我国某前广泛使用的是那一种?   

32.列举5种以上的电话新业务

.找错题:

1.请问下面程序有什么错误?

int a[60][250][1000],i,j,k;

for(k=0;k<=1000;k++)

for(j=0;j<250;j++)

for(i=0;i<60;i++)

a[i][j][k]=0;

把循环语句内外换一下

2.#define Max_CB 500

void LmiQueryCSmd(Struct MSgCB * pmsg)

{

unsigned char ucCmdNum;

......

for(ucCmdNum=0;ucCmdNum<Max_CB;ucCmdNum++)

{

......;

}

死循环

3.以下是求一个数的平方的程序,请找出错误:

#define SQUARE(a)((a)*(a))

int a=5;

int b;

b=SQUARE(a++);

4.typedef unsigned char BYTE

int examply_fun(BYTE gt_len; BYTE *gt_code)

{

BYTE *gt_buf;

gt_buf=(BYTE *)MALLOC(Max_GT_Length);

......

if(gt_len>Max_GT_Length)

{

return GT_Length_ERROR;

}

.......

}

.问答题:

1.IP Phone的原理是什么?

IPV6

2.TCP/IP通信建立的过程怎样,端口有什么作用?

三次握手,确定是哪个应用程序使用该协议

3. 1号信令和7号信令有什么区别,我国某前广泛使用的是那一种?

4. 列举5种以上的电话新业务?

微软亚洲技术中心的面试题!!!

1.进程和线程的差别。

线程是指进程内的一个执行单元,也是进程内的可调度实体.

与进程的区别:

(1)调度:线程作为调度和分配的基本单位,进程作为拥有资源的基本单位

(2)并发性:不仅进程之间可以并发执行,同一个进程的多个线程之间也可并发执行

(3)拥有资源:进程是拥有资源的一个独立单位,线程不拥有系统资源,但可以访问隶属于进程的资源.

(4)系统开销:在创建或撤消进程时,由于系统都要为之分配和回收资源,导致系统的开销明显大于创建或撤消线程时的开销。

2.测试方法

人工测试:个人复查、抽查和会审

机器测试:黑盒测试和白盒测试

2Heapstack的差别。

Heap是堆,stack是栈。

Stack的空间由操作系统自动分配/释放,Heap上的空间手动分配/释放。

Stack空间有限,Heap是很大的自由存储区

C中的malloc函数分配的内存空间即在堆上,C++中对应的是new操作符。

程序在编译期对变量和函数分配内存都在栈上进行,且程序运行过程中函数调用时参数的传递也在栈上进行

3Windows下的内存是如何管理的?

4.介绍.Net.Net的安全性。

5.客户端如何访问.Net组件实现Web Service

6C/C++编译器中虚表是如何完成的?

7.谈谈COM的线程模型。然后讨论进程内/外组件的差别。

8.谈谈IA32下的分页机制

小页(4K)两级分页模式,大页(4M)一级

9.给两个变量,如何找出一个带环单链表中是什么地方出现环的?

一个递增一,一个递增二,他们指向同一个接点时就是环出现的地方

10.在IA32中一共有多少种办法从用户态跳到内核态?

通过调用门,从ring3ring0,中断从ring3ring0,进入vm86等等

11.如果只想让程序有一个实例运行,不能运行两个。像winamp一样,只能开一个窗口,怎样实现?

用内存映射或全局原子(互斥变量)、查找窗口句柄..

FindWindow,互斥,写标志到文件或注册表,共享内存。. 

12.如何截取键盘的响应,让所有的‘a’变成‘b’?

键盘钩子SetWindowsHookEx

13ApartmentCOM中有什么用?为什么要引入?

14.存储过程是什么?有什么用?有什么优点?

我的理解就是一堆sql的集合,可以建立非常复杂的查询,编译运行,所以运行一次后,以后再运行速度比单独执行SQL快很多

15Template有什么特点?什么时候用?

16.谈谈Windows DNA结构的特点和优点。

17. 网络编程中设计并发服务器,使用多进程 多线程 ,请问有什么区别?

1,进程:子进程是父进程的复制品。子进程获得父进程数据空间、堆和栈的复制品。

2,线程:相对与进程而言,线程是一个更加接近与执行体的概念,它可以与同进程的其他线程共享数据,但拥有自己的栈空间,拥有独立的执行序列。

两者都可以提高程序的并发度,提高程序运行效率和响应时间。

线程和进程在使用上各有优缺点:线程执行开销小,但不利于资源管理和保护;而进程正相反。同时,线程适合于在SMP机器上运行,而进程则可以跨机器迁移。

思科

1. 用宏定义写出swapxy

#define swap(x, y)

x = x + y;

y = x - y;

x = x - y;

2.数组a[N],存放了1N-1个数,其中某个数重复一次。写一个函数,找出被重复的数字.时间复杂度必须为oN)函数原型:

int do_dup(int a[],int N)

3 一语句实现x是否为2的若干次幂的判断

int i = 512;

cout << boolalpha << ((i & (i - 1)) ? false : true) << endl;

4.unsigned int intvert(unsigned int x,int p,int n)实现对x的进行转换,p为起始转化位,n为需要转换的长度,假设起始点在右边.x=0b0001 0001,p=4,n=3转换后x=0b0110 0001

unsigned int intvert(unsigned int x,int p,int n){

unsigned int _t = 0;

unsigned int _a = 1;

for(int i = 0; i < n; ++i){

_t |= _a;

_a = _a << 1;

}

_t = _t << p;

x ^= _t;

return x;

}

慧通:

1. 什么是预编译,何时需要预编译:

1、总是使用不经常改动的大型代码体。

2、程序由多个模块组成,所有模块都使用一组标准的包含文件和相同的编译选项。在这种情况下,可以将所有包含文件预编译为一个预编译头。

2. 上述三个有什么区别?

char * const p;

char const * p

const char *p

解答:

char * const p; //常量指针,p的值不可以修改

char const * p//指向常量的指针,指向的常量值不可以改

const char *p //char const *p

3. 解释下列输出结果

char str1[] = "abc";

char str2[] = "abc";

const char str3[] = "abc";

const char str4[] = "abc";

const char *str5 = "abc";

const char *str6 = "abc";

char *str7 = "abc";

char *str8 = "abc";

cout << ( str1 == str2 ) << endl;

cout << ( str3 == str4 ) << endl;

cout << ( str5 == str6 ) << endl;

cout << ( str7 == str8 ) << endl;

结果是:0 0 1 1

解答:str1,str2,str3,str4是数组变量,它们有各自的内存空间;

str5,str6,str7,str8是指针,它们指向相同的常量区域。

4. 以下代码中的两个sizeof用法有问题吗?[C]

void UpperCase( char str[] ) // str 中的小写字母转换成大写字母

{

for( size_t i=0; i<sizeof(str)/sizeof(str[0]); ++i )

if( 'a'<=str[i] && str[i]<='z' )

str[i] -= ('a'-'A' );

}

char str[] = "aBcDe";

cout << "str字符长度为: " << sizeof(str)/sizeof(str[0]) << endl;

UpperCase( str );

cout << str << endl;

答:函数内的sizeof有问题。根据语法,sizeof如用于数组,只能测出静态数组的大小,无法检测动态分配的或外部数组大小。函数外的str是一个静态定义的数组,因此其大小为6,函数内的str实际只是一个指向字符串的指针,没有任何额外的与数组相关的信息,因此sizeof作用于上只将其当指针看,一个指针为4个字节,因此返回4

4. 一个32位的机器,该机器的指针是多少位

指针是多少位只要看地址总线的位数就行了。80386以后的机子都是32的数据总线。所以指针的位数就是4个字节了。

5. 指出下面代码的输出,并解释为什么。

main()

{

int a[5]={1,2,3,4,5};

int *ptr=(int *)(&a+1);

printf("%d,%d",*(a+1),*(ptr-1));

}

输出:2,5

*(a+1)就是a[1]*(ptr-1)就是a[4],执行结果是25

&a+1不是首地址+1,系统会认为加一个a数组的偏移,是偏移了一个数组的大小(本例是5int

int *ptr=(int *)(&a+1);

ptr实际是&(a[5]),也就是a+5

原因如下:

&a是数组指针,其类型为 int (*)[5];

而指针加1要根据指针类型加上一定的值,

不同类型的指针+1之后增加的大小不同

a是长度为5int数组指针,所以要加 5*sizeof(int)

所以ptr实际是a[5]

但是prt(&a+1)类型是不一样的(这点很重要)

所以prt-1只会减去sizeof(int*)

a,&a的地址是一样的,但意思不一样,a是数组首地址,也就是a[0]的地址,&a是对象(数组)首地址,a+1是数组下一元素的地址,即a[1],&a+1是下一个对象的地址,即a[5].

6.请问以下代码有什么问题:

1).

int main()

{

char a;

char *str=&a;

strcpy(str,"hello");

printf(str);

return 0;

}

没有为str分配内存空间,将会发生异常

问题出在将一个字符串复制进一个字符变量指针所指地址。虽然可以正确输出结果,但因为越界进行内在读写而导致程序崩溃。

2).

char* s="AAA";

printf("%s",s);

s[0]='B';

printf("%s",s);

有什么错?

"AAA"是字符串常量。s是指针,指向这个字符串常量,所以声明s的时候就有问题。

cosnt char* s="AAA";

然后又因为是常量,所以对是s[0]的赋值操作是不合法的。

1、写一个“标准”宏,这个宏输入两个参数并返回较小的一个。

.#define Min(X, Y) ((X)>(Y)?(Y):(X))//结尾没有;

2、嵌入式系统中经常要用到无限循环,你怎么用C编写死循环。

while(1){}或者for(;;)

3、关键字static的作用是什么?

定义静态变量

4、关键字const有什么含意?

表示常量不可以修改的变量。

5、关键字volatile有什么含意?并举出三个不同的例子?

提示编译器对象的值可能在编译器未监测到的情况下改变。

6. int (*s[10])(int) 表示的是什么啊

int (*s[10])(int) 函数指针数组,每个指针指向一个int func(int param)的函数。

1.有以下表达式:

int a=248; b=4;int const c=21;const int *d=&a;

int *const e=&b;int const *f const =&a;

请问下列表达式哪些会被编译器禁止?为什么?

*c=32;d=&b;*d=43;e=34;e=&a;f=0x321f;

*c 这是个什么东东,禁止

*d 说了是const 禁止

e = &a 说了是const 禁止

const *f const =&a; 禁止

2.交换两个变量的值,不使用第三个变量。即a=3,b=5,交换之后a=5,b=3;

有两种解法, 一种用算术算法, 一种用^(异或)

a = a + b;

b = a - b;

a = a - b;

or

a = a^b;// 只能对int,char..

b = a^b;

a = a^b;

or

a ^= b ^= a;

3.cc++中的struct有什么不同?

cc++struct的主要区别是c中的struct不可以含有成员函数,而c++中的struct可以。c++structclass的主要区别在于默认的存取权限不同,struct默认为public,而class默认为private

4.#include <stdio.h>

#include <stdlib.h>

void getmemory(char *p)

{

p=(char *) malloc(100);

strcpy(p,"hello world");

}

int main( )

{

char *str=NULL;

getmemory(str);

printf("%s/n",str);

free(str);

return 0;

}

程序崩溃,getmemory中的malloc 不能返回动态内存, free()对str操作很危险

5.char szstr[10];

strcpy(szstr,"0123456789");

产生什么结果?为什么?

长度不一样,会造成非法的OS

6.列举几种进程的同步机制,并比较其优缺点。

原子操作

信号量机制

自旋锁

管程,会合,分布式系统

7.进程之间通信的途径

共享存储系统

消息传递系统

管道:以文件系统为基础

8.

面试经典试题

silver6 | 02 一月, 2007 11:41

面试经典试题

Author:Vince

————即使你是个编程高手,你在面试前也应该要看看这套题,她也许会给你带来好运,否则你有可能后悔当初为什么没有看而跳楼自杀,这样我会很内疚的。这套题看似简单,但你未必能得高分,即使你看不懂也要把她背下来!

欢迎转载此文,转载时请注明文章来源:文斯测试技术研究中心 http://blog.csdn.net/vincetest

1 编程基础

1.1 基本概念

1. const的理解:const char*, char const*, char*const的区别问题几乎是C++面试中每次 都会有的题目。 事实上这个概念谁都有只是三种声明方式非常相似很容易记混。 Bjarne在他的The C++ Programming Language里面给出过一个助记的方法: 把一个声明从右向左读。

char * const cp; ( * 读成 pointer to )

cp is a const pointer to char

const char * p;

p is a pointer to const char;

char const * p;

同上因为C++里面没有const*的运算符,所以const只能属于前面的类型。

2. c指针

int *p[n];-----指针数组,每个元素均为指向整型数据的指针。

int (*)p[n];------p为指向一维数组的指针,这个一维数组有n个整型数据。

int *p();----------函数带回指针,指针指向返回的值。

int (*)p();------p为指向函数的指针。

3. 数组越界问题

下面这个程序执行后会有什么错误或者效果:

#define MAX 255

int main()

{

unsigned char A[MAX],i;

for (i=0;i<=MAX;i++)

A[i]=i;

}

解答:MAX=255,数组A的下标范围为:0..MAX-1,这是其一,其二 i循环到255,循环内执行: A[255]=255;这句本身没有问题,但是返回for (i=0;i<=MAX;i++)语句时,由于unsigned char的取值范围在(0..255),i++以后i又为0..无限循环下去.

注:char类型为一个字节,取值范围是[-128127]unsigned char [0 ,255]

4. C++:memset ,memcpy strcpy 的根本区别?

#include "memory.h"

memset用来对一段内存空间全部设置为某个字符,一般用在对定义的字符串进行初始化为‘ '‘';例:char a[100];memset(a, '', sizeof(a));

memcpy用来做内存拷贝,你可以拿它拷贝任何数据类型的对象,可以指定拷贝的数据长度;例:char a[100],b[50]; memcpy(b, a, sizeof(b));注意如用sizeof(a),会造成b的内存地址溢出。

strcpy就只能拷贝字符串了,它遇到''就结束拷贝;例:char a[100],b[50];strcpy(a,b);如用strcpy(b,a),要注意a中的字符串长度(第一个‘'之前)是否超过50位,如超过,则会造成b的内存地址溢出。

strcpy

原型:extern char *strcpy(char *dest,char *src);

用法:#include

功能:把src所指由NULL结束的字符串复制到dest所指的数组中。

说明:srcdest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串。

返回指向dest的指针。

memcpy

原型:extern void *memcpy(void *dest, void *src, unsigned int count);

用法:#include

功能:由src所指内存区域复制count个字节到dest所指内存区域。

说明:srcdest所指内存区域不能重叠,函数返回指向dest的指针。

Memset

原型:extern void *memset(void *buffer, char c, int count);

用法:#include

功能:把buffer所指内存区域的前count个字节设置成字符c

说明:返回指向buffer的指针。

5. ASSERT()是干什么用的

ASSERT()是一个调试程序时经常使用的宏,在程序运行时它计算括号内的表达式,如果表达式为FALSE (0), 程序将报告错误,并终止执行。如果表达式不为0,则继续执行后面的语句。这个宏通常原来判断程序中是否出现了明显非法的数据,如果出现了终止程序以免导致严重后果,同时也便于查找错误。例如,变量n在程序中不应该为0,如果为0可能导致错误,你可以这样写程序:

......

ASSERT( n != 0);

k = 10/ n;

......

ASSERT只有在Debug版本中才有效,如果编译为Release版本则被忽略。

assert()的功能类似,它是ANSI C标准中规定的函数,它与ASSERT的一个重要区别是可以用在Release版本中。

6. system"pause");系统的暂停程序,按任意键继续,屏幕会打印,"按任意键继续。。。。。" 省去了使用getchar();

7. 请问C++的类和C里面的struct有什么区别?

c++中的类具有成员保护功能,并且具有继承,多态这类oo特点,而c里的struct没有

8. 请讲一讲析构函数和虚函数的用法和作用?

析构函数也是特殊的类成员函数,它没有返回类型,没有参数,不能随意调用,也没有重载。知识在类对象生命期结束的时候,由系统自动调用释放在构造函数中分配的资源。这种在运行时,能依据其类型确认调用那个函数的能力称为多态性,或称迟后联编。另:析构函数一般在对象撤消前做收尾工作,比如回收内存等工作,虚拟函数的功能是使子类可以用同名的函数对父类函数进行重载,并且在调用时自动调用子类重载函数,如果是纯虚函数,则纯粹是为了在子类重载时有个统一的命名而已。

9. 全局变量和局部变量有什么区别?实怎么实现的?操作系统和编译器是怎么知道的?

全局变量的生命周期是整个程序运行的时间,而局部变量的生命周期则是局部函数或过程调用的时间段。其实现是由编译器在编译时采用不同内存分配方法。全局变量在main函数调用后,就开始分配,如果是静态变量则是在main函数前就已经初始化了。而局部变量则是在用户栈中动态分配的(还是建议看编译原理中的活动记录这一块)

10. 8086是多少尉的系统?在数据总线上是怎么实现的?

8086系统是16位系统,其数据总线是20位。

1.2 程序设计

1. 编写用C语言实现的求n阶阶乘问题的递归算法:

long int fact(int n)
{

int x;

long int y;

if(n<0)

{

printf("error!");

}

if(n==0)

return 1;

x=n-1;

y=fact(x);

return (n*y);

}

2. 二分查找算法:

1) 递归方法实现:

int BSearch(elemtype a[],elemtype x,int low,int high)

/*在下届为low,上界为high的数组a中折半查找数据元素x*/

{

int mid;

if(low>high) return -1;

mid=(low+high)/2;

if(x==a[mid]) return mid;

if(x<a[mid]) return(BSearch(a,x,low,mid-1));

else return(BSearch(a,x,mid+1,high));

}

2) 非递归方法实现:

int BSearch(elemtype a[],keytype key,int n)

{

int low,high,mid;

low=0;high=n-1;

while(low<=high)

{

mid=(low+high)/2;

if(a[mid].key==key) return mid;

else if(a[mid].key<key) low=mid+1;

else high=mid-1;

}

return -1;

}

3. 递归计算如下递归函数的值(斐波拉契):

f(1)=1

f(2)=1

f(n)=f(n-1)+f(n-2) n>2

解:

int f(int n)

{

int i,s,s1,s2;

s1=1;/*s1用于保存f(n-1)的值*/

s2=1;/*s2用于保存f(n-2)的值*/

s=1;

for(i=3;i<=n;i++)

{

s=s1+s2;

s2=s1;

s1=s;

}

return(s);

}

4. 交换两个数,不用第三块儿内存:

int a = ……;

int b = ……;

a = a + b;

b = a - b;

a = a - b;

5. 冒泡排序:

void BubbleSort(elemtype x[],int n)

{

int i,j;

elemtype temp;

for(i=1;i<n;i++)

for(j=0;j<n-i;j++)

{

if(x[j].key>x[j+1].key)

{

temp=x[j];

x[j]=x[j+1];

x[j+1]=temp;

}

}

}

6. c语言 文件读写

#include "stdio.h"

main()

{

FILE *fp;

char ch,filename[10];

scanf("%s",filename);

if((fp=fopen(filename,"w")==NULL)

{

printf("cann't open filen");

exit(0);

}

ch=getchar();

while(ch!='#')

{

fputc(ch,fp);

putchar(ch);

ch=getchar();

}

fclose(fp);

}

7. winsocket编程

#include <Winsock2.h>

#include <stdio.h>

void main()

{

WORDwVersionRequested;

WSADATA wsaData;

int err;

wVersionRequested = MAKEWORD(1,1);

err = WSAStartup(wVersionRequested,&wsaData);

if( err != 0)

{

return;

}

if(LOBYTE( wsaData.wVersion ) != 1||

HIBYTE( wsaData.wVersion) != 1)

{

WSACleanup();

return;

}

SOCKET sockSrv=socket(AF_INET,SOCK_STREAM,0);

SOCKADDR_IN addrSrv;

addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);

addrSrv.sin_family=AF_INET;

addrSrv.sin_port=htons(6000);

bind(sockSrv,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));

listen(sockSrv,5);

SOCKADDR_IN addrClient;

int len=sizeof(SOCKADDR);

while(1)

{

SOCKET sockConn=accept(sockSrv,(SOCKADDR*)&addrClient,&len);

char sendBuf[100];

sprint(sendBuf,"Welcome %s to http://www.sunxin.org",

inet_ntoa(addrClient.sin_addr));

send(sockConn,sendBuf,strlen(sendBuf)+1,0);

char recvBuf[100];

recv(sockConn,recvBuf);

printf("%sn",recvBuf);

closesocket(sockConn);

WSACleanup();

}

}

注:这是Server端;File->New->Win32 Console Application,工程名:TcpSrv;然后,File->New->C++ Source File,文件名:TcpSrv;在该工程的SettingLinkObject/library modules项要加入ws2_32.lib

#include <Winsock2.h>

#include <stdio.h>

void main()

{

WORDwVersionRequested;

WSADATA wsaData;

int err;

wVersionRequested = MAKEWORD(1,1);

err = WSAStartup(wVersionRequested,&wsaData);

if( err != 0)

{

return;

}

if(LOBYTE( wsaData.wVersion ) != 1||

HIBYTE( wsaData.wVersion) != 1)

{

WSACleanup();

return;

}

SOCKET sockClient=socket(AF_INET,SOCK_STREAM,0);

SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");

addrSrv.sin_family=AF_INET;

addrSrv.sin_porthtons(6000);

connect(sockClient,(SOCKADDR*)&addrSrv,sizeof(SOCKADDR));

char recvBuf[100];

recv(sockClient,recvBuf,100,0);

printf("%sn",recvBuf);

send(sockClient,"This is zhangsan",strlen("This is zhangsan")+1,0);

closesocket(sockClient);

WSACleanup();

}

注:这是Client端;File->New->Win32 Console Application,工程名:TcpClient;然后,File->New->C++ Source File,文件名:TcpClient;同理,在该工程的SettingLinkObject/library modules项要加入ws2_32.lib

8. 类的知识

C++

#include <iostream.h>

class human

{

public:

human(){ human_num++;};

static int human_num;

~human()

{

human_num--;

print();

}

void print()

{

cout<<"human num is: "<<human_num<<endl;

}

protected:

private:

};

int human::human_num = 0;

human f1(human x)

{

x.print();

return x;

}

int main(int argc, char* argv[])

{

human h1;

h1.print();

human h2 = f1(h1);

h2.print();

return 0;

}

输出:

1

1

0

0

1

2

----------------------------

分析:

human h1; //调用构造函数,---hum_num = 1;

h1.print(); //输出:"human is 1"

human h2 = f1(h1); //再调用f1(h1)的过程中,由于函数参数是按值传递对象,调用默认的复制构造函数, 一般分类 :: 评论 (2) :: 静态链接网址 :: 引用 (0)

C/C++ 程序设计员应聘常见面试试题深入剖析

silver6 | 25 九月, 2006 09:07

本文的写作目的并不在于提供C/C++程序员求职面试指导,而旨在从技术上分析面试题的内涵。文中的大多数面试题来自各大论坛,部分试题解答也参考了网友的意见。

   许多面试题看似简单,却需要深厚的基本功才能给出完美的解答。企业要求面试者写一个最简单的strcpy函数都可看出面试者在技术上究竟达到了怎样的程 度,我们能真正写好一个strcpy函数吗?我们都觉得自己能,可是我们写出的strcpy很可能只能拿到10分中的2分。读者可从本文看到strcpy 函数从2分到10分解答的例子,看看自己属于什么样的层次。此外,还有一些面试题考查面试者敏捷的思维能力。

  分析这些面试题,本身包含很强的趣味性;而作为一名研发人员,通过对这些面试题的深入剖析则可进一步增强自身的内功。

  2.找错题

  试题1:

void test1()
{
 char string[10];
 char* str1 = "0123456789";
 strcpy( string, str1 );
}

  试题2:

void test2()
{
 char string[10], str1[10];
 int i;
 for(i=0; i<10; i++)
 {
  str1[i] = 'a';
 }
 strcpy( string, str1 );
}

  试题3:

void test3(char* str1)
{
 char string[10];
 if( strlen( str1 ) <= 10 )
 {
  strcpy( string, str1 );
 }
}

  解答:

  试题1字符串str1需要11个字节才能存放下(包括末尾的’’),而string只有10个字节的空间,strcpy会导致数组越界;

   对试题2,如果面试者指出字符数组str1不能在数组内结束可以给3分;如果面试者指出strcpy(string, str1)调用使得从str1内存起复制到string内存起所复制的字节数具有不确定性可以给7分,在此基础上指出库函数strcpy工作方式的给10 分;

  对试题3,if(strlen(str1) <= 10)应改为if(strlen(str1) < 10),因为strlen的结果未统计’’所占用的1个字节。

  剖析:

  考查对基本功的掌握:

  (1)字符串以’’结尾;

  (2)对数组越界把握的敏感度;

  (3)库函数strcpy的工作方式,如果编写一个标准strcpy函数的总分值为10,下面给出几个不同得分的答案:

  2分

void strcpy( char *strDest, char *strSrc )
{
  while( (*strDest++ = * strSrc++) != ‘’ );
}

  4分

void strcpy( char *strDest, const char *strSrc )
//将源字符串加const,表明其为输入参数,加2分
{
  while( (*strDest++ = * strSrc++) != ‘’ );
}

  7分

void strcpy(char *strDest, const char *strSrc)
{
 //对源地址和目的地址加非0断言,加3分
 assert( (strDest != NULL) && (strSrc != NULL) );
 while( (*strDest++ = * strSrc++) != ‘’ );
}

  10分

//为了实现链式操作,将目的地址返回,加3分!

char * strcpy( char *strDest, const char *strSrc )
{
 assert( (strDest != NULL) && (strSrc != NULL) );
 char *address = strDest;
 while( (*strDest++ = * strSrc++) != ‘’ );
  return address;
}

  从2分到10分的几个答案我们可以清楚的看到,小小的strcpy竟然暗藏着这么多玄机,真不是盖的!需要多么扎实的基本功才能写一个完美的strcpy啊!

  (4)对strlen的掌握,它没有包括字符串末尾的''。

  读者看了不同分值的strcpy版本,应该也可以写出一个10分的strlen函数了,完美的版本为: int strlen( const char *str ) //输入参数const

{
 assert( strt != NULL ); //断言字符串地址非0
 int len;
 while( (*str++) != '' )
 {
  len++;
 }
 return len;
}

  试题4:

void GetMemory( char *p )
{
 p = (char *) malloc( 100 );
}

void Test( void )
{
 char *str = NULL;
 GetMemory( str );
 strcpy( str, "hello world" );
 printf( str );
}

  试题5:

char *GetMemory( void )
{
 char p[] = "hello world";
 return p;
}

void Test( void )
{
 char *str = NULL;
 str = GetMemory();
 printf( str );
}

  试题6:

void GetMemory( char **p, int num )
{
 *p = (char *) malloc( num );
}

void Test( void )
{
 char *str = NULL;
 GetMemory( &str, 100 );
 strcpy( str, "hello" );
 printf( str );
}

  试题7:

void Test( void )
{
 char *str = (char *) malloc( 100 );
 strcpy( str, "hello" );
 free( str );
 ... //省略的其它语句
}

  解答:

  试题4传入中GetMemory( char *p )函数的形参为字符串指针,在函数内部修改形参并不能真正的改变传入形参的值,执行完

char *str = NULL;
GetMemory( str );

  后的str仍然为NULL;

  试题5中

char p[] = "hello world";
return p;

  的p[]数组为函数内的局部自动变量,在函数返回后,内存已经被释放。这是许多程序员常犯的错误,其根源在于不理解变量的生存期。

  试题6的GetMemory避免了试题4的问题,传入GetMemory的参数为字符串指针的指针,但是在GetMemory中执行申请内存及赋值语句

*p = (char *) malloc( num );

  后未判断内存是否申请成功,应加上:

if ( *p == NULL )
{
 ...//进行申请内存失败处理
}

  试题7存在与试题6同样的问题,在执行

char *str = (char *) malloc(100);

  后未进行内存是否申请成功的判断;另外,在free(str)后未置str为空,导致可能变成一个“野”指针,应加上:

str = NULL;

  试题6的Test函数中也未对malloc的内存进行释放。

  剖析:

  试题4~7考查面试者对内存操作的理解程度,基本功扎实的面试者一般都能正确的回答其中50~60的错误。但是要完全解答正确,却也绝非易事。

  对内存操作的考查主要集中在:

  (1)指针的理解;

  (2)变量的生存期及作用范围;

  (3)良好的动态内存申请和释放习惯。

  再看看下面的一段程序有什么错误:

swap( int* p1,int* p2 )
{
 int *p;
 *p = *p1;
 *p1 = *p2;
 *p2 = *p;
}

  在swap函数中,p是一个“野”指针,有可能指向系统区,导致程序运行的崩溃。在VC++中DEBUG运行时提示错误“Access Violation”。该程序应该改为:

swap( int* p1,int* p2 )
{
 int p;
 p = *p1;
 *p1 = *p2;
 *p2 = p;
}

  3.内功题

  试题1:分别给出BOOL,int,float,指针变量 与“零值”比较的 if 语句(假设变量名为var)

  解答:

   BOOL型变量:if(!var)

   int型变量: if(var==0)

   float型变量:

   const float EPSINON = 0.00001;

   if ((x >= - EPSINON) && (x <= EPSINON)

   指针变量:  if(var==NULL)

  剖析:

  考查对0值判断的“内功”,BOOL型变量的0判断完全可以写成if(var==0),而int型变量也可以写成if(!var),指针变量的判断也可以写成if(!var),上述写法虽然程序都能正确运行,但是未能清晰地表达程序的意思。


   一般的,如果想让if判断一个变量的“真”、“假”,应直接使用if(var)、if(!var),表明其为“逻辑”判断;如果用if判断一个数值型变 量(short、int、long等),应该用if(var==0),表明是与0进行“数值”上的比较;而判断指针则适宜用if(var==NULL), 这是一种很好的编程习惯。

  浮点型变量并不精确,所以不可将float变量用“==”或“!=”与数字比较,应该设法转化成“>=”或“<=”形式。如果写成if (x == 0.0),则判为错,得0分。

  试题2:以下为Windows NT下的32位C++程序,请计算sizeof的值

void Func ( char str[100] )
{
 sizeof( str ) = ?
}

void *p = malloc( 100 );
sizeof ( p ) = ?

  解答:

sizeof( str ) = 4
sizeof ( p ) = 4

  剖析:

  Func ( char str[100] )函数中数组名作为函数形参时,在函数体内,数组名失去了本身的内涵,仅仅只是一个指针;在失去其内涵的同时,它还失去了其常量特性,可以作自增、自减等操作,可以被修改。

  数组名的本质如下:

  (1)数组名指代一种数据结构,这种数据结构就是数组;

  例如:

char str[10];
cout << sizeof(str) << endl;

  输出结果为10,str指代数据结构char[10]。

  (2)数组名可以转换为指向其指代实体的指针,而且是一个指针常量,不能作自增、自减等操作,不能被修改;

char str[10];
str++; //编译出错,提示str不是左值 

  (3)数组名作为函数形参时,沦为普通指针。

  Windows NT 32位平台下,指针的长度(占用内存的大小)为4字节,故sizeof( str ) 、sizeof ( p ) 都为4。

  试题3:写一个“标准”宏MIN,这个宏输入两个参数并返回较小的一个。另外,当你写下面的代码时会发生什么事?

least = MIN(*p++, b);

  解答:

#define MIN(A,B) ((A) <= (B) ? (A) : (B))

  MIN(*p++, b)会产生宏的副作用

  剖析:

  这个面试题主要考查面试者对宏定义的使用,宏定义可以实现类似于函数的功能,但是它终归不是函数,而宏定义中括弧中的“参数”也不是真的参数,在宏展开的时候对“参数”进行的是一对一的替换。

  程序员对宏定义的使用要非常小心,特别要注意两个问题:

  (1)谨慎地将宏定义中的“参数”和整个宏用用括弧括起来。所以,严格地讲,下述解答:

#define MIN(A,B) (A) <= (B) ? (A) : (B)
#define MIN(A,B) (A <= B ? A : B )

  都应判0分;

  (2)防止宏的副作用。

  宏定义#define MIN(A,B) ((A) <= (B) ? (A) : (B))对MIN(*p++, b)的作用结果是:

((*p++) <= (b) ? (*p++) : (*p++))

  这个表达式会产生副作用,指针p会作三次++自增操作。

  除此之外,另一个应该判0分的解答是:

#define MIN(A,B) ((A) <= (B) ? (A) : (B));

  这个解答在宏定义的后面加“;”,显示编写者对宏的概念模糊不清,只能被无情地判0分并被面试官淘汰。

  试题4:为什么标准头文件都有类似以下的结构?

#ifndef __INCvxWorksh
#define __INCvxWorksh
#ifdef __cplusplus

extern "C" {
#endif
/*...*/
#ifdef __cplusplus
}

#endif
#endif /* __INCvxWorksh */

  解答:

  头文件中的编译宏

#ifndef __INCvxWorksh
#define __INCvxWorksh
#endif

  的作用是防止被重复引用。

  作为一种面向对象的语言,C++支持函数重载,而过程式语言C则不支持。函数被C++编译后在symbol库中的名字与C语言的不同。例如,假设某个函数的原型为:

void foo(int x, int y);


  该函数被C编译器编译后在symbol库中的名字为_foo,而C++编译器则会产生像_foo_int_int之类的名字。_foo_int_int这样的名字包含了函数名和函数参数数量及类型信息,C++就是考这种机制来实现函数重载的。

  为了实现C和C++的混合编程,C++提供了C连接交换指定符号extern "C"来解决名字匹配问题,函数声明前加上extern "C"后,则编译器就会按照C语言的方式将该函数编译为_foo,这样C语言中就可以调用C++的函数了。

 试题5:编写一个函数,作用是把一个char组成的字符串循环右移n个。比如原来是“abcdefghi”如果n=2,移位后应该是“hiabcdefgh”

  函数头是这样的:

//pStr是指向以''结尾的字符串的指针
//steps是要求移动的n

void LoopMove ( char * pStr, int steps )
{
 //请填充...
}

  解答:

  正确解答1:

void LoopMove ( char *pStr, int steps )
{
 int n = strlen( pStr ) - steps;
 char tmp[MAX_LEN];
 strcpy ( tmp, pStr + n );
 strcpy ( tmp + steps, pStr);
 *( tmp + strlen ( pStr ) ) = '';
 strcpy( pStr, tmp );
}

  正确解答2:

void LoopMove ( char *pStr, int steps )
{
 int n = strlen( pStr ) - steps;
 char tmp[MAX_LEN];
 memcpy( tmp, pStr + n, steps );
 memcpy(pStr + steps, pStr, n );
 memcpy(pStr, tmp, steps );
}

  剖析:

  这个试题主要考查面试者对标准库函数的熟练程度,在需要的时候引用库函数可以很大程度上简化程序编写的工作量。

  最频繁被使用的库函数包括:

  (1) strcpy

  (2) memcpy

  (3) memset

  试题6:已知WAV文件格式如下表,打开一个WAV文件,以适当的数据结构组织WAV文件头并解析WAV格式的各项信息。

  WAVE文件格式说明表

偏移地址 字节数 数据类型 内 容
文件头

00H 4 Char "RIFF"标志
04H 4 int32 文件长度
08H 4 Char "WAVE"标志
0CH 4 Char "fmt"标志
10H 4 过渡字节(不定)
14H 2 int16 格式类别
16H 2 int16 通道数
18H 2 int16 采样率(每秒样本数),表示每个通道的播放速度
1CH 4 int32 波形音频数据传送速率
20H 2 int16 数据块的调整数(按字节算的)
22H 2 每样本的数据位数
24H 4 Char 数据标记符"data"
28H 4 int32 语音数据的长度

  解答:

  将WAV文件格式定义为结构体WAVEFORMAT:

typedef struct tagWaveFormat
{
 char cRiffFlag[4];
 UIN32 nFileLen;
 char cWaveFlag[4];
 char cFmtFlag[4];
 char cTransition[4];
 UIN16 nFormatTag ;
 UIN16 nChannels;
 UIN16 nSamplesPerSec;
 UIN32 nAvgBytesperSec;
 UIN16 nBlockAlign;
 UIN16 nBitNumPerSample;
 char cDataFlag[4];
 UIN16 nAudioLength;

} WAVEFORMAT;

  假设WAV文件内容读出后存放在指针buffer开始的内存单元内,则分析文件格式的代码很简单,为:

WAVEFORMAT waveFormat;
memcpy( &waveFormat, buffer,sizeof( WAVEFORMAT ) );

  直接通过访问waveFormat的成员,就可以获得特定WAV文件的各项格式信息。

  剖析:

  试题6考查面试者组织数据结构的能力,有经验的程序设计者将属于一个整体的数据成员组织为一个结构体,利用指针类型转换,可以将memcpy、memset等函数直接用于结构体地址,进行结构体的整体操作。 透过这个题可以看出面试者的程序设计经验是否丰富。

  试题7:编写类String的构造函数、析构函数和赋值函数,已知类String的原型为:

class String
{
 public:
  String(const char *str = NULL); // 普通构造函数
  String(const String &other); // 拷贝构造函数
  ~ String(void); // 析构函数
  String & operate =(const String &other); // 赋值函数
 private:
  char *m_data; // 用于保存字符串
};

  解答:

//普通构造函数

String::String(const char *str)
{
 if(str==NULL)
 {
  m_data = new char[1]; // 得分点:对空字符串自动申请存放结束标志''的空
  //加分点:对m_data加NULL 判断
  *m_data = '';
 }
 else
 {
  int length = strlen(str);
  m_data = new char[length+1]; // 若能加 NULL 判断则更好
  strcpy(m_data, str);
 }
}

// String的析构函数

String::~String(void)
{
 delete [] m_data; // 或delete m_data;
}

//拷贝构造函数

String::String(const String &other)    // 得分点:输入参数为const型
{
 int length = strlen(other.m_data);
 m_data = new char[length+1];     //加分点:对m_data加NULL 判断
 strcpy(m_data, other.m_data);
}

//赋值函数

String & String::operate =(const String &other) // 得分点:输入参数为const型
{
 if(this == &other)   //得分点:检查自赋值
  return *this;
 delete [] m_data;     //得分点:释放原有的内存资源
 int length = strlen( other.m_data );
 m_data = new char[length+1];  //加分点:对m_data加NULL 判断
 strcpy( m_data, other.m_data );
 return *this;         //得分点:返回本对象的引用
}

  剖析:

  能够准确无误地编写出String类的构造函数、拷贝构造函数、赋值函数和析构函数的面试者至少已经具备了C++基本功的60%以上!

  在这个类中包括了指针类成员变量m_data,当类中包括指针类成员变量时,一定要重载其拷贝构造函数、赋值函数和析构函数,这既是对C++程序员的基本要求,也是《Effective C++》中特别强调的条款。

  仔细学习这个类,特别注意加注释的得分点和加分点的意义,这样就具备了60%以上的C++基本功!

  试题8:请说出static和const关键字尽可能多的作用

  解答:

  static关键字至少有下列n个作用:

  (1)函数体内static变量的作用范围为该函数体,不同于auto变量,该变量的内存只被分配一次,因此其值在下次调用时仍维持上次的值;

  (2)在模块内的static全局变量可以被模块内所用函数访问,但不能被模块外其它函数访问;

  (3)在模块内的static函数只可被这一模块内的其它函数调用,这个函数的使用范围被限制在声明它的模块内;

  (4)在类中的static成员变量属于整个类所拥有,对类的所有对象只有一份拷贝;

  (5)在类中的static成员函数属于整个类所拥有,这个函数不接收this指针,因而只能访问类的static成员变量。


  const关键字至少有下列n个作用:

  (1)欲阻止一个变量被改变,可以使用const关键字。在定义该const变量时,通常需要对它进行初始化,因为以后就没有机会再去改变它了;

  (2)对指针来说,可以指定指针本身为const,也可以指定指针所指的数据为const,或二者同时指定为const;

  (3)在一个函数声明中,const可以修饰形参,表明它是一个输入参数,在函数内部不能改变其值;

  (4)对于类的成员函数,若指定其为const类型,则表明其是一个常函数,不能修改类的成员变量;

  (5)对于类的成员函数,有时候必须指定其返回值为const类型,以使得其返回值不为“左值”。例如:

const classA operator*(const classA& a1,const classA& a2);

  operator*的返回结果必须是一个const对象。如果不是,这样的变态代码也不会编译出错:

classA a, b, c;
(a * b) = c; // 对a*b的结果赋值

  操作(a * b) = c显然不符合编程者的初衷,也没有任何意义。

  剖析:

  惊讶吗?小小的static和const居然有这么多功能,我们能回答几个?如果只能回答1~2个,那还真得闭关再好好修炼修炼。

  这个题可以考查面试者对程序设计知识的掌握程度是初级、中级还是比较深入,没有一定的知识广度和深度,不可能对这个问题给出全面的解答。大多数人只能回答出static和const关键字的部分功能。

  4.技巧题

  试题1:请写一个C函数,若处理器是Big_endian的,则返回0;若是Little_endian的,则返回1

  解答:

int checkCPU()
{
 {
  union w
  {
   int a;
   char b;
  } c;
  c.a = 1;
  return (c.b == 1);
 }
}

  剖析:

   嵌入式系统开发者应该对Little-endian和Big-endian模式非常了解。采用Little-endian模式的CPU对操作数的存放方 式是从低字节到高字节,而Big-endian模式对操作数的存放方式是从高字节到低字节。例如,16bit宽的数0x1234在Little- endian模式CPU内存中的存放方式(假设从地址0x4000开始存放)为:

内存地址 存放内容
0x4000 0x34
0x4001 0x12

  而在Big-endian模式CPU内存中的存放方式则为:

内存地址 存放内容
0x4000 0x12
0x4001 0x34

  32bit宽的数0x12345678在Little-endian模式CPU内存中的存放方式(假设从地址0x4000开始存放)为:

内存地址 存放内容
0x4000 0x78
0x4001 0x56
0x4002 0x34
0x4003 0x12

  而在Big-endian模式CPU内存中的存放方式则为:

内存地址 存放内容
0x4000 0x12
0x4001 0x34
0x4002 0x56
0x4003 0x78

  联合体union的存放顺序是所有成员都从低地址开始存放,面试者的解答利用该特性,轻松地获得了CPU对内存采用Little-endian还是Big-endian模式读写。如果谁能当场给出这个解答,那简直就是一个天才的程序员。

  试题2:写一个函数返回1+2+3+…+n的值(假定结果不会超过长整型变量的范围)

  解答:

int Sum( int n )
{
 return ( (long)1 + n) * n / 2;  //或return (1l + n) * n / 2;
}

  剖析:
 
  对于这个题,只能说,也许最简单的答案就是最好的答案。下面的解答,或者基于下面的解答思路去优化,不管怎么“折腾”,其效率也不可能与直接return ( 1 l + n ) * n / 2相比!

int Sum( int n )
{
 long sum = 0;
 for( int i=1; i<=n; i++ )
 {
  sum += i;
 }
 return sum;
}

  所以程序员们需要敏感地将数学等知识用在程序设计中。


美国军工五巨头简介

silver6 | 13 六月, 2006 18:48


近代美国军用企业演变图 


洛克希德.马丁公司(Lockheed Martin Corporation) 

公司概况 
洛克希德.马丁作为全球最大防务商,是一家以宇航和高技术为主的跨国公司,其总部地址
是在马里兰州接近华盛顿特区的市郊。公司约有95%业务来自五角大楼,其他联邦部门,以
及对外军事贸易。2004年,洛克希德.马丁收入为355亿美元,定单总额近740亿美元。135
000名职员遍布全球56个国家,现任董事长兼首席执行官和总裁是Robert J. Stevens。 


公司历史 
1912年,格林.马丁公司创立。 
1916年,洛希德飞机制造公司创立。 
1921年,洛希德飞机制造公司改名为洛克希德飞机公司。 
1961年,格林.马丁公司与美国玛利埃塔公司合并。 
1995年洛克希得公司与马丁.玛利埃塔公司合并。 
1996年收购劳拉公司电子防务与系统集成业务。 
2000年宇航电子分部出售给英国宇航系统公司。 

军用产品 
A-10攻击机升级,F-16战机,F-22隐形战机,F-35隐形战机,F-117隐形战机,P-3反潜机
,S-3巡逻机,U-2侦察机,C-5运输机,C-130运输机,C-141运输机,“海军陆战队一号”
总统直升机,“三叉戟-2”洲际导弹,“宇宙神”系列运载火箭,“智慧女神”运载火箭
,“联合通用导弹”,“陆军战术导弹系统”,“爱国者-3”地对空导弹/“中程增程防空
系统”,“战区高空区域防空系统”,“联合空对地防区外导弹”,“风力修正布弹器”
,“轻标枪”反坦克导弹,“地狱火”反坦克导弹,“紧凑型动能导弹”,“宝石路”制
导炸弹,“多管火箭炮系统”,“高机动火炮系统”,“未来战斗系统”无人车,“濒海
战斗舰”,制导火箭弹药,制导炮弹,“宙斯盾”武器指挥系统,武器平台集成与升级,
军用卫星与空间系统,军用雷达,航空电子设备,军用通信设备,等。 


波音公司(The Boeing Company) 

公司概况 
来自依利诺易州芝加哥的波音是全球第二大防务商,并于2005年重新超越空中客车公司而
成为世界最大飞机制造商。它也是美国第一大出口企业,收入总值高达524亿美元,拥有近
152100名员工,生意遍及世界146个国家与地区。现任首席执行官是Jim McNerney。 

公司历史 
1916年,公司创立。 
1927年成立了波音航空运输公司。 
1934年公司一分为三,演变为现在的波音公司,联合航空公司,联合技术公司。 
1958年第一代民用喷气客机波音-707正式启用。 
1960年收购皮亚索奇直升机公司,成为波音伏托尔分部。 
1996年收购罗克威尔国际公司的宇航与防务业务。 
1997年与麦克唐纳.道格拉斯公司合并。 
2005年波音的火箭发动机分部洛克达因出售给联合技术公司旗下的普.惠公司。 
2005年与洛克希德.马丁公司合资创建联合发射联盟。 

公司组成 
波音分为两大集团:波音集成防务系统,波音商用机。其他子公司:波音合伙服务集团,
波音资本公司,连线公司。幻影工厂是波音公司的高级研发机构。 

军用产品 
B-1轰炸机,B-52轰炸机,P-8反潜机,E-3预警机,E-737预警机,E-4指挥机,E-6指挥机
,C-17运输机,C-40运输机,KC-10加油机,KC-135加油机,KC-767加油机,“机载激光器
”,“空军一号”总统机,C-32要员机,X-45无人战机,F-15战机,F/A-18战机,AV-8攻
击机,T-45教练机,AH-64武装直升机,CH-46运输直升机,CH-47运输直升机,V-22机,“
扫描鹰”无人机,“蜂鸟”无人直升机,“箭”/“箭-2”地对空导弹,“捕鲸叉”反舰导
弹/“斯拉姆”巡航导弹,“空射巡航导弹”,“硫黄”反坦克导弹,“民兵-3”洲际导弹
,“德尔它”系列运载火箭,“地基中端防御”,“地狱火”反坦克导弹,“杰达姆”制
导炸弹,“小直径炸弹”,“未来战斗系统”集成,“复仇者”野战防空系统,武器平台
集成与升级,军用卫星与空间系统,军用雷达,航空电子设备,军用通信设备,等。 


诺斯罗普.格鲁曼公司(Northrop Grumman Corporation) 

公司概况 
诺斯罗普.格鲁曼在全球防务商排行第三位,也是最大的雷达与军舰制造商。公司总部位于
加利福尼亚州圣地亚哥,在全世界100多个地区拥有工厂或办事机构和125400名职工,年收
入为307亿美元。 

公司历史 
1929年,诺斯罗普航空公司被联合航空运输公司收购,后并入道格拉斯飞机公司。 
1930年,格鲁曼飞机工程公司创立。 
1939年,诺斯罗普公司重新成立。 
1994年,诺斯罗普公司与格鲁曼公司合并。 
2001年收购利顿工业公司。 
2001年收购纽斯波特造船与干船坞公司。 
2002年收购TRW公司。 

公司组成 
诺斯罗普.格鲁曼下设8个业务部:电子系统,集成系统,使命系统,造船系统,纽斯波特
船厂,信息技术部,空间技术部,技术服务部。 

军用产品 
B-2隐形轰炸机,E-2预警机,E-8预警机,E-10预警机,EA-6电子战机,KC-30加油机,X-
47无人战机,“全球鹰”无人机,“火力侦察兵”无人直升机,“尼米兹级”/CVN21航空
母舰,“朱姆沃尔特级”驱逐舰,“弗吉尼亚级”核潜艇,“先进海豹输送系统”,“大
黄蜂级”/LHAR两栖突击舰,“圣安东尼级”两栖运输舰,“海上安全巡防舰“,“艾拉特
级”护卫舰,“民兵-3”导弹升级,航空靶弹,海军舰艇维修保障,武器平台集成与升级
,导弹防御系统,军用卫星与空间系统,军用雷达,航空电子设备,军用通信设备,探雷
与排雷设备,等。 



雷神公司(Raytheon Company) 

公司概况 
雷神公司是位于马塞诸塞州波士顿市郊的一家大型军工企业。公司年收入约220亿美元,其
中超过90%来自国防领域,在29个国家和地区设有工厂或销售部门,拥有8万名员工,2005
排名全球第五大防务商。现任董事长兼首席执行官是William H. Swanson。 

公司历史 
1922年,美国器械公司成立。 
1925年改名为雷神公司,Raytheon原意是“众神之光”。 
第二次世界大战起家为美军制造雷达。 
1945年发明微波炉。 
1948年开始制造导弹。 
1980年收购比奇飞机公司。 
1993年收购了英国宇航公司的霍克商务机生产线。 
1990年代中期收购了德州仪器公司的防务部门E-系统。 
1997年收购通用汽车公司休斯电子分部的军事业务,包括原通用动力公司的导弹业务,德
尔科电子公司防务部。 

公司组成 
雷神分成7个分部:集成防务系统,情报与信息系统,导弹系统,网络中心系统,空间与航
空系统,雷神飞机公司,雷神技术服务有限责任公司。 

军用产品 
“幼畜”空对地导弹,“高速反辐射导弹”,“先进巡航导弹”,“联合防区外武器”,
“战斧”巡航导弹,“响尾蛇”空对空导弹,“先进中距空对空导弹”,“爱国者”/“爱
国者-2”地对空导弹,“毒刺”地对空导弹,“精确攻击导弹”,“动能拦截弹”,“轻
标枪”反坦克导弹,“陶-2”反坦克导弹,“标准-2”/“标准-3”舰对空导弹,“海麻雀
”舰对空导弹,“拉姆”舰对空导弹,“宝石路”制导炸弹,“神剑”制导炮弹,T-6“联
合初级飞机训练系统”,“密集阵”舰防系统,MK45鱼雷,武器平台集成与升级,导弹防
御系统,军用雷达,军用传感器,舰载武器指挥系统,航空电子设备,军用通信设备,夜
视仪器,等。 


通用动力公司(General Dynamics Corporation) 

公司概况 
通用动力是家综合性防务集团公司,总部在弗吉尼亚州巴尔的摩市郊。2005年该公司位居
全球第六大防务商,在世界各地有72200多名职工,收入总值达到212亿美元。现任董事长
兼首席执行官是Nicholas D. Chabraja。 

公司历史 
1899年,电船公司成立。 
1952年改名为通用动力公司。 
1953年与康维尔公司合并。 
1982年收购克莱斯勒公司防务部。 
1991年数据系统分部出售给计算机科学公司。 
1992年战术导弹业务出售给通用汽车公司休斯电子分部。 
1992年赛斯纳商务机生产线出售给达信公司。 
1993年军用飞机业务出售给洛克希德.马丁公司;同年空间系统分部出售给马丁.玛利埃塔
公司。 
1995年收购有百年历史的巴斯钢铁厂。 
1996年康维尔分部出售给麦克唐纳.道格拉斯公司。 
1998年收购另一家大型船厂国家钢铁与造船公司。 
1999年收购湾流宇航公司。 
2001年收购摩托罗拉公司的集成信息系统集团。 
2003年收购通用汽车公司防务部及其在加拿大和欧洲的子公司;同年收购奥地利斯泰尔-戴
姆勒-普希公司与西班牙国营企业聖大巴巴拉系統公司. 
2005年收购威尔第公司。 

公司组成 
通用动力目前由4个分部和2个子公司组成:通用动力宇航集团,通用动力战斗系统,通用
动力海洋系统,通用动力信息系统与技术部,自由人能源公司,材料服务公司。 

军用产品 
“艾布拉姆斯”坦克,远征战车,未来战斗系统作战车/无人车,“食人鱼”/“斯瑞克”
/LAV系列轮式装甲车,“潘多尔”轮式装甲车,“皮萨罗”步兵战车,“海狼”级核潜艇
,“洛杉矶级”核潜艇,“弗吉尼亚级”核潜艇,“俄亥俄级”核潜艇,“伯克级”驱逐
舰,“刘易斯与克拉客级”干货船,“濒海战斗舰”,“九头怪-70”火箭,“远征火力支
援系统”,迫击炮,坦克炮,机炮/机枪,海军舰艇维修保障,各类口径弹药,导弹部件,
军用通信电子设备,核生化防御设备,等。


经典面试问题回答思路

silver6 | 07 六月, 2006 19:37

面试过程中,面试官会向应聘者发问,而应聘者的回答将成为面试官考虑是否接受他的重要依据。对应聘者而言,了解这些问题背后的“猫腻”至关重要。本文对面试中经常出现的一些典型问题进行了整理,并给出相应的回答思路和参考答案。读者无需过分关注分析的细节,关键是要从这些分析中“悟”出面试的规律及回答问题的思维方式,达到“活学活用”。
  
    问题一:“请你自我介绍一下”
    思路: 1、这是面试的必考题目。 2、介绍内容要与个人简历相一致。 3、表述方式上尽量口语化。 4、要切中要害,不谈无关、无用的内容。 5、条理要清晰,层次要分明。 6、事先最好以文字的形式写好背熟。
    问题二:“谈谈你的家庭情况”
    思路: 1、 况对于了解应聘者的性格、观念、心态等有一定的作用,这是招聘单位问该问题的主要原因。 2、 简单地罗列家庭人口。 3、宜强调温馨和睦的家庭氛围。 4、 宜强调父母对自己教育的重视。 5、 宜强调各位家庭成员的良好状况。 6、 宜强调家庭成员对自己工作的支持。 7、 宜强调自己对家庭的责任感。
    问题三:“你有什么业余爱好?”
    思路: 1、业余爱好能在一定程度上反映应聘者的性格、观念、心态,这是招聘单位问该问题的主要原因。 2、 最好不要说自己没有业余爱好。 3、不要说自己有那些庸俗的、令人感觉不好的爱好。 4、 最好不要说自己仅限于读书、听音乐、上网,否则可能令面试官怀疑应聘者性格孤僻。 5、最好能有一些户外的业余爱好来“点缀”你的形象。
    问题四:“你最崇拜谁?”
    思路: 1、最崇拜的人能在一定程度上反映应聘者的性格、观念、心态,这是面试官问该问题的主要原因。 2、 不宜说自己谁都不崇拜。 3、 不宜说崇拜自己。 4、 不宜说崇拜一个虚幻的、或是不知名的人。 5、 不宜说崇拜一个明显具有负面形象的人。 6、所崇拜的人人最好与自己所应聘的工作能“搭”上关系。 7、 最好说出自己所崇拜的人的哪些品质、哪些思想感染着自己、鼓舞着自己。
    问题五:“你的座右铭是什么?” 思路: 1、座右铭能在一定程度上反映应聘者的性格、观念、心态,这是面试官问这个问题的主要原因。 2、不宜说那些医引起不好联想的座右铭。 3、不宜说那些太抽象的座右铭。 4、不宜说太长的座右铭。 5、座右铭最好能反映出自己某种优秀品质。 6、 参考答案——“只为成功找方法,不为失败找借口”
    问题六:“谈谈你的缺点”
    思路: 1、 不宜说自己没缺点。 2、 不宜把那些明显的优点说成缺点。 3、 不宜说出严重影响所应聘工作的缺点。 4、 不宜说出令人不放心、不舒服的缺点。 5、可以说出一些对于所应聘工作“无关紧要”的缺点,甚至是一些表面上看是缺点,从工作的角度看却是优点的缺点。
    问题七:“谈一谈你的一次失败经历” 思路: 1、 不宜说自己没有失败的经历。 2、 不宜把那些明显的成功说成是失败。 3、 不宜说出严重影响所应聘工作的失败经历, 4、所谈经历的结果应是失败的。 5、 宜说明失败之前自己曾信心白倍、尽心尽力。 6、 说明仅仅是由于外在客观原因导致失败。 7、失败后自己很快振作起来,以更加饱满的热情面对以后的工作。
    问题八:“你为什么选择我们公司?”
    思路: 1、 面试官试图从中了解你求职的动机、愿望以及对此项工作的态度。 2、 建议从行业、企业和岗位这三个角度来回答。 3、 参考答案——“我十分看好贵公司所在的行业,我认为贵公司十分重视人才,而且这项工作很适合我,相信自己一定能做好。”
    问题九:“对这项工作,你有哪些可预见的困难?”
    思路: 1、 不宜直接说出具体的困难,否则可能令对方怀疑应聘者不行。 2、可以尝试迂回战术,说出应聘者对困难所持有的态度——“工作中出现一些困难是正常的,也是难免的,但是只要有坚忍不拔的毅力、良好的合作精神以及事前周密而充分的准备,任何困难都是可以克服的。”
    问题十:“如果我录用你,你将怎样开展工作”
    思路: 1、如果应聘者对于应聘的职位缺乏足够的了解,最好不要直接说出自己开展工作的具体办法, 2、可以尝试采用迂回战术来回答,如“首先听取领导的指示和要求,然后就有关情况进行了解和熟悉,接下来制定一份近期的工作计划并报领导批准,最后根据计划开展工作。”
    问题十一:“与上级意见不一是,你将怎么办?”
  思路: 1、一般可以这样回答“我会给上级以必要的解释和提醒,在这种情况下,我会服从上级的意见。” 2、如果面试你的是总经理,而你所应聘的职位另有一位经理,且这位经理当时不在场,可以这样回答:“对于非原则性问题,我会服从上级的意见,对于涉及公司利益的重大问题,我希望能向更高层领导反映。”
  
  问题十二:“我们为什么要录用你?”
    思路: 1、应聘者最好站在招聘单位的角度来回答。 2、 招聘单位一般会录用这样的应聘者:基本符合条件、对这份共组感兴趣、有足够的信心。 3、如“我符合贵公司的招聘条件,凭我目前掌握的技能、高度的责任感和良好的饿适应能力及学习能力 ,完全能胜任这份工作。我十分希望能为贵公司服务,如果贵公司给我这个机会,我一定能成为贵公司的栋梁!”
    问题十三:“你能为我们做什么?”
    思路: 1、 基本原则上“投其所好”。 2、 回答这个问题前应聘者最好能“先发制人”,了解招聘单位期待这个职位所能发挥的作用。 3、 应聘者可以根据自己的了解,结合自己在专业领域的优势来回答这个问题。
    问题十四:“你是应届毕业生,缺乏经验,如何能胜任这项工作?”
    思路: 1、 如果招聘单位对应届毕业生的应聘者提出这个问题,说明招聘单位并不真正在乎“经验”,关键看应聘者怎样回答。 2、对这个问题的回答最好要体现出应聘者的诚恳、机智、果敢及敬业。 3、如“作为应届毕业生,在工作经验方面的确会有所欠缺,因此在读书期间我一直利用各种机会在这个行业里做兼职。我也发现,实际工作远比书本知识丰富、复杂。但我有较强的责任心、适应能力和学习能力,而且比较勤奋,所以在兼职中均能圆满完成各项工作,从中获取的经验也令我受益非浅。请贵公司放心,学校所学及兼职的工作经验使我一定能胜任这个职位。”
    问题十五:“你希望与什么样的上级共事?”
    思路: 1、通过应聘者对上级的“希望”可以判断出应聘者对自我要求的意识,这既上一个陷阱,又上一次机会。 2、 最好回避对上级具体的希望,多谈对自己的要求。 3、 如“做为刚步入社会新人,我应该多要求自己尽快熟悉环境、适应环境,而不应该对环境提出什么要求,只要能发挥我的专长就可以了。”
    问题十六:“您在前一家公司的离职原因是什么?”
    思路: 1、 最重要的是:应聘者要使找招聘单位相信,应聘者在过往的单位的“离职原因”在此家招聘单位里不存在。 2、避免把“离职原因”说得太详细、太具体。 3、不能掺杂主观的负面感受,如“太幸苦”、“人际关系复杂”、“管理太混乱”、“公司不重视人才”、“公司排斥我们某某的员工”等。 4、但也不能躲闪、回避,如“想换换环境”、“个人原因”等。 5、 不能涉及自己负面的人格特征,如不诚实、懒惰、缺乏责任感、不随和等。 6、尽量使解释的理由为应聘者个人形象添彩。 7、如“我离职是因为这家公司倒闭。我在公司工作了三年多,有较深的感情。从去年始,由于市场形势突变,公司的局面急转直下。到眼下这一步我觉得很遗憾,但还要面对显示,重新寻找能发挥我能力的舞台。” 同一个面试问题并非只有一个答案,而同一个答案并不是在任何面试场合都有效,关键在于应聘者掌握了规律后,对面试的具体情况进行把握,有意识地揣摩面试官提出问题的心理背景,然后投其所好。

老师的语录

silver6 | 22 五月, 2006 09:18

1. 兄弟不幸堕落到考研辅导这个行列,今年是第三年。 转自81.china.com 2. 兄弟辅导的中心思想是“国家意志,精神高度,加分意识”。 转自81.china.com 3. 所谓中产阶级,就是在你所生活的那个城市的中心地带,有一所100平 转自81.china.com 以上的flat,有一个亲爱的爱人叫darling,有一个可爱的孩子叫baby,有一辆小汽车,至少是宝来这个级别的叫car,嗯,还有一条经常坐在轿车的副驾驶位置上的小狗叫pet. 转自81.china.com 4. 如果我们这个国家在未来的十年内不出现重大的异变,比如台海战争, 转自81.china.com 比如比萨斯还要难以控制的疾病,那么在座的百分之九十九都会顺利地成长为中产阶级的一员;如果高中以下文化程度的人在未来的十年内,他们本身不出现重大的异变,比如将自己的学历从高中搞到专科、本科,那么,他们当中百分之九十九的将不会顺利地成长为这个阶层的一员。 转自81.china.com 5. 所谓小蜜搞乱了家庭,党校搞乱了文凭。 转自81.china.com 6. 毛泽东什么人?五千年出一个的牛人!今天后生小子菲薄他的很多,兄 转自81.china.com 弟以为,如果不是别有用心,便是思考问题不再一个层面上。 转自81.china.com 7. 短短的浅浅的窄窄的海峡。 转自81.china.com 8. 并不是每个国家都像我们伟大的祖国这样大。 转自81.china.com 9. 一对对恋人,是校园里最美的风景。如果在考研的过程中,在辅导班上 转自81.china.com 你能成就一段姻缘的话,研究生考上了可以不上的。 转自81.china.com 10. 女生傍什么大款?傍大款,仅仅从技术的角度来考虑也是最不安全的。 转自81.china.com 11. 从自己的同学中去寻找自己的恋人,然后两个人相互鼓励着温暖着打拼 转自81.china.com 十年,共同成长为我们这个社会的中产阶级的一员,然后再坐在摇椅里慢慢的看着对方慢慢老去,这是一件多么浪漫的事。 转自81.china.com 12. 你们这个年龄的女孩子,最多叫清纯,漂亮,不能叫美。高耀洁叫美, 转自81.china.com 宋庆龄叫美,袁隆平叫美,周总理,那是美的极致。兄弟往这里一站,约略也可以叫做美的典型。 转自81.china.com 13. 你们是知识女性,应该学会用知识打造自己,培育塑造自己,让自己越 转自81.china.com 老越美。 转自81.china.com 14. 西方国家的金融制度再不健全,都比我们健全。索罗斯在他们那里,毕 转自81.china.com 竟只有一个,但在我们这里,有无数个。 转自81.china.com 15. 问题不在于有没有失业,也不在于失业的多寡,而在于如何对待失业。 转自81.china.com 16. 在每一个打劫者的背后,几乎都有一个令人心酸的故事。他们没文化 转自81.china.com 阿,同志们。如果他们知道当年我们的红军是如何筹饷的时候,他们也许就不会犯这样愚蠢的错误。兄弟当时,几乎有告诉他们应该打劫什么人的冲动。 转自81.china.com 17. 赵铁锤出现的频率比总理还高。 转自81.china.com 18. 天堂里没有煤矿,兄弟祝他们在天堂里幸福。 转自81.china.com 19. 朝鲜战争的意义就在于将中国从近代以来颓靡的国运中给超拔了出来。 转自81.china.com 20. 中国共产党的第一代领导人,放屁都能砸个坑。 转自81.china.com 21. 要打出中国的军威国威来,要让他们知道山神爷是石头做的。 转自81.china.com 22. 里根提出以实力求和平大约相当于黎叔说21世纪什么最重要?人才。 转自81.china.com 23. 美国人连续十一年的关于中国人权状况的白皮书,在客观上刺激了中国 转自81.china.com 的人权进步,但那不是美国人的主观意图。 转自81.china.com 24. 决定一个国家对外政策的核心原因是国家利益。 转自81.china.com 25. 看到美国的时候,把八个字送给它。 转自81.china.com 26. 每个城市都有那么多的色情场所,我郑重地敬告你,哪些地方不是我们 转自81.china.com 这个阶层的人去的。如果你一定要去,也一定要注意安全。 转自81.china.com 27. 16个天安门广场大的嘴巴一天要张三次。 转自81.china.com 28. 你们这些女生看不上你们同班同年级的男生这很正常,你知道吗?你们的心理年龄要比同龄的男生大那么三到五岁,只要看着顺眼,不妨打造他,鼓励他,培养他,使他的心理年龄尽快和你一致起来。那时候,你知道,你的身上不仅洋溢着恋人的光芒,还洋溢着圣母玛利亚的光芒阿。 转自81.china.com 29. 器物层面,制度层面,文化层面。 转自81.china.com 30. 日本人最早跟中国学,但是中国文化里那个仁爱的传统它没有学到;战后,日本人又跟西方学,但基督教文明中的忏悔意识它也没有学到。于是它成为今天这样一个不伦不类的样子。 转自81.china.com 31. 你想搞谁就搞谁,而我连个莱温斯基都搞不定。 转自81.china.com 32. 普京讥讽道:“我需要钱吗?”思考问题就不在一个层面上。 转自81.china.com 33. 当官的一人肩上一把小铁锨,边走边挖坑。 转自81.china.com 34. 像捐钱这样的小事,留给兄弟去做。 转自81.china.com 35. 放屁,他心疼。国有资产流失了那么多,他早该上吊了。 转自81.china.com 36. 富豪榜,黑名单。消失。5-8年。 转自81.china.com 37. 一个学者考虑问题和一个政治家考虑问题,它当然又不在一个层次上。 转自81.china.com 38. 桔生淮南淮北还不一样,何况是一种制度? 转自81.china.com 39. 委员会的单数制与秘密投票箱。 转自81.china.com 40. 金钱政治是进步还是落后? 转自81.china.com 41. 正义有两个原则,一个是平等,一个是差异。罗尔斯于1972年总结的 转自81.china.com 。但我们的老祖宗在实践中早就实践了。算命先生的祖师爷叫徐子平,北宋人,当年传授这个技艺的时候,定下的行规就是只能传给失明的瞎子。所体现的就是这个正义原则的差异原则。但是今天,明眼的也抢瞎子的饭碗了。那是要遭天谴的。 转自81.china.com 42. 是汉化还是我们大家一起被西化了阿? 转自81.china.com 43. 社会演化到今天,我们的妇女何止顶半边天,顶大半个天,顶整个天 转自81.china.com 了。你们不知道,兄弟在家里是一点地位都没有的。 转自81.china.com 44. 我上管天,下管地,中间还要管空气。 转自81.china.com 45. 两千年的文化给我们留下了一个仁的传统;毛泽东给我们留下了一个平 转自81.china.com 等的传统,尽管这个平等的传统是没有多少自由的平等;而小平给我们留下了一个自由的传统,而这个自由的传统又是缺少平等的自由。兄弟想,未来的中国的发展走向,也许是仁、平等、自由这样三种传统的融合的一种发展走向吧。 转自81.china.com 46. 中美关系的大门是被美国人从外面给锸死的。 转自81.china.com 47. 尼克松走下飞机的舷梯,冲着迎接他的周总理伸出手去,她说的第一句 转自81.china.com 话是什么?“我为美国利益而来”。人家不是因为我们总理长得帅,来看帅哥来了。 转自81.china.com 48. 美国,也仅仅是在最近的10几20年里,才逐渐长成了人样。此前,他 转自81.china.com 就是禽兽,就是豺狼。 转自81.china.com 49. 在美国1787年宪法里,他们说妇女不是人,黑人不是一个完整的人。 转自81.china.com 美国妇女获得和男人一样的选举权是在1920年,而黑人,你们知道吗丁路德金的著名的演讲。他被暗杀是在1968年。 转自81.china.com 50. 美国人均汽车是一点三辆,我们有可能赶上美国吗?那是个什么概念? 转自81.china.com 陈淮算过一笔帐:全世界所有的汽车制造厂要连续生产26年,才可以满足中国人均一点三辆的汽车需求。 转自81.china.com 51. 别了,司徒雷登,那是写给谁看的?不是蒋介石,不是美国人,而是苏 转自81.china.com 联人! 转自81.china.com 52. 恐怖主义对于美国来说是锥子,而中国的壮大则是刀子。 转自81.china.com 53. 和平崛起或曰发展,是我们的一厢情愿,它的能否实现,并不仅仅取决 转自81.china.com 于我们。兄弟以为,未来的五十年,也许有三场仗是不能不打的。 转自81.china.com 转自81.china.com 毛泽东思想概论 转自81.china.com 转自81.china.com 54. 所谓马克思主义的中国化,也就是今天某些高人所讲的本土化。 转自81.china.com 55. 恩格斯说,把革命归因于少数恶意者的煽动的迷信的时代已经过去了;列 转自81.china.com 宁说革命是在成熟了的危机和伟大的转折中发生出来的,换句话说,革命是被统治者逼出来的。兄弟用句篱笆女人狗里的歌词,那就是被统治者“再也不能这样活,再也不能这样过”,于是革命发生了。 转自81.china.com 56. 此地不留爷,自有留爷处。处处不留爷,爷在毛泽东时代,是去投八路。 转自81.china.com 57. 在五四运动前后,中国工人阶级的数量是200万左右;同期,中国土匪 转自81.china.com 的数量,是2200万左右。 转自81.china.com 58. 中国共产党建立了自己的武装力量之后,参加工农武装的多了,当土匪 转自81.china.com 的少了,知道原因吗?当红军八路军的死亡概率是20%,而当土匪的死亡概率是50%。 转自81.china.com 59. 以下的这些人物为毛泽东思想的形成做出了突出贡献:陈独秀,北大文 转自81.china.com 科学长,相当于今天的文学院院长或者人文社科部主任,月薪360大洋;李大钊,北大图书馆长,法学教授,月薪220大洋;毛泽东,北大图书馆的临时工,月薪9块大洋。同期,彭德怀在一家军阀的队伍里当连长,月薪5块大洋。 转自81.china.com 60. 正是在北大,毛泽东从一个激进的民主主义者完成了到共产主义者的 转自81.china.com 转变。 转自81.china.com 61. 兄弟有同学姓杜,四月里紫藤花开的时候生了个女儿,取名杜紫藤,后 转自81.china.com 改名杜滴定。 转自81.china.com 62. 知道毛泽东多大读小学吧?16岁。8岁念私塾,因为上课看小说,被老师告诉了他父亲,于是他父亲举着扫帚疙瘩满大街的追打幼小的毛泽东。毛泽东知道跑不过他父亲,于是在跑到村子中央的池塘边的时候,他不跑了。对着追上来的气喘吁吁的父亲说:“你再追,我就跳下池塘,死给你看。”他父亲妥协了,答应不打他。于是,8岁的毛泽东第一次尝到了斗争的好处。16岁的时候,他听说在距他老家30里的地方开办了一所现代意义上的小学叫东山小学的时候,他对ta父亲说: “老爸,我要去念小学。”他爸爸上上下下打量了他好几眼,说:“你看你这么高的个子,比我还高;又是长子,你理应帮我打理一下这个家承担起你做长子的责任来,去念什么啥子小学?”毛回答:“我一定要去。” 转自81.china.com “如果我一定不同意呢?”他父亲瞪着眼珠子问。 转自81.china.com “那我就死给你看!” 转自81.china.com 谈判的结果是他父亲每月给他两块大洋,一身短衫,一身长衫,不给草鞋,允许他再念两年。于是毛泽东高高兴兴地穿着短衫,背着长衫,怀揣着两块大洋,光着脚丫子,去东山小学念小学去了。 转自81.china.com 63. 他不仅丝毫的不以为意,还会冲着你渐去渐远的身影由衷地赞叹"啊,有 转自81.china.com 个性!” 转自81.china.com 64. 走,我带你去吧。 转自81.china.com 65. 像人大那样的衰校还有没有必要考啊? 转自81.china.com 66. 一辈子都追求小概率的事件,这种人生是比较郁闷的;一辈子一次都不 转自81.china.com 追求小概率事件,这样的人生是最郁闷的。 转自81.china.com 67. 一个没有远方的人是注定走不了多远的。 转自81.china.com 68. 思路决定出路。 转自81.china.com 69. 上门板,洗澡避女人青山大学毕业的。” 转自81.china.com 71. 毛泽东思想在抗战时期成熟的原因,年青算不算?江青算不算?要考 转自81.china.com 研,趁年轻;要考研,靠爱情。-----找个恋人吧,还没有找到的。 转自81.china.com 72. 西点军校,林彪,失散的儿子,两个鸡蛋,士兵委员会,张如心,林 转自81.china.com 心如。 转自81.china.com 73. 橘子七八瓣。 转自81.china.com 74. 如果7个人人中,只有你一个人考,我可以负责任的告诉你,你死定了。 转自81.china.com 75. 以斗争求团结则团结存,以妥协退让求团结则团结亡。 转自81.china.com 76. 有时候,是需要以身体的碰撞来达到一种新的平衡的。 转自81.china.com 77. 所谓成功,其实就是一种习惯。 转自81.china.com 78. 当我们这个国家走上依法治国的路径的时候,所谓人民内部矛盾的命题 转自81.china.com 也就应该成为历史的命题了。 转自81.china.com 79. 建设社会主义没有经验,历史该轮到毛泽东犯错误了,毛泽东也就果然 转自81.china.com 犯了错误。中国的,乃至世界的历史,我们看到,它就是在左右摇摆中蹒跚而行的。 转自81.china.com 80. 梁漱溟说,主席,你发烧37度。 转自81.china.com 81. 党史上称是“凯歌行进的年代”,我们的文艺工作者描述是“激情燃烧 转自81.china.com 的岁月”。 转自81.china.com 82. 想想,兄弟们,刚刚建国的时候我们能生产什么?我们除了孩子几乎什 转自81.china.com 么都不能生产。 转自81.china.com 83. 政治/经济/文化,这是分析问题的三个基本方面。请记住:仅仅是为了 转自81.china.com 研究叙述的方便,我们才这样区分;事实上,它们并不截然两分或三分。 转自81.china.com 84. 马克思给我们提供了两对分析问题的框架。社会学之父,政治社会学 转自81.china.com 之父。 转自81.china.com 85. 亚里斯多德2000年前的政治学,到今天,我们发现,过时的话不多; 转自81.china.com 但今天,有很多话,一说出来就过时;甚至还没说出来就过时了。这是大师和小丑的区别。 转自81.china.com 转自81.china.com 邓三 转自81.china.com 86. 北京1300万人,有几个是从当年的周口店下来的? 转自81.china.com 87. 烧饼五毛钱一个。李鸟。厕所。小平你好。 转自81.china.com 88. 眼镜架在鼻鼻上,双手捂在肚肚上,腰带扎在胸膛上。 转自81.china.com 89. 我在北大最豪华的也是东南亚最大的农园餐厅请你们吃每人五块钱的 转自81.china.com 盒饭。 转自81.china.com 90. 说是五块,其实请着请着就超了,至少五块五。 转自81.china.com 91. 如果要闯荡江湖的话,怀揣着一纸全日制大学本科文凭,也足以“一剑 转自81.china.com 寒九州”。 转自81.china.com 92. 兄弟一直以为,研究生考上了可以不上,但不能不考。在备考的这段日 转自81.china.com 子里,你会觉得你的心智都得到了锤炼,兄弟想,这个过程,就是所谓涅磐的过程。 转自81.china.com 93. 思考问题,就不在一个层面上。 转自81.china.com 94. 新闻联播主要是给我们这个国家的高中以下文化程度的人看的。它的作 转自81.china.com 用是鼓劲。你应该注意,新闻联播节目之后,是那档节目?天气预报。新闻联播的阳光灿烂之后,宋英杰或者杨丹马上出来告诉你此地阳关灿烂而彼地风雨交加,间或还有冰雹。他们用自然界的阴晴圆缺来影射社会生活也不可能总是春光明媚的。再接下来才是焦点访谈。告诉我,国家电视台核心的一套节目在7-8点的黄金时间段里安排这样三档节目,是不是刻意的?你会说,老师,我怎么就没想到呢?呵呵,思考问题就不在一个层面上。记住,要提升自己思考问题的层面。 转自81.china.com 95. 你应该具备的是两种眼光:一种是历史的纵深眼光;一种是宽广的世界 转自81.china.com 眼光。也就是上下五千年,纵横数万里。 转自81.china.com 96. 一个人的身高往往与他的智慧成反比。 转自81.china.com 97. 要盯着镜子里的你,至少看成是小平老人家。 转自81.china.com 98. 鸡蛋,它连小鸡都能孵出来,它什么营养能缺? 转自81.china.com 99. 一天要保证八种以上新鲜蔬菜的摄入量。 转自81.china.com 100. 韬光养晦,说白了,就是装孙子。但是,装孙子,不是为了做孙子。 转自81.china.com 101. 所谓可持续发展,就是不发断子绝孙财。这里面有一个代际公平的 转自81.china.com 问题。 转自81.china.com 102. 所谓以人为本,就是拿人当人。记住,你是人。我们是人。 转自81.china.com 103. 人治条件下,最高统治者的身边,一般有两种人。一种是野心家, 转自81.china.com 一种是唯唯诺诺的奴才。两种人谁上台,都不会给那个国家带来稳定。 转自81.china.com 104. 讲依法治国与以德治国相结合,难道我们的法律是缺德的吗? 转自81.china.com 105. 义务教育所要解决的是一个起点的公平问题。所谓免费义务教育, 转自81.china.com 那是一个笑话。 转自81.china.com 106. 我们的运动员是实验室里制造出来的运动员。 转自81.china.com 107. “兄弟”是一个有文化的词:论语里有“四海之内皆兄弟也”; 转自81.china.com 陶渊明杂咏十二首也有“落地为兄弟,何必骨肉亲?”。 转自81.china.com 108. 女生可以用“小妹以为”“小女子以为”。 转自81.china.com 109. 空格,大二号,标准的宋体字。 转自81.china.com 110. 你的英语词汇量如果仅仅有2000,兄弟就可以说:“你还有很大 转自81.china.com 的发展空间。” 转自81.china.com 111. 初级阶段的九个特征用一句话来概括,就是政治经济文化全面落 转自81.china.com 后。用我们同学的话来说就是:“白天停水,晚上停电。要米没米,要面没面。打开书本,找到答案,原来是社会主义初级阶段。往后翻,我靠,还要100年不变!” 转自81.china.com 112. 有一个技术问题不好解决。三个代表,金庸,小说创作。 转自81.china.com 113. 顾准吴敬琏的境界,兄弟也是景行行止,高山仰止,虽不能至,而 转自81.china.com 心向往之。 转自81.china.com 114. 岱年先生正是在江西农场养成了冥想的习惯,这一冥想,冥想出了 转自81.china.com 一个哲学史的大家。-----看人家怎么对待挫折的? 转自81.china.com 115. 臣民意识与公民意识。 转自81.china.com 116. 自由迁徙权。 转自81.china.com 117. 村民意识,村落共同体意识。 转自81.china.com 118. 熟人社会与陌生人社会。 转自81.china.com 119. 单位人与社会人。 转自81.china.com 120. 屁股决定脑袋。 转自81.china.com 121. 教授与叫唤的兽。 转自81.china.com 122. 处处不留爷,爷就去打劫。技术含量不高的工种。 转自81.china.com 123. 性格决定命运,胸襟决定格局,思路决定出路。 转自81.china.com 124. 胸襟要大,格局要宽。 转自81.china.com 125. 大象过河,横断截流。 转自81.china.com 126. 你一定来自那温郁的南方。 转自81.china.com 127. 你看你看你看,民主与科学顶个球。 转自81.china.com 128. 象你我这样的党员,想腐败是没有机会的。这是一个制度的制约。 转自81.china.com 129. 胡长清所创造的纪录很快被另一个人给破了。 转自81.china.com 130. 兄弟是一个单纯并热情的人,阿甘是兄弟的偶像。 转自81.china.com 131. 小拇指说:拜佛的时候,我是领队啊。 转自81.china.com 132. 悦纳自己

华为公司 java 面试题

silver6 | 11 五月, 2006 17:28

第一部分:选择题
QUESTION NO: 1
1、public class Test {
public static void changeStr(String str){
str="welcome";
}
public static void main(String[] args) {
String str="1234";
changeStr(str);
System.out.println(str);
}
}
Please write the output result :

QUESTION NO:2
1. public class Test {
2. static boolean foo(char c) {
3. System.out.print(c);
4. return true;
5. }
6. public static void main( String[] argv ) {
7. int i =0;
8. for ( foo('A'); foo('B')&&(i<2); foo('C')){
9. i++ ;
10. foo('D');
12. }
13. }
14. }
What is the result?
A. ABDCBDCB
B. ABCDABCD
C. Compilation fails.
D. An exception is thrown at runtime.

QUESTION NO: 3
1. class A {
2. protected int method1(int a, int b) { return 0; }
3. }
Which two are valid in a class that extends class A? (Choose two)
A. public int method1(int a, int b) { return 0; }
B. private int method1(int a, int b) { return 0; }
C. private int method1(int a, long b) { return 0; }
D. public short method1(int a, int b) { return 0; }
E. static protected int method1(int a, int b) { return 0; }

QUESTION NO: 4
1. public class Outer{
2. public void someOuterMethod() {
3. // Line 3
4. }
5. public class Inner{}
6. public static void main( String[]argv ) {
7. Outer o = new Outer();
8. // Line 8
9. }
10. }
Which instantiates an instance of Inner?
A. new Inner(); // At line 3
B. new Inner(); // At line 8
C. new o.Inner(); // At line 8
D. new Outer.Inner(); // At line 8//new Outer().new Inner()

QUESTION NO: 5
Which method is used by a servlet to place its session ID in a URL that is written to the servlet’s response output stream?
A. The encodeURL method of the HttpServletRequest interface.
B. The encodeURL method of the HttpServletResponse interface.
C. The rewriteURL method of the HttpServletRequest interface.
D. The rewriteURL method of the HttpServletResponse interface.

QUESTION NO: 6
Which two are equivalent? (Choose two)
A. <%= YoshiBean.size%>
B. <%= YoshiBean.getSize()%>
C. <%= YoshiBean.getProperty("size")%>
D. <jsp:getProperty id="YoshiBean" param="size"/>
E. <jsp:getProperty name="YoshiBean" param="size"/>
F. <jsp:getProperty id="YoshiBean" property="size"/>
G. <jsp:getProperty name="YoshiBean" property="size"/>

QUESTION NO: 7
Which of the following statements regarding the lifecycle of a session bean are correct?
1. java.lang.IllegalStateException is thrown if SessionContext.getEJBObject() is invoked when a stateful session bean instance is passivated.
2. SessionContext.getRollbackOnly() does not throw an exception when a session bean with bean-managed transaction demarcation is activated.
3. An exception is not thrown when SessionContext.getUserTransaction() is called in the afterBegin method of a bean with container-managed transactions.
4. JNDI access to java:comp/env is permitted in all the SessionSynchronization methods of a stateful session bean with container-managed transaction demarcation.
5. Accessing resource managers in the SessionSynchronization.afterBegin method of a stateful session bean with bean-managed transaction does not throw an exception.


第二部分:概念题
1. 描述Struts体系结构?对应各个部分的开发工作主要包括哪些?













2. XML包括哪些解释技术,区别是什么?






3. JSP有哪些内置对象和动作?它们的作用分别是什么?














4、SQL问答题
SELECT * FROM TABLE

SELECT * FROM TABLE
WHERE NAME LIKE '%%' AND ADDR LIKE '%%'
AND (1_ADDR LIKE '%%' OR 2_ADDR LIKE '%%'
OR 3_ADDR LIKE '%%' OR 4_ADDR LIKE '%%' )
的检索结果为何不同?



5、SQL问答题
表结构:
1、 表名:g_cardapply
字段(字段名/类型/长度):
g_applyno varchar 8;//申请单号(关键字)
g_applydate bigint 8;//申请日期
g_state varchar 2;//申请状态
2、 表名:g_cardapplydetail
字段(字段名/类型/长度):
g_applyno varchar 8;//申请单号(关键字)
g_name varchar 30;//申请人姓名
g_idcard varchar 18;//申请人身份证号
g_state varchar 2;//申请状态
其中,两个表的关联字段为申请单号。
题目:
1、 查询身份证号码为440401430103082的申请日期
2、 查询同一个身份证号码有两条以上记录的身份证号码及记录个数
3、 将身份证号码为440401430103082的记录在两个表中的申请状态均改为07
4、 删除g_cardapplydetail表中所有姓李的记录

public class Test {
public static void changeStr(String str){
str="welcome";
}
public static void main(String[] args) {
String str="1234";
changeStr(str);
System.out.println(str);
}
}
这一题我想他主要考查 static这个关键字,changestr是个静态的方法(类方法)那么str应该也是一个静态成员,所有的对象都是公用这样的一个成员,那么对他的修改应该是可以保持的。而为什么最后的结果却是初始值1234,我有点迷惑

终于明白了:按值传递意味着当将一个参数传递给一个函数时,函数接收的是原始值的一个副本。因此,如果函数修改了该参数,仅改变副本,而原始值保持不变。按引用传递意味着当将一个参数传递给一个函数时,函数接收的是原始值的内存地址,而不是值的副本。因此,如果函数修改了该参数,调用代码中的原始值也随之改变。

不管是在c/c++中还是在java函数调用都是传值调用,.
当参数是对象的时候,传递的是对象的引用,这个和c/c++传递指针是一个道理,在函数中改变引用本身,不会改变引用所指向的对象,而在QUESTION NO: 1中只是改变了引用,所以在main函数中输出还是原来的那个值:1234

参数是对象时传的是地址。但str="welcome";相当于str=new String("welcome");,所以原对象没变。
可以参考以下代码:
public class Test {
public int ss = 999;
public Test(int s){
ss = s;
}
public static void changeStr(Test t){
t.ss = 888;
}
public static void main(String[] args) {
Test t = new Test(999);
changeStr(t);
System.out.println(t.ss);
}
}


public class Test {
public int ss = 999;
public Test(int s){
ss = s;
}
public static void changeStr(Test t){
t = new Test(888);
}
public static void main(String[] args) {
Test t = new Test(999);
changeStr(t);
System.out.println(t.ss);
}
}

QUESTION NO:2
1. public class Test {
2. static boolean foo(char c) {
3. System.out.print(c);
4. return true;
5. }
6. public static void main( String[] argv ) {
7. int i =0;
8. for ( foo('A'); foo('B')&&(i<2); foo('C')){
9. i++ ;
10. foo('D');
12. }
13. }
14. }
What is the result?
A. ABDCBDCB
B. ABCDABCD
C. Compilation fails.
D. An exception is thrown at runtime

做一下这个吧!!

第一题终于清楚了。

对象是传引用的。但是下面还是有区别

public class test6 {

public int ss = 999;
public test6(int s){
ss = s;
}
public static void changeStr(test6 t){
t.ss = 888;
}
public static void change(test6 t){

t = new test6(222);
}
public static void main(String[] args) {

test6 t = new test6(999);
changeStr(t);
System.out.println(t.ss);
change(t);
System.out.println(t.ss);

}
}

import javax.swing.JOptionPane;
public class Test {
public void changeStr(String str){
str="welcome";
}
public void main(String[] args) {
String str="1234";
str="welcome";
//changeStr(str);
JOptionPane.showMessageDialog(null,str);
}
}

如果这样做的话结果是welcome

在我我想说的是在C语言以后所有的参数传递都是值传递,问题是传的值是是什么,而没有什么引用传递之类的东西。

关于输出为1234而不是welcome 还有待进一步分析。
我现在去上课了,回来再和大家细说

对第一题的详细分析:
Java中函数参数传递是值传递,在C语言以后的都是这样的,关键是传进来的值是什么(这一点我在上面说了到一次)。
①如果参数是基础类型,如int型的,则传进来的是int型变量的值,这个值放在堆里。
举个例子:
void fun(int i){};
int i = 5;
fun(i);
传进fun函数的是5;
②如果参数是引用类型。如String型的,则传进来的是String型变量的值,这个值放在栈里,此值是该变量将要指向的对象的地址。
举个例子:
void fun(String str0){};
String str = "Hello";
fun(str);

fun()方法调用时第一件事就是,做了一个赋值操作:str0 = str;
这个操作的结果就是将str变量的值传给str0变量的值,也就是使得str0也指向str所指向的对象。对str0所指向的对象做修改操作,也就是对str所指的对象做修改。


有了上面的两点,我想做第一个题目一定是没什么问题的了:

说明:为了方便分析我把changeStr()方法中的参数名改成了str0。
改动后的代码如下:
1.public class Test {
public static void changeStr(String str0){
str0="welcome";
}
public static void main(String[] args) {
String str="1234";
changeStr(str);
System.out.println(str);
}
}

哎,第一题没那么复杂,都说的离谱了,具体讨论请见TIJ的附录一 关于别名和引用那一章.

我们不争论JAVA到底是传值还是传引用,因为两者某种意义上都是正确的.传值的认为传递引用本身是传值行为,这没错,可我们一般把reference当成了对象,所以说成传引用也说得过去,概念就不多说了.
为什么str在changeStr之后没变?这是因为JAVA对所有的外覆类性(基本类型的对应类)是采用所谓的恒常对象(唯读对象,read- only),这些外覆类中的任何函数行为的调用都不会改变原对象,而是产生一个新对象,这就是为什么我们在需要动态增加String时要用 StringBuffer的原因.可对于我们自己所创建的对象,并没有这个"恒常"的特性,所以在这里有个"别名"现象,也就是几个引用同时指向一个对象,任何一个引用对对象的修改都将影响到其他.

在这个例子中,changeStr函数的行为其实产生了一个新的对象,函数内的str是局部性的,它指向新的对象,可对原对象没有产生任何影响.

不知道我的解释清楚了,更具体讨论请见Thinking in Java

对第一题的详细分析:
Java中函数参数传递是值传递,在C语言以后的都是这样的,关键是传进来的值是什么(这一点我在上面说了到一次)。
①如果参数是基础类型,如int型的,则传进来的是int型变量的值,这个值放在堆里。
举个例子:
void fun(int i){};
int i = 5;
fun(i);
传进fun函数的是5;
②如果参数是引用类型。如String型的,则传进来的是String型变量的值,这个值放在栈里,此值是该变量将要指向的对象的地址。
举个例子:
void fun(String str0){};
String str = "Hello";
fun(str);

fun()方法调用时第一件事就是,做了一个赋值操作:str0 = str;
这个操作的结果就是将str变量的值传给str0变量的值,也就是使得str0也指向str所指向的对象。对str0所指向的对象做修改操作,也就是对str所指的对象做修改。


有了上面的两点,我想做第一个题目一定是没什么问题的了:

说明:为了方便分析我把changeStr()方法中的参数名改成了str0。
改动后的代码如下:
1.public class Test {
2. public static void changeStr(String str0){
3. str0="welcome";
4. }
5. public static void main(String[] args) {
6. String str="1234";
7. changeStr(str);
8. System.out.println(str);
9. }
10.}

第7行代码执行过程如下:
将str的值赋给str0,使得str0和str指向同一个String类对象1234
而在changeStr()方法中第3行代码执行的结果是将str0值(也就是对象的地址)做了修改,str0的值为String类对象welcome的地址,这样一来,使得str和str0所指向的对象不再是同一个对象了,而且str的值并没有改变,也就是说str还是指向String类对象1234的。

综上所述,程序最终的结果一定是1234。

补充:
ziyongkun 在 2006-05-10 10:08:00 发的贴子里说的不是很对,并不是一个副本的问题,它们会指向同一个对象的。

QUESTION NO:2
1. public class Test {
2. static boolean foo(char c) {
3. System.out.print(c);
4. return true;
5. }
6. public static void main( String[] argv ) {
7. int i =0;
8. for ( foo('A'); foo('B')&&(i<2); foo('C')){
9. i++ ;
10. foo('D');
12. }
13. }
14. }
========================================================================
考察的是for语句的执行过程:
for(1;2;3)
过程如下:
1;
2;
3;
2;
.
.
.
当i<2时,便不再执行。其实是基础&细心~~~~~~~

4、SQL问答题
SELECT * FROM TABLE

SELECT * FROM TABLE
WHERE NAME LIKE '%%' AND ADDR LIKE '%%'
AND (1_ADDR LIKE '%%' OR 2_ADDR LIKE '%%'
OR 3_ADDR LIKE '%%' OR 4_ADDR LIKE '%%' )
的检索结果为何不同?
=========================================================
前者检索全部,后者有三种情况检索不出:NAME=null或ADDR=null或1_ADDR LIKE 2_ADDR 3_ADDR 4_ADDR其一为null.

4、SQL问答题
SELECT * FROM TABLE

SELECT * FROM TABLE
WHERE NAME LIKE '%%' AND ADDR LIKE '%%'
AND (1_ADDR LIKE '%%' OR 2_ADDR LIKE '%%'
OR 3_ADDR LIKE '%%' OR 4_ADDR LIKE '%%' )
的检索结果为何不同?

答:前者检索所有记录,后者只能检索出 NAME 和ADDR中非Null的记录。


5、SQL问答题
表结构:
1、 表名:g_cardapply
字段(字段名/类型/长度):
g_applyno varchar 8;//申请单号(关键字)
g_applydate bigint 8;//申请日期
g_state varchar 2;//申请状态
2、 表名:g_cardapplydetail
字段(字段名/类型/长度):
g_applyno varchar 8;//申请单号(关键字)
g_name varchar 30;//申请人姓名
g_idcard varchar 18;//申请人身份证号
g_state varchar 2;//申请状态
其中,两个表的关联字段为申请单号。
题目:
1、 查询身份证号码为440401430103082的申请日期
select A.g_applydate
from g_cardapply A inner join g_cardapplydetail B on A.g_applyno = B.g_applyno
where B.g_idCard = '440401430103082'

2、 查询同一个身份证号码有两条以上记录的身份证号码及记录个数
select g_idCard,count(*) as Cnt from g_cardapplydetail
group by g_idcard
having count(*) > 1

3、 将身份证号码为440401430103082的记录在两个表中的申请状态均改为07
update g_cardapplydetail set g_state = '07'
where g_idcard = '440401430103082'

update A set g_state = '07'
from g_cardapply A inner join g_cardapplydetail B on A.g_applyno = B.g_applyno
where B.g_idcard = '440401430103082'


4、 删除g_cardapplydetail表中所有姓李的记录
delete from g_cardapplydetail
where g_name like '李%'

3、 将身份证号码为440401430103082的记录在两个表中的申请状态均改为07
update g_cardapplydetail set g_state = '07'
where g_idcard = '440401430103082'

update A set g_state = '07'
from g_cardapply A inner join g_cardapplydetail B on A.g_applyno = B.g_applyno
where B.g_idcard = '440401430103082'

5、SQL问答题:
/*Select g_cardapply. g_applydate
From g_cardapply, g_cardapplydetail
Where g_cardapply. g_applyno=g_cardapplydetail. g_applyno
And g_cardapplydetail.g_idcard='440401430103082'*/

/*Select *From (select count(*) g_count , g_idcard
From g_cardapplydetail
Group by g_idcard ) a
Where a. g_count >= 2*/

/*Update g_cardapply
set g_state='07'
where g_applyno in (select distinct g_applyno
from g_cardapplydetail
where g_idcard ='440401430103082')
update g_cardapplydetail
set g_state='07'
where g_idcard='440401430103082' */

/*Delete from g_cardapplydetail
Where g_name like '李%'*/
通过测试
PS:偶GF做的,自己先汗一下


金山公司几道面试题

silver6 | 22 四月, 2006 10:43

2. What are three ways in which a thread can enter the waiting state?

解析: 操作系统问题



4. In C++, there're four type of Casting Operators, please enumerate and explain them especially the difference.

解析: C++类型转换问题
答案:

7 以下代码有什么问题,如何修改?
#include <iostream>
#include <vector>
using namespace std;

void print(vector<int>);

int main()
{

vector<int> array;
array.push_back(1);
array.push_back(6);
array.push_back(6);
array.push_back(3);
//删除array数组中所有的6
vector<int>::iterator itor;
vector<int>::iterator itor2;
itor=array.begin();

for(itor=array.begin(); itor!=array.end(); )
{
if(6==*itor)
{
itor2=itor;

array.erase(itor2);
}
itor++;


}

print(array);
return 0;

}
void print(vector<int> v)
{
cout << "n vector size is: " << v.size() << endl;
vector<int>::iterator p = v.begin();
}
我的答案是,迭代器问题,只能删除第一个6,以后迭代器就失效了,不能删除之后的元素。
但我不知道怎么改

void print(const vector<int>&);

int main()
{

vector<int> array;
array.push_back(1);
array.push_back(6);
array.push_back(6);
array.push_back(3);

//删除array数组中所有的6
array.erase( remove( array.begin(), array.end(), 6 ) , array.end() );

print(array);
return 0;

}

void print(const vector<int>& v)
{
cout << "n vector size is: " << v.size() << endl;
copy(v.begin(), v.end(), ostream_iterator<int>(cout, " ") );
}

#include <iostream>
#include <vector>
using namespace std;

int main()
{

vector<int> array;

array.push_back(1);

array.push_back(6);
array.push_back(6);
array.push_back(6);
array.push_back(6);
array.push_back(6);

array.push_back(3);
array.push_back(9);
array.push_back(8);
array.push_back(5);


//&Eacute;&frac34;&sup3;&yacute;array&Ecirc;&yacute;×é&Ouml;&ETH;&Euml;ù&Oacute;&ETH;&micro;&Auml;6
vector<int>::iterator itor;
itor=array.begin();

for(itor=array.begin(); itor!=array.end();++itor )
{
if(6==*itor)
{

itor=array.erase(itor);
--itor;
}

}

cout << "vector size is: " << array.size() << endl;
for(itor=array.begin(); itor!=array.end();++itor )
{
cout<<*itor<<" ";
}


system("pause");

return 0;

}

2. What are three ways in which a thread can enter the waiting state?
尝试答一下
CPU调度给优先级更高的thread,原先thread进入waiting
阻塞的thread获得资源或者信号,进入waiting
还有什么

static_cast 数制转换
dynamic_cast 用于执行向下转换和在继承之间的转换
const_cast 去掉const
reinterpret_cast 用于执行并不安全的orimplmentation_dependent类型转换

我给你一个完整的解释:
执行itor=array.erase(itor);这句话后,itor不会移动,而只是把删除的数后面的数都往前移一位,所以删除了第一个6后,指针指向第2个6,然后在来个itor++,指针就指向array.end()了,给你画个草图:
1 6 6 3 array.end() //最开始指针itor指向第一个6;
1 6 3 array.end() //删除第一个6后,指向第二个6
1 6 3 array.end() //itor++后,就指向3了,所以不能删除


利用Visual Basic开发SAP接口程序初探

silver6 | 17 四月, 2006 08:37

SAP R/3系统是业界最先进、最稳定的ERP系统,国际和国内大型企业采用该系统的比例遥遥领先于其它ERP系统的总和。SAP R/3内建了二次开发平台,使用的开发语言叫做ABAP,是一种类似于COBOL的编程语言。ABAP在报表输出方面功能相对较弱(只能按行打印在屏幕上或者导出到Excel中处理),所以日常工作中经常需要在外部开发程序。通过程序接口自动读取SAP R/3的数据表(视图),在外部进行处理和利用水晶报表等工具生成符合中国人习惯的报表样式。

  SAP R/3的接口方式主要有RFC、IDOC、BAPI三种,本文要介绍的是相对比较简单的RFC(Romote Function Call,远程函数调用)。SAP系统RFC调用的原理其实很简单,有一些类似于三层构架的C/S系统,第三方的客户程序通过接口调用SAP内部的标准或自定义函数,获得函数返回的数据进行处理后显示或打印。下面是RFC调用的模型:


  本文主要不是讨论SAP R/3函数的开发,因为使用SAP的公司一般都有专门的ABAP开发人员。大家如果有机会接触ABAP平台,可以通过事务代码SE37进入ABAP开发平台的"函数编制器"进行函数开发测试。如图:

  下面主要以VB为例介绍一下SAP接口RFC的开发思路。在SAP客户端SAP Gui Client安装的时候,注意选择安装附带的SDK包(最保险是选择完全安装)。RFC接口程序开发,主要用的是"SAP.Functions"这个控件,通过控件在外部程序模拟SAP Gui Client的用户登录和函数调用,然后返回函数的值。请看下面的程序片段和重点注解(尤其是test_Click()):

Private Sub Command1_Click()
 ' 定义R/3用户名和密码变量(用户名应由SAP管理员开运行函数的权限)
 Dim logname As String * 22, password As String * 22
 Call logonr3(logname, password) ' 调用SAP登录界面程序
 If logflag Then ' 调用生产、开发系统开关
  StatusBar1.Visible = True
  StatusBar1.SimpleText = "正在登录SAP R/3系统..."
  Dim R3AppServer As String, R3Client As String, R3SystemNo As String
  If Form2.opPRD.Value Then
   ' 以下服务器参数请根据客户配置情况更改
   R3AppServer = "10.3.1.4" ' 生产系统服务器IP
   R3Client = "800"     '生产系统集团代码
   R3SystemNo = "00" '生产系统号
  Else
   R3AppServer = "10.3.3.1" ' 开发系统服务器IP
   R3Client = "101"
   R3SystemNo = "00"
  End If
  Unload Form2 ' 释放 Form2 , 所有控件及值不可用
  Set Functions = CreateObject("Sap.Functions") ' 创建RFC的本地对象
  Set Connect = Functions.Connection ' 设置连接
  Connect.ApplicationServer = R3AppServer ' 赋值服务器IP
  Connect.Client = R3Client ' 赋值SAP集团代码
  Connect.Language = "ZH" ' 置SAP系统界面中文
  Connect.User = Trim(logname) ' 赋值SAP登录用户名
  Connect.password = Trim(password) ' 赋值SAP登录用户密码
  Connect.SystemNumber = R3SystemNo ' 赋值SAP系统号
  If Not Connect.Logon(0, True) Then ' 软件登录SAP并判断
   MsgBox "登录SAP R/3失败,请重新登录!", vbOKOnly + vbExclamation, "系统提示"
   Command1.SetFocus
  Else ' 登录SAP成功
   Command1.Enabled = False
   Command2.Enabled = True
   test.Enabled = True
  End If

  StatusBar1.SimpleText = ""
  StatusBar1.Visible = False
 End If
End Sub

Private Sub Command2_Click() ' 注销SAP登录
 Connect.LogOff
 Command2.Enabled = False
 Command1.Enabled = True
 test.Enabled = False
End Sub

Private Sub Command3_Click() ' 退出SAP接口演示程序
 If Form1.Command2.Enabled Then
  MsgBox "退出前请断开SAP R/3系统!", vbOKOnly + vbInformation, "系统提示"
 Else
  End
 End If
End Sub

Private Sub Form_Load()
 Command2.Enabled = False
 test.Enabled = False
 logoflag = False
End Sub

Private Sub test_Click() ' SAP RFC远程调用处理主演示
 Dim GetCustomers As Object
 Dim Customers As Object
 Dim i As Integer
  ' 通过RFC接口远程运行SAP内部函数RFC_CUSTOMER_GET
 ' 赋要调用的SAP内建函数名
 Set GetCustomers = Functions.Add("RFC_CUSTOMER_GET")

 GetCustomers.Exports("KUNNR") = "0000000103" ' 向函数入口赋值(客户代码)
 ' 向函数入口赋查询表名称
 Set Customers = GetCustomers.Tables("CUSTOMER_T")

 If GetCustomers.Call Then ' 调用成功遍历显示客户所有信息条目
  For i = 1 To Customers.rowcount
   MsgBox Customers(i, "KUNNR")
  Next i
 Else
  MsgBox " 搜索出错! 出错信息: " + GetCustomers.Exception
 End If
End Sub
  SAP的RFC调用是其接口技术中最简单和易用的一种方式,该方式开发比较简便,特别适合于外部报表开发,但对于大数据量的查询效率相对较低。大家在熟练掌握后,可以进一步学习高级的IDOC和BAPI接口开发技术。

面试与被面试总结

silver6 | 17 四月, 2006 08:34

我从事技术工作,

这几年的面试与被面试总结

先说我去被面试的经验吧。

回答清楚了2个问题,就能顺利过关了。

1。为什么要离开上一家公司。

2。公司为什么要雇佣你。

问第一个问题的是hr(或老板),呵呵 ,即使你技术过关,hr那里没有好的影响,结果是一个字,难!

如何回答呢? hr想推论出你在他的公司能呆多久。这个时候,你甚至可以明确告诉他,我在贵公司至少能呆n(n>=1)年----当然,你没有把握的话,绝对不能乱说,社会上混,要讲信用的。

有一次,我就在这个问题上吃了大亏,我看公司环境还不错,就我自做主张回答1年,结果,hr心目中是m(m>=2)年,呵呵,结果可想而知了。要知道,技术面试都过关了,Hr面试是2选1,在回家的路上,我只能祈祷对手自动放弃或找到了其他更好的工作。:)

问第二个问题的是技术官。你要让他知道你已经做过哪些商业作品。一定要是商业作品。在里面负责哪方面具体工作,对于你熟悉的地方要多说。最好就是能争取笔试或上机,因为用用口说的话,大家理解都不一样,误差可能很大,结果对你相当不利。在这个问题上我也吃过亏的,曾有一个我很看好的职位,认为把握很大,业务理解上也很有优势,和技术官一谈,结果是game over。要知道,在其他公司的上机和笔试中,我都能在应聘者中取得高分。

再说我去面试别人的经验吧。

当时,我的任务是出题,给分。若你觉得题很难,那么,请千万不要放弃,显然,你的对手也觉得难。只要坚持,我会认为这人有耐心很毅力,在以后的工作中也是好的合作者。题一定要做完,表现出认真的态度,若有疑问或卡壳,还可以寻求面试官的帮助,这些不会减分,相反,会增加你和他们的接触机会,面试官会评估你的沟通能力。

有一次,有1个人来面试,题没有完全ok,但很规范,态度很认真,他把他知道的都做上去了,我给了他技术类的高分。后来,顺利进入公司,再后来进步很快,成了重要角色。

若文章对你有帮助的话,请在此讨论。

祝你成功


面试题

silver6 | 14 四月, 2006 09:36

1.链表和数组的区别在哪里?
2.编写实现链表排序的一种算法。说明为什么你会选择用这样的方法?
3.编写实现数组排序的一种算法。说明为什么你会选择用这样的方法?
4.请编写能直接实现strstr()函数功能的代码。
5.编写反转字符串的程序,要求优化速度、优化空间。
6.在链表里如何发现循环链接?
7.给出洗牌的一个算法,并将洗好的牌存储在一个整形数组里。
8.写一个函数,检查字符是否是整数,如果是,返回其整数值。(或者:怎样只用4行代码编写出一个从字符串到长整形的函数?)
9.给出一个函数来输出一个字符串的所有排列。
10.请编写实现malloc()内存分配函数功能一样的代码。
11.给出一个函数来复制两个字符串A和B。字符串A的后几个字节和字符串B的前几个字节重叠。
12.怎样编写一个程序,把一个有序整数数组放到二叉树中?
13.怎样从顶部开始逐层打印二叉树结点数据?请编程。
14.怎样把一个链表掉个顺序(也就是反序,注意链表的边界条件并考虑空链表)?
另外:

一、单项选择题:(共12题,每题2分,共24分)

1. 下面哪一个不是C++的标准数据类型? ( )

A. int B. char

C. bool D. real

2. break关键字在哪一种语法结构中不能使用? ( )

A. for语句 B. switch语句

C. if语句 D. while语句

3. 类的继承方式有几种? ( )

A. 两种 B. 三种

C. 四种 D. 六种

4. extern关键字的作用是什么? ( )

A. 声明外部链接 B. 声明外部头文件引用

C. 声明使用扩展C++语句 D. 声明外部成员函数、成员数据。

5. C库函数strstr的功能是? ( )

A. 查找子串 B. 计算字符串长度

C. 字符串比较 D. 连结字符串

6. stl::deque是一种什么数据类型? ( )

A. 动态数组 B. 链表

C. 堆栈 D. 树

7. STL库里含有下面的哪一种泛型算法? ( )

A. KMP查找 B. 折半查找

C. 冒泡排序 D. 快速排序

8. 现在最快且最通用的排序算法是什么? ( )

A. 快速排序 B. 冒泡排序

C. 选择排序 D. 外部排序

9. Win32下的线程的哪一种优先级最高? ( )

A. THREAD_PRIORITY_HIGHEST B. THREAD_PRIORITY_IDLE

C. THREAD_PRIORITY_TIME_CRITICAL D. THREAD_PRIORITY_ABOVE_NORMAL

10. 下面四个选项中,哪一个不是WinMain函数的参数? ( )

A. HINSTANCE B. INT

C. LPSTR D. WPARAM

11. VC++的编译器中,运算符new底层的实现是什么? ( )

A. VirtualAlloc() B. HeapAlloc()

C. GlobalAlloc() D. AllocateUserPhysicalPages()

12. 下面哪一本C++参考书最厚? ( )

A. 《Think in C++》 B. 《深入浅出MFC》

C. 《C++ Primer》 D. 《Effective C++》

二、不定项选择题:(共6题,每题3分,共18分,多选、错选、漏选均不给分)

1. vector::iterator重载了下面哪些运算符? ( )

A. ++ B. >>

C. *(前置) D. ==

2. CreateFile( )的功能有哪几个? ( )

A. 打开文件 B. 创建新文件

C. 文件改名 D. 删除文件

3. 下面哪些是句柄(HANDLE)? ( )

A. HINSTANCE B. HWND

C. HDC D. HFONT

4. 下面哪些不是OpenGL标准几何元素的绘制模式? ( )

A. GL_FOG B. GL_LINE_STRIP

C. GL_POINTS D. GL_TRIANGLE_FAN

5. 下面哪些运算符不能被重载? ( )

A. 做用域运算符“::” B. 对象成员运算符“.”

C. 指针成员运算符“->” D. 三目运算符“? :”

6. 下面哪些人曾参与了世界上第一个C++编译器的开发? ( )

A. Bill Gates B. Stanley Lippman

C. Anderson Hejlsberg D. Bjarne Stroustrup

三、填空题:(共8题,每题3分,共24分)

1. 一个大小为320 X 192,颜色为灰度索引色的设备相关位图有______字节。如果此位图颜色为24位真彩色,则它的大小有______字节。

2. Windows API的中文意义是________________。

3. 计算反正弦的库函数是______;计算浮点数绝对值的库函数是______;计算浮点数n次方的库函数是______;将浮点数转化为字符串的库函数是______。

4. 如果i等于5,那么( ++i ) - -的返回值是_____。

5. API LoadBitmap()的功能是从______中读取位图数据到内存。

6. new和_____对应,malloc和_____对应,他们之间_____交叉混用。calloc的功能是___________,realloc的功能是____________。

7. SendMessage和PostMessage都会向窗体发送一个消息,但SendMessage_________而PostMessage____________。

8. 输出指定圆心、半径、边数的圆上的点:

const int nCount = 12;

const double dOrgX = 5.0,

dOrgY = 3.0;

const double dRadius = 2.0;

for( int i = 0; i < nCount; i++ )

{

double dAngle = M_PI * 2.0 / (double)nCount * i;

cout << "第" << i << "点:X = " << ________; cout << ", Y = " << __________ << endl;

}

三、判断题:(共12题,每题2分,共24分)

1. 一个类必须要有一个不带参数的构造函数。 □

2. 你不能写一个虚的构造函数。 □

3. 类里面所有的函数都是纯虚函数时才是纯虚类。 □

4. const成员函数对于任何本类的数据成员都不能进行写操作。 □

5. 函数中带默认值的参数必须位于不带默认值的参数之后。 □

6. char *p = "Test"; p[0] = 'R'; □

7. cout << "Test"; □

8. stl::list不支持随机访问叠代器。 □

9. stl::vector的效率比stl::list高。 □

10. VC和VC++是一回事,而VC++是一种比C++更难一些的语言。 □

11. 理论上,new和malloc造成的内存泄露都会由操作系统回收。 □

12. 在C++中struct和class的差别很大,所以从语法上不能混用。 □

四、简述题(共3题,每题5分,共15分)

1. 请简述PeekMessage和GetMessage的区别。





2. 请列出你所知道的在Windows SDK平台上,实现计时功能的方法。





3. 请简述你所知道的const的各种用法。









五、编程题:(共3题,第1小题7分,第2小题14分,第3小题24分)

1. 深度遍历二叉树。

struct Node

{

Node *Parent;

Node *Left, *Right;

};

void Through(Node *Root)

{









}



2. 二分法查找。

int DicFind( int *Array, int Count, int Value )

{

















}



3. 写出字符串类String的默认构造函数、析构函数和重载赋值运算符。

已知类String的原型为:

class String

{

public:

String( const char *pStr = NULL ); // 默认构造函数

~String( void ); // 析构函数

String &operate = ( const String &Source ); // 重载赋值运算符

private:

char *m_pData; // 指向字符串的指针

};

今天下午的两道面试题

silver6 | 07 四月, 2006 18:42

1。 一人岁数的3次方是四位数,四次方是六位数,并知道此人岁数的3次方和4次方用遍了0~9十个数字。编写一程序求此人的岁数。

2。对1,2,3, 4, 5 这五个数任意取出两个数,列出他们的所有组合。

public static int getAge() {
int age;
int third;
int fourth;

for (int i = 11; true; i++) {
if (i < 200) {
third = (int) Math.pow(i, 3);
fourth = (int) Math.pow(i, 4);
if (getLength(third, fourth) == 10) {
age = i;
break;
}

}
}
return age;
}

public static int getLength(int args1, int args2) {
String str1 = String.valueOf(args1);
String str2 = String.valueOf(args2);
String str = str1 + str2;
if (str.length() != 10) {
return -1;
}
int[] intarray = new int[10];
for (int i = 0; i < str.length(); i++) {
intarray[i] = Integer.parseInt(str.substring(i,i+1));
}
Arrays.sort(intarray);
if(intarray[0]!=0 && intarray[9]!=9)
return -1;

return 10;
}

第二题还更简单了

for(int i=1; i<6; i++){
for(int j=1; j<6; j++){
if(i==j){
System.out.println(j+""+j);
}else{
System.out.println(i+""+j);
System.out.println(j+""+i);
}
}
}

public class A {
// http://community.csdn.net/Expert/topic/4667/4667929.xml?temp=.57922
public static void main(String[] args) {
String t;
String[] s = new String[5];
int j = s.length;
for(int i=0; i<j; i++) {
s[i] = new Integer(i+1).toString();
}

for(int i=0; i<j; i++) {
t = s[i];
for(int a=0; a<j; a++) {
t += s[i];
System.out.println(t);
}
System.out.println();
}
}
}

第二题还更简单了

for(int i=1; i<6; i++){
for(int j=1; j<6; j++){
if(i==j){
System.out.println(j+""+j);
}else{
System.out.println(i+""+j);
System.out.println(j+""+i);
}
}
}
============================================================
楼上的没看清题目,它是让你对1,2,3, 4, 5 这五个数任意取出两个数,列出他们的所有组合,所以重复的数字不应该算在里面。
第二题应该改为:
for(int i=1; i<6; i++){
for(int j=1; j<6; j++){
if(i==j){
break;
}else{
System.out.println(i+""+j);
System.out.println(j+""+i);
}
}
}

public class B {
public static void main(String[] args) {
for (int i = 1; i < 6; i++) {
int t = i;
for(int a = 0; a<5; a++) {
int c = a+1;
if(c == t) {
continue;
}else {
System.out.println(t*10+c);
}
}
System.out.println();
}
}
}

第二题
public class Test
{
public static void main(String[] args)
{
int[][] a=new int[5][];
for(int i=0;i<a.length;i++)
{
a[i]=new int[i+1];
}
for(int i=1;i<=a.length;i++)
{

for(int j=i+1;j<=a.length;j++)
{
System.out.print(i);
System.out.print(j+" ");
}
System.out.print(" ");
}

for(int i=a.length;i>0;i--)
{

for(int j=i-1;j>0;j--)
{
System.out.print(i);
System.out.print(j+" ");
}
System.out.print(" ");
}
}
}

public class Test {

public static int getDigits(String str) {
int[] intarr = new int[10];
for (int i = 0; i < 10; i++)
intarr[i] = 0;
for (int i = 0; i < str.length(); i++) {
int j = Integer.parseInt(str.substring(i, i + 1));
intarr[j] = 1;
}
int num = 0;
for (int i = 0; i < 10; i++)
num = num + intarr[i];
return num;
}

private static int getAge() {
int age;
int third;
int fourth;
for (age = 1; age < 100; age++) {
third = (int) Math.pow(age, 3);
fourth = (int) Math.pow(age, 4);
if (third < 1000 || third >= 10000)
continue;
if (fourth < 100000 || fourth >= 1000000)
continue;
String str = String.valueOf(third) + String.valueOf(fourth);
if (getDigits(str) == 10)
return age;
}
return 0;
}
}

第二道题
class Combine
{
public static void main(String[] args)
{
for(int i=1; i<5; i++)
{
for(int j=i+1; j<6; j++)
{
System.out.println(i+""+j);
System.out.println(j+""+i);
}
}
}

public class Age
{
public static void main(String [] args)
{
String str1 = null;
String str2 = null;
String str3 = null;
String str4 = "0123456789";
for(int i=10;i<50;i++)
{
str1 = Integer.toString(i*i*i);
str2 = Integer.toString(i*i*i*i);
str3 = str1+str2;
if((str1.length() == 4) && (str2.length() ==6))
{
boolean flag = true;
for(int j=0;j<10;j++)
if(str3.indexOf(str4.charAt(j))==-1)
flag = false;
if(flag){
System.out.println(">>>"+i);
System.out.println(str3);
}
}
}

}
}


Strus常见错误及原因分析

silver6 | 07 四月, 2006 09:31

本篇文章包含了在用Struts开发web应用时经常碰到的一些异常和错误,根据异常或错误信息本身,经常可以找到潜在的错误发生原因。

下面列出了一些Struts的常见错误和异常,并给出了一些可能发生此类错误或异常的原因。有的后面有相关连接,你可以通过它找到更多的信息。

Cannot retrieve mapping for action

异常

javax.servlet.jsp.JspException: Cannot retrieve mapping for action /Login /Login是你的action名字)

可能原因

action没有再struts-config.xml 中定义,或没有找到匹配的action,例如在JSP文件中使用 <html:form action="Login.do".将表单提交给Login.do处理,如果出现上述异常,请查看struts-config.xml中的定义部分,有时可能是打错了字符或者是某些不符合规则,可以使用struts console工具来检查。

Cannot retrieve definition for form bean null

异常

org.apache.jasper.JasperException: Cannot retrieve definition for form bean null

可能原因

这个异常是因为Struts根据struts-config.xml中的mapping没有找到action期望的form bean。大部分的情况可能是因为在form-bean中设置的name属性和action中设置的name属性不匹配所致。换句话说,actionform都应该各自有一个name属性,并且要精确匹配,包括大小写。这个错误当没有name属性和action关联时也会发生,如果没有在action中指定name属性,那么就没有name属性和action相关联。当然当action制作某些控制时,譬如根据参数值跳转到相应的jsp页面,而不是处理表单数据,这是就不用name属性,这也是action的使用方法之一。

No action instance for path /xxxx could be created

异常

No action instance for path /xxxx could be created

可能原因

特别提示:因为有很多中情况会导致这个错误的发生,所以推荐大家调高你的web服务器的日志/调试级别,这样可以从更多的信息中看到潜在的、在试图创建action类时发生的错误,这个action类你已经在struts-config.xml中设置了关联(即添加了<action>标签)。

struts-config.xml中通过action标签的class属性指定的action类不能被找到有很多种原因,例如:

  • 定位编译后的.class文件失败。Failure to place compiled .class file for the action in the classpath (web开发中,class的的位置在r WEB-INF/classes,所以你的action class必须要在这个目录下。例如你的action类位于WEB-INF/classes/action/Login.class,那么在struts-config.xml中设置action的属性type时就是action.Login).
  • 拼写错误,这个也时有发生,并且不易找到,特别注意第一个字母的大小写和包的名称。

struts-config.xml中指定的action类没有继承自Stuts的Action类,或者你自定义的Action类没有继承自Struts提供的Action类。

你的action类必须继承自Struts提供的Action类。

你的classpath的问题。例如web server没有发现你的资源文件,资源文件必须在WEB-INF/classes/目录下

Problem in struts-config.xml file with action mapping.

Problem with data-sources.xml file.


[推荐]计算机行业日语常用语

silver6 | 07 四月, 2006 08:39

[推荐]计算机行业日语常用语

作者 :光棍



/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
第1回



セットに関すること
例えば:
   Ⅰ:中国語で     将B設給A
     日本語で言えば  ①AにBをセットする それとも  ②BをAに入れる 
   Ⅱ:中国語で     将B和A交換
     日本語で言えば  AとBを入れ換える
   Ⅲ:中国語で     求A和B的差  
     日本語で言えば  AとBの差を取る
   Ⅳ:中国語で     求A減B
     日本語で言え   AからBを引く
   Ⅴ:中国語で     A加B後再放入A(或B)
     日本語で言えば  AにBを加えて、A(或B)にいれる



/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
第2回
昨日は第1回でした、今日はその第2回で、よろしければ読んでください!



皆さん,Q&A、メール等のような文書



例えば:有るものに対して100%自分がAと思っている,その場合
中国語で言えば:  応該是+A(名詞) 
日本語で言えば:
        (名詞)A+のではないかと思います。 丁寧
        名詞A+でしょうか         やや丁寧
        名詞A+です           あまり丁寧ではない
例:
  中国語で: 他的理解不対、応該是××
  日本語で: 彼が理解したのは間違っていると思い、何か××のではない かと思います。
        彼が理解したのは間違っていると思い、正しいことは××でしょうか。



/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
第3回
今日はその第3回で、よろしければ読んでください!



置き換える’の使用方法



①A和B 全部表示東西時
 日本語で言えば:AをBに置き換える      
 中国語で言えば:将A从該位置取走、用B替換到該位置上



②A表示東西、B表示場所時
日本語で言えば:AをBに置き換える      
中国語で言えば:将A移動到B中



③A和B 全部表示東西
日本語で言えば: AとBを置き換える      
中国語で言えば: A与B互換 【A⇔B】



/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
第4回
さて、先週第三回までやってきましたが、今日はその第四回で、よろしければ読んでください!



①我方認為応該…
こちら側は××と思っております。
◆例:こちら側は以上の通り処理を行なうのが正しいと思っております。



②○○中是「××」記述的、但我方認為応該…
○○には「××」と書いてありますが、こちら側は…と思っております。
◆ 例:詳細設計書には「A=0」と書いてありますが、こちら側はA≠0と思っております。



③如果用○○的方法来処理、将会産生××的結果。
もし○○のように処理すれば、××になります。
◆ 例:もしこのように処理すれば、仕様書と合わない結果になる(恐れがある)。



④因為○○的原因、請××。
○○ため××して下さい。
◆ 例:MAIN PGMでAを使用するため、Aを定義してください。



⑤○○中是「××」記述的、但実際上△△不存在。
○○には××と書いてありますが、実は△△が存在していない。
◆ 例:詳細設計書には三つのSELECT条件が書いてありますが、実は種別という項目が存在していません。



⑥根拠○○和○○  从◇◇中取得●●。
○○と○○より、◇◇から●●取得する。
◆例:商品コードと銘柄コードより、銘柄マスタから銘柄名を取得する。


(待续) 转自WWW.JSOB.COM
-------------------------------------------------------------------
http://www.jsob.com
对日软件外包IT人的乐园!
中国金马对日软件外包项目交易网(Japanese Software Outsourcing Business Online Market)
是中国第一家对日软件项目外包交易网,无偿提供对日软件外包的合作机遇,对日外包论坛的信息交流平台

JSOB 站点的BBS的内容主要是日语学习,日本项目经验指教,日本软件项目信息交流,希望能得到在日华人朋友的帮助和指教,这里还却非常缺斑竹,有兴趣的可以直接在论坛事务中发帖申请,条件就一个,日语懂一点,对中日软件外包话题比较有兴趣就可以了,多谢指教。JSOB的ADMIN的联系方法是 jsob@hotmail.com 再次感谢!

比赛贴~微软又一道笔试题

silver6 | 04 四月, 2006 09:48

怎样只用4行代码编写出一个从字符串到长整形的转换函数?

我的方法,不过好象比4行多 *_#!~
long atol(char *str)
{
char c = *str;
if( !isdigit(c) ) str++;
for(long value = 0; *str != ''; value = value * 10 + (*str -'0'),str++);
return c == '-' ? -value : value ;
}

void stol(const char * des, long& num)
{
for (int base = 1, i = 0; des[i] != ''; base = 10, ++i)
{
num *= base;
num += (int)(des[i] - '0');
}
}
num 要初始化为0


void stol(const char * des, long& num)
{
for (int i=num=0; des[i] != ''; i++)
{
num *= 10;
num += (int)(des[i] - '0');
}
}

void stol(char *str, long &num)
{
while(*str != '')
{
num = num * 10 + (*str - '0');
str++;
}
}

void stol(const char * des, long& num)
{
char p = des[0];
for (int b = 1, pos = 1, base = 1; des[pos] != ''; b = 10, ++pos, base *= 10)
{
(num *= b) += (int)(des[pos] - '0');
}
p == '-' ? (num *= -1) : (num = (int)(des[0] - '0') * base + num);
}
改了一下

真的是微软的笔试题么?
我只用了一行。
#include <iostream>
using namespace std;

long str2long(char* p,long xxx=0L)
{
return *p==''?xxx:str2long(p,xxx*10+(*p+++0-'0'));
}

int main()
{
char *str="123456789",*p=str;
cout<<str2long(p);
getchar();
return 0;
}

用STL,四行
#include <sstream>
#include <iostream>
#include <string>

using namespace std;

long ToLong(string& s)
{
long l;
istringstream iss(s);
iss>>l;
return l;
}
int main(int argc, _TCHAR* argv[])
{
string s = "-12356";
cout<<ToLong(s);
return 0;
}

谢谢刚才上面的帖子提醒负数的问题,我更正了,还是只用一行:
#include <iostream>
using namespace std;

long str2long(char* p,long xxx=0L,bool IsPositive=true)
{
return *p==''?(IsPositive?xxx:xxx*(-1)):(*p=='-'?str2long(++p,0L,false):str2long(p,xxx*10+*p+++0-'0',IsPositive));
}

int main()
{
char *str="-123456789",*p=str;
cout<<str2long(p);
getchar();
return 0;
}


设计模式笔记(5 COMPOSITE & DECORATOR)

silver6 | 04 四月, 2006 09:46

COMPOSITE(组合)
适用性:
1.想表示对象的部分整体层次结构
2.希望用户忽略组合对象和单个对象的不同。

思考:
组合模式的所有组件应该具备同一个接口。一直感觉,这种组合是一种递归组合的概念。所有的组件,按照树的结构组织起来,树的叶结点行为可能和中间结点的行为并不一致,这看上去违背了Liskov原则,似乎是一个容易引起迷惑的地方。
树的叶结点可能并不能增加子结点,删除子结点的行为也可能失败。而一个中间结点则可能不具备一些叶结点才具备的具体功能。用户需要在这两者之间平衡。
我对
COMPOSITE的理解可以概括成组件的递归组合。这个概括过于简短,我不确定是否确实抓住了这个模式的本质,还是我过于缺乏理解。如果我的理解没有问题的话,那么,GUI系统的嵌套窗口对象可算是典型的COMPOSITE模式了。

DECORATOR(装饰)
适用性:
1.在不影响其他同类对象的情况下,给某个对象透明的增加一些额外的功能。

思考:
考虑重载某个虚方法,并且,在这个方法中调用父类的重载方法。派生类的方法对父类的方法进行了“修饰”。这种方法依赖于类的派生。
考虑一个接口A,和实现了该接口的一系列的类,以及实例。现在,有一个装饰类,也实现了接口A,并且,持有一个到其他实例的指针:
Interface A;
class Decorator : public A{
A * instance;
//实现接口A,在相关方法中调用instance的同名方法。
};
我们看到,只要在
Decorator实现的A接口的方法中,在调用instance的同名方法前后增加一些功能,就可以起到改变instance行为的效果。
和Strategy的区别在于:
Strategy是一种有扰的设计,要求设计的类本身具备策略调整能力。而Decorator并不要求设计类时考虑支持Decorator

设计模式笔记(7 FLYWEIGHT & PROXY)

silver6 | 04 四月, 2006 09:45

FLYWEIGHT(享元)
意图:
运用共享技术有效地支持大量细粒度的对象。

适用性:
1.一个程序应用了大量的对象,造成很大的存储开销。
2.对象的大多数状态可变为外部状态。
3.如果删除对象的外部状态,那么可以用相对较少的公象对象取代很多组对象。
4.应用程序不依赖于对象标识

思考:
上述的适用性和别的模式中介绍的不太一样。基本上,适合使用FlyWeight模式的场景需要同时满足上述四个条件,而别的模式大多只要满足适用性的一两条,就可能适合采用该模式。
从第一个适用性条件可以看出,这基本上属于开销优化的范围。因此,除非事先有足够的领域知识能够加以预见,否则,是不必在早期设计中考虑使用该模式的。要想成功运用该模式,必须的一个条件是:除了那些外部状态,余下的状态将是需要共享的。这也就意味着一般而言,FLYWEIGHT是只读的--变化的部分仍然需要加以分离出来--从这个意义上来说,“享元”的中文翻译更好地表达了这层意思。一个最好的情况是,共享的这些对象没有外部状态,且只作为系统共享的只读对象。关于第四条,可以认为是一种补充说明,对象标识本身其实也是可以作为变化的部分加以分离的。
上面的讨论强调了“只读”,事实上,本模式并不要求FLYWEIGHT是只读的。但是,必须看到修改FLYWEIGHT的后果:这种影响是全局的,接近于全局变量的变种。某些时候也许我们确实需要这种全局的作用效果,但是滥用这一能力可能导致理解上的困难和程序行为的判断困难。FlyWeight的主要目的不在于此。
通常,享元也并不能当作一个纯粹的只读对象,那么,将变化的部分加以分离可能是必须的工作,也有必要对分离的效果加以评估再决定是否和如何运用FlyWeight模式。

PROXY(代理)
意图:
为其他对象提供一种代理以控制对这个对象的访问。

适用性:
书中列出了几种运用proxy的场景作为适用性的说明:
1.远程代理,为一个不在同一地址空间的对象提供局部代理。
2.虚代理,根据需要创建很大的对象。
3.保护代理控制对原始对象的访问。
4.智能引用,取代简单指针,在访问对象时提供附加操作。例如:智能指针;第一次访问持久对象时,将它装入内存;在访问一个实际对象前,检查其是否加锁。

思考:
相对于Decorator而言,通常Proxy是更重量级的。Proxy和Bridge模式也有很多相似之处:透过一个接口去访问真正实现功能的对象。 Decorator和Proxy的区别在于,Decorator目标仅仅在于增加某些方法的职责,并不打算全面掌控目标对象,另外,Decorator也并不确定自己将要修饰的可能会是什么对象。Proxy模式则相反,Proxy需要全面了解甚至需要构建被代理对象,而Proxy和被代理对象之间的关系也是静态决定的。有一点是相同的:一个实际对象既可以有多个Decorator,也可以有多个Proxy。
Proxy和Bridge虽然有相似性,但是Bridge的目的仅仅是为了维持接口和实现的各自演化,Bridge模式并不打算用来支持创建非常复杂的实现。Bridge模式的接口和实现在语意上是完全一致的。而Proxy模式,虽然一般而言Proxy和被代理对象之间具备一致的接口,但这完全是不必要的。当弱化Proxy的额外处理能力,强化Decorator的职责范围,这三个模式之间的实现区别将会不那么显著,我们需要警惕的是,这三者之间的意图则是差别非常巨大的。

管理者

silver6 | 28 三月, 2006 20:04

1、管理者要是坐下,部下就躺下了。

  2、管理就是行动。

  3、管理就是树立榜样。

  4、高层管理不等于高高在上。

  5、管理者必须进行问题管理,而不是危机管理。

  6、干部怕的就是不知道自己怕什么。

  7、没思路的领导不想互动,没控制力的领导不敢互动。

  8、干部怎样对待问题?要100%地落实责任,即“见数也见人”的原则。每个1%的问题都可以转化为100%的责任,100%的责任人。

  9、干部怎样对员工?创造一个充满活力的氛围。

  10、干部怎样对市场?创与闯。既要创新、创造;又要有闯劲、冲劲。

  11、干部怎样对待管理?悟性和韧性。

  12、干部的目标:做超级领导,即你的领导水平达到了能够让下属在没有领导的时候仍能够正常工作。形成有活力的员工,有合力的组织。

  13、干部是事业成败的关键。

  14、如果你或你的部门没有了上升的空间,也将失去生存空间。

  15、终端的问题就是领导的问题。

  16、看不出问题是最大的问题。

  17、重复出现的问题是作风上的问题。

  18、部下素质低不是你的责任,但是不能提高部下的素质是你的责任。

  19、观念不变原地转,观念一变天地宽。

  20、管事先管人,管人带作风。

  21、渐进就是守旧。所以经营理念创新,就要反渐进,必须一步到位。

  22、不只做一颗螺丝钉,要经营一部机器。

  23、先画靶子再打枪。

  24、特殊论就是给问题放行。

  25、“立刻办”是奔着有预算的目标立刻办;“想想看”是没有预算的闭门造车。

  26、开发的是市场而不是产品。

  27、市场目标的确定不是以个人能力为限,而是以用户满意度为准。

  28、对市场目标的确定就是以在市场上有竞争力增值为标准。

  29、带动全球经济增长的火车头减速并不意味着所有的车厢都减速。

  30、零增长不等于零需求。

  31、有效供给才能创造出市场。

  32、海尔人只有创业没有守业。

  33、海尔国际化战略能否成功,主要是靠每一个海尔人的国际化,有了每一个人的国际化才能保证海尔集团的国际化。

  34、企业竞争力的实现取决于创新的细胞——SBU。

  35、企业核心竞争力就是获取用户资源的能力。

  36、一个企业的竞争力是看一个企业的员工是增值的资产还是负债。

  37、要以秒为计算单位。

  38、客户的要求不等于客户的需求。

  39、造势产品输入的是用户的需求,输出的是用户的满意。

  40、企业一旦站立到创新的浪尖上,维持的办法只有一个,就是要持续创新。

  41、要持续造势,就要把企业做成一条流动的河。源头是创新的SBU,河的终点是用户的满意度,即对企业忠诚的用户。

  42、把每位员工经营成创新的SBU并不断经营出高素质的人才的决定性因素就是管理者能否经营自我。

  43、成为SBU的四个要素是:市场目标、市场定单、市场效果、市场报酬。

  44、SBU具体的体现就是速度和创新。

  45、经营企业就是要经营人,经营人首先要尊重人。

  46、止谤莫如自修。战胜非议的唯一途径就是战胜自我。

  47、挑战目标首先要挑战自我。

  48、工作要简化,不要简单化。

  49、求人不如求己。

  50、“想干与不想干”是有没有责任感问题,是“德”的问题;“会干与不会干”是“才”的问题,但是不会干是被动的,是按照别人的要求去干;“能干与不能干”是创新的问题,即能不能不断提高自己的目标。

  51、没有市场定单的管理者就是不要管理的管理者;没有市场定单的员工就是不干工作的员工,责任不在员工身上,而在于管理者;没有市场定单的工作就是无效工作。

  52、决胜在终端。

  53、流程再造就是先要再造人。

  54、企业内部管理革命是为了创造企业外部的市场。

  55、不是因为有些事情难以做到,我们才失去了斗志,而是因为我们失去了斗志,那些事情才难以做到。

  56、我们所有的质量问题,都是人的问题,设备不好是人不好;零部件不合格是人不合格;我们所有发展不起来的问题都是思路问题,不是缺人是缺思路;不是缺件是缺思路。

  57、企业发展的空间无限大,企业与用户的距离无限小。

  58、有价值的定单是企业发展的永恒的主题,企业要发展必须有定单而且是有价值的定单。

  59、质量无止境,企业无边界,名牌无国界。

  60、“一站到位”的服务,“一票到底”的流程。

  61、员工齐心,管理用心,对用户真心。

  62、企业生命之树的土壤是用户。

  63、企业做到极致,满足用户需求,无有他奇,只是本然。

  64、要在国际市场竞争中取胜,第一是质量,第二是质量,第三还是质量。

  65、质量不打折、服务不打折、信誉不打折。

  66、质量一次就做对。

  67、有缺陷的产品就是废品。

  68、在一个管理好的企业内部没有激动人心的事情发生。

  69、管理的关键不在于知而在于行。

  70、没有定单就没有目标,没有目标就没有工资。

  71、盘活资产首先要盘活人。

  72、在别人否定自己之前先自我否定。

  73、只有自己才能打倒自己。

  74、突破自我,突破思维定势,突破昨天。

  75、智力比知识重要,素质比智力重要,觉悟比素质更重要。

  76、创新的目标是创造有价值的定单;创新的本质是创造性的破坏,破坏所有阻碍创造有价值定单的枷锁;创新的途径是创造性的模仿和借鉴,即借力。

  77、监控就是爱护,委任就是信任。

  78、观念创新就是目标创新,目标创新就是提出别人认为不可能达到的目标,并用创新的办法实现它。

  79、每个中高级管理人员只有自己先找到市场才能找到市场中竞争的方向。

  80、不能用职能管理的手推职能管理的山。

  81、永远战战兢兢,永远如履薄冰。

  82、职能签字是事先没有市场目标的签字,事先无人负责的签字。用户的签字才是有效的签字。

  83、用户的钞票才是企业的选票,用户的口碑才是企业的金杯。

  84、只有真正实现了问题清零和买断损失,才能卖出有价值的定单。

  85、要效果,不要借口。

  86、没有思路就没有出路。

  87、举一纲而万目张,失一机而万事毁。

  88、管理无小事。

  89、物流以时间消灭空间,商流以空间消灭时间。

  90、什么是不简单?能够把简单的事千百遍都做对,就是不简单;什么不容易?大家公认的非常容易的事情认真地做好,就是不容易。

  91、图难于其易,为大于其细。

  92、把不可能变成可能。

  93、昨天的成功经验与辉煌可能是明天成功的阻碍。

  94、要做到实事求是,有两点很重要:其一是能不能实事求是,即思维方式的改变问题;其二是敢不敢实事求是,即思想境界的提高问题。

  95、解决无效管理,首先要在思想观念上树立以几何级数去提高工作效果的信心;其次,要有创新是无止境的观念,创新的空间存在于每个地方、每个人、每件事上。

  96、一切结论产生在调查研究之后;在调查研究中,如果找不出原因和解决办法就不能放过。

  97、抓管理肯定要数,但如果就数抓数,最后连数也得不到,或者只抓到一个假数。抓好提高人的素质工作,数自然会产生;不抓人的工作,数就会越来越差,不能见数不见人。

  98、以人为本的管理就是管理人员的创新精神。

  99、真正的人才是在寻找实现自我的机遇。

  100、市场是每个人的上级。


一道华为面试题

silver6 | 25 三月, 2006 20:39

将一个单链表反序,只有一个链表头节点head,还有两个指向节点元素类型的指针p和q,不许申请新的节点及指针变量什么的.用c或c++实现算法.

int MyList::Reverse()
{
ListNode *ptr = _ptrFront;
ListNode *ptrpre = 0;

_ptrFront = _ptrEnd;
_ptrEnd = ptr;
while(ptr!=_ptrFront)
{
ListNode *temp = ptr->Next();
ptr->Next(ptrpre);
ptrpre = ptr;
ptr = temp;
}
_ptrFront->Next(ptrpre);
return 0;
}

void InvertLinkedList( LinkList &L )
{
LinkList p,s;
// 逆置头指针L所指链表
p = L; L = NULL; // 设逆置后的链表的初态为空表
while ( p ) { // p 为待逆置链表的头指针
s = p; p = p->next; // 从 p 所指链表中删除第一个结点(s 结点)
s->next = L; L = s; // 将 s 结点插入到逆置表的表头
}
}

p=head->next;q=p->next;head=q->next;p->next=NULL;
do
{
q->next=p;
p=q;
q=head;
head=head->next;
}while(head);

令P指向节点1,Q指向节点2,Head指向节点3,由于P转换后为尾节点,所以P->Next指向NULL
循环移动,直到Head为NULL

哦,只有一个head,改一下:
int MyList::Reverse()
{
ListNode *ptr = _ptrFront;
ListNode *ptrpre = 0;

//_ptrFront = _ptrEnd;
//_ptrEnd = ptr;
while(ptr!=NULL)
{
ListNode *temp = ptr->Next();
ptr->Next(ptrpre);
ptrpre = ptr;
ptr = temp;
}
//_ptrFront->Next(ptrpre);
_ptrFront = ptrpre;
return 0;
}

int MyList::Reverse()
{
ListNode *ptr = _ptrFront;
ListNode *ptrpre = 0;

//_ptrFront = _ptrEnd;
//_ptrEnd = ptr;
while(ptr!=NULL)
{
_ptrFront = ptr->Next();
ptr->Next(ptrpre);
ptrpre = ptr;
ptr = _ptrFront;

}
_ptrFront = ptrpre;
return 0;
}

#include <iostream.h>

struct A
{
int m_value;
A *next;
};

A *Reverse(A *head)
{
A *p, *q;
if (head->next == NULL || head->next->next == NULL)
return head;

p = head->next;
q = p->next;
p->next = head;
head->next = NULL;
while (q != NULL)
{
head = p;
p = q;
q = q->next;
p->next = head;
}
return p;
}

int main(){
A array[5];

for(int i=0; i<5; i++)
{
array[i].m_value = i;
if (i == 4)
array[i].next = NULL;
else
array[i].next = &array[i+1];
}

A *head = array;

head = Reverse(head);

while (head != NULL)
{
cout<<head->m_value<<endl;
head = head->next;
}

return 0;
}

yiyo2025(EricKong)
你写的这个函数有个很明显的BUG哦
if (head->next == NULL || head->next->next == NULL)
return head;
???
这样当链表只有两个接结点的时候,第三个结点为空,直接返回头指针,根本没改变两个结点的顺序!
我帮你改了一下,呵呵

A *Reverse(A *head)
{
A *p1,*p2;
p1=head;
if(head->next==NULL)
return head;
p2=p1->next;
p1->next=NULL;
while(p2->next!=NULL)
{
head=p2->next;
p2->next=p1;
p1=p2;
p2=head;
}
p2->next=p1;
return p2;


华为笔试的一道题,看似简单

silver6 | 25 三月, 2006 18:44

在windows下,写出运行结果,说明为什么?
1,
int arr[]={6,7,8,9,10};

int *ptr=arr;

*(ptr++)+=123;

printf("line11%d,%d",*ptr,*(++ptr));

printf("line22%d,%d",*ptr,*(ptr++));

2,
int arr[]={6,7,8,9,10};

int *ptr=arr;

*(ptr++)=*(ptr++)+123;

printf("%d,%d",*ptr,*(++ptr));

?


同理,这一段输出:
int arr[]={6,7,8,9,10};

int *ptr=arr;

*(ptr++)=*(ptr++)+123;

printf("%d,%d,%d",*ptr++,*(++ptr),*(++ptr));
为10,10,9


即使是相同编译器,利用debug和release模式编译后,

老实说,很不同意。
debug 和 release 发生在源码区别上,至少 vc 如此, 编译器都是一样编译的,怎么可能不同?
除非发生以下情况

#ifdef _DEBUG
operator ++(a, 0){
...
}
#else
operator ++(a, 0){
...
}
#endif

1,在pritf语句中,表达式从右向左计算。

2,++ptr是在printf执行过程之中计算的。

3,ptr++是在printf执行完成以后计算的。

4,以下四个表达式执行之后结果一样的:

*(ptr++)=*(ptr++)+123;
*(++ptr)=*(++ptr)+123;
*(++ptr)=*(ptr++)+123;
*(ptr++)=*(++ptr)+123;

5,下面这个表达式和上面的四个执行之后结果是不一样的,:

*(ptr++)+=123; //为什么不一样?或者用堆栈的前序表达式和后序表达式能够说清楚吧!


*(ptr++)+=123; 等价代码为
*ptr = *ptr + 123;
ptr++;
而*(ptr++)=*(ptr++)+123; 等价为
*ptr = *ptr + 123;
ptr++;
ptr++;
再因为调用printf的时候是从右向左压栈,因此先计算后面的表达式。
所以会有以上结果


2005年华为招聘--C语言笔试试题

silver6 | 24 三月, 2006 19:21

一、判断题(对的写T,错的写F并说明原因,每小题4分,共20分)

1、有数组定义int a[2][2]={{1},{2,3}};a[0][1]的值为0。(

2int (*ptr) (),ptr是一维数组的名字。(

3、指针在任何情况下都可进行>,<,>=,<=,==运算。(

4switch(c) 语句中c可以是int ,long,char ,float ,unsigned int 类型。(

5#define print(x) printf(the no, #x,is )

二、填空题(共30分)

1、在windows下,写出运行结果,每空2分,共10分。

char str[ ]= Hello;

char *p=str;

int n=10;

sizeof(str)=( )

sizeof(p)=( )

sizeof(n)=( )

void func(char str[100])

{ }

sizeof(str)=( )

2void setmemory(char **p, int num)

{ *p=(char *) malloc(num);}

void test(void)

{ char *str=NULL;

getmemory(&str,100);

strcpy(str,hello);

printf(str);

}

运行test函数有什么结果?( 10

3、设int arr[]={6,7,8,9,10};

int *ptr=arr;

*(ptr++)+=123;

printf(%d,%d,*ptr,*(++ptr));

( ) 10

二、编程题(第一小题20,第二小题30分)

1 不使用库函数,编写函数int strcmp(char *source, char *dest)

相等返回0,不等返回-1

2 写一函数int fun(char *p)判断一字符串是否为回文,是返回1,不是返回0,出错返回-1


Oracle DBA面试题

silver6 | 23 三月, 2006 10:56

问题

  1如果信息采集管理系统(ICM)崩溃了怎么办?

  2你如何加速打补丁的过程?

  3打补丁的过程中出错了,你怎么办?

  4请提供克隆过程和克隆之后采取的手工操作的大概步骤。

  5介绍一下AutoConfig。AutoConfig是如何知道XML文件中的哪个树脂需要被放入哪一个文件的?

  6你能告诉我,你对一个发生故障的自服务登录问题做哪些测试吗?你要检查哪个配置文件操作选项和文件?

  7如果你不能看到并发管理日志和输出文件,是哪里出错了?

  8你是如何更改并发管理日志和输出文件的位置的?

  9如果用户正遇到性能方面的问题,你如何找到问题的原因?

  10你如何更改应用程序的密码?

  11请写出DBC文件的位置,并且解释它的重要性和应用程序如何知道DBC文件名?

  答案

  1所有其他的管理器都会继续工作。ICM只会处理队列控制请求,意思是开启和关闭其他并发的管理器。

  2

  2.1你可以合并多个补丁。

  2.2你可以为一个非交互的补丁创建一个响应文件。

  2.3你可以通过选项(nocompiledb, nomaintainmrc, nocompilejsp)来应用补丁,并且在应用了所有的补丁之后,一次运行它们。

  3 查看失败工作的日志,找到并且纠正错误,用adctrl 工具重新开启工作。

IT工作市场是如此的紧张,每个可获得的职位都有一堆人在申请。Naveen Nahata为Oracle E-Business Suite的数据库管理员申请者提供了以下一些面试时的技术问题,它可以帮助申请者们快速脱颖而出。如果你的面试官有类似的问题问你,发个邮件给我,我将会把它添加在列表中。――编者按

  问题

  1如果信息采集管理系统(ICM)崩溃了怎么办?

  2你如何加速打补丁的过程?

  3打补丁的过程中出错了,你怎么办?

  4请提供克隆过程和克隆之后采取的手工操作的大概步骤。

  5介绍一下AutoConfig。AutoConfig是如何知道XML文件中的哪个树脂需要被放入哪一个文件的?

  6你能告诉我,你对一个发生故障的自服务登录问题做哪些测试吗?你要检查哪个配置文件操作选项和文件?

  7如果你不能看到并发管理日志和输出文件,是哪里出错了?

  8你是如何更改并发管理日志和输出文件的位置的?

  9如果用户正遇到性能方面的问题,你如何找到问题的原因?

  10你如何更改应用程序的密码?

  11请写出DBC文件的位置,并且解释它的重要性和应用程序如何知道DBC文件名?

  答案

  1所有其他的管理器都会继续工作。ICM只会处理队列控制请求,意思是开启和关闭其他并发的管理器。

  2

  2.1你可以合并多个补丁。

  2.2你可以为一个非交互的补丁创建一个响应文件。

  2.3你可以通过选项(nocompiledb, nomaintainmrc, nocompilejsp)来应用补丁,并且在应用了所有的补丁之后,一次运行它们。

  3 查看失败工作的日志,找到并且纠正错误,用adctrl 工具重新开启工作。

4在源文件上(所有层)运行pre-clone,使用RMAN复制数据库(或者从热或者冷备份中重新存储数据库),拷贝文件系统,然后在目标文件(所有层)上运行post-clone 。

  手工步骤(可能会更多):

  4.1改变所有的非网站配置选项数值(快速克隆的话,只改变网站级别的配置文件选项)。

  4.2 修改工作流和并发管理器表。

  4.3更改打印机。

  5 AutoConfig 使用了一个上下文文件来维护关键的配置文件。一个上下文文件就是一个XML文件,在$APPL_TOP/admin 目录下,进行集中式的存储。

  当你运行AutoConfig 的时候,它读取XML文件,并且创建所有的AutoConfig 管理配置文件。

  对于AutoConfig维护的每个配置文件,都存在一个临时文件来判断哪个数值是从哪个XML文件中得来的。

  6

  6.1检查DBC文件中的guest的用户名和密码,配置选项guest的用户名和密码、数据库。

  6.2查看apache/jserv是否启动了。

  6.3运行IsItWorking, FND_WEB.PING, aoljtest等。

  7很有可能是FNDFS监听器停止了。看看FND_CONCURRENT_REQUESTS 表中的OUTFILE_NODE_NAME 和 LOGFILE_NODE_NAME 的数值。看看FND_NODES 表。看看tnsnames.ora 中的FNDFS_ entry 。

  8日志问卷爱女的位置是由$APPLCSF/$APPLLOG 参数来决定的,输出文件的位置是由$APPLCSF/$APPLOUT 决定的。

  9

  9.1追踪这个会话(用等待)并且使用tkprof 来分析追踪文件。

  9.2生成statspack 报告并进行分析。

  9.3使用top/iostat/sar/vmstat 监控O/s 。

  9.4通过ping这类基本的测试结果来判断网络的瓶颈。

  10

  10.1 使用FNDCPASS 来更改APPS密码。

  10.2 手工修改wdbsvr.app/cgiCMD.dat 文件。

  10.3 更改所有从其他环境指过来的数据库链接。

  11

  11.1位置:$FND_TOP/secure directory

  11.2 重要性:在其他事务中指向数据库服务器。

  11.3 应用程序通过使用“Applications Database Id.”来了解DBC文件的名字。


昨天一外企的面试题目

silver6 | 21 三月, 2006 10:01

1。有几种方法计算运行一个方法所需的时间。
2。怎样调用一个类的私有方法。

?


1。1种方法是在函数调用前new一个Date,返回后再new一个Date,相减可得,当然也可以在函数内部的首句和末句new Date计算(感觉比较傻)
2。可以将此类的private function封装在一个public function中,再调用公用方法

PS:感觉自己想的太简单,还是听高手正解~~

感觉和楼上的一样呀.
计算方法运行的时间应该还可以写一个Thread类型的计时器,进入方法体的时候开启这个线程,结束的时候停止.这样就可以算出运行了多长时间了.

调用一个类的PRIVATE方法的话,继承了那个类也算可以调用它的PRIVATE方法吧.

1.在调用发前new两个Date,调用后new一个Date,分别为date1,date2,date3
则方法运行时间为:(date3-date2)-(date2-date1)
因为new一个Date也需要时间

2.如果非要在类外部直接通过对对象发消息传递是不可能的,他破坏了面向对象程序的封装性

1. 方法如下:
(1).通过在方法首先与结束处加上Date来相减; ---上面已提
(2).通过在首行与结束加对另外一个线程来实现; ---上面已提
(3).通过Proxy的方式,即调用时通过proxy来调用,在proxy中加入时间运行算;
(4). 如果你支持AspectJ的话,就更好办了。

2. 调用private方法,我想的到只有一种,就是"反射"。

怎么没人用System.currentTimeMillis(),而要new一个Date


a1: //initialize paramter
long a = System.cur....();
//invoke this method
a = System.curr...() - a;
System.out.println(a);

a2:
cannot。

1)System.currentTimeMillis();最常用的测时间方法,也是优化程序的工具。
2)要想直接调用一个类的私有方法,最好的办法就是用内部类

1)System.currentTimeMillis();最常用的测时间方法,也是优化程序的工具。
2)要想直接调用一个类的私有方法,最好的办法就是用内部类

这两个问题可以找到共同点,那就是 “反射”,

第一个问题用 AOP,
第二个问题可以这样。

import java.lang.reflect.Method;

class A {
private int count;

private int getCount() {
return count;
}

private void setCount(int count) {
this.count = count;
}

public String toString() {
return "Count :" + count;
}
}
/**
* @author Daniel Young
*/

public class B {

public static void main(String[] args) {
A a = new A();

Class clazz = a.getClass();

try {
Method method = clazz.getDeclaredMethod("setCount",
new Class[] { int.class });

method.setAccessible(true);

method.invoke(a, new Object[] { new Integer(5) });

System.out.println("Created & initialized instance :" + a);

} catch (Exception e) {
e.printStackTrace();
}
}
}


这个华为的题怎么作,关于字符串的

silver6 | 21 三月, 2006 09:54

char str1[]="abcdnabcdmabcduabcdoabcdg";
char str2[]="abcd";
求str1中abcd出现的次数
以下是我写的但是不对 输不出来,麻烦帮我看看那里错了?我用的是每4个一比较,逐个比较
#include "stdio.h"
#include "string.h"
main()
{
char str1[]="abcdnabcdmabcduabcdoabcdg";
char str2[]="abcd";
char *p,*t;
p=str1;
t=str2;
int k=0;
int i=0;
int j=0;
int len=strlen(str1);
for(i=0;i<=len-1;i++)
p++; t=str2;
for(j=0;j<4;j++)

if(*p==*t)
{
p++;
t++;
}
k++;

if(j==3)
printf("%d",k);


return k;
}

#include <stdio.h>
#include <string.h>

main()
{
int i;
int j;
int num;
int len;

char str1[] = "abcdnabcdmabcduabcdoabcdg";
char str2[] = "abcd";
char *p, *t;
p = str1;
t = str2;

num = 0;
len = strlen(str1);

for(i = 0; i < len; i++)
{
if(*p == 'a')
{
for(j = 0; j < 4; j++)
{
if(p++ == t++)
;
}
t = str2;
num++;
}
else
{
p++;
}
}
printf("%dn", num);
}

int strstr_cnt(const char *string ,const char *substring)
{
int i,j,k,count=0;
for(i=0;string[i];i++)
for(j=i,k=0;string[j]==substring[k];j++,k++)
if(!substring[k+1])
count++;
return(count);
}

int substr_time(const char *strSrc, const char *strSub)
{
int appTime = 0;

cout << strlen(strSub)<<endl;

while(*strSrc != '')
{
if( *strSrc == strSub[0] )
{
if(!strncmp(strSrc,strSub,strlen(strSub)))
{
appTime++;
}
}
strSrc++;
}

return appTime;
}

#include <iostream>

using namespace std;

int main()
{
char str1[]="abcdnabcdmabcduabcdoabcdg";
char str2[]="abcd";
const int len = 4;
int num = 0;
int j = 0;

for(int i=0; str1[i] != ''; i++)
{
if(str1[i] == str2[j])
{
if(j == len - 1)
{
num ++;
j = 0;
}
else
{
j++;
}
}
else
j = 0;
}
cout<< num<< endl;
}

#include "stdio.h"
void get_next(char *ch, int len ,int *next )
{
int j,k;
j=0;
k=-1;
next[0]=-1;
while(j<len)
{
if(k==-1||ch[j]==ch[k])
{
j++;
k++;
if(ch[j]==ch[k])
next[j]=next[k];
else
next[j]=k;
}
else
k=next[k];
}
}

int kmpindex(char *s,char *t,int s_len, int t_len,int star)
{
int next[20],i=star,j=0,v;
get_next(t,t_len,next);
while(i<s_len&&j<t_len)
{
if(j==-1||s[i]==t[j])
{
i++;
j++;
}
else
j=next[j];

if(j==t_len)
v=i-t_len;
else
v=-1;
}
return(v);
}

void main()
{
int j,s_len,t_len, n=0 , star=0;
char *s="abcdnabcdmabcduabcdoabcdg";
char *t="abcd";

while(star<=s_len-t_len&&j!=-1)
{
j=kmpindex(s,t,s_len,t_len,star);
star=j+t_len+1;
if(j!=-1)n++ ;
}
printf("%dn", n );
}

int getcount(char *str1,char *str2)
{int len=0;n=0;
for(;str1!='';str1++)
{ while(len<strlen(str2))
{if(*str1==*str2++)
len++;
else break;
}
if(len==strlen(str2))
n++;
}
return n;
}

#include <stdio.h>
#include <stdlib.h>
char str1[]="abcdnabcdmabcduabcdoabcdg";
char str2[]="abcd";
int Find_str(char *,char *);
void main()
{
int num;
num = Find_str(str1,str2);
printf("the num is %d",num);
}

int Find_str(char *str1,char *str2)
{
char *ptr1;
char *ptr2;
char *ptr;

int retcode = 0;
ptr1 = str1;
while(*ptr1!='')
{
if(*ptr1==*str2)
{
ptr=ptr1;
ptr2=str2;
while((*ptr!='')&&(*ptr2!='')&&(*ptr==*ptr2))
{
ptr++;
ptr2++;
}
if(*ptr2=='')
{
retcode++;
}
}
ptr1++;
}
return retcode;
}

#include "stdio.h"
#include "string.h"

void main()
{
char str1[] = "abcdnabcdmabcduabcdoabcdg";
char str2[] = "abcd";
unsigned count = 0;
unsigned j = 0;
unsigned k;

for (unsigned i = 0; i < strlen(str1) - 3;)
{
k = 0;
j = i;
while (str1[i] == str2[k])
{
i++;
k++;
}
if (k >= strlen(str2))
{
i = j + 4;
count++;
}
else if (k == 3)
{
i = j + 3;
}
else if (k == 2)
{
i = j + 2;
}
else
{
i = j + 1;
}


}

printf("%dn",count);
}

可以先自己写一个查找字符串的函数,
如 int find(char str1[], char str2[], int i);
其中str1为原字符串,str2为被查找字符串(假设str1和str2最后一个字符是 ''),
i是从这个字符串中最几个字符开始查找。 当找到后,返回被查找
字符串第一个出现的位置,如果未找到,返回-1.

然后在主程序中用如下代码

char str1[]="abcdnabcdmabcduabcdoabcdg";
char str2[]="abcd";

int count = 0;
int pos; // 4为str2的长度(可以用strlen得到,不会连这个函数也不让用吧?
for(pos = find(str1, str2, 0); pos != -1;
pos = find(str1, str2, pos + 4))
count++;

printf("the repeat count: %dn", count);


摩托罗拉部分C++面试题

silver6 | 13 三月, 2006 18:50

1.介绍一下STL,详细说明STL如何实现vector。
2.如果用VC开发程序,常见这么几个错误,C2001,c2005,c2011,这些错误的原因是什么。
3.继承和委派有什么分别,在决定使用继承或者委派的时候需要考虑什么。
4.指针和引用有什么分别;如果传引用比传指针安全,为什么?如果我使用常量指针难道不行吗?
5.参数传递有几种方式;实现多态参数传递采用什么方式,如果没有使用某种方式原因是什么;
6.结合一个项目说明你怎样应用设计模式的理念。
7.介绍一下你对设计模式的理解。(这个过程中有很多很细节的问题随机问的)
8.C++和C定义结构的分别是什么。
9.构造函数可否是虚汗数,为什么?析构函数呢,可否是纯虚的呢?
10,拷贝构造函数相关问题,深拷贝,浅拷贝,临时对象等。
11.结合1个你认为比较能体现OOP思想的项目,用UML来描述。(最好这个项目继承,多态,虚函数都有体现)这个问题大概会占面试时间的一半,并且会问很多问题,一不小心可能会被问住)。
12。基类的有1个虚函数,子类还需要申明为virtual吗?为什么。
13.C也可以通过精心封装某些函数功能实现重用,那C++的类有什么优点吗,难道仅仅是为实现重用。
14.C++特点是什么,如何实现多态?画出基类和子类在内存中的相互关系。
15.为什么要引入抽象基类和纯虚函数?
16.介绍一下模板和包容器。如何实现?(也许会让你当场举例实现)
17.你如何理解MVC。简单举例来说明其应用。
18,多重继承如何消除向上继承的二义性。

关于问题2:我想是我说自己常用VC编程,他们觉得那你要常常用的话,这种常见错误肯定知道原因。我当时想:你就不能说错误提示是什么,我也好分析一下,那么多错误代码,我哪记得哪个对应哪个啊。
以下回答部分问题,有的还是没有找到答案:
1.没用过STL,只是有听说过,特点是泛型,也是基于多态和模板技术。向量是可以看作是动态数组。再深的就答不出了。
2.见MSDN.
3.这是他们问的最后一个问题。我当时不知道使用中有什么差别,离开前问了他们。继承和委派差别主要是语义不同。详见《高质量C++编程》和《设计模式》第一章。
4.定义引用必须要初始化,指针不必。后面的不知道。
5.传值,传地址,传引用;多态通常使用后两个;不知道有无使用传值的。
6.略。最好能抽象层次比较高。
7.这个我觉得他当时问的有问题,C++和C定义结构没有区别,只是在定义结构类型变量的时候,C++不需要struct关键字。
9.构造函数不可是虚函数,析构函数可以是,也可以是纯虚的。见《thinking in c++》第14章
10.钱能那本《C++程序设计》有很详细的说明。
11.略。最好能体现你基类设计的比较好,多态等应用。
12.不需要。
13.应该是白盒和黑盒的区别。欢迎补充。
14.特点封装,继承,重载,多态;多态是通过虚函数和滞后联编实现。那个著名的图就不画了。他们可能会让你写几个类来说明,或者给你几个,让你描述。
15.见钱能那本《C++程序设计》,P370-P375.这里略。
16.不知道,但是《thinking in c++》有说明。
17.model,view,controler.我以改变用户输入方式不应当影响视图来说明的。
18.《thinking in c++》有说明

LINK2001....以前真的去查过.....
  一.由于编码错误导致的LNK2001。
  1.不相匹配的程序代码或模块定义(.DEF)文件能导致LNK2001。例如,
如果在C++ 源文件内声明了一变量“var1”,却试图在另一文件内以变量
“VAR1”访问该变量,将发生该错误。
  2.如果使用的内联函数是在.CPP文件内定义的,而不是在头文件内定
义将导致LNK2001错误。
  3.调用函数时如果所用的参数类型同函数声明时的类型不符将会产生
LNK2001。
  4.试图从基类的构造函数或析构函数中调用虚拟函数时将会导致LNK2001。
  5.要注意函数和变量的可公用性,只有全局变量、函数是可公用的。
  静态函数和静态变量具有相同的使用范围限制。当试图从文件外部访问
任何没有在该文件内声明的静态变量时将导致编译错误或LNK2001。
  函数内声明的变量(局部变量) 只能在该函数的范围内使用。
  C++ 的全局常量只有静态连接性能。这不同于C,如果试图在C++的
多个文件内使用全局变量也会产生LNK2001错误。一种解决的方法是需要时在
头文件中加入该常量的初始化代码,并在.CPP文件中包含该头文件;另一种
方法是使用时给该变量赋以常数。
  二.由于编译和链接的设置而造成的LNK2001
  1.如果编译时使用的是/NOD(/NODEFAULTLIB)选项,程序所需要的运行
库和MFC库在连接时由编译器写入目标文件模块, 但除非在文件中明确包含
这些库名,否则这些库不会被链接进工程文件。在这种情况下使用/NOD将导
致错误LNK2001。
  2.如果没有为wWinMainCRTStartup设定程序入口,在使用Unicode和MFC
时将得到“unresolved external on _WinMain@16”的LNK2001错误信息。
  3.使用/MD选项编译时,既然所有的运行库都被保留在动态链接库之内,
源文件中对“func”的引用,在目标文件里即对“__imp__func” 的引用。
如果试图使用静态库LIBC.LIB或LIBCMT.LIB进行连接,将在__imp__func上发
生LNK2001;如果不使用/MD选项编译,在使用MSVCxx.LIB连接时也会发生LNK2001。
  4.使用/ML选项编译时,如用LIBCMT.LIB链接会在_errno上发生LNK2001。
  5.当编译调试版的应用程序时,如果采用发行版模态库进行连接也会产
生LNK2001;同样,使用调试版模态库连接发行版应用程序时也会产生相同的
问题。
  6.不同版本的库和编译器的混合使用也能产生问题,因为新版的库里可
能包含早先的版本没有的符号和说明。
  7.在不同的模块使用内联和非内联的编译选项能够导致LNK2001。如果
创建C++库时打开了函数内联(/Ob1或/Ob2),但是在描述该函数的相应头
文件里却关闭了函数内联(没有inline关键字),这时将得到该错误信息。
为避免该问题的发生,应该在相应的头文件中用inline关键字标志内联函数。
  8.不正确的/SUBSYSTEM或/ENTRY设置也能导致LNK2001

编译器错误 C2001
常数中有换行符

字符串常数不能继续到第二行,除非进行下列操作:

用反斜杠结束第一行。
用一个双引号结束第一行上的字符串,并在下一行用另一个双引号开始该字符串。
用 n 结束第一行是不够的。例如:

printf("Hello, // error
world");
printf("Hello,n // error
world");
printf("Hello, // OK
world");
printf("Hello," // OK
" world");
下一行开始处位于行继续符后的空格包含在字符串常数中。以上显示的示例都没有将换行符嵌入字符串常数中。可以按如下所示嵌入换行符:

printf("Hello,n
world");
printf("Hello,
nworld");
printf("Hello,n"
"world");
printf("Hello,"
"nworld");

//////////////////////////////////////////////////////////////////////////////

编译器错误 C2005

#line 应输入行号,却找到“token”

#line 指令后面必须跟行号。下面的示例生成 C2005:

// C2005.cpp
int main() {
int i = 0;
#line i // C2005

// try ...
// #line 0
}

//////////////////////////////////////////////////////////////////////////////

编译器错误 C2011

“identifier”:“type”类型重定义

该标识符已定义为 type 类型。如果多次将某个类型库导入同一个文件,也可能生成 C2011。

例如:

struct S;
union S; // Error C2011

多重继承上的二义性见例子:
class A{
public:
ostream &print(ostream&)const;
void highlight();
};
class B{
public:
bool onExhibit()const;
private:
bool highlight(int zoo_location);
};
calss C:public B
{
ostream &print(ostream&)const;
void dance(dance_type)const;
};
class D:public C,public A
{
void cuddle()const;
};
void main()
{
//以下调用都是二义的
C::print(ostream&)const;
A::print(ostream&)const;
}
如果在两个或多个基类中都找到了声明,则调用是二义的.
解决二义的方法是采用虚拟继承.


Java编程思想读书笔记(1、2、3章)

silver6 | 06 一月, 2006 11:57

一.所有对象都必须由你建立

   1. 存储在哪里

   1. 寄存器:我们在程序中无法控制

   2. stack:存放基本类型的数据和对象的reference,但对象本身不存放在stack中,而是存放在Heap中

   3. Heap:存放用new产生的数据

   4. Static storage:存放在对象中用static定义的静态成员

   5. Constant storage:存放常量

   6. NON-RAM:硬盘等永久存储空间

   2. 特例:基本型别

   基本类型数据存放在Stack中,存放的是数据。而产生对象时,只把对象的reference存放在stack中,用于指向某个对象,对象本身存放在Heap中。

   3. Java中的数组

   当你产生某个存储对象的数组时,真正产生的其实是存储reference的数组。引数组建立后,其中的每一个reference都会被自动设为null,表示“不指向任何对象”。

   二.建立新的数据型别:Class

   1. 数据成员和函数

   1.1 基本成员的缺省值

   1) 当class的某个成员属于基本型别时,即使你没有为它提供初值,Java仍保证它有一个缺省值。

   2) 只有当变量身份是“class内的成员时,Java才保证为该变量提供初值。

   三.函数(Mehtods),引数(arguments),返回值(return values)

   1. 引数列

   当引数传递的是对象时,传递的是对象的reference。

   四.注解用内嵌式文档

   Java提供两种注解风格:/*XXXX*/、//XXXX

  第3章 控制程序流程
   一.使用Java运算符

   1.关系运算符

   1.) 当对两个对象运用关系运算符进行比较时,比较的是object reference,如:

   Integer n1 = new Integer(3);
   Integer n2 = new Integer(3);
   System.out.println(n1==n2);
   结果为false,因为两个object reference(n1和n2)值是不同的
   2) quals()的缺省行为也是拿referenct来比较。不过Java中的class覆写了equals方法,如:

   Integer n1 = new Integer(3);
   Integer n2 = new Integer(3);
   System.out.println(n1.quals(n2));//值为true
   2. 逻辑运算符

   1) 只能将and、or、not施用于boolean值身上。如果逻辑运算符两边的值存在non-boolean值,将会出错,如:

   int test1 = 1;
   System.out.println((test && 1<2);//编辑出错,test是non-boolean值
   3. 位移运算符

   如果所操作的位移对象是char、byte、short,位移动作发生之前,其值会先被晋升为int,运算结果会是int。

   二.流程控制

   1. 迭代(iteration)

   1.1 逗号运算符

   逗号运算符只能用于for循环的控制表达式中的initialization和step两部分中,如:for(int i=0, j=I+1; I<5; i++, j=I*2)

   1.2 break和continue

   break表示退出循环;continue表示退出本次循环,回来循环起始位置。

   1.3 label

   label只有放在迭代语句之前才起作用,在label和迭代语句之间插入任何语句都不会起作用。

   2. Switch

   switch中的选择器必须是int或char型,如:

   float i = 2;
   switch ( i )//将出错,因为i不是int或char之一
   3. 计算细节

   1) 从float或double转为整数值,总是以完全舍弃小数的方式进行。

   4. Math.random()的输出范围是[0, 1]。

JNI完全手册(二)

silver6 | 06 一月, 2006 11:32

我的项目比较复杂,需要调用动态链接库,这样在JNI传送参数到C程序时,需要对参数进行处理转换。才可以被C程序识别。
大体程序如下:

  1. public class SendSMS {
  2. static
  3. {
  4. System.out.println(System.getProperty("java.library.path"));
  5. System.loadLibrary("sms");
  6. }
  7. public native static int SmsInit();
  8. public native static int SmsSend(byte[] mobileNo, byte[] smContent);
  9. }

在这里要注意的是,path里一定要包含类库的路径,否则在程序运行时会抛出异常:
java.lang.UnsatisfiedLinkError: no sms in java.library.path
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1491)
at java.lang.Runtime.loadLibrary0(Runtime.java:788)
at java.lang.System.loadLibrary(System.java:834)
at com.mobilesoft.sms.mobilesoftinfo.SendSMS.<clinit>(SendSMS.java:14)
at com.mobilesoft.sms.mobilesoftinfo.test.main(test.java:18)
Exception in thread "main"
指引的路径应该到.dll文件的上一级,如果指到.dll,则会报:
java.lang.UnsatisfiedLinkError: C:sms.dll: Can't find dependent libraries
at java.lang.ClassLoader$NativeLibrary.load(Native Method)
at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1560)
at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1485)
at java.lang.Runtime.loadLibrary0(Runtime.java:788)
at java.lang.System.loadLibrary(System.java:834)
at com.mobilesoft.sms.mobilesoftinfo.SendSMS.<clinit>(SendSMS.java:14)
at com.mobilesoft.sms.mobilesoftinfo.test.main(test.java:18)
Exception in thread "main"
通过编译,生成com_mobilesoft_sms_mobilesoftinfo_SendSMS.h头文件。(建议使用Jbuilder进行编译,操作比较简单!)这个头文件就是Java和C之间的纽带。要特别注意的是方法中传递的参数jbyteArray,这在接下来的过程中会重点介绍。
  1. /* DO NOT EDIT THIS FILE - it is machine generated */
  2. #include <jni.h>
  3. /* Header for class com_mobilesoft_sms_mobilesoftinfo_SendSMS */
  4. #ifndef _Included_com_mobilesoft_sms_mobilesoftinfo_SendSMS
  5. #define _Included_com_mobilesoft_sms_mobilesoftinfo_SendSMS
  6. #ifdef __cplusplus
  7. extern "C" {
  8. #endif
  9. /*
  10. * Class: com_mobilesoft_sms_mobilesoftinfo_SendSMS
  11. * Method: SmsInit
  12. * Signature: ()I
  13. */
  14. JNIEXPORT jint JNICALL Java_com_mobilesoft_sms_mobilesoftinfo_SendSMS_SmsInit
  15. (JNIEnv *, jclass);
  16. /*
  17. * Class: com_mobilesoft_sms_mobilesoftinfo_SendSMS
  18. * Method: SmsSend
  19. * Signature: ([B[B)I
  20. */
  21. JNIEXPORT jint JNICALL Java_com_mobilesoft_sms_mobilesoftinfo_SendSMS_SmsSend
  22. (JNIEnv *, jclass, jbyteArray, jbyteArray);
  23. #ifdef __cplusplus
  24. }
  25. #endif
  26. #endif

对于我要调用的C程序的动态链接库,C程序也要提供一个头文件,sms.h。这个文件将要调用的方法罗列了出来。
  1. /*
  2. * SMS API
  3. * Author: yippit
  4. * Date: 2004.6.8
  5. */
  6. #ifndef MCS_SMS_H
  7. #define MCS_SMS_H
  8. #define DLLEXPORT __declspec(dllexport)
  9. /*sms storage*/
  10. #define SMS_SIM 0
  11. #define SMS_MT 1
  12. /*sms states*/
  13. #define SMS_UNREAD 0
  14. #define SMS_READ 1
  15. /*sms type*/
  16. #define SMS_NOPARSE -1
  17. #define SMS_NORMAL 0
  18. #define SMS_FLASH 1
  19. #define SMS_MMSNOTI 2
  20. typedef struct tagSmsEntry {
  21. int index; /*index, start from 1*/
  22. int status; /*read, unread*/
  23. int type; /*-1-can't parser 0-normal, 1-flash, 2-mms*/
  24. int storage; /*SMS_SIM, SMS_MT*/
  25. char date[24];
  26. char number[32];
  27. char text[144];
  28. } SmsEntry;
  29. DLLEXPORT int SmsInit(void);
  30. DLLEXPORT int SmsSend(char *phonenum, char *content);
  31. DLLEXPORT int SmsSetSCA(char *sca);
  32. DLLEXPORT int SmsGetSCA(char *sca);
  33. DLLEXPORT int SmsSetInd(int ind);
  34. DLLEXPORT int SmsGetInd(void);
  35. DLLEXPORT int SmsGetInfo(int storage, int *max, int *used);
  36. DLLEXPORT int SmsSaveFlash(int flag);
  37. DLLEXPORT int SmsRead(SmsEntry *entry, int storage, int index);
  38. DLLEXPORT int SmsDelete(int storage, int index);
  39. DLLEXPORT int SmsModifyStatus(int storage, int index); /*unread -> read*/
  40. #endif

在有了这两个头文件之后,就可以进行C程序的编写了。也就是实现对JNI调用的两个方法。在网上的资料中,由于调用的方法实现的都比较简单,(大多是打印字符串等)所以避开了JNI中最麻烦的部分,也是最关键的部分,参数的传递。由于Java和C的编码是不同的,所以传递的参数是要进行再处理,否则C程序是会对参数在编译过程中提出警告,例如;warning C4024: 'SmsSend' : different types for formal and actual parameter 2等。
Sms.c的程序如下:
  1. #include "sms.h"
  2. #include "com_mobilesoft_sms_mobilesoftinfo_SendSMS.h"
  3. JNIEXPORT jint JNICALL Java_com_mobilesoft_sms_mobilesoftinfo_SendSMS_SmsInit(JNIEnv * env, jclass jobject)
  4. {
  5. return SmsInit();
  6. }
  7. JNIEXPORT jint JNICALL Java_com_mobilesoft_sms_mobilesoftinfo_SendSMS_SmsSend(JNIEnv * env, jclass jobject, jbyteArray mobileno, jbyteArray smscontent)
  8. {
  9. char * pSmscontent ;
  10. //jsize theArrayLengthJ = (*env)->GetArrayLength(env,mobileno);
  11. jbyte * arrayBody = (*env)->GetByteArrayElements(env,mobileno,0);
  12. char * pMobileNo = (char *)arrayBody;
  13. printf("[%s]n ", pMobileNo);
  14. //jsize size = (*env)->GetArrayLength(env,smscontent);
  15. arrayBody = (*env)->GetByteArrayElements(env,smscontent,0);
  16. pSmscontent = (char *)arrayBody;
  17. printf("<%s>n", pSmscontent);
  18. return SmsSend(pMobileNo,pSmscontent);
  19. }

对于C或C++,在程序上是会有稍微的不同,这可以由读者对其进行适当的修改。这里要注意的是GetArrayLength,GetByteArrayElements等这些JNI中已经包含的方法,这些方法是专门对转换参数类型而提供的。具体的方法有很多,在下一篇中会做专门的介绍。
在完成了上述的文件后,可以对sms.c进行编译,生成.dll文件(建议在release中编译,这样动态链接库的容积会比较小!)
完成.dll文件的编译后,就可以在Java中调用C程序中的方法了。例如文件test.java
  1. public class test {
  2. public test() {
  3. }
  4. public static void main(String[] args) {
  5. byte[] mobileno = {
  6. 0x31, 0x33, 0x36, 0x36, 0x31, 0x36, 0x33, 0x30, 0x36, 0x36, 0x37, 0x00};
  7. String smscontentemp = "早上好";
  8. byte[] temp = {0};
  9. try {
  10. byte[] smscontentdb = smscontentemp.getBytes("gbk");
  11. byte[] smscontent = new byte[smscontentdb.length + temp.length];
  12. System.arraycopy(smscontentdb, 0, smscontent, 0, smscontentdb.length);
  13. System.arraycopy(temp, 0, smscontent, smscontentdb.length, temp.length);
  14. SendSMS sendSMS = new SendSMS();
  15. sendSMS.SmsInit();
  16. if (sendSMS.SmsSend(mobileno, smscontent) >= 0) {
  17. System.out.println("chenggong !");
  18. }
  19. else {
  20. System.out.println("shibai !");
  21. }
  22. }catch (Exception ex) {}
  23. }
  24. }

在这个文件中要注意的有一点,就是在传递字节数组到C程序中时,最后的结尾一定要以0结束。这是一个偷懒的做法,不过是个有效的做法。因为大多数情况下,接口是由第三方提供的。所以我们一般是不知道在C的方法里,具体是怎么处理参数的。而C又是要求数组是有长度。所以,在Java中,如果你不想写程序传数组的长度,那么在数组中以0结尾就是最方便的方法了。当然,如果有更好的方法也希望大家提出。
到这里,一个完整的Java通过JNI调用动态链接库的程序就完成了。实际上也不是很复杂。只要多注意一下细节,是很容易得出来的。

JNI完全手册1

silver6 | 06 一月, 2006 11:29

最近在公司里做了一个手机的项目,需要JAVA程序在发送短信的时候和第三方的短信服务器连接。短信接口是用C++写的。琢磨了三天,大致搞懂了JNI的主体部分。先将心得整理,希望各位朋友少走弯路。
  
  首先引用一篇文章,介绍一个简单的JNI的调用的过程。
  
  JAVA以其跨平台的特性深受人们喜爱,而又正由于它的跨平台的目的,使得它和本地机器的各种内部联系变得很少,约束了它的功能。解决JAVA对本地操作的一种方法就是JNI。
  
  JAVA通过JNI调用本地方法,而本地方法是以库文件的形式存放的(在WINDOWS平台上是DLL文件形式,在UNIX机器上是SO文件形式)。通过调用本地的库文件的内部方法,使JAVA可以实现和本地机器的紧密联系,调用系统级的各接口方法。
  
  简单介绍及应用如下:
  
  一、JAVA中所需要做的工作

  在JAVA程序中,首先需要在类中声明所调用的库名称,如下:
  static {
  System.loadLibrary(“goodluck”);
  }

  在这里,库的扩展名字可以不用写出来,究竟是DLL还是SO,由系统自己判断。
  还需要对将要调用的方法做本地声明,关键字为native。并且只需要声明,而不需要具 体实现。如下:
  public native static void set(int i);
  public native static int get();
  然后编译该JAVA程序文件,生成CLASS,再用JAVAH命令,JNI就会生成C/C++的头文件。
  例如程序testdll.java,内容为:
  public class testdll
  {
  static
  {
  System.loadLibrary("goodluck");
  }
  public native static int get();
  public native static void set(int i);
  public static void main(String[] args)
  {
  testdll test = new testdll();
  test.set(10);
  System.out.println(test.get());
  }
  }

  用javac testdll.java编译它,会生成testdll.class。
  再用javah testdll,则会在当前目录下生成testdll.h文件,这个文件需要被C/C++程序调用来生成所需的库文件。
  
  二、C/C++中所需要做的工作

  对于已生成的.h头文件,C/C++所需要做的,就是把它的各个方法具体的实现。然后编译连接成库文件即可。再把库文件拷贝到JAVA程序的路径下面,就可以用JAVA调用C/C++所实现的功能了。
  接上例子。我们先看一下testdll.h文件的内容:
  /* DO NOT EDIT THIS FILE - it is machine generated */
  #include
  /* Header for class testdll */
  #ifndef _Included_testdll
  #define _Included_testdll
  #ifdef __cplusplus
  extern "C" {
  #endif
  /*
  * Class: testdll
  * Method: get
  * Signature: ()I
  */
  JNIEXPORT jint JNICALL Java_testdll_get (JNIEnv *, jclass);
  /*
  * Class: testdll
  * Method: set
  * Signature: (I)V
  */
  JNIEXPORT void JNICALL Java_testdll_set (JNIEnv *, jclass, jint);
  #ifdef __cplusplus
  }
  #endif
  #endif
  在具体实现的时候,我们只关心两个函数原型
  JNIEXPORT jint JNICALL Java_testdll_get (JNIEnv *, jclass); 和
  JNIEXPORT void JNICALL Java_testdll_set (JNIEnv *, jclass, jint);
  这里JNIEXPORT和JNICALL都是JNI的关键字,表示此函数是要被JNI调用的。而jint是以JNI为中介使JAVA的int类型与本地的int沟通的一种类型,我们可以视而不见,就当做int使用。函数的名称是JAVA_再加上java程序的package路径再加函数名组成的。参数中,我们也只需要关心在JAVA程序中存在的参数,至于JNIEnv*和jclass我们一般没有必要去碰它。
  好,下面我们用testdll.cpp文件具体实现这两个函数:
  #include "testdll.h"
  int i = 0;
  JNIEXPORT jint JNICALL Java_testdll_get (JNIEnv *, jclass)
  {
  return i;
  }
  JNIEXPORT void JNICALL Java_testdll_set (JNIEnv *, jclass, jint j)
  {
  i = j;
  }

  编译连接成库文件,本例是在WINDOWS下做的,生成的是DLL文件。并且名称要与JAVA中需要调用的一致,这里就是goodluck.dll 。把goodluck.dll拷贝到testdll.class的目录下,java testdll运行它,就可以观察到结果了。
  
  我的项目比较复杂,需要调用动态链接库,这样在JNI传送参数到C程序时,需要对参数进行处理转换。才可以被C程序识别。
  
  大体程序如下:
  public class SendSMS {
  static
  {
  System.out.println(System.getProperty("java.library.path"));
  System.loadLibrary("sms");
  }
  public native static int SmsInit();
  public native static int SmsSend(byte[] mobileNo, byte[] smContent);
  }
  在这里要注意的是,path里一定要包含类库的路径,否则在程序运行时会抛出异常:
  java.lang.UnsatisfiedLinkError: no sms in java.library.path
  at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1491)
  at java.lang.Runtime.loadLibrary0(Runtime.java:788)
  at java.lang.System.loadLibrary(System.java:834)
  at com.mobilesoft.sms.mobilesoftinfo.SendSMS.(SendSMS.java:14)
  at com.mobilesoft.sms.mobilesoftinfo.test.main(test.java:18)
  Exception in thread "main"
  指引的路径应该到.dll文件的上一级,如果指到.dll,则会报:
  java.lang.UnsatisfiedLinkError: C:sms.dll: Can't find dependent libraries
  at java.lang.ClassLoader$NativeLibrary.load(Native Method)
  at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1560)
  at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1485)
  at java.lang.Runtime.loadLibrary0(Runtime.java:788)
  at java.lang.System.loadLibrary(System.java:834)
  at com.mobilesoft.sms.mobilesoftinfo.SendSMS.(SendSMS.java:14)
  at com.mobilesoft.sms.mobilesoftinfo.test.main(test.java:18)
  Exception in thread "main"

看TVB连续剧所记录下的一些经典的话语

silver6 | 16 十二月, 2005 09:42

放下利害、放下尊严、放下身份,爱情面前,比法律更人人平等。

真正聪明的女人都会知道,她无论和什么男人说话时,懂得的事都应该比男人少。

男人有权就会变得蛮横,女人要变得蛮横才会有权。

最理想的夫妻关系是,亲密而带适当,坦诚中保留部分隐秘,既可两情,又有个人天地。

男人都会喜欢听话的女人,但男人若是喜欢一个女人,就会不知不觉听那女人的话。

女人成功背后多有一个伤她的男人,男人成功背后多有一个爱她的女人。

做情人的时候,女人会让男人心痛
做妻子的时候,女人会让男子头痛

男人认为女人可爱最重要
女人认为男人可靠最重要

迁就,容忍,屈服,接纳,适应,宽恕,谅解,妥协,毅力,认命,婚姻爱情可训练出“十项全能”

一个成功的男人就是能够赚到比女人花得更多钱的人,
一个成功的女人就是能够找到一个这样的男人

一个女人会为未来担心,直到她找到一个丈夫为止,
一个男人从不会为未来担心,直到他找到一个妻子为止。

男人想做女人的初恋情人,
女人想做男人的最后一个情人。

聪明的女人都知道,软弱是对付男人最好的战略。

男人就算有了一万个女人也希望这个一万个女人只有他一个男人。

女人走投无路的时候会和男人结婚,男人走投无路的时候女人会和他离婚。

爱,毋须找出合理的借口,不爱,则信手拈来千万个理由。

爱须冒险,情更伤神,若无二者,何谓人生?

为何总是鼓吹爱得要生要死,而不可以爱得环欢喜喜?

男人对女人应该多一点爱,少一点了解。
女人对男人应该多一点了解,少一点爱。

女人在任何一场争吵中都会说最后一句话,
一个男人若继续说话,就是一场新的战争的开始

 查看全文

男人最帅的41个瞬间  

silver6 | 14 十二月, 2005 14:00

男人最帅的41个瞬间  


 1.不说话的时候。
沉默但目光专注地看你说话的男人,一定内心丰富,这一刻的男人,因为他身上似乎有一种至命的磁场,让你觉得他酷极了。

2.含着半口饮料微笑。
为了回应你,他哪怕嘴里含着咖啡或者美酒,也不急着咽下,先反馈给你一个积极友好的笑容,这样的绅士举止,当然会让你心头顿生暖意与好感。

3.果决而内疚地摁灭烟火头。
只是因为你的出现,正在抽烟的他,立即用这一动作欢迎你,无声,但那动作非常男性化,这比为你脱外套拉椅子,更贴心也更有说服力。

4.“我干, 你随意”。
酒桌上说这话的男人,豪爽,但不乏柔情,非常善解人意,仿佛可以为你赴汤蹈火,但背影一点也不冰冷。

5.“不要在风口接电话”。
他在街头用手机给远方的女友打电话时说了这么一句话,风吹着他的脸,他眯着的眼,很迷人吧!

6.一下子强有力地把你拽到怀里。
一切不容置疑,男人的霸气通过一种温暖的手段淋淳尽臻地表现出来,你绝对拒绝不了。

7.镜子前拉一下领带。
这时的男人很认真,而且有种片刻的孩子气,这很会激发温存欲望。

8.下楼时吹了口哨。
那是一小节美妙但已成他记忆一部分的旋律,女性喜欢考究男人的唇齿,而那一刻,他会满足你的。

9.无辜地耸耸肩膀。
喜欢看男人这时的身体语言,每一个细节都令你怜惜疼爱。

10.嚼口香糖的男人,有些玩世不恭,特别是NBA的球星,总是忙里偷闲地嚼着口香糖,一种无所谓的感觉,带点男人的“痞”。

11.在海滩上躺着晒太阳的男人。
古胴色皮肤,迷离的双眼,你是不是有种“活埋”他的冲动?

12.突然把车开到你身边,摇下车窗对你笑,这是许多浪漫故事的开头。

13.在寒风中不停跳着等人,双手插在口袋里,领子高高竖起。这一刻,你是否希望你就是他要等的人。

14.弯腰轻抚一只摇尾巴的狗。
有爱心的男人,看起来特别舒服。

15.掏钱买单的男人,并且说:“不用找了!”

16.双手从背后变出一朵玫瑰的时候,你一定会认为他是最好的魔术师。也许他改变不了风向,但可以改变你的心情。

17.他顽皮地跑,因为他手里拿着你吃剩的蛋糕,他总喜欢分享你的剩菜。

18.他做俯卧撑的时候,脸上都是性感的汗珠。很有男人味。

19.抱着篮球向你走来。
活力龙,总会给你带去兴奋。

20.就职演说前的停顿,目光扫视全场。
大气的男人,很有慑服力。

21.坏坏地注视着你,光明正大地暖昧。
这种目光恭维,是种深刻的激光式的抚摸。

22.灿烂地笑,关键是露出两排洁白清新的牙齿。
女人的唇,男人的齿,都是性感利器。

23.额纹,这是思考或疑问时的皱纹,35岁以上男人,如果没有额纹,那就是如同外婆没有白发。眉宇处如果有个昂扬的“川”字,那就更有内容了。

24.奔跑或大步流星。
因为豪迈,也是自信。

25.男人刮胡子时。
白色泡沫,非常有遐想空间,青亮的下巴,如果还有美人沟的话,那是种会让女人发出尖叫的性感。

26.正在换灯泡或钉钉子的男人。
动手能力强的男人,有种让踏实的感觉。

27.教孩子读书弹琴的时候(正式教师除外)。
所以许多贵夫人会与其孩子的钢琴教师发生不伦之恋,原因就在此。

28.摘下手套与你握手,热情,但手心不湿。

29.愉快地答应你去摘星或赴汤蹈火的时候。

30.男人快速做出决定的时候。
最怕男人拖泥带水,当然,床上活动除外。

31.男人戴安全帽的时候。一种奇怪的俊朗。

32.接吻的男人。
那一刻有种贪婪的魅力,仿佛要一手遮天,独吞天下。

33.单手持枪射击的男人。
如果他是光头,效果会更好。

34.自嘲,而且会让你一笑。

35.穿着一条不用皮带的牛仔裤,当然,腹肌要发达。

36.咬紧牙着的时候,那是一张充满张力的刚毅的脸。
“用力”是男人的“第三”性征。

37.美好的地勾引你的时候。
不会勾引的男人是残缺的。

38.扔掉自己外套,几乎是扑向你的时候。

39.兴奋得发抖到缺氧的男人。
这时,你一定会产生一种崇高理想:为他灭火!

40.和他打赌,他又输了,这一刻,他非常可爱,他是你胜利成果。

41.他说,他并不爱你的时候,这份魅力,最具毒性,小心为是。

总之,魅力是瞬间的,因为需要捕捉;魅力也是永恒的,如果你有爱~~~~~~~

sql server 函數

silver6 | 09 十二月, 2005 11:07

1.字符串函数
长度与分析用

datalength(Char_expr) 返回字符串包含字符数,但不包含后面的空格

substring(expression,start,length) 不多说了,取子串

right(char_expr,int_expr) 返回字符串右边int_expr个字符

字符操作类

upper(char_expr) 转为大写

lower(char_expr) 转为小写

space(int_expr) 生成int_expr个空格

replicate(char_expr,int_expr)复制字符串int_expr次

reverse(char_expr) 反转字符串

stuff(char_expr1,start,length,char_expr2) 将字符串char_expr1中的从

start开始的length个字符用char_expr2代替

ltrim(char_expr) rtrim(char_expr) 取掉空格


ascii(char) char(ascii) 两函数对应,取ascii码,根据ascii吗取字符


字符串查找

charindex(char_expr,expression) 返回char_expr的起始位置

patindex("%pattern%",expression) 返回指定模式的起始位置,否则为0


2.数学函数

abs(numeric_expr) 求绝对值

ceiling(numeric_expr) 取大于等于指定值的最小整数

exp(float_expr) 取指数

floor(numeric_expr) 小于等于指定值得最大整数

pi() 3.1415926.........

power(numeric_expr,power) 返回power次方

rand([int_expr]) 随机数产生器

round(numeric_expr,int_expr) 安int_expr规定的精度四舍五入

sign(int_expr) 根据正数,0,负数,,返回+1,0,-1

sqrt(float_expr) 平方根


3.日期函数

getdate() 返回日期

datename(datepart,date_expr) 返回名称如 June

datepart(datepart,date_expr) 取日期一部份

datediff(datepart,date_expr1.dateexpr2) 日期差

dateadd(datepart,number,date_expr) 返回日期加上 number

上述函数中datepart的

写法 取值和意义

yy 1753-9999 年份

qq 1-4 刻

mm 1-12 月

dy 1-366 日

dd 1-31 日

wk 1-54 周

dw 1-7 周几

hh 0-23 小时

mi 0-59 分钟

ss 0-59 秒

ms 0-999 毫秒


日期转换

convert()



4.系统函数

suser_name() 用户登录名

user_name() 用户在数据库中的名字

user 用户在数据库中的名字

show_role() 对当前用户起作用的规则


db_name() 数据库名

object_name(obj_id) 数据库对象名

col_name(obj_id,col_id) 列名

col_length(objname,colname) 列长度

valid_name(char_expr) 是否是有效标识符
 查看全文

毕业快三年了,对做软件感触很深,特将最近一年多来遇到的问题和解决方式与大家共享

silver6 | 09 十二月, 2005 10:51

IE信息设定: HKEY_CURRENT_USERSoftwareMicrosoftWindowsShellNoRoamMUICache
1、浮点数格式:
a、浮点数的范围:



-2(2m-1)*(1-2-n)

2、帮助文档的制作
每一节的标题注脚:$
每一节的跳转命(不能是中文):#
每一节的关键字索引:K
节序号:+
跳转文本在RTF文件中是带双下划线的文本
3、Dumpbin.exe:用于检查COFF目标文件,标准COFF目标库文件,可执行文件,和动态连接库文件
4、Q:ZIP与RAR之类密码能否用SOFTICE或TRW动态跟踪破解?——《看雪论坛》
A: 不能,WinZip和WinRAR是通过与CRC结合的方式进行加密,它们在解压的时候会不管3721先把带上用户输入的密码的CRC放进解压流程中,先 解出来再说,最后才进行原始的CRC判定,如果最后得到的CRC与原来的不一样,那就是解压失败。因为CRC是不可逆推的,所以也没办法得到原始的密码, 同时也因为把对比的过程放在了最后,所以才没办法用SoftICE等工具进行破解,只能穷举(目前来说)。
5、Q:为什么在WinNT/2000/XP系统,bpx hmemcpy断点无效?
A: hmemcpy是Win9x系统内部的一个函数,俗称万能断点,但在一般的编程书籍上很少提到,原因它是底层的东西,没有特殊需要,一般不直接调用。它的 操作很简单,只是将内存中的一块数据拷贝到另一个地方,Win9x系统里很频繁地调用它处理数据。在Win NT/2K系统上相关的函数是memcpy,但在Win NT/2K上不同于Windows 9x上,很少再调用memcpy来处理数据了,用此函数设断基本上什么也拦不住。
6、Q:为何同一函数有几种形式,如MessageBoxA(W)?
A: MessageBoxA(W)是MessageBoxA,MessageBoxW两种形式缩写,Windows函数是区分字符集的:A表示ANSI,W表 示Wide,即Unicode (Wide character-set),前者就是通常使用的单字节方式,而后者是双字节方式,方便处理双字节字符。Win98基本是使用ANSI字符串来进行内部 操作的,但它仍可处理少数Unicode字串符函数,如MessageBoxW、MessageBoxExW等。而Win2000/XP所有核心函数都是 Unicode字串符。
7、Q:为什么SoftICE或TRW再运行一些软件时会中断跳出?
A:用命令FAULTS off关闭错误跟踪功能。
8、Q:F11与F12区别?
A:F11对应的命令是:G@ss:sp,假如你目前正中断在程序中,下这个指令会在堆栈的返回地址设个暂时断点并执行到此断点。
F12 对应的命令是:P RET 。SoftICE或TRW将一直单步执行直到它找到一条返回语句(RET、RETF),也就是说让SoftICE一直执行代码,直到出现 RET (XXXX) 命令,再跳出来拦截,这时,当前 IP(EIP) 会是停在 RET (XXXX) 后的某一条语句上,通常是在某一个CALL XXXXXXXX 后面。
说明:F11功能键在SoftICE中有效,在TRW中可以用pmodule命令代替F11或F12,可瞬间回到到前程序领空。
9、Q:SoftICE与TRW2000的断点有什么不同?
A:在这里以G命令来解释,如对G 401000命令,大家都知道是执行到401000停下,但SoftICE认为是到当前段的401000停下(也就是说在当前应用程序领空),而 TRW200却不管段址如何,只要EIP是401000便停下。 这样一般跟踪一软件只要G 401000便解决。这个功能看起来简单,却极为有用。有了这条命令,只要把当前跟踪到的EIP记下,下一次一G便到。而在SoftICE下,一般先用其 Symbol Loader装载程序,先来到当前应用程序的领空,然后再G 401000才能到达指定地址处。其它断点命令,如bpx原理与此类似。
10、Q:如何在对话框中加入工具条
在 OnInitDialog 中加入下面代码:
BOOL CYourDlg::OnInitDialog()
{
CDialog::OnInitDialog();

// Create the toolbar. To understand the meaning of the styles used, you
// can take a look at the MSDN for the Create function of the CToolBar class.

ToolBar.Create(this, WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_TOOLTIPS |CBRS_FLYBY | CBRS_BORDER_BOTTOM);

// I have assumed that you have named your toolbar''s resource as IDR_TOOLBAR1.
// If you have given it a different name, change the line below to accomodate
// that by changing the parameter for the LoadToolBar function.

ToolBar.LoadToolBar(IDR_TOOLBAR1);

CRect rcClientStart;
CRect rcClientNow;
GetClientRect(rcClientStart);

// To reposition and resize the control bar

RepositionBars(AFX_IDW_CONTROLBAR_FIRST, AFX_IDW_CONTROLBAR_LAST,0, reposQuery, rcClientNow);
CPoint ptOffset(rcClientNow.left - rcClientStart.left,rcClientNow.top-rcClientStart.top);

CRect rcChild;
CWnd* pwndChild = GetWindow(GW_CHILD);

while (pwndChild)
{
pwndChild->GetWindowRect(rcChild);
ScreenToClient(rcChild);
rcChild.OffsetRect(ptOffset);
pwndChild->MoveWindow(rcChild, FALSE);
pwndChild = pwndChild->GetNextWindow();
}
CRect rcWindow;
GetWindowRect(rcWindow);
rcWindow.right += rcClientStart.Width() - rcClientNow.Width();
rcWindow.bottom += rcClientStart.Height() - rcClientNow.Height();
MoveWindow(rcWindow, FALSE);

// And position the control bars
RepositionBars(AFX_IDW_CONTROLBAR_FIRST, AFX_IDW_CONTROLBAR_LAST, 0);

return TRUE; // return TRUE unless you set the focus to a control
}

Q:如何改变对话框的形状?
可用下面一些函数:
CreatePolygonRgn
CreateRectRgn
CreateRoundRectRgn 等.
CRgn m_rgn; // Put this in your dialog''s header file. i.e. a member variable

// This Gets the size of the Dialog: This piece of code is to be placed in the
// OnInitDialog Function of your dialog.

CRect rcDialog
GetClientRect(rcDialog);

// The following code Creates the area and assigns it to your Dialog
m_rgn.CreateEllipticRgn(0, 0, rcDialog.Width(), rcDialogHeight());
SetWindowRgn(GetSafeHwnd(), (HRGN) m_rgn, TRUE);
Q:如何实现非客户区移动?
可用下面二种方法
// Handler for WM_LBUTTONDOWN message

void CYourDialog::OnLButtonDown(UINT nFlags, CPoint point)
{
CDialog::OnLButtonDown(nFlags, point);
PostMessage( WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM( point.x, point.y));
}

// Handler for WM_NCHITTEST message
LONG CYourDialog::OnNcHitTest( UINT uParam, LONG lParam )
{
int xPos = LOWORD(lParam);
int yPos = HIWORD(lParam);
UINT nHitTest = CDialog::OnNcHitTest(CSize(xPos, yPos));
return (nHitTest == HTCLIENT) ? HTCAPTION : nHitTest;
}

Q:如何使对话框初始为最小化状态?
在 OnInitDialog 中加入下面代码:
SendMessage(WM_SYSCOMMAND, SC_MAXIMIZE, NULL);
Q:如何限定对话框大小范围?

在 WM_SIZING中加入下面代码:
void CYourDialog::OnSizing(UINT fwSide, LPRECT pRect)
{
if(pRect->right - pRect->left <=200)
pRect->right = pRect->left + 200;

if(pRect->bottom - pRect->top <=200)
pRect->bottom = pRect->top + 200;

CDialog::OnSizing(fwSide, pRect);
}
Q:如何在对话框中加入状态条?
定义 CStatusBar 变量:
CStatusBar m_StatusBar;
定义状态条指定状态:
static UINT BASED_CODE indicators[] =
{
ID_INDICATOR_CAPS,
ID_INDICATOR_NUM
};
在 OnInitDialog 中加入下面代码:
m_StatusBar.CreateEx(this,SBT_TOOLTIPS,WS_CHILD|WS_VISIBLE|CBRS_BOTTOM,AFX_IDW_STATUS_BAR);

// Set the indicators namely caps and nums lock status
m_StatusBar.SetIndicators(indicators,sizeof(indicators)/sizeof(UINT));

CRect rect;
GetClientRect(&rect);

m_StatusBar.SetPaneInfo(0,ID_INDICATOR_CAPS,SBPS_NORMAL,rect.Width()/2);
m_StatusBar.SetPaneInfo(1,ID_INDICATOR_NUM,SBPS_STRETCH ,rect.Width()/2);

RepositionBars(AFX_IDW_CONTROLBAR_FIRST,AFX_IDW_CONTROLBAR_LAST,ID_INDICATOR_NUM);

m_StatusBar.GetStatusBarCtrl().SetBkColor(RGB(180,180,180));

11. Microsoft Distributed Transaction Coordinator服务(MSDTC.EXE)默认监听3372TCP端口
12. #pragma alloc_text( "textsection", function1, ... )
13. Unicode 字符串数据类型是C语言规范的一部分,使用下列方法来使用Unicode 字符串:
l将字符串常量加上前缀L。例如,L”Some text”是一个Unicode 字符串,而”Some text”是8-bit ANSI。
l使用wchar_t数据类型。DDK头文件定义了WCHAR为wchar_t,PWSTR为wchar_t*。
l使用常数UNICODE_NULL去终止Unicode 字符串,UNICODE_NULL被定义为16 bits的零。

cvs服务器的安装作者:weiqiong 发表时间:2002/12/30 08:32pm安装cvs后服务器和客户端就都安装了,主要是需要配置服务器端:1.查看是否安装cvs(我的redhat7.3缺省是装了的)rpm -qa|grep cvs一般安装在/usr/bin/cvs,如果未安装,到www.cvshome.org下载一个最新的rpm安装即可2.建立cvs用户组,便于管理 cvs用户groupadd cvs3.建立cvs组的cvsroot用户和所属的目录useradd -g cvs -G cvs -d /home/cvsroot cvsroot4.为cvsroot用户添加密码passwd cvsroot5.改变/home/cvsroot的目录属性chmod 775 /home/cvsroot6.初始化cvs源代码库,此操作生成目录/home/cvsroot/CVSROOT,其下为一些初始化文件cvs -d /home/cvsroot init7.创建可以登陆cvs服务的用户及密码,需要创建文件passwdvi /home/cvsroot/CVSROOT/passwd文件内容如下:weiqiong:xxxxxx:cvsrootchenxu:xxxxxx: cvsroot此文件的意思是weiqiong和chenxu两个用户可以登陆cvs服务器,登陆后其权限为用户cvsroot的权限注意:cvs用户和 服务器用户是可以不一样的8.xxxxxx为密码,由以下文件生成:vi /home/cvsroot/passwdgen.pl文件内容: #!/usr/bin/perlsrand (time());my $randletter = "(int (rand (26)) + (int (rand (1) + .5) % 2 ? 65 : 97))";my $salt = sprintf ("%c%c", eval $randletter, eval $randletter);my $plaintext = shift;my $crypttext = crypt ($plaintext, $salt);print "${crypttext}n";9.如果需要密码为:some,则敲入:passwdgen.pl "some"回车即可得到加密密码,用其替换passwd文件中的xxxxxx10.加入cvs服务(我的redhath7.3缺省就有cvs服务,所以 不用加)vi /etc/servicescvspserver 2401/tcp #pserver cvs servicecvspserver 2401/udp #pserver cvs service 11.cvs服务由inted来唤起,因此需要改动inetd提供的服务,如果你的redhat使用的是inetd 方式则在文件/etc/inetd.conf中加入如下的内容:cvspserver stream tcp nowait root /usr/bin/cvs cvs --allow-root=/home/cvsroot pserver 我的redhat7.3使用的是xinetd方式,所以在xinetd.d目录下添加需要启动的服务: cd /etc/xinetd.d vi cvspserver 文件内容: service cvspserver { disable = no flags = REUSE socket_type = stream wait = no user = root server = /usr/bin/cvs server_args = -f --allow-root=/home/cvsroot pserver log_on_failure += USERID }12.重新启动inetd或者xinetd: /etc/rc.d/init.d/xinetd restart13.检查cvspserver服务是否已经启动netstat -l |grep cvspserver应该有如下结果:tcp 0 0 *:cvspserver *:* LISTEN14.试用: cvs -d :pserver:weiqiong@202.204.114.37:/home/cvsroot login 敲入命令回车后提示输入weiqiong的密码,你按照自己设置的密码输入,如果没有什么错误信息出现就是成功了(我的机器IP地址是 202.204.114.37,也可以用localhost)
14、ActiveX控件的调试:2005.3.27-2005.3.28
这次编写的ActiveX控件是DynaGraph,用于实时显示三组动态曲线。
a、如何实现控件属性的加载和保存,如VB中的ReadProperties和WriteProperties?
在DoPropExchange(CPropExchange* pPX)中进行,诸如:
PX_Long(pPX,"Height",m_lHeight,250);
PX_Long(pPX,"Width",m_lWidth,380);
参见MSDN/ActiveX controls:Serializing
b、由于粗心,导致产生"参数无效错误",错误如下:
m_rtBound.left=GRID_EDGE_SPACE;m_rtBound.left=GRID_EDGE_SPACE;m_rtBound.right =m_rtGrid.right-GRID_EDGE_SPACE;m_rtBound.bottom=m_rtGrid.bottom-GRID_EDGE_SPACE; 由于把top写成了left,导致top没有赋值,出现溢出[不在有效范围内]
c、由于VC的Bug,导致在添加属性和方法时,相应的ID没有同步,从而导致很多的属性和方法的ID没有相互对应,导致"无效参数数目"错误,而且无法对其进行跟踪(因为ID错位)。
方法(以DrawGraph为例):
BEGIN_DISPATCH_MAP(CDynaGraphCtrl, COleControl)
DISP_FUNCTION(CDynaGraphCtrl, "DrawGraph", DrawGraph, VT_EMPTY, VTS_PI4 VTS_PI4 VTS_PI4 VTS_I2)
END_DISPATCH_MAP()
dispidDrawGraph = 15L,
afx_msg void DrawGraph(long FAR* pPressData, long FAR* pSpeedData, long FAR* pCtrlData, short sLen);
void CDynaGraphCtrl::DrawGraph(long FAR* pPressData,long FAR* pSpeedData,long FAR* pCtrlData,short sLen)
属性(以BackColor为例):
BEGIN_DISPATCH_MAP(CDynaGraphCtrl, COleControl)
DISP_PROPERTY_EX(CDynaGraphCtrl, "BackColor", GetBackColor, SetBackColor, VT_COLOR)
END_DISPATCH_MAP()
dispidBackColor = 3L,
afx_msg OLE_COLOR GetBackColor();
afx_msg void SetBackColor(OLE_COLOR nNewValue);
OLE_COLOR CDynaGraphCtrl::GetBackColor() { }
void CDynaGraphCtrl::SetBackColor(OLE_COLOR nNewValue) {}

16、ODBC connect string sample:
“DBQ=E:工程PROGRAMME舱盖升降系统HATCHHatchDB.mdb;UID=SA;PWD="";DRIVER=Microsoft Access Driver (*.mdb)”
17、由于坐标的不一致,导致移动控件始终不是按照预期的目的在移动。即少用了一个ScreenToClient(),正确代码如下[Hatch]:2005/4/11
GetCursorPos(&pt);
ScreenToClient(&pt);
if(pt.x!=m_ptLPPPosOldX.x)
{
m_ctlLPPointer.GetWindowRect(&m_rtLPPointer);
ScreenToClient(&m_rtLPPointer);
m_rtLPPointer.left-=m_ptLPPPosOldX.x-pt.x;
m_rtLPPointer.right-=m_ptLPPPosOldX.x-pt.x;
m_ctlLPPointer.SetWindowPos(&CWnd::wndTop,m_rtLPPointer.left,m_rtLPPointer.top,
m_rtLPPointer.right-m_rtLPPointer.left,m_rtLPPointer.bottom-m_rtLPPointer.top,
SWP_SHOWWINDOW);
m_ptLPPPosOldX=pt;
}
18、VB的ActiveX中的Extender在VB中是不兼容的,所以如果要在VC中使用VB开发的控件,则不能包含Extender。4/11/05
19、自绘控件的无闪烁更新,使用InvalidateControl(&m_rtBound);更新绘图区域,而不用更新没有变化的区域。[DynaGraph: DrawGraph]4/12/2005
20、向导中文乱码:原因尚未查证,但是可以使用Dialog替代PROPPAGE则可解决这个问题。
21、 在对话框中加入属性页,当对话框失去焦点后,对话框便假死:主要是因为在创建属性页时,没有将扩展属性中的WS_EX_CONTROLPARENT加上, 导致对话框无法处理属性页的相关消息,而我的属性页又没有建立相应的消息处理机制,故此。下例中this是对话框[Hatch: OnInitDialog]:2005-4-14
m_PSheet.Create(this,WS_CHILD|WS_VISIBLE|WS_TABSTOP|WS_BORDER|WS_OVERLAPPED,
WS_EX_OVERLAPPEDWINDOW|WS_EX_DLGMODALFRAME|WS_EX_CONTROLPARENT);
22、 在子对话框类中的CPropertySheet m_PSheet成员变量,初始化时执行添加属性页时,不能多次显示—隐藏子对话框:主要是因为m_Psheet对像没有执行析构,添加进去的属性页仍然 存在,解决的办法是可以在创建显示之前,删掉以前的即可,如下[Hatch: OnInitDialog]:2005-4-14
while(m_PSheet.GetPageCount()>0)
m_PSheet.RemovePage(0);//删掉以前的

m_PSheet.AddPage(&m_TestPage);
m_PSheet.AddPage(&m_ConfigPage);
m_PSheet.Create(this,WS_CHILD|WS_VISIBLE|WS_TABSTOP|WS_BORDER|WS_OVERLAPPED,
WS_EX_OVERLAPPEDWINDOW|WS_EX_DLGMODALFRAME|WS_EX_CONTROLPARENT);
23、DC[Device Contexts(设备相关):MSDN]
设 备相关是一个Windows数据结构,它包含了诸如显示器或打印机等设备的绘制属性.所有的绘制调用是直接通过设备相关对象进行的,其中封装了诸如画线, 形状和文本等Windows APIs.设备相关允许在Windows中独立使用.设备相关可以用来绘制屏幕,绘制打印或者绘制媒体文件.
CPaintDC: CPaintDC对象封装了Windows的通用习惯,调用BeginPaint函数,然后在设备相关中进行绘制,再调用EndPaint函数. CpaintDC在构造函数中调用BeginPaint,在析构函数调用EndPaint.这简化的处理是创建CDC对象--绘制—销毁CDC对象.在框 架中,许多事件是自动处理的.特别是,你的OnDraw函数是一个CpaintDC已经准备好的(通过OnPrepareDC),并且你只是简单地绘制. 它通过框架进行销毁,在设备相关中在调用OnDraw函数返回是释放给Windows.
CClientDC:CclientDC对象封装了只有在客户窗口区相关的设备相关.CClientDC的构造函数调用GetDC函数,它的析构函数调用ReleaseDC函数.
CWindowDC:CWindowDC对象封装了响应整个窗口的设备相关,包括框架.
CMetaFileDC:CMetaFileDC对象封装了绘制到一个窗口媒体文件.调用OnDraw的方式与CpaintDC相比较,你自己必须在这里面调用OnPrepareDC
24、串口操作函数
a.打开串口
HANDLE CreateFile(LPCTSTR lpFileName,DWORD dwDesiredAccess, DWORD dwShareMode,
LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition,
DWORD dwFlagsAndAttributes, HANDLE hTemplateFile);
b.设置缓冲
BOOL SetupComm( HANDLE hFile, DWORD dwInQueue, DWORD dwOutQueue);
c、关闭串口
BOOL CloseHandle(HANDLE hObject);
d、配置串口
BOOL GetCommState( HANDLE hFile, LPDCB lpDCB );
BOOL SetCommState( HANDLE hFile, LPDCB lpDCB );
BOOL BuildCommDCB( LPCTSTR lpDef, LPDCB lpDCB);
BOOL BuildCommDCBAndTimeouts(LPCTSTR lpDef, LPDCB lpDCB,LPCOMMTIMEOUTS lpCommTimeouts);
e、串口属性
BOOL GetCommProperties( HANDLE hFile, LPCOMMPROP lpCommProp);
f、串口读写
BOOL ReadFile( HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead,
LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped );
BOOL ReadFileEx(
HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, LPOVERLAPPED lpOverlapped,
LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine );
BOOL WriteFile( HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite,
LPDWORD lpNumberOfBytesWritten, LPOVERLAPPED lpOverlapped);
BOOL WriteFileEx(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite,
LPOVERLAPPED lpOverlapped, LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine );
g、重叠操作
BOOL GetOverlappedResult(HANDLE hFile, LPOVERLAPPED lpOverlapped,
LPDWORD lpNumberOfBytesTransferred, BOOL bWait );
h、超时
BOOL GetCommTimeouts( HANDLE hFile, LPCOMMTIMEOUTS lpCommTimeouts);
BOOL SetCommTimeouts(HANDLE hFile, LPCOMMTIMEOUTS lpCommTimeouts);
i、通信状态和通信错误
BOOL ClearCommError( HANDLE hFile, LPDWORD lpErrors, LPCOMSTAT lpStat);
25.数据库在执行插入语句时,始终不能插入数据:4/25/2005
原是语句如下:
INSERT INTO ExpResult(Name,ExpID,MinPress,MaxPress,AvrPress,ResultA,ResultB,ResultC,ResultD,Result,
DateStart,DateStop,Reserved1,Reserved2,Reserved3) VALUES ('23_0',1,0.000000,0.000000,0.000000, 24.000000,
234.000000,234.000000,0.000000,'',0,0,0,0.000000,'')
原因:因为我在数据库中对字符串设置了默认值为NULL,二在这儿有两个'',操作就不成功,将其改为下面的格式即可:
INSERT INTO ExpResult(Name,ExpID,MinPress,MaxPress,AvrPress,ResultA,ResultB,ResultC,ResultD,Result,
DateStart,DateStop,Reserved1,Reserved2,Reserved3) VALUES ('23_0',1,0.000000,0.000000,0.000000, 24.000000,234.000000,234.000000,0.0000,'Null',0,0,0,0.0000,'Null')即不能给无效 的数据进去罢了.
26.使用SQL语句创建表单,关键字需要自增,使用Counter,如下:2005/5/9
szSQL.Format("CREATE TABLE Data200504(IDD Counter PRIMARY KEY UNIQUE NOT NULL,StepDisplace INTEGER,PPPress SINGLE,PRESSAB INTEGER,CtrlPressC INTEGER,DateTimes INTEGER)");
27.在表单中的字段名字不能用保留字,否则在执行SQL时会不成功,诸如:Date,DateTime等。
28. 奇耻大辱啊,因为系统所使用的ActiveX和DLL没有注册,造成编译后的文件无法正常运行,有的是悄然无声;有的出现内存访问冲突.在注册后也出现这 样的问题,主要是因为注册的空降位置在system32下,而在当前路径下仍然有一份相应的文件.还有就是非system32下的进行注册怎么也不好 使,不知到底是为啥.最后写成一个只执行一次的批处理文件来解决此问题[register.bat],内容如下:[氡气 5/10/2005]
Copy G:Share氡气ReleaseMSCOMCTL.ocx C:WINNTsystem32
Copy G:Share氡气ReleaseFM20.dll C:WINNTsystem32
Copy G:Share氡气ReleaseMSCOMM32.ocx C:WINNTsystem32
Copy G:Share氡气ReleaseMSCOMCT2.ocx C:WINNTsystem32
Copy G:Share氡气ReleaseMyPic.ocx C:WINNTsystem32
regsvr32.exe /s MSCOMCTL.ocx
regsvr32.exe /s FM20.dll
regsvr32.exe /s MSCOMM32.ocx
regsvr32.exe /s MSCOMCT2.ocx
regsvr32.exe /s MyPic.ocx
29.因为发行版本的程序,调试版本的控件而导致程序无法启动.[氡气]

30.在多线程里面调用成员对象[ActiveX]的方法产生异常,原因未知,估计是因为变量作用域问题.[舱盖升降系统,工作线程中调用m_ctlLEDP1.SetValue("11.22");]
解决方法:最好不要在线程里面操作有关界面的东西,而是发送消息来进行处理
原因:VB开发的控件没有正常版权,在[系统信息]中看到版本和制造商为“不可用”,即为版权问题。而VC开发的是有上面的正确信息,调用一切正常。问题有待于进一步研究2005-6-3
ACTIVEX 控件是 COM对象. 它按COM的方式运行. 对于运行在单线程公寓模型内的 COM 来说, 它是线程不安全的,不能直接将 COM 裸指针传递至其它的线程. 如果你确信要这么做,请对COM接口进行 线程调度:
IMyObject* p = ...;
IStream* pStream = 0;
HRESULT hr = CoMarshalInterThreadInterfaceInStream(__uuidof(p), p, &pStream);
if(FAILED(hr))
{
... ERROR !
}
DWORD dwID;
HANDLE hThread = CreateThread(NULL, 0, ThreadFnc, (void*)pStream, 0, &dwID);
....

DWORD WINAPI ThreadProc(LPVOID lp)
{
IStream* pStream = (IStream*)lp;
IMyObject* pItf = NULL;
HRESULT hr=CoGetInterfaceAndReleaseStream(pStream, __uuidof(pItf), (void**)&pItf);
if(FAILED(hr))
// ERROR
pStream->Release();
return 0;
}

// ....
hr = pItf->CallSomtMethod(para);
...
pItf->Release();
return 0;
}

COM库是针对线程有效的,因此你需要在线程起始处AfxOleInit()或者在起始处 ::CoInitialize(NULL); 结束处 ::CoUninitialize();
31.在AD采集时,始终出现前一个通道影响后一个通道,原因可能是因为没有通道建立延时[调用的DLL][ 舱盖升降系统]
32.AD采集数据线不能太长,如超过1m,这样会采集不到正确的数据.[舱盖升降系统]
33.DA输出时,输出信号会一直保留,直到下一次输出为止.[ 舱盖升降系统2005/5/20]
34.对话框中的打印实例:[轴承测试,6/17/2005]
void CDataMan::OnBtnPrint()
{
if(NULL==m_ctlDataIndex.GetFirstSelectedItemPosition())
{
AfxMessageBox("你没有选中待打印的记录,不能进行打印!");
return;
}
CDC dc;
CPrintDialog printDlg(FALSE);

if (printDlg.DoModal()==IDCANCEL)
return;//Get printer settings from user

dc.Attach(printDlg.GetPrinterDC());
//将纸张改为横向的
LPDEVMODE lpDM=printDlg.GetDevMode();
lpDM->dmOrientation=DMORIENT_LANDSCAPE;
lpDM->dmFields|=DM_ORIENTATION;
dc.ResetDC(lpDM);
//Get and attach a printer DC
dc.m_bPrinting = TRUE;
CString strTitle; // Get the application title
strTitle.LoadString(AFX_IDS_APP_TITLE);

DOCINFO di; // Initialise print document details
::ZeroMemory (&di, sizeof (DOCINFO));
di.cbSize = sizeof (DOCINFO);
di.lpszDocName = strTitle;

BOOL bPrintingOK = dc.StartDoc(&di);
// Begin a new print job. Get the printing extents and
//ore in the m_rectDraw field of a CPrintInfo object
CPrintInfo Info;

m_nWidth =dc.GetDeviceCaps(HORZRES);
m_nHeight=dc.GetDeviceCaps(VERTRES);
Info.m_rectDraw.SetRect(0,0,m_nWidth,m_nHeight);

m_fRatioX=(float)m_nWidth/PAGE_WIDTH;
m_fRatioY=(float)m_nHeight/PAGE_HEIGHT;

OnBeginPrinting(&dc,&Info);
//Call your "Init printing" function
for(UINT page = Info.GetMinPage(); page <=
Info.GetMaxPage() && bPrintingOK; page++)
{
dc.StartPage(); // begin new page
Info.m_nCurPage = page;
OnPrint(&dc,&Info);
//Call your "Print page" function
bPrintingOK = (dc.EndPage() > 0); // end page
}
OnEndPrinting(&dc, &Info);
// Call your "Clean up" function
if (bPrintingOK)
dc.EndDoc();// end a print job
else
dc.AbortDoc();// abort job.
dc.DeleteDC();// delete the printer DC]
}

void CDataMan::OnBeginPrinting(CDC *pDC, CPrintInfo *pInfo)
{
POSITION pos=m_ctlDataIndex.GetFirstSelectedItemPosition();
int nRow=m_ctlDataIndex.GetNextSelectedItem(pos);

m_uaPrint.RemoveAll();
do{
m_uaPrint.Add(nRow);
nRow=m_ctlDataIndex.GetNextSelectedItem(pos);
}while(nRow>=0);

m_penTable.CreatePen(PS_SOLID,1,RGB(10,10,10));
m_pOldPen=pDC->SelectObject(&m_penTable);

m_RptFont.CreateFont(FONT_HEIGHT*m_fRatioX,0, 0, 0,
FW_NORMAL, FALSE, FALSE, 0,ANSI_CHARSET,OUT_DEFAULT_PRECIS,
CLIP_DEFAULT_PRECIS,DEFAULT_QUALITY,DEFAULT_PITCH| FF_ROMAN, NULL);

//因为我在表格中只使用一种字体,所以可以在这里将字体选入设备中
m_pOldFont=pDC->SelectObject(&m_RptFont);

int nPage=m_uaPrint.GetSize();
nPage=nPage/(TABLE_ROW_NUMBER-1);
nPage+=(m_uaPrint.GetSize()%(TABLE_ROW_NUMBER-1)==0)?0:1;
pInfo->SetMinPage(1);
pInfo->SetMaxPage(nPage);
}

void CDataMan::OnPrint(CDC *pDC, CPrintInfo *pInfo)
{
int nTabs[TABLE_COLUMN_NUMBER]={
(COL_1+TABLE_LEFT_SPACE)*m_fRatioX,(COL_2+TABLE_LEFT_SPACE)*m_fRatioX,
(COL_3+TABLE_LEFT_SPACE)*m_fRatioX,(COL_4+TABLE_LEFT_SPACE)*m_fRatioX,
(COL_5+TABLE_LEFT_SPACE)*m_fRatioX,(COL_6+TABLE_LEFT_SPACE)*m_fRatioX};
CString szPrint;
TEXTMETRIC metrics;
pDC->GetTextMetrics(&metrics);

pDC->FillSolidRect(0,0,m_nWidth,m_nHeight,RGB(0XFF,0XFF,0XFF));
//打印文字内容//////////////////////////////////////////////////
szPrint.Format("令号: %s",m_ctlDataIndex.GetItemText(m_uaPrint.GetAt(0),2));
pDC->TextOut((PAGE_LEFT_SPACE+TABLE_LEFT_SPACE)*m_fRatioX,
(PAGE_TOP_SPACE+TABLE_TOP_SPACE)*m_fRatioX,szPrint);

szPrint.Format("附件号: ");
pDC->TextOut((PAGE_LEFT_SPACE+TABLE_LEFT_SPACE)*m_fRatioX,
(PAGE_TOP_SPACE+TABLE_TOP_SPACE+TABLE_ROW_HEIGHT)*m_fRatioY,szPrint);

//表单标题
szPrint=m_szRptTitle;
int nPosX=pInfo->m_rectDraw.right/2-(szPrint.GetLength()*metrics.tmMaxCharWidth)/2;
pDC->TextOut(1600*m_fRatioX,(PAGE_TOP_SPACE+TABLE_TOP_SPACE)*m_fRatioY,szPrint);

//列标题
szPrint.Format("t附件名称t轴承型号t轴承序号t测试时长(s)t测试类型t测试结果(KHz)");
pDC->TabbedTextOut(TABLE_LEFT_POSITION*m_fRatioX,(TABLE_TOP_POSITION+TABLE_TOP_SPACE)*m_fRatioY,szPrint,sizeof(nTabs),nTabs,0);
//"操作员","测试日期","轴承型号","轴承编号","测试结果","时间长度","门限电压","A导通","B导通","标志信息"
int nIndex=0;
int nRow;
for(nRow=1;nRow<=TABLE_ROW_NUMBER-1&&nRow<=m_uaPrint.GetSize();nRow++)//打印
{
nIndex=m_uaPrint.GetAt(nRow-1);
szPrint.Format("t%st%st%st%st%st%s",m_ctlDataIndex.GetItemText(nIndex,3),
m_ctlDataIndex.GetItemText(nIndex,4),m_ctlDataIndex.GetItemText(nIndex,5),
m_ctlDataIndex.GetItemText(nIndex,7),m_ctlDataIndex.GetItemText(nIndex,8),
m_ctlDataIndex.GetItemText(nIndex,9));
pDC->TabbedTextOut(TABLE_LEFT_POSITION*m_fRatioX,
(TABLE_TOP_POSITION+nRow*TABLE_ROW_HEIGHT+TABLE_TOP_SPACE)*m_fRatioY,
szPrint,sizeof(nTabs),nTabs,0);
}

m_uaPrint.RemoveAt(0,nRow>=TABLE_ROW_NUMBER?11:nRow-1);//去掉已经打印的部分
szPrint.Format("t工作者:%st日期:%s", m_ctlDataIndex.GetItemText(nIndex,0),
m_ctlDataIndex.GetItemText(nIndex,1));
int nRootTab[]={(COL_1+TABLE_LEFT_SPACE)*m_fRatioX,(PAGE_WIDTH-PAGE_RIGHT_SPACE-900)*m_fRatioY};
pDC->TabbedTextOut(TABLE_LEFT_POSITION*m_fRatioX,
(TABLE_TOP_POSITION+TABLE_ROW_NUMBER*TABLE_ROW_HEIGHT+TABLE_TOP_SPACE)*m_fRatioY,szPrint,sizeof(nRootTab),nRootTab,0);

//打印表格/////////////////////////////////////////////////////////////////////
for(nRow=0;nRow<TABLE_ROW_NUMBER+1;nRow++)
{//打印横线
pDC->MoveTo(TABLE_LEFT_POSITION*m_fRatioX,(TABLE_TOP_POSITION+nRow*TABLE_ROW_HEIGHT)*m_fRatioY);
pDC->LineTo((PAGE_WIDTH-PAGE_RIGHT_SPACE)*m_fRatioX,(TABLE_TOP_POSITION+nRow*TABLE_ROW_HEIGHT)*m_fRatioY);
}

int nColPos[]={COL_1*m_fRatioX,COL_2*m_fRatioX,COL_3*m_fRatioX,COL_4*m_fRatioX,COL_5*m_fRatioX,COL_6*m_fRatioX,COL_END*m_fRatioX};
for(int nCol=0;nCol<sizeof(nColPos)/sizeof(int);nCol++)
{//打印竖线
pDC->MoveTo(nColPos[nCol],TABLE_TOP_POSITION*m_fRatioY);
pDC->LineTo(nColPos[nCol],(TABLE_TOP_POSITION+TABLE_ROW_NUMBER
*TABLE_ROW_HEIGHT)*m_fRatioY);
}
}

void CDataMan::OnEndPrinting(CDC *pDC, CPrintInfo *pInfo)
{
pDC->SelectObject(m_pOldFont);
pDC->SelectObject(m_pOldPen);

m_pOldFont=NULL;
m_pOldPen=NULL;

m_penTable.DeleteObject();
m_RptFont.DeleteObject();
}

35.数据库的模糊匹配问题:在数据库的模糊匹配问题上,在不同地方使用的是不同的通配符,这一定的注意,要不然在一个地方测试通过了,但是在另一个地方 却会出现无名的异常.在ACCESS里面的通配符为'*'(匹配多个字符)和'?'(匹配单个字符)。但是在ODBC中使用时,却是使用'%'(匹配多个 字符)和"_"(匹配单个字符)。我在Hatch 中使用的是CDatabase和CRrectset,里面就应该使用"%"和"_"才能正常匹配。【2005-6-28 Hatch/CData
SELECT Name,MinPress,MaxPress,ResultName1,ResultName2,ResultName3,ResultName4, ResultA,ResultB,ResultC,ResultD,DateStart,Operator,ExpNo,PdtNo FROM ExpResult, ExpItem, ExpRsltInfo WHERE Name LIKE 'sd%' AND ExpID=ExpItem.IDD AND ExpNo='sd'"
36.在使用CListCtrl时,如果要显示表格线条,只需要将其扩展属 性中加上LVS_EX_GRIDLINES即可,可以使用GetExtendedStyle()来的到现有的List属性,而使用 SetExtendedStyle()来进行设置即可.[6/30/2005]
37.在使用CListCtrl时,使用了Sort进行排序,这时 却只显示了最后的一行,其余的全部都是空行.Sort的选项有:None,Ascending和Descending.当选择为None时就正常显示,其 余的升序和降序都不能正常显示.[6/30/2005]
38.对于BSTR*类型参数的传递,在DynaGraph中的SetCaption定义如下:7/7/2005
void SetCaption(BSTR* pInfo, short nChoose);
我要调用他来进行Caption改变,但是我测试了很久都未能实现[以前成功使用过,不过太久了],而我又不想定义太多的变量来进行操作,所以问题变产生了。可行的解决方式如下[懒人方式]:
BSTR str;
str=(BSTR)m_szValue.GetBuffer(0);
m_ctlDGG.SetCaption(&str,++n);
39.字符编码转换问题.[7/13/2005 Antipush use Dynagraph.ocx]
在 进行VC ActiveX(DynaGraph.ocx)在VB(Antipush)中使用时,出现了在ActiveX中不能正确识别所传入的字符串,究其原因,是 因为字符编码不一致所造成的.之后在VB中使用编码转换函数进行转换之后在传入ActiveX中,问题得到圆满解决.
在VB中用于编码转换的函数是:StrConv(string,conversion,LCID),conversion选择的是vbFromUnicode.
如果是要用API进行转换,可以使用MultiByteToWideChar(…),可以参看MSDN的 Unicode and Character Set Functions
如果要查看编码方面的资料,可以到http://www.paper.edu.cn/home.jsp,有一篇叫做《汉字编码及其应用的研究》的论文。
40.VB中解决传递引用(byref)空指针(NULL)的问题. [7/13/2005 Antipush use Dynagraph.ocx]
在VB 中,首先是没有指针,其次是没有真正意义上的空指针,而引用是针对传入的变量而言,而不是常数,再有就是ActiveX是没有重新声明接口的方式,故是没 有办法传递引用参数类型的ActiveX的空指针的.只有通过别的办法来进行解决,例如传递标志,特殊数字等.但是如果是API的话,可以把传引用 (byref)的声明更改为传值(byval)的声明即可以解决.
41.在VB中的几个常值:TRUE=-1;FALSE=0;vbNull=1;Null=asc.还需要注意的是,在不同语言的开发工具之间,对于数字的编码以不一定相同.(0)[7/13/2005]
42.IO输入有信号正/负之分,连接反了不能采集到信号。


一道面试题

silver6 | 09 十二月, 2005 10:49

一个单向链表,不知道头节点,一个指针指向其中的一个节点,问如何删除这个指针指向的节点?
当时我没答出来,后来问考官,它告诉我正解,大家下讨论一下。

设ListNode *p 指向链表某一节点

p->data = p->next->data;
ListNode *t = p->next;
p->next = p->next->next;
delete t;

题目有问题啊
如果是单循环链表就没有问题了

typedef struct linknode
{
int data;
struct linknode *next;
}node;


void del(node *p)
{
node *q;
q=p;
while(q->next!=p)
{
q=q->next;
}

q->next=p->next;
free(p);
}
//当然还有很多细节没有考虑
大概思路就是这样

void del(node *p)
{
node *q;
q=p;
while(q->next!=p)
{
q=q->next;
}

q->next=p->next;
free(p);
}


(int&)a 与 (int)&a 有什么区别!疑惑!!!!公司应聘考试题目!

silver6 | 08 十二月, 2005 13:34

请问各位前辈
#include<iostream>
using namespace std;
void main()
{
float a = 1.0f;
cout << &a << endl;
cout << (int)&a << endl;
cout << (int&)a << endl;
cout << boolalpha << ( (int)a == (int&)a ) << endl; // 输出什么?
float b = 0.0f;
cout << (int)b << endl;
cout << (int&)b << endl;
cout << boolalpha << ( (int)b == (int&)b ) << endl; // 输出什么?
}

其中:(int&)a 与 (int)&a 有什么区别

谢谢先!!!

(int&)a == static_cast<int&>(a)
(int)&a == reinterpret_cast<int>(&a);

(int&)a 不经过转换, 直接得到a在内存单元的值
(int)a a在内存中的值转换成int类型

float类型在内存中存储的形式是 ,符号位 指数 尾数
由754标准:阶码采用增码(该数补码的反符号),尾数采用原码
所以1.0f 在内存中的形式为
0011 1111 1000 0000 0000 0000 0000 0000
所以输出的是 0x3f800000
0 在内存中的的存储形式
0000 0000 0000 0000 0000 0000 0000 0000

(int&)a 把a强制转换成整形引用类型
(int)&a 把a的地址强制转换成整型
不过最好不要(int)&a


BENQ笔试题,不会做,求解

silver6 | 08 十二月, 2005 13:32

1,把一个32位数倒置
2,输入一个数字,把这个数字变成字符型
谁能帮帮我?
我的思路是把1里面的数拆到数组里,但是好象会超过LONG 的范围
2提我不知道怎么判断我输入了多大的数啊?

32位数倒置什么意思?
是2进制位倒置还是10进制位导致?

bool itoa(int num , char* p , int leng)
{
int count = 0;
int flag = 0;
char* q;
char* ip;
if (leng == 0 || p == NULL)
return 0;
if (num < 0)
{
num =- num;
flag = 1;
count ++;
*p = '-';
}

if (num == 0)
{
*p = '0';
*(p+1)=0;
return 1;
}

while (num > 0 && leng > count)
{
*(p+count) = '0' + num%10;
num /= 10;
count ++;
}

if (num > 0) return 0;
*(p + count) = 0;

q = p + count - 1;
ip = p;
if (flag)
ip = p + 1;

while(q > ip)
{
char a = *q;
*q = *ip;
*ip = a;
q --;
ip ++;
}

return 1;
}

void main()
{

int s = -1234567890;
char a[11];

if (itoa(s,a,11))
printf("%s",a);
}


一个女生教你怎么追MM

silver6 | 04 十二月, 2005 15:51

我是女生,看到有的男生想追自己喜欢的女孩子又不敢追,还想人家倒追她,我很反感.
从一个女生的角度,我比较了解女孩子的心理。女孩子大多不会主动出击,去追求自己喜欢的男孩,除了确实太喜欢了或者是那种比较有个性的勇敢的女孩子。所以,如果你很喜欢一个女孩子,并且认为她对你也有点意思,那就主动点,别跟她搞拉锯战,自己难受,说不定你喜欢的人也痛苦。
任何一个女孩子在被人追的时候,心理都是很复杂的。她也许很开心,但是又带着点惶恐,她对这个闯进自己平静的生活的男孩子,有着欲拒还迎的矛盾心理,她不是故意的。不要以为她在考验你,她其实也在和自己斗争,她怕受到伤害。
不要怕你的主动会带来她的反感,你不主动,她也不主动,也就慢慢淡下来了。如果你开始的表白被她拒绝,那也很正常呀。不要气馁,谁知道这个女孩子心里在想什么呢?
也许你再表白两次,她就会被你打动,一个心地善良的好女孩是很容易感动的。
如果你受到一次挫折,就立刻离开,再也不去答理这个女孩,把自己紧紧地保护起来,默默地舔舐伤口,在你痛苦的同时,殊不知,那个女孩子也许也正在心里遗憾、后悔呢!也许她会偷偷哭泣,后悔拒绝了你,再看到你漠然的眼神,她也很痛心,但是她却不会对你说,绝对不会请求你回来追她。你的过度的自尊心,可能会伤害了女孩子敏感的心。
她会认为你不是真诚的喜欢他,要不怎么会就这么放弃了她?
有人说,男生真难,追女孩子太不容易了。可是我的感觉却是,这种现象跟男人和女人的社会角色定位是分不开的,从生理和社会的角度,女人总是被动的。如果反过来,让男人都脉脉含羞,女人变得勇往直前,世界才乱了套呢!女人的羞涩总是美好的、动人的呀~我总是听说是某个勇敢的男人战胜了多少困难,最终获得佳人芳心。相反的例子却少得很。
有的男生,就怕别人说自己什么死缠烂打,落下不好的名声。可是我觉得男生追求自己喜欢的女孩子,受了点挫折还继续对这个女孩子好,说明人家确实很喜欢,很有诚意,如果没成功,也不遗憾,并没什么啊?谁让人家喜欢了?最讨厌别人跟着瞎掺乎,也最讨厌那种自己没主意,过于在乎别人对自己看法的男生,活该这种男生找不到女朋友。
是男人就勇敢点,女孩子本来就感性,容易沉浸在爱情里。虽然你付出了辛苦,而一旦你的真心打动了她,那么你得到的将是更多更久的加倍的爱。这样的例子,在身边比比皆是。女孩子对自己的男朋友都是很温柔很贴心的,为了换来这份甜蜜,开头的辛苦算什么啊?而且大多好女孩都爱得挺投入挺专一的。

所以,建议有的男生勇敢一点,去追求自己喜欢的女孩子,不要那么畏畏缩缩,一来是让人觉得你没男人气概,二来是你自己怪难受的,然而最最最重要的还是:最后你什么都得不到。幸福总是自己挣来的,别指望别人施舍给你!

再补充一句,我觉得主动点儿挺好的,因为你的目标是你自己真心喜欢的,女孩子往往被动,被动的只能选择接受和拒绝,所以我宁愿主动出击,爱我所爱,无怨无悔!

----- 人生很美好,快乐在其中,要学会寻找!

一、应该给MM留下什么样的第一印象(时间:刚开始接触MM)
1、我认为最关键的,是要让MM看到你的上进心。
男人的最大魅力在于事业有成,年轻人工作时间不长谈不上“有成”,这时候你就要让MM觉得你是个有上进心的人。
别的可以胡说八道,但这个问题不能含糊,你一定要告诉MM,你对未来充满信心,你不满足于现状,并且你已经有了长远的计划,总之你的未来不是梦。
2、要显得有信心、有责任心
不要像个小孩子,女孩子都很懒希望能找个依靠,你要拿出自己的信心和责任心来。
有一个错的选择总比没有选择要好的多。
3、不要太正经,但也不要太随便
该正经的地方就正经,该调侃的的时候就调侃。
女孩子都喜欢有点玩世不恭的男人,所以别显得对什么都特别在意,那样太呆板。
4、显得成熟一点
遇事镇定、从容不迫的男人对MM有致命的吸引力。
二、如何与MM展开进一步接触(时间:开始追的阶段)
1、这个阶段最关键的是不能着急,不要把事情弄的那么清楚,让人家一眼就能看出你在 追人家。
想一想,一般人都不会一眼就看上你,但也不会看一眼就讨厌你,都是老百姓家的孩子(除非你长得象周润发刘德华或者凯文科斯特纳),好感是需要随着了解的不断增加而实现的,所以问题的关键是你要得的进一步发展的机会。
站在女孩子的角度替人家想一想:你这么直接了当的冲过来要搞对象,女孩子肯定有心理压力。这要是接触一阵后发现不喜欢你,那不就成了耍你了么?所以如果你开始就摆出志在必得的姿势出来,基本上会被立刻闷回去。
2、要低姿态起步
首先要把关系定位成“朋友”,本来是“普通朋友”,你希望成为“好朋友”,有品位的还可以要求对方成为“红颜知己”什么的,总之千万不要说“追你”。
你想想,你如果根本不提“追”,那么女孩子也就更没机会“拒绝”你——你没追她怎么拒绝你?!
这样可以减轻女孩子的心理压力,使你们能顺利的交往下去。不要幻想认识三天就答应嫁给你,要充分的交往、了解,感情不是凭空产生的。
3、交往的过程中不要太急躁
要有张有弛,不要整天缠着人家,谁这样对你,你也会腻。我有个好朋友对我说,追女孩子的关键是八个字—— “忽冷忽热、欲擒故纵”(这是我同学多少年心血的结晶)。
你整天缠着人家自然不觉得你好,你适当的冷个一两天,女孩子就会想起你在的好处了。
还有就是不要拿出“非你不娶”的志气来,太掉价了不好,有时候可以耍点花招。
4、要适当的创造机会
前面说了,不要使事情立刻变成“你在追别人”,而你又需要得到接近女孩子的机会,这时就要看你的创造力了。
你可以搜集情报,想办法把守株待兔变成一场邂逅;也可以装做漫不经心的找出最最充足的理由邀请对方和你一起做什么事。
总之这个是最有技术含量的地方,实在不行可以找前辈请教。
5、切忌切忌:随便送人家礼物是不礼貌的
有些人追女孩子心切,喜欢经常买东西送人家,殊不知追女孩子最忌讳这个。
俗话说“无功不受禄”,你这样送人家东西就是在施加压力,人家会觉得欠你的,所以会 想办法还给你,如果没办法还给你就会想办法不和你交往,免得总是欠你人情。
如果你想显示自己的诚意,倒不妨请女孩子一起消费,比如说找好的餐厅吃饭,或者找贵 的地方一起玩什么的,女孩子自然能看出你花了很多钱,但钱终究是两个人一起花了而不是变成东西带回家。
三、“女朋友”到底是什么?
1、“女朋友”是一种事实,而不是一份承诺
你和女孩子开始交往,从“普通朋友”变成“好朋友”,再到“非常非常好、无话不谈的朋友”,某一个阳光灿烂的午后,你“不小心”拉了她的手;“月上柳梢头”,你突然袭击吻了她。这时她就已经是你的女朋友了,无论她是否承认,她心理已经认为你是他男朋友了。
我知道最高明的,直到上床了都没问过“你是否愿意做我女朋友”,最后还是女孩子急了 :“你怎么还不求我做你女朋友啊!”
所以说,千万不要急于把窗户纸捅破,情况越朦胧对你越有利。
2、“表白”是什么?
前面说了,表白实际上就是一个形式而已,正确的顺序应该是:事实上已经成为你女朋友 了,你才能向人家表白,水到渠成。 很多人弄不明白这个问题,总以为人家先答应做自己女朋友,然后再如何如何,我只能说非常非常“单纯”,也非常非常“愚蠢”。
3、有没有“迫不得已非表白不可”的时候?
有,比如说出现第三者,或者你和女孩子关系没有成熟但两个人可能分开一段时间。
这时候的表白就是条件不成熟的表白,风险非常大,类似于下围棋的时候形势严峻,落後的一方迫于无奈放出“胜负手”,赢了就赢了,输了也只能说“倒霉都是天生的”。
4、“爱”字不要轻易出口
经常看见论坛出现“大胆的表白”,说实话我真的认为这是非常不成熟的一种表现。“爱”是一个神圣的字,意味着追求,也意味着承诺,甚至体现出一种责任。
随便说“爱”的男人是不负责任的。
四、文明恋爱,不可强求
1、不是每个MM都能追到手的
好女孩子总会有很多人追,不可能遂了每个人的心愿,总会有失败者。举个例子,就算你刻苦钻研掌握了最搞超的追MM原理,你一样追不上TWINS里的任何一个。
换个角度考虑问题,一个小学没毕业的农村小保姆,即使对你再好,每个月赚600给你买700的礼物(透支),愿意为你“当牛做马”,你也不会爱上她。如果她每天哭哭啼啼的缠着,你肯定觉得烦。
所以说爱情是需要物质基础的,至少需要平衡。
2、追MM做是一种严肃的社会活动
千万不要把人家搞烦了,要给自己留后路。大丈夫何患无妻?有些MM确实势利眼(少数),如果不服气,你可以发愤图强,用事实证明“她当时瞎了眼”,绝对不要误人误己。

最后补充两点:
①千万不要在MM面前显得愤世嫉俗,愤世嫉俗有时候意味着“你很失败”。

一道面试题 没答出来 高人指教

silver6 | 02 十二月, 2005 16:57

编写一个C语言程序,实现父、子进程之间进行CPU的竞争与同步的过程。
可以由一个父进程创建两到三个子进程,每个进程独立完成不同的任务,如输出不同的数据等,以此来观察各进程占有CPU的情况。(可以利用wait函数来进行进程同步的控制。)

int main()
{
pid_t pid;
int i;

pid = fork();

if (pid == 0){
for (i = 0; i < 14; i++){
sleep (rand()%4);
printf("-SON-n");
}
return 0;
}

sleep (rand()%4);
printf("+FATHER+ Waiting for son's termination...n");
waitpid (pid, NULL, 0);
printf("+FATHER+ ...endedn");

return 0;
}


华为面试题

silver6 | 02 十二月, 2005 16:53

有1,2,....一直到n的无序数组,求排序算法,并且要求时间复杂度为O(n),空间复杂度O(1),使用交换,而且一次只能交换两个数.

//这是昨天在华为的面试题,楞是没做出来.

#include<stdio.h>
#include<stdlib.h>

int print( int*, int );
int swap( int&, int& );
int main()
{
int *a, n, i;
scanf( "%d", &n );
a = ( int* ) malloc ( ( n + 1 ) * sizeof( int ) );
for( i = 1; i <= n; i++ )
a[i] = i;
for( i = 1; i <= n; i++ )
swap( a[i], a[rand()%n+1] );
print( a, n );
for( i = 1; i <= n; i++ )
{
while( a[i] != i )
swap( a[i], a[a[i]] );
}
print( a, n );
return 0;
}
int swap( int &i, int &j )
{
int temp = i;
i = j;
j = temp;
return 0;
}
int print( int a[], int n )
{
int i;
for( i = 1; i <= n; i++ )
printf( "%4d", a[i] );
printf( "n" );
return 0;
}


TO:zez(思恩 闭关练功ing...) , 你的第一种算法不行吧, 第一个位置没交换好你就i++了,
象我的程序一样要加一句话才行:
int i,b;
for (i =0;i<n; i++)
{
while( a[i] != ( i + 1 ) )
{
b=a[i];
a[i]=a[a[i]-1];
a[a[i]-1]=b;
}
}
看似两重循环, 实则复杂度为O(n).

int i,b;
for i =0;i<n; i++
{
b=a[i];
a[i]=a[a[i]-1];
a[a[i]-1]=b;
}
这种方法是不行的,不信看我的测试程序
#include <stdio.h>
#include <malloc.h>
void swap(int&,int&);
int main()
{
int *a;
int n;
int i,j,b;
scanf( "%d", &n );
a = ( int* ) malloc ( ( n ) * sizeof( int ) );
for( i = 0; i <n; i++ )
a[i] = i+1;
for( i = 0; i <n; i++ )
swap( a[i], a[rand()%n] );

for(i=0;i<n;i++)
printf("%d ",a[i]);
printf("n");

for(i=0;i<n;i++)
{
//swap(a[i],a[a[i]-1]);
swap(a[i],a[a[i]-1]);
}
for(i=0;i<n;i++)
printf("%d ",a[i]);
printf("n");
free(a);
getchar();
return 0;
}
void swap(int& a,int& b)
{
int temp;
temp=a;
a=b;
b=temp;
}

输入 10
输出:4 8 1 2 3 10 9 7 5 6
1 7 3 4 2 6 5 8 9 10
哪位老兄再对程序该进一下,怎样才能得到准确的结果。

 查看全文

笔试题

silver6 | 01 十二月, 2005 09:30

1.代码如下:
class A
{
};
class B
{
A a;
};
A和B的关系是
A。继承(Inheritance)
B.聚合(Aggreation)/组合( Composition)
C.引用(Reference)
D.单件(Singleton)
2.有代码如下
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
#define NULL 0
void AppendNode(int **ppNode,int nCount,int nValue)
{
if( ppNode != NULL )
{
*ppNode = (int *) realloc(*ppNode,(nCount+1)*sizeof(int));
(*ppNode)[nCount] = nValue;
}
}

int main()
{
int NodeArray[5] = {1,2,3,4,5};
int **ppNode;
*ppNode = NodeArray;
AppendNode(ppNode,5,4);
return 0;
}
请问程序中是否有错误
A。有错误数组操作越界
B。有错误有内存泄露
C。有错误用堆内存分配函数操作栈上内存
D。没有错误

3。某模块提供了如下的接口
class CDataOperator
{
public:
virtual void function(int data) = 0;
};
class CData
{
private:
int m_data[100];
public:
...
void Apply(CDataOperator &opt);
};
void CData::Apply(CDataoperator &opt)
{
for( int k = 0; k < 100; k++)
{
opt.function(m_data[k]);
}
}
请编写一个函数DataSum,返回其参数data对象的成员变量m_data中所有元素的和。
int DataSum(CData &data);

class CDataSumOperator : public CDataOperator{
public :
int he;
CDataSumOperator(): he(0){}
void function(int data){
he += data;
}
};

int DataSum(CData &data)
{
CDataSumOperator temp;
data.Apply(temp);
return temp.he;
}


新浪的技术人员问我的一道面试题

silver6 | 01 十二月, 2005 09:28

在数据库中有10000条记录,每次提取100条,应该怎么写?

不同数据库不同,
mysql ,postgres用的是limit,
oracle, db2用的是rownum函数,
sql server就惨了,只能 top ... not in top..


oracle:取100 - 200

slect * from
(
select * from table where rownum<=200
) where rownum>=100

select top 100 * from Users


一道华为公司的面试题目.怎么把字符串转化为字节数组?

silver6 | 01 十二月, 2005 09:26

一道华为公司的面试题目.怎么把字符串转化为字节数组?


比如 CString *str="ABCD";(长度不确定的字符串)  (VC中)

char *str="ABCD";(长度不确定的字符串)  (C语言中)

变为 byte DATA[4]; (要求字节数组长度应和字符串一致)
DATA[0]='A';
DATA[1]='B';
DATA[2]='C';
DATA[3]='D';

char *str='ABCD',*p=str;
byte *b = (byte *) malloc(strlen(str)),*c=b;
while (*p) *c++=*p++;

// ssh.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <iostream.h>
#define N 6

int main(int argc, char* argv[])
{
char *p="abcde";
char array[N];
for(int i=0;i<N;i++)
{
array[i]=*p;
p++;
}
cout<<p-6<<endl;
cout<<array<<endl;
return 0;
}

#include <iostream>
using namespace std;

char OneChar(const char* pChar = 0)
{
static const char* psChar;
if(NULL != pChar)
{
psChar = pChar;
return *psChar;
}

if('' != *psChar)
{
return *psChar++;
}
else
{
return 0;
}
}

const char* pChar = "ABCD" ;

void main()
{
int i = 0;
char Data[4];
char c;
OneChar(pChar);
while((c = OneChar()) != 0)
{
Data[i++] = c;
}
}

//动态字符维数
#include <iostream>
using namespace std;

char OneChar(const char* pChar = 0)
{
static const char* psChar;
if(NULL != pChar)
{
psChar = pChar;
return *psChar;
}

if('' != *psChar)
{
return *psChar++;
}
else
{
return 0;
}
}

const char* pChar = "ABCDE" ;

void main()
{
int i = 0;
char *pData = new char[strlen(pChar)];
char c;
OneChar(pChar);
while((c = OneChar()) != 0)
{
pData[i++] = c;
}

for(i = 0; i < strlen(pChar); i++)
cout << pData[i] << endl;
}

#include <iostream>
using namespace std;

void main()
{
char* pChar = "ABCDE";
char* pData = new char[strlen(pChar) + 1];
int i = 0;
while(*pChar != '')
{
pData[i++] = *pChar;
cout << *pChar << endl;
pChar++;
}
}


一个笔试题

silver6 | 01 十二月, 2005 09:21

class StringBuf
{
StringBuffer x,y;
public StringBuf()
{
x=new StringBuffer("A");
y=new StringBuffer("B");
append(x,y);
System.out.println("x>> "+x+" y>> "+y);
}
void append(StringBuffer x,StringBuffer y)
{
x=x.append(y);
y=x;
}
public static void main(String[] args)
{
StringBuf str=new StringBuf();
}
}

我对这个题目不是搞得很清楚.可以给我说说吗.
为什么会输出 x>>AB y>>B
谢谢了!

x=new StringBuffer("A");
y=new StringBuffer("B");
起初x=A,y=B

append(x,y);
执行append(x,y)后
y被加到x后面
x变成AB
因为函数是传值调用,append(StringBuffer x,StringBuffer y)里的y不是构造的y
所以构造函数里的y没变,还是B

改变参数引用值是没用的.只有改变参数引用所对应的对象才会起作用.

可以这么理解
张三和李四都是人名
a(张三,李四)
{
张三赚500块;
李四=张三;//在局部范围内,李四和张三都成了张三的名字
//想得到原李四,在这个局部范围再也找不着了.
}
调用完a后,回到大范围,李四还是原来的李四,张三还是原来的张三.

class A
{
StringBuffer x,y;
public A()
{
x=new StringBuffer("AA");
y=new StringBuffer("BB");
foo(x,y);
System.out.println("x>> "+x+" y>> "+y);
}
void foo(StringBuffer a,StringBuffer b)
{
/*a= */ a.append(b);
b=a;
}
public static void main(String[] args)
{
A str=new A();
}
}
这样就清楚了。

void append(StringBuffer x,StringBuffer y){//x,y局部变量
x=x.append(y);//x(成员)=x(局部变量).append(y(局部变量))
y=x;//y(局部变量)=x(局部变量)
}

明白了,那两个x,y参数真是糊弄人的!
改成a,b就清楚了

可以这么看
在foo中,定义了两个引用a和b,a和x同时指向一个StringBuffer,b和y同时指向一个StringBuffer,a.append(b)将a和x指向的对象修改了,所以显示出来x就也变化了,这里操纵的是指向的对象。

b指向了a所指向的对象,但y仍然指向原来的对象,这里改变的是应用本身。


在b=a;后面加上System.out.println(b.toString());就更明显了

void append(StringBuffer x,StringBuffer y){//x,y局部变量
x=x.append(y);//x(局部变量)=x(成员).append(y(局部变量))
y=x;//y(局部变量)=x(局部变量)
}

对于这个你只要把StringBuffer类型 理解为String 类型就可以了,其实两种类型是用在字符串变量中,只是StringBuffer用在多操作的字符串

StringBuffer在堆内存中只有1份
void append(StringBuffer x,StringBuffer c){//x,c栈变量(就是引用)
c.append(x);System.out.println(c);//append使栈变量c指向堆中的值发生改变
x.append(c);System.out.println(x);
System.out.println(x);
c=x;System.out.println(c);//引用指向改变
}

************ 下文(转载)能很好地解答这问题 ************

在不同的java新闻组中,参数是传值还是传址一直是一个经常被争辩的话题。误解的中心是以下两个事实:

对象是传引用的
参数是传值的
这两个能够同时成立吗?一个字:是!在java中,你从来没有传递对象,你传递的仅仅是对象的引用!一句话,java是传引用的。然而,当你传递一个参数,那么只有一种参数传递机制:传值!

通常,当程序员讨论传值和传引用时,他们是指语言的参数传递机制,c++同时支持这两种机制,因此,以前使用过c++的程序员开始好像不能确定的java是如何传参数的。java语言为了事情变得简单只支持参数传值的机制。

java中的变量有两种类型:引用类型和原始类型。当他们被作为参数传递给方法时,他们都是传值的。这是一个非常重要的差别,下面的代码范例将说明这一点。在继续前,我们有必要定义一下传值和传引用。

传值意味着当参数被传递给一个方法或者函数时,方法或者函数接收到的是原始值的副本。因此,如果方法或者函数修改了参数,受影响的只是副本,原始值保持不变。

关于java中的参数传递的混乱是因为很多java程序员是从c++转变过来的。c++有引用和非引用类型的变量,并且分别是通过传引用和传值得。java语言有原始类型和对象引用,那么,按照逻辑,java对于原始类型使用传值而对引用是传引用的,就像c++一样。毕竟,你会想到如果你正在传递一个引用,那么它一定是传引用的。这是一个很诱惑人的想法,但是是错误的!

在c++和java中,当函数的参数不是引用时,你传递的是值得副本(传值)。但是对于引用类型就不同了。在c++中,当参数是引用类型,你传递的是引用或者内存地址(传引用),而在java中,传递一个引用类型的参数的结果只是传递引用的副本(传值)而非引用自身。

这是一个非常重要的区别!java不考虑参数的类型,一律传递参数的副本。仍然不信?如果java中是传引用,那么下面的范例中的swap方法将交换他们的参数。因为是传值,因此这个方法不是像期望的那样正常工作。

class Swap{
public static void main(String args[]) {
Integer a, b;
int i,j;
a = new Integer(10);
b = new Integer(50);
i= 5;
j = 9;
System.out.println("Before Swap, a is " + a);
System.out.println("Before Swap, b is " + b);

swap(a, b);

System.out.println("After Swap a is " + a);
System.out.println("After Swap b is " + b);

System.out.println("Before Swap i is " + i);
System.out.println("Before Swap j is " + j);

swap(i,j);

System.out.println("After Swap i is " + i);
System.out.println("After Swap j is " + j);
}
public static void swap(Integer ia, Integer ib){
Integer temp = ia;
ia = ib;
ib = temp;
}
public static void swap(int li, int lj) {
int temp = li;
li = lj;
lj = temp;
}
}
上面程序的输出是:

Before Swap, a is 10
Before Swap, b is 50
After Swap a is 10
After Swap b is 50
Before Swap i is 5
Before Swap j is 9
After Swap i is 5
After Swap j is 9

因为swap方法接收到的是引用参数的副本(传值),对他们的修改不会反射到调用代码。

译者注:在传递引用和原始类型时还是有不同的,考虑以下的代码:

class Change{
public static void main(String args[]) {
StringBuffer a=new StringBuffer("ok");
int i;
i = 5;
System.out.println("Before change, a is " + a);
change(a);
System.out.println("After change a is " + a);
System.out.println("Before change i is " + i);
change(i);
System.out.println("After change i is " + i);
}

public static void change(StringBuffer ia){
ia.append(" ok?");
}

public static void change(int li) {
li = 10;
}
}


程序的输出为:
Before change, a is ok
After change a is ok ok?
Before change i is 5
After change i is 5


即如果传递的是引用,那么可以修改引用对象的内容,这个改变会影响到原来的对象,而传递的如果是原始类型则不会有影响。这个也是造成误解的原因之一吧。

在最上面的程序当中,
operate()中的操作x.append(y),实际上是改变了x引用的内容,由于a跟x引用同一个对象,所以a的引用也会随之改变
而y=x只是改变operate()中y的引用,这个是局部的,不会影响到main()中b的引用
所以结果是AB,B

java中基本类型是传值调用,即先把值copy一份,是把这个copy的值传给形参;所以改变的是copy的值;

对象是传址调用,就是把对象的地址再copy一份,传给形参,copy后的值和被copy的值指向同一个对象,这样通过引用修改对象影响到对象的变化,但是修改copy后的指向不影响原对象的引用

画个草图看看就很清晰了


一道面试题(指针问题)

silver6 | 01 十二月, 2005 09:19

#include "iostream.h"
void main()
{

char (*a)[5];
char (*b)[5];

a = new char[2][5];
b=a;
char c[5]="1234";
*b =c;printf("%sn",b);//不能编译通过?
b=&c;printf("%sn",b);//能编译通过 *b=c不就是*b=c吗?
delete []a;


}

c类型是char
&c类型是char[5]

原因是数组,*b是一个地址的值,而c是一个数组。应该用地址方式赋值也就是 b = &c 应该也可以这样 b = c!

*b 是一个char[5]类型的数组,但是数组是不能作为左值的
b是一个char[5]类型的指针,指针可以作为左值

*b 是一个char[5]类型的数组,但是数组是不能作为左值的
b是一个char[5]类型的指针,指针可以作为左值.

b 是一个指针,它指向的是一个char[5]类型的数组,是一个左值。
但*b就是一个右值了。


今天的慧通面试题

silver6 | 01 十二月, 2005 09:16

今天参加了慧通的面试,笔试过了
一面时问了很多,把不理解的贴出来,请大家讲讲
什么是预编译
char * const p;
char const * p
const char *p

上述三个有什么区别?
全局变量存放在什么地方?

两个字符串,s,t;把t字符串插入到s字符串中,s字符串有足够的空间存放t字符串

void insert(char *s, char *t, int i);

预编译:前边都有#,是编译之前的处理

char * const p;
char const * p
const char *p
后两者相同,指针可以改变,p++合法,而第一中是内容可变,(*p)++合法

全局变量?不知道

void insert(char *s, char *t, int i)
{
int j;
int ns = 0;
int nt = 0;
while ( *s++ )
ns++;

s = s - ns -1;

while ( *t++ )
nt++;

t = t - nt -1;

for ( j=i;j<ns;j++)
s[j+nt]=s[j];

for ( j=i;j<nt+i;j++)
s[j] = t[j-i];

}

1.
c编译系统在对程序进行通常的编译之前,先进行预处理。c提供的预处理功能主要有以下三种:1)宏定义 2)文件包含 3)条件编译

1. 宏定义

不带参数的宏定义
用一个指定的标识符来代表一个字符串,形式:#define 标识符 字符串
几点说明:
1) 宏名一般用大写
2) 宏定义不作语法检查,只有在编译被宏展开后的源程序时才会报错
3) 宏定义不是c语句,不在行末加分号
4) 宏名有效范围为定义到本源文件结束
5) 可以用#undef命令终止宏定义的作用域
6) 在宏定义时,可以引用已定义的宏名

带参数的宏定义
定义形式:#define 宏名(参数表) 字符串
这和函数有些类似,但他们是不同的:
1) 函数调用时,先求实参表达式值,再代入形参,而宏只是简单替换,并不求值
2) 函数调用是在程序运行时分配内存的,而宏展开时并不分配内存,也没有返回值的概念
3) 对函数中的实参和形参都要定义类型,而且要求一致,宏名无类型,其参数也没有类型。
4) 函数只有一个返回值,而宏可以得到几个结果
5) 宏替换不占运行时间,只占编译时间,而函数调用占运行时间

2. 文件包含处理

#include "文件1" 就是将文件1的全部内容复制插入到#include位置,作为一个源文件进行编译。
在#include命令中,文件名可以用" "也可以用< >,假如现在file1.c中包含file2.h文件," "表示系统先在file1.c所在目录中找file2.h,如果找不到,再按系统指定的标准方式检索目录,< >表示系统直接按指定的标准方式检索目录。所以用" "保险一点。

3. 条件编译

条件编译指不对整个程序都编译,而是编译满足条件的那部分。条件编译有以下几种形式:
1)#ifdef 标识符
  程序段1
  #else
程序段2
#endif
它的作用:当标识符在前面已经被定义过(一般用#define),则对程序段1编译,否则对程序段2编译。
2)#ifndef 标识符
程序段1
#else
程序段2
#endif
它的作用和#ifdef相反,当标识符没被定义过,对程序段1编译,否则对程序段2编译。
3)#if 表达式
程序段1
  #else
 程序段2
#endif
它的作用:当表达式值为真(非0)时,对程序段1编译,否则对程序段2编译。


char * const p; 固定 指针的 指向

const char * p; 固定 指针指向的 数值!

“前固数,后固址”

char * const p; //常量指针,p的值不可以修改
char const * p;//指向常量的指针,指向的常量值不可以改
const char *p; //和char const *p

char * const p; //常指针,是指把指针本身而不是把它指向的对象声明为常量
char const * p //指向常量的指针
const char *p //同char const *p

char * const p; //指向字符常量的指针
char const * p //指向字符的常量指针
const char *p //同上


全局变量放在静态存储区

void insert(char *s, char *t, int i)
{
int j;
int ns = 0;
int nt = 0;
while ( *s++ )
ns++;

s = s - ns -1;

while ( *t++ )
nt++;

t = t - nt -1;

for ( j=i;j<ns;j++)
s[j+nt]=s[j];

for ( j=i;j<nt+i;j++)
s[j] = t[j-i];

}
这个程序实现好像有问题啊,谁能把这个程序给改进一下呢?

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
void insert(char *s, char *t, int i)
{
int len = strlen(s)-i;

int tlen = strlen(t);
// memmove(s+i+tlen, s+i, len+1); // 加1的目的是将''也拷贝
// memmove(s+i, t, tlen);
// return;

int j;
char* psrc = s + i + len - 1;
char* pdes = psrc + tlen;

if (len < 0)
return;

*(pdes+1) = 0;

for (j = len; j > 0; j--, pdes--, psrc--) // 后移
*pdes = *psrc;

pdes = s + i;

for (j = 0; j < tlen; j++, pdes++, t++) // 插入
*pdes = *t;
}


void main(int argv, char* argc[])
{
char buffer[1000];
if (argv < 4)
{
printf("Usage f str str2 posn");
return;
}

strcpy(buffer, argc[1]);
insert(buffer, argc[2], atoi(argc[3]) );

printf("!%s!n", buffer);
}

 查看全文

我公司面试的题目

silver6 | 01 十二月, 2005 09:11

1。请大概描述一下Vector和ArrayList的区别,Hashtable和HashMap的区别。(5)

2。请问你在什么情况下会在你的JAVA代码中使用可序列化?(5)
为什么放到HttpSession中的对象必须要是可序列化的?(5)

3。为什么在重写了equals()方法之后也必须重写hashCode()方法?(10)

4。sleep()和wait()有什么区别?(10)

5。编程题:用最有效率的方法算出2乘以17等于多少?(5)

6。JAVA是不是没有内存泄漏问题?看下面的代码片段,并指出这些代码隐藏的问题。(10)
...
Object[] elements = new Object[10];
int size;
...
public Object pop() {
if (size == 0)
return null;
Object o = elements[--size];
return o;
}

7。请阐述一下你对JAVA多线程中“锁”的概念的理解。(10)

8。所有的递归实现都可以用循环的方式实现,请描述一下这两种实现方式各自的优劣。
并举例说明在什么情况下可以使用递归,而在什么情况下只能使用循环而不能使用递归?(5)

9。请简要讲一下你对测试驱动开发(TDD)的认识。(10)

10。请阐述一下你对“面向接口编程”的理解。(10)

11。在J2EE中有一个“容器(Container)”的概念,不管是EJB、PICO还是Spring都有他们
各自实现的容器,受容器管理的组件会具有有生命周期的特性,请问,为什么需要容器?
它的好处在哪里?它会带来什么样的问题?(15)

12。请阐述一下你对IOC(Inversion of Control)的理解。(可以以PICO和Spring的IOC作为例子说明他们在实现上各自的特点)(10)

13。下面的代码在绝大部分时间内都运行得很正常,请问在什么情况下会出现问题?问题的根源在哪里?(10)
import java.util.LinkedList;

public class Stack {

LinkedList list = new LinkedList();

public synchronized void push(Object x) {
synchronized(list) {
list.addLast( x );
notify();
}
}

public synchronized Object pop()
throws Exception {
synchronized(list) {
if( list.size() <= 0 ) {
wait();
}
return list.removeLast();
}
}
}

你拿了多少分?

11。在J2EE中有一个“容器(Container)”的概念,不管是EJB、PICO还是Spring都有他们
各自实现的容器,受容器管理的组件会具有有生命周期的特性,请问,为什么需要容器?
它的好处在哪里?它会带来什么样的问题?(15)
-------------这个问题也觉得有点傻,比如web container,你说你为什么需要它呢?没有它,还做什么J2EE啊,有些容器对于J2EE是必需的吧?

1>这个讨论的很多了.主要是线程安全,性能上面
2>a 将对象的状态保存在存储媒体中以便可以在以后重新创建出完全相同的副本;
b 对象进行反序列化时,将创建出与原对象完全相同的副本。
c>httpSession是一个处于网络上的存储的一个映象的集合,存贮了用户会话的信息
3> java.lang.Object中定义!我自己的理解的是hashCode()是对象的内存地址派生而来的,在集合框家Map也是基于hashCode();
4> sleep(int i)是线程的方法,是让cpu交出的线程使用权限一定时间(i毫秒),采用"时间片乱转法".
wait 是OBJECT的方法,才用琐的机制,让正在使用它的线呈停住!等待别的对象调用notifyAll()的方法释放锁!
5>c语言的问提 无非是在完2进制的左翼还是右移的问题(高汇编的同志因该很厉害!)
6>int size;注意如果初试画为负数 该为public Object pop() {
if (size <= 0)
return null;
Object o = elements[--size];
return o;
}
7>才用同步标志位,解决锁的问题....(说起来的东西很多 ,主要了解 同步方法,同步快,wait...)
8>"所有的递归实现都可以用循环的方式实现"这话绝对有问题.
循环是才用的是内存块里,低归需要一定量寻址过程.效率是循环高!质量是低归高!
9>不是所云
10>1封装,2隐常实现3,重用.易于组建的扩展
11>容器即中间件! 容器实现的J2EE中的web,ejb的矿家,其主件在各自受管理的平台下基于多线呈的组件的重用实现~~!是开发者从大量的开发中解脱出来!
特点:安全,易于扩展,企业的负载平衡,提供了大量的组件(jndi,datasource,jms,servlet,ldap,jts...).
问题:
...不知道!
12>spring了解 PICO不懂为和物!?
13>问题是在当调用wait()以后,notify()不能换醒自己的线程@!!!!

13。下面的代码在绝大部分时间内都运行得很正常,请问在什么情况下会出现问题?问题的根源在哪里?(10)
答:
有一点需要注意的是,我们应该让需要Obj.wait的线程先启动。因为执行顺序是需要Obj.wait()的线程a先启动,然后它运行到Obj.wait()的时候,进入搁置状态,让其他线程先执行。于是带用Obj.notify()的线程b开始执行了,一直到b执行到了Obj.notify()以后(Obj.notify()实际上就是通知因为Obj.wait()被搁置的线程:"轮到你了"),b被搁置,然后继续做a的Obj.wait()以后的内容.
所以我们假如让带有Obj.notify()的线程b先运行的话,那么b执行完毕以后,b执行的Obj.notify()没有找到任何在因Obj.wait()而进入搁置状态的线程.然后开始做带有Obj.wait()的线程a的话.a运行到了Obj.wait()就进入搁置状态,等待另外一个线程中的Obj.notify()来唤醒它,不过可惜它永远也等不到了,因为带有Obj.notify()的线程已经到搁置的线程中来找过它一次,很可惜的是没找到.于是线程a就一直搁置

1,同步与不同步
2,会在保存状态信息的时候,比如图形界面中保存状态信息的时候用,
好象没有这样吧(可能是有的服务器要求这样吧),反正我用TOMCAT的时候没有这样.不一定非要把数据钝化到硬盘上.
3,这个好象没有什么规定吧,我觉得更应该是个编程习惯.如过我重载了equals,不重载hashCode程序也能运行,只不过不能用map了 .不过一般都会一起重载
4,sleep 程序暂停一段时间(不释放锁),如果CPU空闲将运行程序.wait()必须在对象的同步块中执行(释放同步锁),她必须由notify(),notifyAll()唤起,wait(long mill)就不说了
5,上面都说了其实我觉得考这个好象没什么必要
6,有程序有,public Object pop() {
if (size == 0)
return null;
--size;
Object o = element[size];//加上elements[size]==null;出了栈的对象设为null
return o;
}
7, 是多线程程序同步与互斥,同一时间只有一个线程可以访问锁资源
8,懒得打字了
9,不知道
10,面向接口(1,2 句话说不清楚,反正好处是太多了)
11,容器,(所谓的中间件)屏蔽了复杂的网络,多线程,对象的创建与销毁,事物,还有可以用到集群哦,好处太多了
12,IOC(所谓的依赖注射模式)SPING不了解,可以配制的程序吧,我觉得可以适当的用不能滥用
13,这个是JDK设计的问题,应该用组合来实现,不应该用继承,如果我调用它继承下来的add(),get()方法就会有问题

你们公司技术不错啊.

。为什么在重写了equals()方法之后也必须重写hashCode()方法?(10)


请解释!

在TIJ上也有这样的题目,不知道为社么?

4。sleep()和wait()有什么区别?(10)

sleep()好象是线程仍然持有对象的所有权。
wait()则是释放了锁定。

1。请大概描述一下Vector和ArrayList的区别,Hashtable和HashMap的区别。(5)

Vector有互斥,而ArrayList没有。?


8。所有的递归实现都可以用循环的方式实现,请描述一下这两种实现方式各自的优劣。
并举例说明在什么情况下可以使用递归,而在什么情况下只能使用循环而不能使用递归?(5)

递归在运行速度上不如循环。不知道?

第一,谈谈final, finally, finalize的区别。   

final?修饰符(关键字)如果一个类被声明为final,意味着它不能再派生出新的子类,不能作为父类被继承。因此一个类不能既被声明为 abstract的,又被声明为final的。将变量或方法声明为final,可以保证它们在使用中不被改变。被声明为final的变量必须在声明时给定初值,而在以后的引用中只能读取,不可修改。被声明为final的方法也同样只能使用,不能重载finally?再异常处理时提供 finally 块来执行任何清除操作。如果抛出一个异常,那么相匹配的 catch 子句就会执行,然后控制就会进入 finally 块(如果有的话)。

finalize?方法名。Java 技术允许使用 finalize() 方法在垃圾收集器将对象从内存中清除出去之前做必要的清理工作。这个方法是由垃圾收集器在确定这个对象没有被引用时对这个对象调用的。它是在 Object 类中定义的,因此所有的类都继承了它。子类覆盖 finalize() 方法以整理系统资源或者执行其他清理工作。finalize() 方法是在垃圾收集器删除对象之前对这个对象调用的。

  第二,Anonymous Inner Class (匿名内部类) 是否可以extends(继承)其它类,是否可以implements(实现)interface(接口)?   

匿名的内部类是没有名字的内部类。不能extends(继承) 其它类,但一个内部类可以作为一个接口,由另一个内部类实现。

第三,Static Nested Class 和 Inner Class的不同,说得越多越好(面试题有的很笼统)。

Nested Class (一般是C++的说法),Inner Class (一般是JAVA的说法)。Java内部类与C++嵌套类最大的不同就在于是否有指向外部的引用上。具体可见http: www.frontfree.netarticlesservicesview.asp?id=704&page=1

注: 静态内部类(Inner Class)意味着1创建一个static内部类的对象,不需要一个外部类对象,2不能从一个static内部类的一个对象访问一个外部类对象

  第四,&和&&的区别。   

&是位运算符。&&是布尔逻辑运算符。

第五,HashMap和Hashtable的区别。

都属于Map接口的类,实现了将惟一键映射到特定的值上。

HashMap 类没有分类或者排序。它允许一个 null 键和多个 null 值。

Hashtable 类似于 HashMap,但是不允许 null 键和 null 值。它也比 HashMap 慢,因为它是同步的。

第六,Collection 和 Collections的区别。

Collections是个java.util下的类,它包含有各种有关集合操作的静态方法。

Collection是个java.util下的接口,它是各种集合结构的父接口。

  第七,什么时候用assert。

  断言是一个包含布尔表达式的语句,在执行这个语句时假定该表达式为 true。如果表达式计算为 false,那么系统会报告一个 AssertionError。它用于调试目的:

assert(a 0); throws an AssertionError if a = 0

  断言可以有两种形式:

  assert Expression1 ;
   assert Expression1 Expression2 ;

  Expression1 应该总是产生一个布尔值。
   Expression2 可以是得出一个值的任意表达式。这个值用于生成显示更多调试信息的 String 消息。
断言在默认情况下是禁用的。要在编译时启用断言,需要使用 source 1.4 标记:

  javac -source 1.4 Test.java

  要在运行时启用断言,可使用 -enableassertions 或者 -ea 标记。
   要在运行时选择禁用断言,可使用 -da 或者 -disableassertions 标记。
   要系统类中启用断言,可使用 -esa 或者 -dsa 标记。还可以在包的基础上启用或者禁用断言。

  可以在预计正常情况下不会到达的任何位置上放置断言。断言可以用于验证传递给私有方法的参数。不过,断言不应该用于验证传递给公有方法的参数,因为不管是否启用了断言,公有方法都必须检查其参数。不过,既可以在公有方法中,也可以在非公有方法中利用断言测试后置条件。另外,断言不应该以任何方式改变程序的状态。


  第八,GC是什么 为什么要有GC (基础)。

  GC是垃圾收集器。Java 程序员不用担心内存管理,因为垃圾收集器会自动进行管理。要请求垃圾收集,可以调用下面的方法之一:

  System.gc()
   Runtime.getRuntime().gc()

  第九,String s = new String(xyz);创建了几个String Object

  两个对象,一个是“xyx”,一个是指向“xyx”的引用对象s。

  第十,Math.round(11.5)等於多少 Math.round(-11.5)等於多少   

  Math.round(11.5)返回(long)12,Math.round(-11.5)返回(long)-11;

  第十一,short s1 = 1; s1 = s1 + 1;有什么错 short s1 = 1; s1 += 1;有什么错  

  short s1 = 1; s1 = s1 + 1;有错,s1是short型,s1+1是int型,不能显式转化为short型。可修改为s1 =(short)(s1 + 1) 。short s1 = 1; s1 += 1正确。

  第十二,sleep() 和 wait() 有什么区别 搞线程的最爱   

  sleep()方法是使线程停止一段时间的方法。在sleep 时间间隔期满后,线程不一定立即恢复执行。这是因为在那个时刻,其它线程可能正在运行而且没有被调度为放弃执行,除非(a)“醒来”的线程具有更高的优先级,(b)正在运行的线程因为其它原因而阻塞。

  wait()是线程交互时,如果线程对一个同步对象x 发出一个wait()调用,该线程会暂停执行,被调对象进入等待状态,直到被唤醒或等待时间到。

  第十三,Java有没有goto  

  Gotojava中的保留字,现在没有在java中使用。

  第十四,数组有没有length()这个方法 String有没有length()这个方法?  
  数组没有length()这个方法,有length的属性。
   String有有length()这个方法。

  第十五,Overload和Override的区别。Overloaded的方法是否可以改变返回值的类型  

  方法的重写Overriding和重载Overloading是Java多态性的不同表现。重写Overriding是父类与子类之间多态性的一种表现,重载Overloading是一个类中多态性的一种表现。如果在子类中定义某方法与其父类有相同的名称和参数,我们说该方法被重写 (Overriding)。子类的对象使用这个方法时,将调用子类中的定义,对它而言,父类中的定义如同被“屏蔽”了。如果在一个类中定义了多个同名的方法,它们或有不同的参数个数或有不同的参数类型,则称为方法的重载(Overloading)。Overloaded的方法是可以改变返回值的类型。

  第十六,Set里的元素是不能重复的,那么用什么方法来区分重复与否呢 是用==还是equals() 它们有何区别  
  Set里的元素是不能重复的,那么用iterator()方法来区分重复与否。equals()是判读两个Set是否相等。

  equals()和==方法决定引用值是否指向同一对象equals()在类中被覆盖,为的是当两个分离的对象的内容和类型相配的话,返回真值。

  第十七,给我一个你最常见到的runtime exception。  

  ArithmeticException, ArrayStoreException, BufferOverflowException, BufferUnderflowException, CannotRedoException, CannotUndoException, ClassCastException, CMMException, ConcurrentModificationException, DOMException, EmptyStackException, IllegalArgumentException, IllegalMonitorStateException, IllegalPathStateException, IllegalStateException,
ImagingOpException, IndexOutOfBoundsException, MissingResourceException, NegativeArraySizeException, NoSuchElementException, NullPointerException, ProfileDataException, ProviderException, RasterFormatException, SecurityException, SystemException, UndeclaredThrowableException, UnmodifiableSetException, UnsupportedOperationException

  第十八,error和exception有什么区别  

  error 表示恢复不是不可能但很困难的情况下的一种严重问题。比如说内存溢出。不可能指望程序能处理这样的情况。

  exception 表示一种设计或实现问题。也就是说,它表示如果程序运行正常,从不会发生的情况。

第十九,List, Set, Map是否继承自Collection接口  

  List,Set是

  Map不是

  第二十,abstract class和interface有什么区别  

  声明方法的存在而不去实现它的类被叫做抽象类(abstract class),它用于要创建一个体现某些基本行为的类,并为该类声明方法,但不能在该类中实现该类的情况。不能创建abstract 类的实例。然而可以创建一个变量,其类型是一个抽象类,并让它指向具体子类的一个实例。不能有抽象构造函数或抽象静态方法。Abstract 类的子类为它们父类中的所有抽象方法提供实现,否则它们也是抽象类为。取而代之,在子类中实现该方法。知道其行为的其它类可以在类中实现这些方法。

  接口(interface)是抽象类的变体。在接口中,所有方法都是抽象的。多继承性可通过实现这样的接口而获得。接口中的所有方法都是抽象的,没有一个有程序体。接口只可以定义static final成员变量。接口的实现与子类相似,除了该实现类不能从接口定义中继承行为。当类实现特殊接口时,它定义(即将程序体给予)所有这种接口的方法。然后,它可以在实现了该接口的类的任何对象上调用接口的方法。由于有抽象类,它允许使用接口名作为引用变量的类型。通常的动态联编将生效。引用可以转换到接口类型或从接口类型转换,instanceof 运算符可以用来决定某对象的类是否实现了接口。

  第二十一,abstract的method是否可同时是static,是否可同时是native,是否可同时是synchronized  

  都不能

  第二十二,接口是否可继承接口 抽象类是否可实现(implements)接口 抽象类是否可继承实体类(concrete class)

  接口可以继承接口。抽象类可以实现(implements)接口,抽象类是否可继承实体类,但前提是实体类必须有明确的构造函数。

  第二十三,启动一个线程是用run()还是start()

  启动一个线程是调用start()方法,使线程所代表的虚拟处理机处于可运行状态,这意味着它可以由JVM调度并执行。这并不意味着线程就会立即运行。run()方法可以产生必须退出的标志来停止一个线程。

  第二十四,构造器Constructor是否可被override  

  构造器Constructor不能被继承,因此不能重写Overriding,但可以被重载Overloading。

  第二十五,是否可以继承String类  

  String类是final类故不可以继承。

  第二十六,当一个线程进入一个对象的一个synchronized方法后,其它线程是否可进入此对象的其它方法  

  不能,一个对象的一个synchronized方法只能由一个线程访问。

  第二十七,try {}里有一个return语句,那么紧跟在这个try后的finally {}里的code会不会被执行,什么时候被执行,在return前还是后  

  会执行,在return前执行。

  第二十八,编程题 用最有效率的方法算出2乘以8等於几   
  有C背景的程序员特别喜欢问这种问题。

  2 3

  第二十九,两个对象值相同(x.equals(y) == true),但却可有不同的hash code,这句话对不对   

  不对,有相同的hash code。

  第三十,当一个对象被当作参数传递到一个方法后,此方法可改变这个对象的属性,并可返回变化后的结果,那么这里到底是值传递还是引用传递

  是值传递。Java 编程语言只由值传递参数。当一个对象实例作为一个参数被传递到方法中时,参数的值就是对该对象的引用。对象的内容可以在被调用的方法中改变,但对象的引用是永远不会改变的。


  第三十一,swtich是否能作用在byte上,是否能作用在long上,是否能作用在String上   

  switch(expr1)中,expr1是一个整数表达式。因此传递给 switch 和 case 语句的参数应该是 int、 short、 char 或者 byte。long,string 都不能作用于swtich。

  第三十二,编程题 写一个Singleton出来。   

  Singleton模式主要作用是保证在Java应用程序中,一个类Class只有一个实例存在。

  一般Singleton模式通常有几种种形式

  第一种形式 定义一个类,它的构造函数为private的,它有一个static的private的该类变量,在类初始化时实例话,通过一个public的getInstance方法获取对它的引用,继而调用其中的方法。

public class Singleton {
   private Singleton(){}
   在自己内部定义自己一个实例,是不是很奇怪?
   注意这是private 只供内部调用
   private static Singleton instance = new Singleton();
   这里提供了一个供外部访问本class的静态方法,可以直接访问  
   public static Singleton getInstance() {
     return instance;   
   }
}

  第二种形式

public class Singleton {
   private static Singleton instance = null;
   public static synchronized Singleton getInstance() {
   这个方法比上面有所改进,不用每次都进行生成对象,只是第一次     
   使用时生成实例,提高了效率!
   if (instance==null)
     instance=new Singleton();
return instance;   }
}

  其他形式

  定义一个类,它的构造函数为private的,所有方法为static的。

  一般认为第一种形式要更加安全些

  第三十三 Hashtable和HashMap

  Hashtable继承自Dictionary类,而HashMap是Java1.2引进的Map interface的一个实现

  HashMap允许将null作为一个entry的key或者value,而Hashtable不允许

  还有就是,HashMap把Hashtable的contains方法去掉了,改成containsvalue和containsKey。因为contains方法容易让人引起误解。

  最大的不同是,Hashtable的方法是Synchronize的,而HashMap不是,在多个线程访问Hashtable时,不需要自己为它的方法实现同步,而HashMap就必须为之提供外同步。

  Hashtable和HashMap采用的hashrehash算法都大概一样,所以性能不会有很大的差异。


华为面试题:怎么判断链表中是否有环?????

silver6 | 28 十一月, 2005 08:47

定义两个指针,一前一后,同时移动,前面的移动比后面的慢,如果是循环的则后面的肯定会追上前面的

bool CircleInList(Link* pHead)
{
if(pHead == NULL || pHead->next == NULL)//无节点或只有一个节点并且无自环
{
return (false);
}
if(pHead->next == pHead)//自环
{
return (true);
}
Link *pTemp1 = pHead;//step 1
Link *pTemp = pHead->next;//step 2
while(pTemp != pTemp1 && pTemp != NULL && pTemp->next != NULL)
{
pTemp1 = pTemp1->next;
pTemp = pTemp->next->next;
}
if(pTemp == pTemp1)
{
return (true);
}
return (false);
}

 查看全文

一道笔试题不理解

silver6 | 25 十一月, 2005 23:36


main()
{
int a[5]={1,2,3,4,5};
int *ptr=(int *)(&a+1);

printf("%d,%d",*(a+1),*(ptr-1));
}

int *ptr=(int *)(&a+1); //指向整个数组末尾
int *ptr=(int *)(a+1); //指向a的下一个元素

main()
{
int a[5]={1,2,3,4,5};
int *ptr=(int *)(&a+1);

printf("%d,%d",*(a+1),*(ptr-1));
}

cout<<*(a+1)<<endl; output:2 没有什么费话~
cout<<*(ptr-1)<<endl; output :5
因为 int *ptr=(int *)(&a+1);
这里是(&a +1) 而非 a+1

&a的类型是数组,所以加1的话,系统会认为加一个a数组的偏移,即5个int

&a+1就是首地址+1
主要是(int*)做了操作,具体什么操作也不是很了解。等高手回答。
如果
&a0x0012ff6c ""

&a+10x0012ff6d ""
这里
int *ptr=(int *)(&a+1);
ptr的地址和(&a +1)的地址并不相同
等待高手回答(int *)做了什么操作

&a[0] 才是首地址。

&a是指向首地址的指针。

事实证明:
*(a+1)就是a[1],*(ptr-1)就是a[4]
执行结果是2,5
&a+1不是首地址+1,系统会认为加一个a数组的偏移,是偏移了一个数组的大小(本例是5个int)

,&a可以认为是整个数组的地址,因此不能单纯的用首地址+1。

1.int * 是强制转换为int型指针。
2.对于int a[5]={1,2,3,4,5};a就是数组首地址。a+1是首地址+1. a 等价于&a[0].
3. &a不是首地址,可以看作是整个数组的指针。&a+1是 a[5]后面的地址.
&a+1≠a+1

废话少说;接:2,5

int a[5]={1,2,3,4,5};

//
// &a 指向是 a[5]的类型, &a + 1指向下一个a[5]类型,等同于指向第6(索引为5)个int
// int *ptr = (int*)(&a + 1) 强制转换指针为int*
int *ptr=(int *)(&a+1);

printf("%d,%d",*(a+1),*(ptr-1)); //ptr - 1 指向上一个int,即索引号为4的整数

int *ptr=(int *)(&a+1);
则ptr实际是&(a[5]),也就是a+5
原因如下:
&a是数组指针,其类型为 int (*)[5];
而指针加1要根据指针类型加上一定的值,
不同类型的指针+1之后增加的大小不同
a是长度为5的int数组指针,所以要加 5*sizeof(int)
所以ptr实际是a[5]
但是prt与(&a+1)类型是不一样的(这点很重要)
所以prt-1只会减去sizeof(int*)

int *ptr=(int *)(&a);
0040105B lea eax,[ebp-14h] ;a[0]的地址
0040105E mov dword ptr [ebp-18h],eax

int *ptr=(int *)(&a+1);
0040105B lea eax,[ebp] ;这里比上边增加了14h,即20个字节
0040105E mov dword ptr [ebp-18h],eax

&a是数组指针,其类型为 int (*)[5];
同意,谭浩强的c语言编程里讲的很清楚!


面试题!!!

silver6 | 25 十一月, 2005 23:34

1.全局变量和局部变量有什么区别?实怎么实现的?操作系统和编译器是怎么知道的?
2.请问交换机和路由器分别的实现原理是什么?分别在哪个层次上面实现的?
3.请你详细的解释一下IP协议的定义,在哪个层上面,主要有什么作用? TCP与UDP呢?
4.以下代码有什么问题?
struct Test
{
Test( int ) {}
Test() {}
void fun() {}
};
void main( void )
{
Test a(1);
a.fun();
Test b();
b.fun();
}
5.写一个函数,将其中的t都转换成4个空格。

都是华为的老题

1、全局变量是整个程序都可访问的变量,谁都可以访问,生存期在整个程序从运行到结束(在程序结束时所占内存释放),而局部变量存在于模块(子程序,函数)中,只有所在模块可以访问,其他模块不可直接访问,模块结束(函数调用完毕),局部变量消失,所占据的内存释放。
全局变量分配在全局数据段并且在程序开始运行的时候被加载. 局部变量则分配在堆栈里面。

2、交换机用在局域网中,交换机通过纪录局域网内各节点机器的MAC地质(物理地址)就可以实现传递报文,无需看报文中的IP地质。路由器识别不同网络的方法是通过识别不同网络的网络ID号(IP地址的高端部分)进行的,所以为了保证路由成功,每个网络都必须有一个唯一的网络编号。路由器通过察看报文中IP地址,来决定路径,向那个子网(下一跳)路由,也就是说交换机工作在数据链路层看MAC地址,路由器工作在网际层看IP地质
但是由于现在网络设备的发展,很多设备既有交换机的功能有由路由器的功能(交换试路由器)使得两者界限越来越模糊。
3、IP协议是网络层的协议,它实现了Internet中自动路由的功能,即寻径的功能,TCP协议是一个传输性的协议它向下屏蔽了IP协议不可靠传输的特性,向上提供一个可靠的点到点的传输,UDP提供的是一种无连接的服务,主要考虑到很多应用不需要可靠的连接,但需要快速的传输
4、
Test b();//定义了一个函数


一道外企软件公司笔试题

silver6 | 23 十一月, 2005 16:58

Given the following,
1.class X2{
2. public X2 x;
3. public static void main(String[] args){
4. X2 x2=new X2();
5. X2 x3=new X2();
6. x2.x=x3;
7. x3.x=x2;
8. x2=new X2();
9. x3=x2;
10. doComplexStuff();
11.}
12.}
after line 9 runs,how many objects are eligible for garbage collection?
A.0 B.1 C.2 D.3 E.4

8. x2=new X2();
9. x3=x2;
这时只有第8行的这个new X2对象被引用,所以不被回收,其余的第4,5 行的对象new X2()没有被引用所以被垃圾回收,所以我认为是2个。

我觉得是2。

到第9行时,
4. X2 x2=new X2();
5. X2 x3=new X2();
可以回收,而9. x3=x2;则是
x3、x2共同指向8.x2=new X2();创建的对象。

所以是2。

应该是2.
为什么楼上的感觉是 3 个呢?我感觉不出来3 个。
创建了3个对象,2个成为了垃圾。8、9行的代码说明有两个引用指向对象3#。

public class GcTest {
public GcTest g;
public static void main(String[] args) {
GcTest x2 = new GcTest();
GcTest x3 = new GcTest();
x2.g = x3;
x3.g = x2;
x2 = new GcTest();
x3=x2;
System.gc();
}
@Override
protected void finalize() throws Throwable {
System.out.println("clear");
}

}

测试了一下,输出2次clear

To gemouzhi:没感觉、感觉不出来?不要这样说。
既然有2个人说3,就想听听为什么。

测试的代码,上面 simbas00给了。

To sussman:我的详细的解释。
这个题糊弄人的地方,在
2. public X2 x;
因此,要清楚引用变量(或者叫句柄)和对象是不同的两个东西。句柄将持有对象的ref,它不是对象。有几个句柄?4个,x2、x3、x2.x和x3.x,程序中有几个对象?数new出现的次数(Class的那个方法这里不考虑)。3个。

垃圾对象是引用全部失效的对象,
6. x2.x=x3;
7. x3.x=x2;
说明,对象1#和2#的引用曾经被x3.x和x2.x持有,当

8. x2=new X2();
9. x3=x2;
8后,x2.x为null,9之后,x3.x为null。因此
对象1#和2#成为垃圾。
而对象3#有句柄x2和x3持有。

x2其成员变量x的内存分配,一定在heap中。

恩,我到希望是这样,因为这样更好叫我理解,但对象的成员变量分配在heap上,你有根据吗?

有的话,给你加100分。

x2指向的对象是新对象,但是这个时候并没有进行gc,所以x2原来指向的堆上的对象还是存活的

而且我按simbas00给的代码打出x2.x都是@9664a1。这些都是小问题。

对象的成员变量分配在heap上,我还真没弄明白,你先找些根据。

这个GcTest 也是对象吧GcTest x2是她的成员吧,你的意思是x2也分配在heap上?

public class GcTest {
public GcTest g;
public static void main(String[] args) {
GcTest x2 = new GcTest();
GcTest x3 = new GcTest();
x2.g = x3;
x3.g = x2;

的代码可能有问题。
public class A {
public A g;
public static void main(String[] args) {
A x2 = new A();
System.out.println(x2.g);

A x3 = new A();
x2.g = x3;System.out.println(x2.g);
x3.g = x2;
x2 = new A();System.out.println(x2.g);
x3=x2;
System.gc();
}
@Override
protected void finalize() throws Throwable {
System.out.println("clear");
}

}

null
A@11b86e7
null
clear
clear

1.class X2{
2. public X2 x;//这个是X2的成员变量,内存组织描述在field_info里,
3. public static void main(String[] args){//主方法
4. X2 x2=new X2();//x2是X2的局部变量,分配在栈上,只是一个ref,他指向一个在heap上分配的内存new X2();,这个好象是16K,这个new X2();中的x的成员变量是和这个对象的生命周期是一样的.因为我还再查关于成员变量堆内存的组织形式.
5. X2 x3=new X2();//x3同x2
6. x2.x=x3;//这里用x2的x成员变量指向了x3也同时指向的 在heap上分配的new X2();
7. x3.x=x2;//这里用x3的x成员变量指向了x2也同时指向的 在heap上分配的new X2();
8. x2=new X2();//这里x2在栈中新指向了另一个new X2();而原来的她所指向的那个对象只有x3的x作为她的ref,到这里我认为还没有任何的垃圾.
9. x3=x2;//这步才是产生垃圾最重要的那部分,因为x3指向了新的对象,也就是说没有任何栈上的指针指向最初分配的那两个对象了.就相当于两个内存的heap上的内存块互相指着.
而这种没有栈指针依赖的对象是无法存活的.
例如你直接写这样的代码:new X2();就会利马变成垃圾.
所以在这一步同时出现了两个垃圾对象,也就是最初的两个new X2();
10.
11.}
12.}
结论: 答案是两个

我希望你能楼主和大家,当然还有yqj2065(严千钧)看一下,第8行,因为我认为这里并不产生垃圾

这是我对这个帖子的半完整解释.

遗留的问题:成员变量在heap上的组织形式.

谢谢各位观看.

这道题似乎没有那么复杂,支持选 C 回收了 2 个,试解释如下:

Given the following,
1.class X2{
2. public X2 x;
3. public static void main(String[] args){
4. X2 x2=new X2();
5. X2 x3=new X2();
6. x2.x=x3;
7. x3.x=x2;
8. x2=new X2();
9. x3=x2;
10. doComplexStuff();
11.}
12.}
after line 9 runs,how many objects are eligible for garbage collection?
A.0 B.1 C.2 D.3 E.4

--
运行到line 5时,共创建了 2 个实例,并且交叉赋值给 x2, x2.x, x3, x3.x
这没有什么特别的,概括地讲也就是说:
x2,x3分别持有一个实例,同时根据成员变量x可以访问另外一个。

--
运行到line 8时,情况发生了变化,x2指向一个新的实例(x2.x自然而然也就null了)
此时
x2持有第 3 个实例,但 x2.x = null (并不指向任何实例)
由于 x3 及 x3.x 仍然持有前面创建的 2 个实例,所以目前还没有对象被释放。

--
运行到line 9时,x3也指向新的实例(和x2引用同一个实例)
此时
x3原来持有的实例被释放
能够通过 x3.x 访问的实例也被释放

--
用符号ABC表示实例就是从

x2 -> A
x2.x -> B
x3 -> B
x3.x -> A

最终演变为

x2 -> C
x2.x is null
x3 -> C
x3.x is null

至此 A 和 B 将被 gc

答案是2个,没问题。但是使用finalize的测试是不对的。
上面大家分析的已经很不错了,我只是想说说上面的finalize的测试方法为什么是错误的?!

我们知道gc是个不确定的行为,我们无法控制,JVM回收垃圾一直都是不可控的。
我认为这个题目出的比较好,如果这个代码
public class GcTest {
public GcTest g;
public static void main(String[] args) {
GcTest x2 = new GcTest();
GcTest x3 = new GcTest();
x2.g = x3;
x3.g = x2;
x2 = new GcTest();
x3=x2;
System.gc();
}
@Override
protected void finalize() throws Throwable {
System.out.println("clear");
}

}
输出多少次clear我觉得都是没有问题的,(当然不会超过3次,因为一共就创建了3个对象)。这个代码和题目是不一样的。
题目中line9之后还有line10,这个是非常重要的,也就是说line9之后这个方法的作用域还没有结束,这时候符合垃圾回收的对象应该是
1。null
2。没有被引用的对象
而line10之后,就会有“结束作用域的局部对象”也符合垃圾回收的条件。
上面的finalize的测试就是犯了这个错误,实际上你这里按照题目的问题应该是3个对象,因为按照上面3条原则,创建的3个对象都是局部的,所以结束了函数作用域一定都符合垃圾回收的条件。之所有只输出了2次clear是因为gc是不确定的,这里gc了2个对象而已,但是符合垃圾回收的对象是3个!


几个笔试题

silver6 | 23 十一月, 2005 16:55

1 比较下面三种软件出错方式处理的优缺点!
1)发现错误时,抛出异常。
2)用函数的返回值判断程序是否正常。
3)在函数的参数中设置一个引用类型的参数(指针),用这个参数的返回值判断程序是正确还是错误。

2 说说你对OOA(面向对象分析),OOD(面向对象设计),OOP(面向对象编程)的理解。

3 你认为掌握哪些知识或能力,可认为精通或熟悉J2EE下的应用开发!

小弟是第一次应聘,遇到这样的题,乱写一气!呵呵!!

请大家谈谈自己的想法,谢谢了!!

 查看全文

JavaBean与Java的区别

silver6 | 15 十一月, 2005 17:40

对于初学JSP又没学过Java,之后又觉得不学Java,Jsp实在做不好,遂又开始学Java,Java学了不多久忽然又觉得JavaBean对Jsp比较重要,开始试着编写JavaBean的我来说。如果不把Java与JavaBean分清楚的话还不如去当老干妈或者阿香婆,反正是做酱的。 我是什么时候开始意识到Java与JavaBean有区别的呢?当然看书是看不来的,本人对书都是一目十行的。在这就不具体写我所遇到的混乱了,那只会让已经混乱的人更混乱,不混乱的人笑疯掉。不过还是要感谢QQJava牛棚群的饼干,真是一句话点醒梦中人那,他说:“那是JSP的语法”(原话忘记了见谅),但是之后他又说了一句名言,他说:“他们本来就不是一个东西”。导致我开始想他们之间的区别。 进入正题: 1.明确JavaBean是Java的一个类。既然是类那么我们就直接去用它的接口就行了,其他的对于初学者无需考虑(其实是本人水平有限)。 2.三个规则。 |——无参构建子,本人认为就是初始化Bean要得到的参数即类的变量。 |——Sreializable Interface,基本上不用管了。 |——拥有Property Interface,这才是以下要着重说的。 JavaBean中有了两类著名的方法: Set方法——方法名以set开头,用于接收从页面传到Bean的值。 public String setName(String name) { this.name=name } Get方法——方法名以get开头,用于从Bean传值到页面。 public String getName() { return (name); } 如果我们要在页面调用JavaBean有两种形式 1. 用JSP的动作下配合使用。 当 property="*" 说明由表单直接提交多个值到Bean里,据我目前的水平,认为这是唯一会用到setProperty的地方。 这句话具体调用的是上面出现过的getName方法,要注意这个Property="name",在这个标签里写所以省略了get而且首字母变为小写。 据QQJava牛棚群的高人饼干说,命名Bean的方法时get或set方法后面的第一个字母要大写,调用时省略get或set,并且首字母也小写。(目前本人认为这种说法仅限于Jsp的这两个标签里)。 2.直接调用 在声明过useBean动作后 a.setXXX("...");//调用set方法传值给Bean a.getXXX("...");//调用get方法得到return的值 注意:此时函数名要写全 下面将举个本人自己写的JavaBean作具体解说,本人问过高人了,据说是没有概念错误,但是没有调试过望大家海涵。 /* import db.Conndb; import java.sql.*; public class bulildtable { private String type=null; private String name=null; //无参建构子(本人自认为) public void setName(String name) //得到值 { this.name=name; } public void setType(String type) { this.type=type; } public String [] Type(String type) //实现Bean功能的方法1 { Conndb conn=new Conndb(); String sql="select * form devtype where type='"+type+"'"; ResultSet=conn.executeQuery(sql); if(rs.next()) { String [] tt=new String[16]; for(int i=0;i<16;i++) { tt[i]=rs.getString("no"+(i+1)); } } return(tt); } public int typecount(String [] type) //实现Bean功能的方法2 { int j=0; for(int i=0;i<16;i++) { if(!tt[i].equals()&&(tt[i]!=null)) { j++; } } return (j); } public String [] CreatArray() //实现Bean功能的方法3 { int j=typecount(Type(type)); String [] type=Type(type); String [] tt=new String [j]; for(int i=0;i-1){ sql.append(list.get(n)).append(" varchar(20)"); } sql.append(")"); return(sql.toString()); } //该段由Java程序员讨论群的Jonson提供。 */ 除去以上讲的还要加上一些注意 1.JavaBean应该是没有main方法。 似乎是因为 public static void main(String[] args) { getnameBean getnamebean = new getnameBean(); }//不太清楚因为高人没给咱讲明白。 剩下的部分就一样了。 恕本人水平有限,我认为已经把Java与JavaBean的区别说得比较清楚了,另外还有哪些不足,希望看过此文的诸位可以知无不言,言无不尽,觉得在下写得实在是误人子弟的请大声的骂出来,如果不能回帖或者觉得只回帖骂在下不过瘾的,可以给我发垃圾邮件。 参考书籍:JSP工程应用与项目实践,塞奎春,机械工业出版社 请教高人:Java牛棚 富丽饼干,魔之卡卡,双面人.... Java程序员讨论 Jonson,雨婷.... 最后要说的,本文采用古龙后期作品的自然段分段方式,祝大家阅读愉快。

网易面试,问atoi实现的效率改进问题

silver6 | 10 十一月, 2005 08:58

今天去一面,面试官云风要我把笔试时做的atoi实现改进一下,我想了半天,终于想出一点,即确定某字符所在的万、千、百、十位后,本来是循环乘10,我说可以做一个数组里面就放上10000,1000,100,10,1,找到位数后直接索引再乘那个字符,这样多次乘法就减为一次了。可是云风说还可以改进,然后提示除了在数组里放上10000,1000,100,10,1之外还可以放别的数,甚至多位一起乘,当时真是紧张,完全没明白!
哪位高手指点一下?要是还有二面,我就好答了。我先去debug一下tc库里atoi的实现吧,等看懂了再来帖~

这是我刚开始学C++的时候,不知道C++里有可以把字符串转换成数字的函数是什么时,自己写的一个函数:
int strtoint(string s)
{
if (s[0] != '-')
{
s = "+" + s;
}
int n = 0;
for(int i = 1, l = s.size();i < l;i++)
{
if ((s[i] > 57)||(s[i] < 48))
{
cerr << "Please enter integrity!" << 'n';
system("pause");
exit(1);
}
n = n * 10 + (s[i] - 48);
}
if (s[0] == '-')
n = -1 * n;
return n;
}

最简单的是调试跟进去,前提是你已经安装了CRT的源代码,我VC7看到的代码是这样的:
long __cdecl _tstol(
const _TCHAR *nptr
)
{
int c; /* current char */
long total; /* current total */
int sign; /* if '-', then negative, otherwise positive */
#if defined (_MT) && !defined (_UNICODE)
pthreadlocinfo ptloci = _getptd()->ptlocinfo;

if ( ptloci != __ptlocinfo )
ptloci = __updatetlocinfo();

/* skip whitespace */
while ( __isspace_mt(ptloci, (int)(_TUCHAR)*nptr) )
#else /* defined (_MT) && !defined (_UNICODE) */
while ( _istspace((int)(_TUCHAR)*nptr) )
#endif /* defined (_MT) && !defined (_UNICODE) */
++nptr;

c = (int)(_TUCHAR)*nptr++;
sign = c; /* save sign indication */
if (c == _T('-') || c == _T('+'))
c = (int)(_TUCHAR)*nptr++; /* skip sign */

total = 0;

while ( (c = _tchartodigit(c)) != -1 ) {
total = 10 * total + c; /* accumulate digit */
c = (_TUCHAR)*nptr++; /* get next char */
}

if (sign == '-')
return -total;
else
return total; /* return result, negated if necessary */
}

#define _tchartodigit(c) ((c) >= '0' && (c) <= '9' ? (c) - '0' : -1)

int StrToInt(char* str)
{
int total=0;
while(*str != 0)
{
total = total * 10 + (int)(*str - '0');
}
return total;
}

long __cdecl atol(
const char *nptr
)
{
int c; /* current char */
long total; /* current total */
int sign; /* if '-', then negative, otherwise positive */

/* skip whitespace */
while ( isspace((int)(unsigned char)*nptr) )
++nptr;

c = (int)(unsigned char)*nptr++;
sign = c; /* save sign indication */
if (c == '-' || c == '+')
c = (int)(unsigned char)*nptr++; /* skip sign */

total = 0;

while (isdigit(c)) {
total = 10 * total + (c - '0'); /* accumulate digit */
c = (int)(unsigned char)*nptr++; /* get next char */
}

if (sign == '-')
return -total;
else
return total; /* return result, negated if necessary */
}

vc6下的源码。 atoi 也是调用 atol


几道笔试题目

silver6 | 10 十一月, 2005 08:55

1.设计函数 int atoi(char *s)
2. What do the following declarations mean?
  (1)const int a;
  (2)int const a;
  (3)const int *a;
  (4)int * const a;
  (5)int const * a const;
3.编程
  将整数转换成字符串:void itoa(int,char);
  例如itoa(-123,s[])则s=“-123”;
4.10个人分成4组 有几种分法?(程序)(不能重复,如:1,1,1,7=7,1,1,1)
5.如图:
     7 8 9 10
     6 1 2 11
     5 4 3 12
    16 15 14 13
    设“1”的坐标为(0,0) “7”的坐标为(-1,-1) 编写一个小程序,使程序做到输入坐标(X,Y)之后显示出相应的数字。
6.编最优化Bubble(int *pIntArray,int L),要求:交换元素不能用临时变量,如果有序需要最优。

6.
void bubble(int* pSrc,int length)
{
int i,j;
for(i=n;i>2;i--)
{
for(j=1;j<i-1;j++)
{
if(pSrc[j]>pSrc[j+1])
{
pSrc[j]=pSrc[j]^pSrc[j+1];
pSrc[j+1]=pSrc[j+1]^pSrc[j];
pSrc[j]=pSrc[j]^pSrc[j+1];
}
}
}
}

1.

int atoi(char *s)
{
int result = 0;
int i, j, m, temp;
char c;

j = 0;
while(s[j]!='')
{
j++;
}

for(i=j-1;i>=0;i--)
{
c = s[i];
temp = c - '0';
for(m=0;m<j-i-1;m++)
{
temp = temp*10;
}
result = result + temp;
printf("c=%d, temp=%d, result=%dn", c, temp, result);
}

return result;
}


2,(1)const int a;表示常量
  (2)int const a;表示常量
  (3)const int *a;指针a指向的数据不允许改变
  (4)int * const a;指针a的地址不变
  (5)int const * a const;地址,数据都不允许改变


6.最优

void bubble(int *a,int n)
{
int i,j,change;
for(i=1,change=1; i<n && change; ++i)
{
change = 0;
for (j=0; j<n-i; ++j)
if (a[j] > a[j+1])
{
a[j]=a[j]^a[j+1];
a[j+1]=a[j+1]^a[j];
a[j]=a[j]^a[j+1];
}
}
}

void bubble(int *a,int n)
{
int i,j,change;
for(i=1,change=1; i<n && change; ++i)
{
change = 0;
for (j=0; j<n-i; ++j)
if (a[j] > a[j+1])
{
a[j]=a[j]^a[j+1];
a[j+1]=a[j+1]^a[j];
a[j]=a[j]^a[j+1];
change=true;
}
}
}

5.如图:
     7 8 9 10
     6 1 2 11
     5 4 3 12
    16 15 14 13
    设“1”的坐标为(0,0) “7”的坐标为(-1,-1) 编写一个小程序,使程序做到输入坐标(X,Y)之后显示出相应的数字。
#include <iostream.h>
int x1=0,y1=0,x2=0,y2=0;
int main(){
int i,j,n,num=1;
cout<<"Please input x-coordinate: ";
cin>>x1;
cout<<"Please input y-coordinate: ";
cin>>y1;
for(i = 2;i < 6;i++)
for(n = 0;n < 2;n++)
for(j = 1;j < i;j++){
if(i % 2){
if(n == 0){
if((x1 == x2)&&(y1 == y2))
break;
y2--;
num++;
}
else{
if((x1 == x2)&&(y1 == y2))
break;
x2--;
num++;
}
}
else{
if(n == 0){
if((x1 == x2)&&(y1 == y2))
break;
y2++;
num++;
}
else{
if((x1 == x2)&&(y1 == y2))
break;
x2++;
num++;
}
}
}
cout<<"x-coordinate: "<<x1<<" y-coordinate: "<<y1<<endl;
cout<<"The number is: "<<num<<endl;
return 0;
}

第五题:先找到所有平方数的位置,是有规律的:
奇数平方数1,9,25……在从1开始想右上直线延伸,4,16,36……从4开始向左下直线延伸,这样可以快速确定平方数位置。输入n,求得n两边的平方数,例如输入27,则确定25和36位置,中间从26到36的5+6=11个数位置就是联系排列,只有一个拐弯,在26+5=31处,接下来不就ok了?


C#面试题

silver6 | 10 十一月, 2005 08:53

一、选择填空题(每空2分,共60分)
1.在对SQL Server 数据库操作时应选用()。
a)SQL Server .NET Framework 数据提供程序;
b)OLE DB .NET Framework 数据提供程序;
c)ODBC .NET Framework 数据提供程序;
d)Oracle .NET Framework数据提供程序;
2.下列选项中,()是引用类型。
a)enum类型
b)struct类型
c)string类型
d)int类型
3.关于ASP.NET中的代码隐藏文件的描述正确的是()
a)Web窗体页的程序的逻辑由代码组成,这些代码的创建用于与窗体交互。编程逻辑唯一与用户界面不同的文件中。该文件称作为“代码隐藏”文件,如果用C#创建,该文件将具有“.ascx.cs”扩展名。
b)项目中所有Web窗体页的代码隐藏文件都被编译成.EXE文件。
c)项目中所有的Web窗体页的代码隐藏文件都被编译成项目动态链接库(.dll)文件。
d)以上都不正确。
4.以下描述错误的是()
a)在C++中支持抽象类而在C#中不支持抽象类。
b)C++中可在头文件中声明类的成员而在CPP文件中定义类的成员,在C#中没有头文件并且在同一处声明和定义类的成员。
c)在C#中可使用 new 修饰符显式隐藏从基类继承的成员。
d)在C#中要在派生类中重新定义基类的虚函数必须在前面加Override。
5.C#的数据类型有()
a)值类型和调用类型;
b)值类型和引用类型;
c)引用类型和关系类型;
d)关系类型和调用类型;
6.下列描述错误的是()
a)类不可以多重继承而接口可以;
b)抽象类自身可以定义成员而接口不可以;
c)抽象类和接口都不能被实例化;
d)一个类可以有多个基类和多个基接口;
7.在DOM中,装载一个XML文档的方法()
a)save方法
b)load方法
c)loadXML方法
d)send方法
8.下列关于构造函数的描述正确的是()
a)构造函数可以声明返回类型。
b)构造函数不可以用private修饰
c)构造函数必须与类名相同
d)构造函数不能带参数
9.以下是一些C#中的枚举型的定义,其中错误的用法有()
a)public enum var1{ Mike = 100, Nike = 102, Jike }
b)public enum var1{ Mike = 100, Nike, Jike }
c)public enum var1{ Mike=-1 , Nike, Jike }
d)public enum var1{ Mike , Nike , Jike }
10.int[][] myArray3=new int[3][]{new int[3]{5,6,2},new int[5]{6,9,7,8,3},new int[2]{3,2}}; myArray3[2][2]的值是()。
a)9
b)2
c)6
d)越界
11.接口是一种引用类型,在接口中可以声明(),但不可以声明公有的域或私有的成员变量。
a)方法、属性、索引器和事件;
b)方法、属性信息、属性;
c)索引器和字段;
d)事件和字段;
12.ASP.NET框架中,服务器控件是为配合Web表单工作而专门设计的。服务器控件有两种类型,它们是( )
a)HTML控件和Web控件
b)HTML控件和XML控件
c)XML控件和Web控件
d)HTML控件和IIS控件
13.ASP.NET中,在Web窗体页上注册一个用户控件,指定该控件的名称为”Mike”,正确的注册指令为( )
a)<%@Register TagPrefix = “Mike” TagName = “Space2” Src = “myX.ascx”%>
b)<%@Register TagPrefix = “Space2” TagName = “Mike” Src = “myX.ascx”%>
c)<%@Register TagPrefix = “SpaceX” TagName = “Space2” Src = “Mike”%>
d)以上皆非
14.在ADO.NET中,对于Command对象的ExecuteNonQuery()方法和ExecuteReader()方法,下面叙述错误的是()。
a)insert、update、delete等操作的Sql语句主要用ExecuteNonQuery()方法来执行;
b)ExecuteNonQuery()方法返回执行Sql语句所影响的行数。
c)Select操作的Sql语句只能由ExecuteReader()方法来执行;
d)ExecuteReader()方法返回一个DataReder对象;
15.下列ASP.NET语句(b)正确地创建了一个与SQL Server 2000数据库的连接。
a)SqlConnection con1 = new Connection(“Data Source = localhost; Integrated Security = SSPI; Initial Catalog = myDB”);
b)SqlConnection con1 = new SqlConnection(“Data Source = localhost; Integrated Security = SSPI; Initial Catalog = myDB”);
c)SqlConnection con1 = new SqlConnection(Data Source = localhost; Integrated Security = SSPI; Initial Catalog = myDB);
d)SqlConnection con1 = new OleDbConnection(“Data Source = localhost; Integrated Security = SSPI; Initial Catalog = myDB”);
16.Winform中,关于ToolBar控件的属性和事件的描述不正确的是()。
a)Buttons属性表示ToolBar控件的所有工具栏按钮
b)ButtonSize属性表示ToolBar控件上的工具栏按钮的大小,如高度和宽度
c)DropDownArrows属性表明工具栏按钮(该按钮有一列值需要以下拉方式显示)旁边是否显示下箭头键
d)ButtonClick事件在用户单击工具栏任何地方时都会触发
17.在ADO.NET中执行一个存储过程时,如果要设置输出参数则必须同时设置参数的方向和( ),必要时还要设置参数尺寸。
a)大小;
b)上限;
c)初始值;
d)类型;
18.如果将窗体的FormBoderStyle设置为None,则( )。
a)窗体没有边框并不能调整大小;
b)窗体没有边框但能调整大小;
c)窗体有边框但不能调整大小;
d)窗体是透明的;
19.如果要将窗体设置为透明的,则( )
a)要将FormBoderStyle属性设置为None;
b)要将Opacity属性设置为小于100%得值;
c)要将locked 属性设置为True;
d)要将 Enabled属性设置为True;
20.下列关于C#中索引器理解正确的是( )
a)索引器的参数必须是两个或两个以上
b)索引器的参数类型必须是整数型
c)索引器没有名字
d)以上皆非
21.下面描述错误的是( )。
a)窗体也是控件;
b)窗体也是类;
c)控件是从窗体继承来的;
d)窗体的父类是控件类;
22.要对注册表进行操作则必须包含( )。
a)System.ComponentModel命名空间;
b)System.Collections命名空间;
c)System.Threading命名空间;
d)Microsoft.Win32命名空间;
23.要创建多文档应用程序,需要将窗体的( )属性设为true。
a)DrawGrid;
b)ShowInTaskbar;
c)Enabled;
d)IsMdiContainer;
24.如果设treeView1=new TreeView(),则treeView1.Nodes.Add("根节点")返回的是一个 ()类型的值。
a)TreeNode;
b)int;
c)string;
d)TreeView;
25.下面关于XML的描述错误的是()。
a)XML提供一种描述结构化数据的方法;
b)XML 是一种简单、与平台无关并被广泛采用的标准;
c)XML文档可承载各种信息;
d)XML只是为了生成结构化文档;

.在对SQL Server 数据库操作时应选用()
a;
2.下列选项中,()是引用类型。
c)string类型//其构造函数为静态构造函数所以看起来像值类型

3.关于ASP.NET中的代码隐藏文件的描述正确的是()
c)项目中所有的Web窗体页的代码隐藏文件都被编译成项目动态链接库(.dll)文件。

4.以下描述错误的是()
a)在C++中支持抽象类而在C#中不支持抽象类。

5.C#的数据类型有()
a)值类型和调用类型;

6.下列描述错误的是()
d)一个类可以有多个基类和多个基接口;

7.在DOM中,装载一个XML文档的方法()

b)load方法

8.下列关于构造函数的描述正确的是()
c)构造函数必须与类名相同

9.以下是一些C#中的枚举型的定义,其中错误的用法有()
a)public enum var1{ Mike = 100, Nike = 102, Jike }
b)public enum var1{ Mike = 100, Nike, Jike }
c)public enum var1{ Mike=-1 , Nike, Jike }
d)public enum var1{ Mike , Nike , Jike }
??忘记了

10.int[][] myArray3=new int[3][]{new int[3]{5,6,2},new int[5]{6,9,7,8,3},new int[2]{3,2}}; myArray3[2][2]的值是()。
d)越界

11.接口是一种引用类型,在接口中可以声明(),但不可以声明公有的域或私有的成员变量。
a)方法、属性、索引器和事件;

12.ASP.NET框架中,服务器控件是为配合Web表单工作而专门设计的。服务器控件有两种类型,它们是( )
a)HTML控件和Web控件


13.ASP.NET中,在Web窗体页上注册一个用户控件,指定该控件的名称为”Mike”,正确的注册指令为( )
a)<%@Register TagPrefix = “Mike” TagName = “Space2” Src = “myX.ascx”%>
b)<%@Register TagPrefix = “Space2” TagName = “Mike” Src = “myX.ascx”%>
c)<%@Register TagPrefix = “SpaceX” TagName = “Space2” Src = “Mike”%>
d)以上皆非
14.在ADO.NET中,对于Command对象的ExecuteNonQuery()方法和ExecuteReader()方法,下面叙述错误的是()。
c)Select操作的Sql语句只能由ExecuteReader()方法来执行;

15.下列ASP.NET语句(b)正确地创建了一个与SQL Server 2000数据库的连接。

b)SqlConnection con1 = new SqlConnection(“Data Source = localhost; Integrated Security = SSPI; Initial Catalog = myDB”);


16.Winform中,关于ToolBar控件的属性和事件的描述不正确的是()。
a)Buttons属性表示ToolBar控件的所有工具栏按钮
b)ButtonSize属性表示ToolBar控件上的工具栏按钮的大小,如高度和宽度
c)DropDownArrows属性表明工具栏按钮(该按钮有一列值需要以下拉方式显示)旁边是否显示下箭头键
d)ButtonClick事件在用户单击工具栏任何地方时都会触发
17.在ADO.NET中执行一个存储过程时,如果要设置输出参数则必须同时设置参数的方向和( ),必要时还要设置参数尺寸。

b)上限;

18.如果将窗体的FormBoderStyle设置为None,则( )。
a)窗体没有边框并不能调整大小;
b)窗体没有边框但能调整大小;
c)窗体有边框但不能调整大小;
d)窗体是透明的;
19.如果要将窗体设置为透明的,则( )

b)要将Opacity属性设置为小于100%得值;

20.下列关于C#中索引器理解正确的是( )

b)索引器的参数类型必须是整数型

21.下面描述错误的是( )。

c)控件是从窗体继承来的;

22.要对注册表进行操作则必须包含( )。
a)System.ComponentModel命名空间;
b)System.Collections命名空间;
c)System.Threading命名空间;
d)Microsoft.Win32命名空间;
23.要创建多文档应用程序,需要将窗体的( )属性设为true。

d)IsMdiContainer;
24.如果设treeView1=new TreeView(),则treeView1.Nodes.Add("根节点")返回的是一个 ()类型的值。
a)TreeNode;
b)int;
c)string;
d)TreeView;
25.下面关于XML的描述错误的是()。

d)XML只是为了生成结构化文档;

刚进来就看见个垃圾问题!

1.在对SQL Server 数据库操作时应选用()。
a)SQL Server .NET Framework 数据提供程序;
b)OLE DB .NET Framework 数据提供程序;
c)ODBC .NET Framework 数据提供程序;
d)Oracle .NET Framework数据提供程序;

这个题是那个BC出的啊?
就算我不知道,难道会因为这个而没办法写程序?!
如果是的话,那么那些教材和参考书是干什么的? 还有我们这个CSDN是干什么的?

真是搞不清楚,出题的人怎么就那么喜欢搞这种死记硬背的东西.

类似的垃圾问题还很多,例如7,9,10.
9和10更是过分,这种问题直接运行不就行了,编译都过不了的问题难道会有哪个程序员会放着不管吗?

这些出题的人真是该反省一下!


一道偏理论的面试题

silver6 | 10 十一月, 2005 08:52

1。请实现一个类型,该类型只能在栈上分配,不能从堆上分配
2。请实现一个类型,该类型只能在堆上分配,不能从栈上分配

第一个问题说明显一点就是这个类不能这样使用:
CMyClass* myClass = new CMyClass();
第二个问题恰好相反只能这样使用

1。重载一个private的operator new
2。将ctor作为private,写一个public的static的CreateObject方法,在其中用new
创建object。


VIA杭州笔试题最后一道

silver6 | 03 十一月, 2005 09:07

请进行优化:

long multiple(int vertical1[], int vertical2[],int value)
{
int i =0;
int sum=0;
for(i=0;i<value;i++){
if(i&0x01)
sum -= (vertical1[i]*vertical2[i])>>16;
else
sum += (vertical1[i]*vertical2[i])>>16;
}
return sum;
}

我的办法是去掉if,拆分成两个小循环

for(i=0;i<value;i+=2)
sum += (vertical1[i]*vertical2[i])>>16;

for(i=1;i<value;i+=2)
sum -= (vertical1[i]*vertical2[i])>>16;

然而(vertical1[i]*vertical2[i])>>16;这句该怎么优化?

int类型为32bit 范围0-ffffffff;
(vertical1[i]*vertical2[i])>>16;
相当于(vertical1[i]*vertical2[i])/65536;

我的优化方式为:

for(int i=0;i<value;){
sum+=(vertical1[i]*vertical2[i])>>16;
++i;
sum-=(vertical1[i]*vertical2[i])>>16;
++i;
}

long multiple(int *vertical1, int *vertical2,int value)
{
int i =0;
int sum=0;
for(int i=0;i<value;){ //借用楼上对if的优化代码
sum+=(++vertical1 * ++vertical2)>>16;
++i;
sum-=(++vertical1 * ++vertical2)>>16;
++i;
}
}
return sum;
}
把vertical[i]改成用指针的形式,每次++操作. 可能会更优化一些,

if((vertical1[i]&0xffffff00)||(vertical2&0xffffff00))
sum+=(vertical1[i]*vertical2[i])>>16;


一外企笔试题

silver6 | 03 十一月, 2005 09:04

You have four colored cubes. Each side of each cube is a single color, and there are four colors: blue (B), red (R), green (G) and yellow (Y) Describing the six faces as front, back, left, right, top, bottom, the cube colors are:

Cube Front Back Left Right Top Bottom
1 R B G Y B Y
2 R G G Y B B
3 Y B R G Y R
4 Y G B R R R

The objective is to find ways to stack the four cubes as a vertical column so that each side of the column is showing all four colors.

In a compiled language of your choice, write a program to find all successful permutations


近期各种面试题总结,

silver6 | 02 十一月, 2005 09:25

1)sizeof相关系列问题
2)const相关系列问题
3)大量林锐书的习题,以及各种变种
这三个几乎是每次必出现
下面的这些是程序相关题,很多都是以前有讨论过的,还请各位大侠能整理个比较适合做面试时答案的解答,多谢了.最好能给出讨论链接,让我等后辈有学习的机会.
1)求出相似度的算法.
2)写出二分查找的代码.
3)写出在母串中查找子串出现次数的代码.
*4)写出快速排序或者某种排序算法代码
出现次数相当频繁
5)写出查找从一个集合中输出所有子集合的算法.
*6)实现strcpy函数
出现次数相当频繁
*7)实现strcmp函数
出现次数相当频繁
8)将一个单链表逆序
9)循环链表的节点对换和删除。
*10)将一个数字字符串转换为数字."1234" -->1234
出现次数相当频繁
11)实现任意长度的整数相加或者相乘功能。
*12)写函数完成内存的拷贝


威盛的一道笔试题

silver6 | 02 十一月, 2005 09:20

#include <stdio.h>
char *returnStr()
{
char p[]="hello world!";
return p;
}
int main()
{
char *str;
str=returnStr();

printf("%sn",str);
}
问上述的输出是什么?
还有就是我把上述函数稍改一下
#include <stdio.h>
char *returnStr()
{
char *p="hello world!";
return p;
}
int main()
{
char *str;
str=returnStr();

printf("%sn",str);
}
这个输出又是什么?各是什么原因呢

char p[]="hello world!";
p指向一个局部的数组地址,分配在栈中。
char *p="hello world!";
p指向一个字面常量。字面常量分配在哪里俺就不知道了。总之不会是局部的。

所以:
第一个指向的是个已被释放的内存,不会输出hello world!,要出错的吧
第二个输出的是: hello world!

1: 一切皆有可能
char[]为局部变量,returnStr结束后可能被覆盖
2: hello world!
"hello world!"是data segment的数据,不会改

第一种情况输出的应该是乱码,第二种情况输出的是hello world!。
前者char p[]这行的p是局部变量,由于是数组类型返回p后,p被销毁,所以就会输出乱码。
后者char *p这行的p虽然也是局部变量,但由于p是指针类型的,所以返回的p在赋予main里的str时会重新申请一块内存来存放数据,最后显示也就正常了。

可以用这段代码比较看一下:
#include <stdio.h>
char r[]="1234567890";
char *s1()
{
char p[]="1234567890";
printf("--------------------n");
printf("in s1 p: %dn",r);
printf("--------------------n");
return r;
}

char *s2()
{
char *q="1234567890";
printf("--------------------n");
printf("in s2 q: %dn",q);
printf("--------------------n");
return q;
}
int main()
{
char *t1,*t2;
t1=s1();
t2=s2();
printf("--------------------n");
printf("in mainn");
printf("p: %d, q: %dn",t1,t2);
printf("--------------------n");

printf("%sn",t1);
printf("%sn",t2);

}

不好意思楼上r的地方没有改回来,应该是下面的:
#include <stdio.h>
char *s1()
{
char p[]="1234567890";
printf("--------------------n");
printf("in s1 p: %dn",p);
printf("--------------------n");
return p;
}

char *s2()
{
char *q="1234567890";
printf("--------------------n");
printf("in s2 q: %dn",q);
printf("--------------------n");
return q;
}
int main()
{
char *t1,*t2;
t1=s1();
t2=s2();
printf("--------------------n");
printf("in mainn");
printf("p: %d, q: %dn",t1,t2);
printf("--------------------n");

printf("%sn",t1);
printf("%sn",t2);

}

这个问题在林锐的高质量C++/C编程指南上有,内容如下:
http://www.cnns.net/ref/cppguide.htm
所以回答是:
1、报错。p是局部变量,保存在栈里,函数结束后p已经销毁,成为wild pointer。
2、hello world!因为p是一个指向字符串常量的指针,字符串常量保存在.data(已定义的全局变量)里,函数返回时那个指针地址还是有效的。
当然,你如果想查看一下,上面的两个程序指针指向不同的地方,你可以打印出指针的地址。
printf("%p",p);还有,你如果想直接打印出字符串常量所存放的地址,你可以用这个
printf("%p","Hello world!");想知道为什么吗?c primer里面有,因为"Hello world!"就可以表示指向这个字符串常量的指针了!

关于char p[] = “Hello world!”的讨论,已经很正确了。
那么现在我们来讨论 char *p = “Hello world!”的问题。
Char * fun()
{
char *p = “Hello world!”
return p;
}
Main ()
{
Char * p = NULL;
P = fun();
Cout<< p;
Cout<<&p;
}
我们发现其可以完全打印出hello world,并且打印其地址,并且不会有任何问题。到底是什么原因哪?
我们在main中在重新定义一个char变量*p1
*p1 = fun();
打印出*p1的值和地址,我们惊奇的发现p1和p的地址相同。不幸的是我们定义*p2=fun(),其打印出的地址和前两次也相同。所以说“返回的p在赋予main里的p时会重新申请一块内存来存放数据,最后显示也就正常了”是不正确的,如果是这样应该其内存是不相同的。但是这好像还是不能完全说明问题,问题是“hello world”数据到底放在哪里了那?
我们知道程序内存主要分三部分:静态存储区,堆,栈,那么到底放在那个上面了那?
我们在定义一个函数
Char * fun2()
{
char *p = “Hello world!”
return p;
}
此时和在main调用fun()一样,分别定义*p,*p1,*p2,分别调用fun2();打印其结果和地址,你会吃惊的发现此时的地址居然和调用fun()函数的地址完全相同,我没有吓唬你。是真的完全一样。至此我们可以明白一点原来fun()和fun2()中的地址完全相同,也就是说他们共同应用的是一块地址,能够在整个程序运行过程中共同占有一块地址的。肯定放在静态存储区上,至此问题明了。
Char *p = “Hello World!”数据放在静态存储区上,为了我们说明问题,我们在多做几个实验。
我们定义全局变量char *p1= “Hello World!”,那么这次我们分别调用不同的指针指向fun(),fun2(),全局*p,在打印其地址。看到地址我们有吃惊,居然地址又是完全相同,到底怎么回事?
原因很简单,我们在定义这些变量的时候,编译器会根据我们定义的值在静态存储区开辟地址,保存内容,简单的把地址返回给不同的地址指针而已。如果你还是不相信,你可以把全局变量*p1的值更改为其他字符串,你会发现*p1的地址和fun(),fun2()的地址是相邻的。我们知道全局变量肯定放在静态存储区,所以现在我们更加肯发定fun,fun2内的char *p= “Hello World!”数据放在静态存储区。
现在完了,没有。
我们在main中定义*p,指向fun();

Char *p = null;//良好的习惯
p= fun();
p[0] = ‘U’;//我的意图很明显就是想变成“Uello World!”
编译通过,高兴。
运行出错,追踪,p[0] = ‘U’;在这句出错,运行错误说明不能更改p[0]的值。哦,至此我们明白了,原来编译器是这样给我们作的
const char temp[] = “Hello World!”;
char *p1 = temp;
为了验证编译器是否这样做我们定义
全局变量
char pp[] = “Hello World!”;
在main中调用char *p = pp;
p[0] = ‘U’;
打印p,终于按我们的要求打印出 Uello World!
再看看p1和pp的地址,发现不相同,但是地址相邻。为什么?
const对象和非const对象内容当然不相同了!
至此我们总结如下:
我们在函数,全局内定义的char *p = “Hello World!”;编译器都会为我们作为全局变量定义。伪代码如下
const char temp[] = “Hello World!”;
char *p1 = temp;
任何调用“Hello World!”只是返回temp的一个const指针。


这几天笔试经常出现的笔试题

silver6 | 02 十一月, 2005 09:19

1.win2k,vc++6下,指出下面定义的含义和所占的字节数:
int a;
int a[];
int *a;
int *a[];
int (*a)[];
int (*a)();
int *a();
int **a;
2. array和list的区别
3. 列举出几种进程调度方法,并说出区别
4.定义的解释,int *p, int (*p)();
5.结实数据类型定义:int(*f[10])(int)

int a; 4
int a[]; 数组未知大小
int *a; 4
int *a[]; 数组未知大小
int (*a)[];4
int (*a)();4
int *a(); 返回int*的函数,未知大小
int **a;4

5.int(*f[10])(int):
f是一个10个元素的数组,每个元素为int(*)(int)类型的函数指针

4.定义的解释,int *p, int (*p)();
答: int *p 定义了一个指针
   int (*p)(); 定义一个指向函数的指针

5.结实数据类型定义:int(*f[10])(int)
答:
  这里定义了一个指向函数的指针数组
比如:
int f1(int);
int f2(int);
.....
f[1] = f1;
f[2] = f2;
f[1](); //调用

这些问题要看书,然后多碰一些实际的问题。

呵呵,因为我没有用 cc++ 做过项目,这些基本的东西容易忘记

int a; // 定义一个整型变量
int a[]; // 定义一个整型数组,在 c 中 数组名其实等同于一个指针常量
int *a; // 定义一个整型指针变量
int *a[]; // 定义一个整型指针数组, 理解为: int* a[];
int (*a)[]; // 定义一个指向整型数组的指针
int (*a)(); // 定义一个指向返回值为整型的函数的指针
int *a(); // 声明一个返回整型指针的函数
int **a; // 定义指向整型指针变量的指针, 等同于 int *a[];

这样的问题一定要在实际问题中多碰碰,然后理解就容易记得牢靠


华为笔试题 关于全局变量

silver6 | 02 十一月, 2005 09:17

A.整个程序中是唯一的。
B.在编译连接的时候它的地址就是确定的。(题目记得不全)

有谁碰过类似的题目?帮忙看一下。

有点困惑就是:如果程序包括多个进程的话,那么各个进程中的全局变量可不可以同名?

全局变量的定义是这样的吧:全局变量也称为外部变量,它是在函数外部定义的变量。 它不属于哪一个函数,它属于一个源程序文件。其作用域是整个源程序。在函数中使用全局变量,一般应作全局变量说明。 只有在函数内经过说明的全局变量才能使用。全局变量的说明符为extern。 但在一个函数之前定义的全局变量,在该函数内使用可不再加以说明

从定义来看应该是唯一的吧!

不知道大家是怎么看的!

A.整个程序中是唯一的。
B.在编译连接的时候它的地址就是确定的。

肯定是A啊,关于地址我想要到执行时才能够确定吧。

B.在编译连接的时候它的地址就是确定的
我认为这是正确的,因为全局变量和static变量都是存放在静态数据区,其在编译时期就确定了.

多进程中,全局变量名称是完全一样的,名称、值都是一样的。
多进程就是一个进程的多份拷贝。

我认为B
对于A, static全局变量是可以有多个的。
不过“全局”有点模糊,是生存期全局还是作用域全局。作用域全局的肯定只有一个。
static的生存期是全局的,但作用域是局部的(文件或者函数)

B,全局变量(无论static与否)其地址都是在连接时候确定的。

进程有自己的内存空间.
线程是共享内存的.
一个全局变量应该只能作用与进程.
进程间通讯没有听说有用全局变量的.但是线程可以用全局变量做锁.


今天遇到的面试题目

silver6 | 01 十一月, 2005 13:41

1.有以下表达式:
int a=248; b=4;int const c=21;const int *d=&a;
int *const e=&b;int const *f const =&a;
请问下列表达式哪些会被编译器禁止?为什么?
*c=32;d=&b;*d=43;e=34;e=&a;f=0x321f;

2.交换两个变量的值,不使用第三个变量。即a=3,b=5,交换之后a=5,b=3;

3.c和c++中的struct有什么不同?

4.#include <stdio.h>
#include <stdlib.h>
void getmemory(char *p)
{
p=(char *) malloc(100);
strcpy(p,"hello world")
}
int main( )
{
char *str=NULL;
getmemory(str);
print("%s/n",str);
free(str);
return 0;
}
程序运行的结果是什么?为什么?

5.char szstr[10];
strcpy(szstr,"0123456789");
产生什么结果?为什么?

6.列举几种进程的同步机制,并比较其优缺点。

7.进程之间数据交换的途径

8.类的静态成员和非静态成员有何区别?

9.纯虚函数如何定义?使用时应注意什么?

10.数组和链表的区别

11.写一个函数比较两个字符串str1和str2的大小,若相等返回0,若str1大于
str2返回1,若str1小于str2返回-1

12.ISO的七层模型是什么?tcp/udp是属于哪一层?tcp/udp有何优缺点?

2, 3, 4都是老题
2题 有两种解法, 一种用算术算法, 一种用^(异或)
3题 主要区别是默认的存取权限不同
4题 由于函数参数是传值的, 所以返回主函数后str还是NULL
5题 由于定义的字符串长度小于拷贝的字符串长度, 会造成非法操作

11题主要是字典序比较
12题只要学过网络的都应该会做

第2题:
a = a + b;
b = a - b;
a = a - b;
or
a = a^b;// 只能对int,char..
b = a^b;
a = a^b;

1.有以下表达式:
int a=248; b=4;int const c=21;const int *d=&a;
int *const e=&b;int
请问下列表达式哪些会被编译器禁止?为什么?
*c=32;d=&b;*d=43;e=34;e=&a;f=0x321f;
----------
*c 这是个什么东东,禁止
*d 说了是const, 禁止
e = &a 说了是const 禁止


const *f const =&a; //禁止

2.交换两个变量的值,不使用第三个变量。即a=3,b=5,交换之后a=5,b=3;
a =a^b;
b =b^a;
a=a^b;

3
3.c和c++中的struct有什么不同?
不想再说了,


5.char szstr[10];
strcpy(szstr,"0123456789");
长度不一样,会造成非法的OS

12.ISO的七层模型是什么?tcp/udp是属于哪一层?tcp/udp有何优缺点?

应用层
会话层
表示层
运输层
网络层
物理链路层
物理层
tcp /udp属于运输层
TCP 服务提供了数据流传输、可靠性、有效流控制、全双工操作和多路复用技术等。
与 TCP 不同, UDP 并不提供对 IP 协议的可靠机制、流控制以及错误恢复功能等。由于 UDP 比较简单, UDP 头包含很少的字节,比 TCP 负载消耗少。

7.进程之间数据交换的途径
共享段
内存映射文件
剪切板
socket
mailslot
管道
文件(这个不知道算不算)

c和c++中struct的主要区别是c中的struct不可以含有成员函数,而c++中的struct可以。c++中struct和class的主要区别在于默认的存取权限不同,struct默认为public,而class默认为private。

1: 禁止的有*c *d=43 e=&a;f=0x321f;
2:
a=a-b;
b=a+2b
b=a/2+b/2;
a=a+b;
3:
c中的struct不能有函授成员,c++中的可以有函数成员,和class的概念差不多。
4:
输出为空,有内存泄露
5:
szstr不是字符串。不能进行strcpy,strlen等操作
6:
同步机制
原子操作
自旋锁
信号量
优缺点不知道
7:
进程间交换数据的条件:共享内存和消息机制
8:
类的静态成员每个类只有一个,非静态成员每个对象一个
9:
virtual void f()=0;
是接口,子类必须要实现
10:
数组:数据顺序存储,固定大小
连表:数据可以随机存储,大小可动态改变
11:
大小?难道是长度?
strlen(str1)==strlen(str2)?0:(strlen(str1)>strlen(str2)?1:-1)
12:
应用层,表示层,会话层 ,传输层,网络层,数据连楼层,物理层
tcp/udp 传输层
tcp: 提供稳定的传输服务,有流量控制,缺点是包头大,冗余性不好
udp: 不提供稳定的服务,包头小,开销小


c++面试题

silver6 | 27 十月, 2005 17:15

定义了一个基类CLayer,想让它的派生类CCircle对用户不可见,只能调用基类CLayer里的方法,问:
要到下面空格处完成两到三个方法。
layer.h #include layer.h

class CLayer class CCircle():public CLayer
{ {
public: public:
CCircle();
virtual void Draw();
virtual void Draw(); virtual int GetRadius();
virtual int GetRadius(); private:
(1) int Radius;
-----------------
(2) }
-----------------
(3)
__________________
protect:
CLayer();
virtual ~CLayer();
}

只能通过左边的基类来访问CCircle,请问上面的空格怎样填写

mainfrm.h

class CCircle;

class CLayer
{
public:
virtual void Draw(){};
virtual int GetRadius(){return 0;};
typedef enum{ CIRCLE = 0, OTHER = 1}CLASSTYPE;
static CLayer* GetObject(CLASSTYPE enmType);
void ReleaseObject(){delete this;};
protected:
CLayer(){};
virtual ~CLayer(){};
};

class CCircle : public CLayer
{
public:
CCircle(){Radius = 3;};
virtual void Draw(){};
virtual int GetRadius(){return Radius;};
private:
int Radius;
};

mainfrm.cpp

CLayer* CLayer::GetObject(CLASSTYPE enmType)
{
if (CIRCLE == enmType)
{
return new CCircle();
}
else
{
return NULL;
}
}

CMainFrame::CMainFrame()
{
CLayer* pL = CLayer::GetObject(CLayer::CIRCLE); // 创建对象
if (pL)
{
int iR = pL->GetRadius(); //访问方法
pL->ReleaseObject(); // 销毁
}
}


面试题目 VC(c++)

silver6 | 27 十月, 2005 17:12

1 dll,lib处理实现 .lib文件中包含什么? dll在内存中被多个函数共享,有几个拷贝?
2 template<double>,template<int>等编译的时候作为几个类
3 struct ,class的区别,联系
4 MAcro,inline区别,实现.编译运行时
5 进程与线程区别
6 hdc-cdc区别联系
7 model dialog,modeless dialog,从创建到销毁全过程具体描述
8 各个线程new的内存,别的线程是否可以使用?
9 RUNTIME_CLASS, is what??

1 dll,lib处理实现 .lib文件中包含什么? dll在内存中被多个函数共享,有几个拷贝?
简单说,lib里面只有符号,dll里面才是具体的实现.dll在内存中被函数共享有几个拷贝??比较奇怪的问题,dll是在进程空间,所以每个进程有一份dll的copy,可以用GetModuleHandle去判断是否dll已经被load进进程地址空间.
2 template<double>,template<int>等编译的时候作为几个类
如果没有记错,是两个.模板都是编译时产生代码,所以会出现两个类.如果程序中的类型较多,就会展开比较大的代码,但是速度会快.
3 struct ,class的区别,联系
只是成员变量或者函数默认的属性,struct默认是public,class是private
4 MAcro,inline区别,实现.编译运行时
准确来说,内联要更加安全.使用内联,参数需要精确地进行一次求值,参数类型被检查,并且被正确地进行必要的转换,避免了宏的一些问题.也方便调试.简单说,内联更加像函数.
5 进程与线程区别
很多书上都有介绍,一般来说,进程是不活泼的,是线程的容器;线程是在进程里面创建的,执行代码的.
6 hdc-cdc区别联系
cdc是一块空间,保存一定的数据,hdc是放在进程的句柄表里面,用来标示所代表的cdc的
7 model dialog,modeless dialog,从创建到销毁全过程具体描述
模式的是CDialog的DoModal调用CreateIndirect创建对话框,然后通过一个循环自己处理消息的分发;无模式的是通过create创建,类似于一般窗口
8 各个线程new的内存,别的线程是否可以使用?
不可以,因为线程new的空间是在自己的进程空间,别的进程是得不到的.
9 RUNTIME_CLASS, is what??
建议看一下深入浅出mfc

5 进程与线程区别: 最主要: 线程是执行代码的,CPU调度的单元,进程是个资源的容器

8. 同一进程内的线程之间共享进程的地址空间和所有资源

1 dll并不是拷贝到每一个调用者的进程空间,而是只在内存中保留一份拷贝。通过引用计数的方式控制其卸载。
但是dll中的全局变量是要被拷贝到每一个调用者的进程空间的
2 对于第八题,new的内存是在系统中的,虽然它会随着创建进程的消失而被自动回收,但是,还是可以将指针作为参数传递给别的线程或者进程,虽然这种做法不被推荐使用。
但是,如果如本题所说,在同一个进程种的线程,是否可以传递堆的指针,我觉得是可以的,而且没有风险。

.关于dll,代码是放到了RAM中,其他进程都可以通过静态或者动态映射到其地址空间,共享该分页,任何对该dll的使用会引起计数器加一.之前和hookapi有点混了.

那个指针传递给别的进程,好像不能直接用.必须分配的空间是在别的进程,这样的指针在别的空间才用效,好像要用到VirtualAllocEx分配虚拟空间,对于进程间的WM_SetText这类消息,指针里面的数据也是被复制到了对应进程的空间才有效,呵呵.举个例子,a空间里面的0x12345678标示字符串"ABC",但是b空间0x12345678也许是"efg",所以a给b里面传这个指针是不能用的.但是同一个进程里面的线程是可以使用别的线程分配的空间的.

对于第十个问题,是Doc/view框架里面的,可以通过设定view和doc之间的映射,那个单文档多视图做过,不过单视图多文档没有做过,可能需要动态调整各个文档在视图里面的位置吧,没有实践就没有发言权,就此打住,哈哈.


Spring简介

silver6 | 24 十月, 2005 18:50

Spring简介
关于Spring Framework,今年夏天你可能已经听见很多的议论。在本文中,我将试图解释Spring能完成什么,和我怎么会认为它能帮助你开发J2EE应用程序。

另一framework? 你可能正在想“不过是另外一个的framework”。当已经有许多开放源代码(和专有) J2EE framework时,为什么你应该费心读这篇文章,或下载Spring Framework?

我相信Spring是独特的,因为若干个原因:
. 它定位的领域是许多其他流行的framework没有的。Spring关注提供一种方法管理你的业务对象。
. Spring是全面的和模块化的。Spring有分层的体系结构,这意味着你能选择使用它孤立的任何部分,它的架构仍然是内在稳定的。因此从你的学习中,你可得到最大的价值。例如,你可能选择仅仅使用Spring来简单化JDBC的使用,或用来管理所有的业务对象。
. 它的设计从底部帮助你编写易于测试的代码。Spring是用于测试驱动工程的理想的framework。

Spring对你的工程来说,它不需要一个以上的framework。Spring是潜在地一站式解决方案,定位于与典型应用相关的大部分基础结构。它也涉及到其他framework没有考虑到的内容。

尽管它仅仅是一个从2003年2月才开始的开源工程,但Spring有较长的历史根基。这个开源工程是起源自我在2002年后期出版的《Expert One-on-One J2EE设计与开发》书中的基础代码。这本书展示了Spring背后的基础架构。然而,这个基础架构的概念要追溯到2000年的早些时候,并且反映了我为一系列成功的商业工程开发基础结构的经验。

从2003年1月,Spring已经落户于SourceForge上。现在有10个开发人员,其中6是高度投入的积极分子。

Spring的架构性的好处
在我们进入细节以前,让我们看一下Spring可以给一个工程带来的一些好处:

. Spring能有效地组织你的中间层对象,无论你是否选择使用了EJB。如果你仅仅使用了Struts或其他的包含了J2EE特有APIs的framework,你会发现Spring关注了遗留下的问题,。

. Spring能消除在许多工程上对Singleton的过多使用。根据我的经验,这是一个主要的问题,它减少了系统的可测试性和面向对象特性。

. Spring能消除使用各种各样格式的属性定制文件的需要,在整个应用和工程中,可通过一种一致的方法来进行配置。曾经感到迷惑,一个特定类要查找迷幻般的属性关键字或系统属性,为此不得不读Javadoc乃至源编码吗?有了Spring,你可很简单地看到类的JavaBean属性。倒置控制的使用(在下面讨论)帮助完成这种简化。

. Spring能通过接口而不是类促进好的编程习惯,减少编程代价到几乎为零。
. Spring被设计为让使用它创建的应用尽可能少的依赖于他的APIs。在Spring应用中的大多数业务对象没有依赖于Spring。
. 使用Spring构建的应用程序易于单元测试
. Spring能使EJB的使用成为一个实现选择,而不是应用架构的必然选择。你能选择用POJOs或local EJBs来实现业务接口,却不会影响调用代码。
. Spring帮助你解决许多问题而无需使用EJB。Spring能提供一种EJB的替换物,它们适于许多web应用。例如,Spring能使用AOP提供声明性事务而不通过使用EJB容器,如果你仅仅需要与单个的数据库打交道,甚至不需要JTA实现。
. Spring为数据存取提供了一致的框架,不论是使用JDBC或O/R mapping产品(如Hibernate)。
Spring确实使你能通过最简单可行的解决办法解决你的问题。这些特性是有很大价值的。

Spring能做什么?

Spring提供许多功能,在此我将快速地依次展示其各个主要方面。

任务描述:
首先,让我们明确Spring范围。尽管Spring覆盖了许多方面,但我们已经有清楚的概念,它什么应该涉及和什么不应该涉及。

Spring的主要目的是使J2EE易用和促进好编程习惯
Spring不重新开发已有的东西。因此,在Spring中你将发现没有日志记录的包,没有连接池,没有分布事务调度。这些均有开源项目提供(例如Commons Logging 用来做所有的日志输出,或Commons DBCP用来作数据连接池),或由你的应用程序服务器提供。因为同样的的原因,我们没有提供O/R mapping层,对此,已有有好的解决办法如Hibernate和JDO。

Spring的目标是使已存在的技术更加易用。例如,尽管我们没有底层事务协调处理,但我们提供了一个抽象层覆盖了JTA或任何其他的事务策略。

Spring没有直接和其他的开源项目竞争,除非我们感到我们能提供新的一些东西。例如,象许多开发人员,我们从来没有为Struts高兴过,并且感到在MVC web framework中还有改进的余地。在某些领域,例如轻量级的IoC容器和AOP框架,Spring有直接的竞争,但是在这些领域还没有已经较为流行的解决方案。(Spring在这些区域是开路先锋。)

Spring也得益于内在的一致性
所有的开发者都在唱同样的的赞歌,基础想法依然是Expert One-on-One J2EE设计与开发的那些。
并且我们已经能够使用一些主要的概念,例如倒置控制,来处理多个领域。

Spring在应用服务器之间是可移植的
当然保证可移植性总是一次挑战,但是我们避免任何特定平台或非标准化,并且支持在WebLogic,Tomcat,Resin,JBoss,WebSphere和其他的应用服务器上的用户。

倒置控制容器
Spring的设计核心是 org.springframework.beans 包, 为与JavaBeans一起工作而设计。 这个包一般不直接被用户使用, 但作为基础为更多的其他功能服务. 下一个较高层面的抽象是"Bean Factory"。 Spring bean factory 是一个普通的Factory,它使对象能够按名称获取,并且能管理对象之间的关系。

Bean factories 支持两种对象模式:
. Singleton:在此模式中,有一个具有特定名称的共享对象实例,它在查找时被获取。这是默认的,而且是最为经常使用的。它对于无状态对象是一种理想的模式。
.Prototype:在此模式中,每次获取将创建一个独立的对象。例如,这可以被用于允许用户拥有他们自己的对象。

由于 org.springframwork.beans.factory.BeanFactory是一个简单的接口,它能被为了底层存储方法而实现。你能够方便地实现你自己的BeanFactory,尽管很少用户需要。最为常用的定义是:
.XmlBeanFactory: 可解析简单直观的定义类和命名对象属性的XML结构。 我们提供了一个DTD来使编写更容易。
.ListableBeanFactoryImpl:可提供解析存放在属性文件中的bean定义,和可通过编程创建BeanFactories。

每个bean定义可能是一个POJO(通过类名和JavaBean初始属性定义),或是一个FactoryBean。FactoryBean接口添加了一个间接层。通常,这用于使用AOP或其他方法来创建代理对象:例如,添加了声明性事务管理的代理。(这在概念上和EJB侦听相似,但在实践中实现更简单。)

BeanFactories能在一个层次结构中可选择性的参与,根据来自祖先的继承定义。这使在整个应用中公共配置的共享成为可能,虽然个别资源,如controller servlets,也拥有他们自己的独立的对象集合。

这种使用JavaBeans的动机在<Expert One-on-One J2EE Design and Development>的第四章中有描述,在TheServerSide网站上的有免费的PDF(http://www.theserverside.com/resources/article.jsp?l=RodJohnsonInterview).

通过BeanFactory概念,Spring成为一个倒置控制的容器。(我非常不喜欢container这个术语,因为它使人联想到重量级容器,如EJB容器。Spring的BeanFactory是一个可通过一行代码创建的容器,并且不需要特殊的部署步骤。)

位于倒置控制背后的概念是在Hollywood原则中经常表述:"Don’t call me, I’ll call you." IoC将控制职责搬进了框架中,并脱离应用代码。涉及到配置的地方,意思是说在传统的容器体系结构中,如EJB,一个组件可以调用容器并问“我需要它给我做工作的对象X在哪里?”;使用IoC容器则只需指出组件需要X对象,在运行时容器会提供给它。容器基于方法名作出这种说明,或可能根据配置数据如XML。

倒置控制的几个重要好处。如:
. 因为组件不需要在运行时间寻找合作者,所以他们可以更简单的编写和维护。在Spring的IoC版本里,组件通过暴露JavaBean的setter方法表达他们依赖的其他组件。这相当于EJB通过JNDI来查找,EJB查找需要开发人员编写代码。
. 同样原因,应用代码更容易测试。JavaBean属性是简单的,Java核心的,并且容易测试:仅编写一个包含自身的Junit测试方法用来创建对象和设置相关属性即可。
. 一个好的IoC实现隐藏了强类型。如果你使用一个普通的factory来寻找合作者,你必须通过类型转换将返回结果转变为想要的类型。这不是一个主要问题,但是不雅观。使用IoC,你在你的代码中表达强类型依赖,框架将负责类型转换。这意味着在框架配置应用时,类型不匹配将导致错误;在你的代码中,你无需担心类型转换异常。
. 大部分业务对象不依赖于IoC容器的APIs。这使得很容易使用遗留下来的代码,且很容易的使用对象无论在容器内或不在容器内。例如,Spring用户经常配置Jakarta Commons DBCP数据源为一个Spring bean:不需要些任何定制代码去做这件事。我们说一个IoC容器不是侵入性的:使用它并不会使你的代码依赖于它的APIs。任何JavaBena在Spring bean factory中都能成为一个组件。

最后应该强调的是,IoC 不同于传统的容器的体系结构( 如EJB), 应用代码最小程度的依靠于容器。这意味着你的业务对象可以潜在的被运行在不同的IoC 框架上-或者在任何框架之外-不需要任何代码改。

以我的经验和作为Spring用户,过分强调IoC给应用代码带来的好处是不容易的。

IoC不是一个新概念,但是它在J2EE团体里面刚刚到达黄金时间。 有一些可供选择的IoC 容器: notably, Apache Avalon, PicoContainer 和 HiveMind. Avalon 不会成为特别流行的,尽管它很强大而且有很长的历史。Avalon是相当的重量级和复杂的,并且看起来比新的IoC解决方案更具侵入性。 PicoContainer是一个轻量级而且更强调通过构造器表达依赖性而不是JavaBean 属性。 与Spring不同,它的设计允许每个类型一个对象的定义(可能局限性结果来自它对Java代码外的元数据的拒绝)。作为和Spring and PicoContainer and other IoC frameworks的比较,可参看文章http://www.springframework.org/docs/lightweight_container.html. 这个业面包含了PicoContainer站点链接 。

Spring BeanFactories 是非常轻量级的。用户已经成功地将他们应用在applets中和单独的Swing应用中。(它们也很好地工作在EJB容器中。) 没有特殊的部署步骤和可察觉的启动时间。这个能力表明一个容器在应用的任何层面差不多立即可以发挥非常大的价值。

Spring BeanFactory 概念应用贯穿于Spring整体, 而且是Spring如此内在一致的关键原因。在IoC容器中,Spring也是唯一的,它使用IoC作为基础概念贯穿于整个框架。

对应用开发人员,最重要的是,一个或多个BeanFactory提供一个定义明确的业务对象层。这是类似的,但比local session bean层更简单。与EJBs不同,在这个层中的对象可能是相关的,并且他们的关系被自己的factory管理。有一个定义明确的业务对象层对于一个成功的体系结构是非常重要的。

Spring ApplicationContext 是BeanFactory的子接口,为下列提供支持:
.消息寻找,国际化支持
.事件机制,允许应用对象发布和随意地注册为事件监听
.便携文件和资源访问


XmlBeanFactory示例
Spring用户通常在XML“bean定义”文件中配置他们的应用。Spring的XML bean定义文档的根是一个<beans> 元素。该元素包含一个或多个 <bean>定义。我们一般指定一个bean定义的类和属性。我们也必须指定ID作为标识,我们将在代码中使用该标志。
让我们来看一个简单的例子,在J2EE应用中常看到用来配置三个应用对象:
. J2EE DataSource
. 使用DataSource的DAO
. 在处理过程中使用DAO的业务对象

在下面的例子中,我们使用一个来自Jakarta Commons DBCP项目的BasicDataSource。这个class(和其他存在的class一样)可以简单地被应用在Spring bean factory中,因为它提供了JavaBean格式的配置。需要在shutdown时被调用的Close方法可通过Spring的"destroy-method"属性被注册,来避免BasicDataSource需要实现任何Spring 接口。

代码: <textarea>
<beans>
<bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName"><value>com.mysql.jdbc.Driver</value></property>
<property name="url"><value>jdbc:mysql://localhost:3306/mydb</value></property>
<property name="username"><value>root</value></property>
</bean> </textarea>


我们感兴趣的BasicDataSource的所有属性都是String型的,因此,我们用<value>元素来指定他们的值。如果必要的话,Spring使用标准的 JavaBean属性编辑器机制来转换String以表示其他的类型。

现在,我们定义了DAO,它有一个对DataSource的bean引用。Bean间关系通过<ref>元素来指定:
代码: <textarea>
<bean id="exampleDataAccessObject" class="example.ExampleDataAccessObject">
<property name="dataSource">
<ref bean="myDataSource"/>
</property>
</bean> </textarea>

业务对象有一个DAO的引用和一个int型属性(exampleParam):
代码:
<textarea><bean id="exampleBusinessObject" class="example.ExampleBusinessObject">
<property name="dataAccessObject"><ref bean="exampleDataAccessObject"/></property>
<property name="exampleParam"><value>10</value></property>
</bean></beans> </textarea>


对象间的关系一般在配置中明确地设置,象此例子一样。我们认为这样做是件好事情。无论如何,Spring也提供了我们叫做"autowire"的支持, 一个la PicoContainer,在那里,它可以指出bean间的依赖关系。这样做的局限性-如使用PicoContainer-是如果有一个特殊类型的多个Bean,要作出一个类型应该与哪个实例相关的判断将是不可能的。好的方面,在factory初始化后,不理想的依赖可能会被捕获到。(Spring 也为清楚的配置提供一种可选的依赖检查,它可以完成这个目的)

如果我们不想明确的编写他们的关系,在上面的例子中,我们可如下使用autowire特性:
<textarea>
<bean id="exampleBusinessObject" class="example.ExampleBusinessObject" autowire="byType">
<property name="exampleParam"><value>10</value></property>
</bean> </textarea>

使用这用用法,Spring将找出exampleBusinessObject的dataSource属性应该被设置为在当前BeanFactory中找到的DataSource实现。在当前的BeanFactory中,如果所需要类型的bean不存在或多于一个,将产生一个错误。我们依然要设置exampleParam属性,因为它不是一个引用。

Autowire支持和依赖检查刚刚加入CVS并将在Spring 1.0 M2(到10/20,2003)中提供。本文中所讨论的所有其他特性都包含在当前1.0 M1版本中。

来自Java代码的外在关系比硬编码有极大的好处,因为改变XML文件而无需改变一行Java代码是可能的。例如,我们可以简单地改变myDataSource的bean定义来提供不同的bean class以使用一个可供选择的连接池,或者一个测试数据源。 在一个单独可选的XML片断中,我们可以用Spring的JNDI 定位FactoryBean来从application server获取一个数据源。

现在让我们来看例子中业务对象的java 代码。注意下面列出的代码中没有对Spring的依赖。不像EJB容器,Spring BeanFactory不是侵入性的:在应用对象里面你通常不需要对他们编码。
代码:
public class ExampleBusinessObject implements MyBusinessObject {

private ExampleDataAccessObject dao;
private int exampleParam;

public void setDataAccessObject(ExampleDataAccessObject dao) {
this.dao = dao;
}

public void setExampleParam(int exampleParam) {
this.exampleParam = exampleParam;
}

public void myBusinessMethod() {
// do stuff using dao
}
}


注意属性设置器,在bean定义文档中,它对应与XML引用。这些将在对象使用之前被Spring调用.

这些应用bean不需要依赖于Spring。他们不需要实现任何Spring接口或者继承Spring的类:他们只需要遵守JavaBeans命名习惯。在Spring 应用环境之外重用它们是非常简单的,例如,一个测试环境。只是例示它有默认的构造器,并且通过setDataSource()和setExampleParam()的调用来手工设置它的属性。只要你有一个没有参数的构造器,如果你想在单行代码支持程序化的创建,你可以自由定义其他的带有多个属性构建的器。

注意,在业务接口中没有声明的JavaBean属性将会一起工作。 他们是一个实现细节。我们可以插入带有不同bean属性的不同的实现类而不影响连接对象或者调用代码。

当然,Spring XML bean factories 有更多的功能没有在这里描述,但是,这将给你一种基本使用的感觉。同时,简单的属性和有JavaBean属性编辑器的属性,Spring可以自动处理lists,maps和java.util.Properties.

Struts常见错误汇总

silver6 | 20 十月, 2005 10:39

以下所说的struts-config.xml和ApplicationResources.properties等文件名是缺省时使用的,如果你使用了多模块,或指定了不同的资源文件名称,这些名字要做相应的修改。   1、“No bean found under attribute key XXX”   在struts-config.xml里定义了一个ActionForm,但type属性指定的类不存在,type属性的值应该是Form类的全名。或者是,在Action的定义中,name或attribute属性指定的ActionForm不存在。   2、“Cannot find bean XXX in any scope”   在Action里一般会request.setAttribute()一些对象,然后在转向的jsp文件里(用tag或request.getAttribute()方法)得到这些对象并显示出来。这个异常是说jsp要得到一个对象,但前面的Action里并没有将对象设置到request(也可以是session、servletContext)里。   可能是名字错了,请检查jsp里的tag的一般是name属性,或getAttribute()方法的参数值;或者是Action逻辑有问题没有执行setAttribute()方法就先转向了。   还有另外一个可能,纯粹是jsp文件的问题,例如会指定一个id值,然后在循环里使用这个值作为name的值,如果这两个值不同,也会出现此异常。(都是一个道理,request里没有对应的对象。)   3、“Missing message for key "XXX"”   缺少所需的资源,检查ApplicationResources.properties文件里是否有jsp文件里需要的资源,例如:      这行代码会找msg.name.prompt资源,如果AppliationResources.properties里没有这个资源就会出现本异常。在使用多模块时,要注意在模块的struts-config-xxx.xml里指定要使用的资源文件名称,否则当然什么资源也找不到,这也是一个很容易犯的错误。   4、“No getter method for property XXX of bean teacher”   这条异常信息说得很明白,jsp里要取一个bean的属性出来,但这个bean并没有这个属性。你应该检查jsp中某个标签的property属性的值。例如下面代码中的cade应该改为code才对:      5、“Cannot find ActionMappings or ActionFormBeans collection”   待解决。   6、“Cannot retrieve mapping for action XXX”   在.jsp的 标签里指定action='/XXX',但这个Action并未在struts-config.xml里设置过。   7、HTTP Status 404 - /xxx/xxx.jsp   Forward的path属性指向的jsp页面不存在,请检查路径和模块,对于同一模块中的Action转向,path中不应包含模块名;模块间转向,记住使用contextRelative="true"。   8、没有任何异常信息,显示空白页面   可能是Action里使用的forward与struts-config.xml里定义的forward名称不匹配。   9、“The element type "XXX" must be terminated by the matching end-tag "XXX".”   这个是struts-config.xml文件的格式错误,仔细检查它是否是良构的xml文件,关于xml文件的格式这里就不赘述了。   10、“Servlet.init() for servlet action threw exception”   一般出现这种异常在后面会显示一个关于ActionServlet的异常堆栈信息,其中指出了异常具体出现在代码的哪一行。我曾经遇到的一次提示如下:   java.lang.NullPointerException    at org.apache.struts.action.ActionServlet.parseModuleConfigFile(ActionServlet.java:1003)    at org.apache.struts.action.ActionServlet.initModuleConfig(ActionServlet.java:955)   为解决问题,先下载struts的源码包,然后在ActionServlet.java的第1003行插入断点,并对各变量进行监视。很丢人,我竟然把struts-config.xml文件弄丢了,因此出现了上面的异常,应该是和CVS同步时不小心删除的。   11、“Resources not defined for Validator”   这个是利用Validator插件做验证时可能出现的异常,这时你要检查validation.xml文件,看里面使用的资源是否确实有定义,form的名称是否正确,等等。

Struts学习傻瓜式入门篇

silver6 | 19 十月, 2005 19:26

该案例包括首页,用户登陆、网站向导页面。就这么简单,没有深奥的struts概念,主要靠动手,然后用心体会。   WEB Server用tomcat4。到http://jakarta.apache.org下载struts1.1,把zip文件释放到c:struts,拷贝C:strutswebappsstruts-example.war到c:tomcat4webapps中,启动tomcat,war包被释放为struts-example文件夹,删除war包,把struts-example文件夹更名为test。   一、把WEB-INFweb.xml改成: action org.apache.struts.action.ActionServlet config /WEB-INF/struts-config.xml 1 action *.cool index.jsp   二、把testWEB-INF struts-config.xml改成:

  三、增加一个FormBean,类路径为test.UserForm,以下是这个类的内容:package test; import org.apache.struts.action.ActionForm; public class UserForm extends ActionForm {  private String name="lpw";//用户名  private String ps="1111";//密码  public UserForm(){}  public void setName(String s) {name=s;}  public String getName() {return name;}  public void setPs(String s) {ps=s;}  public String getPs() {return ps;} }   四、增加一个Action的子类,类路径为test. RegistAction,以下是这个类的内容: package test; import java.lang.reflect.InvocationTargetException; import java.util.Locale; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import javax.servlet.http.HttpServletResponse; import org.apache.struts.action.Action; import org.apache.struts.action.ActionError; import org.apache.struts.action.ActionErrors; import org.apache.struts.action.ActionForm; import org.apache.struts.action.ActionForward; import org.apache.struts.action.ActionMapping; import org.apache.struts.util.MessageResources; import test.UserForm; public final class RegistAction extends Action {  public ActionForward execute(ActionMapping mapping,ActionForm form, HttpServletRequest request, HttpServletResponse response)  throws Exception  {   Locale locale = getLocale(request);   MessageResources messages = getResources(request);   HttpSession session = request.getSession();   UserForm userform = (UserForm) form;   //此处可以调用其他类来执行数据库写入或其他逻辑判断   // 如果UserForm传来的参数name的值为默认的lpw,将forward到failed,   // 该名称将到struts-config.xml的中寻找映射的url地址   // (可以是绝对路径,也可以是相对路径),对于本例,是转到failed.cool,   // 还记得吗?后缀为cool的请求全部到action-mappings中寻找   // 对应的action处理,最终目录是wuwu.jsp*/   if( "lpw".equals(userform.getName()) )    return (mapping.findForward("failed"));   else    return (mapping.findForward("regist"));  } } 五、以下所有新增或修改的页面相当于struts的View部分,把首页index.jsp改成: 站点导航
用户:
密码:
  六、增加hello.jsp,用于站点导航:

site map

The following is content filling by reader   七、增加wuwu.jsp,当没有新用户登陆时,将转到这个页面: 现有用户:
密码:
  没有得到新的用户!   八、增加regist.jsp,当有新用户登陆时,将转到这个页面: 新用户帐号:
密码:   九、启动tomcat4,浏览器中键入http://localhost:8080/test/index.jsp,操作一下,就可以看到结果,并初步理解struts的M、V、C各部分的协同工作原理,当然这是作者的良好意愿,如果读者看得一头雾水,欢迎指出错误在哪里 :)

Struts入门经验

silver6 | 19 十月, 2005 15:56

一个实例: 一个用户注册系统,用户通过网页输入相关信息:注册ID号,密码,EMAIL,若注册成功,则返回成功提示信息,反之出现注册失败提示信息。
以下是相关文件的部分核心代码。

项目建立:
正式开发前,需要在Tocmat(我的tomcat装在c:tomcat)中建立此项目。比较快的一种建立方式为:在C:tomcatwebapps下新建目录test,再将C:tomcatwebappsstruts-example下的
WEB-INF目录拷贝到test目录下,然后将testWEB-INF下的src和classes目录清空,以及struts-config.xml文件中内容清空即可。这样,我们需要的Struts类包及相关的配置文件就都齐了。
开发时,将JSP文件放在test目录下,Java原文件放在testWEB-INFsrc下,编译后的类文件放在testWEB-INFclasses下。

注册页面:reguser.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="/WEB-INF/Struts-bean.tld" prefix="bean" %>
<%@ taglib uri="/WEB-INF/Struts-html.tld" prefix="html" %>
<html:html locale="true">
<head>
<title>RegUser</title>
<html:base/>
</head>
<body bgcolor="white">
<html:errors/>
<html:form action="/regUserAction" focus="logname">
<table border="0" width="100%">
<tr>
<th align="right">
Logname:
</th>
<td align="left">
<html:text property="logname" size="20" maxlength="20"/>
</td>
</tr>
<tr>
<th align="right">
Password:
</th>
<td align="left">
<html:password property="password" size="20" maxlength="20"/>
</td>
</tr>
<tr>
<th align="right">
E-mail:
</th>
<td align="left">
<html:password property="email" size="30" maxlength="50"/>
</td>
</tr>
<tr>
<td align="right">
<html:submit property="submit" value="Submit"/>
</td>
<td align="left">
<html:reset/>
</td>
</tr>
</table>
</html:form>
</body>
</html:html>

此JSP页面不同于普通的JSP页,因为它大量运用了taglib,这些taglib对初学者而言,可能难于掌握,可这却是Struts的精华之一。灵活运用,将大大提高开发效率。

Struts-config.xml:

<Struts-config>
<form-beans>
<form-bean name="regUserForm"
type="org.cjea.Struts.example. RegUserForm "/>
</form-beans>
<action-mappings>
<action path="/regUserAction"
type=" org.cjea.Struts.example.RegUserAction "
attribute=" regUserForm "
scope="request"
validate="false">
<forward name="failure" path="/ messageFailure.jsp"/>
<forward name="success" path="/ messageSuccess.jsp"/>
</action>
</action-mappings>
</Struts-config>

Struts的核心是Controller,即ActionServlet,而ActionServlet的核心就是Struts-config.xml,Struts-config.xml集中了所有页面的导航定义。对于大型的WEB项目,通过此配置文件即可迅速把握其脉络,这不管是对于前期的开发,还是后期的维护或升级都是大有裨益的。掌握Struts-config.xml是掌握Struts的关键所在。

FormBean:RegUserForm

package org.cjea.Struts.example;

import javax.Servlet.http.HttpServletRequest;
import org.apache.Struts.action.ActionForm;
import org.apache.Struts.action.ActionMapping;

public final class RegUserForm extends ActionForm{

private String logname;
private String password;
private String email;

public RegUserForm(){
logname = null;
password = null;
email = null;
}

public String getLogName() {
return this.logname;
}
public void setLogName(String logname) {
this.logname = logname;
}
public void setPassWord(String password) {
this.password = password;
}
public String getPassWord() {
return this.password;
}
public void setEmail(String email) {
this.email = email;
}
public String getEmail() {
return this.email;
}

public void reset(ActionMapping mapping, HttpServletRequest request)
{
logname = null;
password = null;
email = null;
}
}

每一个FormBean 都必须继承ActionForm类,FormBean是对页面请求的封装。即把HTTP request 封装在一个对象中,需要说明的一点就是多个HTTP request可以共用一个FormBean,便于维护和重用。

ActionBean:RegUserAction

package org.cjea.Struts.example;

import javax.Servlet.http.*;
import org.apache.Struts.action.*;

public final class RegUserAction extends Action
{

public ActionForward perform(ActionMapping mapping,
ActionForm form, HttpServletRequest req,
HttpServletResponse res)
{
String title = req.getParameter("title");
String password = req.getParameter("password");
String email = req.getParameter("email");
/*
取得用户请求,做相应数据库操作,略
*/
}
}

FormBean的产生是为了提供数据给ActionBean,在ActionBean中可以取得FormBean中封装的数据,经相应的逻辑处理后,调用业务方法完成相应业务要求。

Servlet的演变:在常规的 JSP,Servlet,JavaBean三层结构中,JSP实现View的功能,Servlet实现Controller的功能,JavaBean实现Model的实现。

在Struts中,将常规情况下的Servlet拆分与ActionServlet、FormBean、ActionBean三个部分。ActionServlet配合Struts-config.xml,专职完成页面导航,而不再负责具体的数据获取与相应逻辑,这两部分功能由FormBean和ActionBean来完成。

Struts优缺点
优点:
Struts跟Tomcat、Turbine等诸多Apache项目一样,是开源软件,这是它的一大优点。使开发者能更深入的了解其内部实现机制。
除此之外,Struts的优点主要集中体现在两个方面:Taglib和页面导航。Taglib是Struts的标记库,灵活动用,能大大提高开发效率。另外,就目前国内的JSP开发者而言,除了使用JSP自带的常用标记外,很少开发自己的标记,或许Struts是一个很好的起点。
关于页面导航,我认为那将是今后的一个发展方向,事实上,这样做,使系统的脉络更加清晰。通过一个配置文件,即可把握整个系统各部分之间的联系,这对于后期的维护有着莫大的好处。尤其是当另一批开发者接手这个项目时,这种优势体现得更加明显。
缺点:
Taglib是Struts的一大优势,但对于初学者而言,却需要一个持续学习的过程,甚至还会打乱你网页编写的习惯,但是,当你习惯了它时,你会觉得它真的很棒。
Struts将MVC的Controller一分为三,在获得结构更加清晰的同时,也增加了系统的复杂度。
Struts从产生到现在还不到半年,但已逐步越来越多运用于商业软件。虽然它现在还有不少缺点,但它是一种非常优秀的J2EE MVC实现方式,如果你的系统准备采用J2EE MVC架构,那么,不妨考虑一下Struts。

Struts实施经验:
1、基于Struts架构的项目开发,首先需要有一个很好的整体规划,整个系统中包括哪几个模块,每个模块各需要多少FormBean和ActionBean等,而且最好有专人负责Struts-config.xml的管理。开发基于Struts的项目的难点在于配置管理,尤其是对Struts-config.xml的管理

2、如果你的项目非常紧,并且项目组中又没有富有经验的Struts开发人员,建议不要冒然采用Struts。Struts的掌握需要一个过程,对于一个熟练的JSP程序员,自学大概需要半个月左右的时间。如果结合titls,则需要更长的时间

3、如果你在网页中大量运用taglib,那么你的美工将做出部分牺牲。当你结合Tiles,功能增强的同时,这种牺牲尤为明显。当然,你对功能和美观的取舍由你自己决定

4、Taglib是一个好东西,但灵活运用它却需要一个过程,如果你不想在Taglib上花太多的时间,那么只需理解与FORM有关的几个标记,其它的标记就放着吧,以后再看,先去研究ActionServlet和Struts-config.xml,你会觉得很有成就感

5、Struts是否只适合于大型项目呢?No!Struts适合于各种大小的项目,当然,对于大型项目,它所体现出来的优势更加明显。

java实现图片验证代码

silver6 | 18 十月, 2005 11:49

java实现图片验证的完整代码,有待验证,觉得还成,保留先 package util; import javax.imageio.ImageIO; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.awt.*; import java.awt.image.BufferedImage; import java.io.IOException; import java.util.Random; /** * 描述: * * @author $author$ * @version $Revision$ */ public class PicCheckCode extends HttpServlet { private Font mFont = new Font("Arial Black", Font.PLAIN, 15); //设置字体 private int lineWidth = 2; //干扰线的长度=1.414*lineWidth private int width = 60; //定义图形大小 private int height = 20; //定义图形大小 private int count = 200; /** * 描述: * * @param fc 描述: * @param bc 描述: * * @return 描述: */ private Color getRandColor(int fc, int bc) { //取得给定范围随机颜色 Random random = new Random(); if (fc > 255) { fc = 255; } if (bc > 255) { bc = 255; } int r = fc + random.nextInt (bc - fc); int g = fc + random.nextInt (bc - fc); int b = fc + random.nextInt (bc - fc); return new Color(r, g, b); } //处理post public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet (request, response); } /** * 描述: * * @param request 描述: * @param response 描述: * * @throws ServletException 描述: * @throws IOException 描述: */ public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //response.reset(); //设置页面不缓存 response.setHeader ("Pragma", "No-cache"); response.setHeader ("Cache-Control", "no-cache"); response.setDateHeader ("Expires", 0); response.setContentType ("image/gif"); // 在内存中创建图象 BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); // 获取图形上下文 Graphics2D g = (Graphics2D) image.getGraphics (); //生成随机类 Random random = new Random(); // 设定背景色 g.setColor (getRandColor (200, 250)); //---1 g.fillRect (0, 0, width, height); //设定字体 g.setFont (mFont); //画边框 g.setColor (getRandColor (0, 20)); //---2 g.drawRect (0, 0, width - 1, height - 1); //随机产生干扰线,使图象中的认证码不易被其它程序探测到 for (int i = 0; i

微软笔试唯一一道C#题

silver6 | 18 十月, 2005 11:47

C#的内存处理和C++有什么不同。。。
这是唯一一道。。。

其他都是C++

1.Basic
考的都是一些基本的知识,如操作系统,网络,不难,可惜很多都忘了。。。
2.推理题
跟GRE的逻辑部分一样,一道逻辑推理,两道分析推理,以前做过的话感觉会好些
3.2个编程题,第一个找一个数组所有数字的最大公约数,第二道是在一个字典中查找所有以所给字母开头的单词。
4.写写对MSN的看法,有什么改进意见。
5.一个循环链表检测程序,挑bug
还要写一些test case 。


2个面试题目

silver6 | 18 十月, 2005 11:44

1. a)下面的代码输出是什么,为什么?
void foo(void)
{
unsigned int a = 6;
int b = -20;
(a+b>6)?puts(">6"):puts("<=6");//puts为打印函数
}
b)运行下面的函数会有什么结果?为什么?
void foo(void)
{
char string[10],str1[10];
int i;
for(i=0;i<10;i++)
{
str1[i] = 'a';
}
strcpy(string, str1);
printf("%s",string);
}

2. 编写strcpy函数
已知strcpy函数的原型是
char *strcpy(char *strDest, const char *strSrc);
其中strDest是目的字符串,strSrc是源字符串。
a)不调用C++/C的字符串库函数,请写出函数strcpy。
b)strcpy能把strSrc的内容复制到strDest,为什么还要char* 类型的返回值?


我的回答是:1.1 输出 >6 因为int b 被强制转换为unsigned int 型,所以变成一个很大的正数;
1.2 由于str1末尾没有‘’结束标志,所以strcpy不知道拷贝到何时结束,会造成内存泄漏。
2. char *strcpy(char *strDest, const char *strSrc)
{
int len;
char* p=strSrc;
while(!*p++)
len++;
strDest=new char[len+1];
assert(!strDest)
while(!*strSrc)
*strDest++ = *strSrc++;
strDest[len]='';
return strDest;
}

高手看看,不知道做的对不对?

2. char *strcpy(char *strDest, const char *strSrc)
{
int len;
char* p=strSrc;
while(!*p++)
len++;
strDest=new char[len+1]; //你在这分配了空间 由谁来释放啊??
assert(!strDest)
while(!*strSrc)
*strDest++ = *strSrc++;
strDest[len]='';
return strDest;
}

8.解:这是出现频率最高的笔试题,应该源自于林锐的《C/C++高级编程指南》
关键字:C++,strcpy,字符串,复制,拷贝,copy,笔试,试题
题目:
已知strcpy函数的原型是:
char * strcpy(char * strDest,const char * strSrc);
1.不调用库函数,实现strcpy函数。
2.解释为什么要返回char *。
解说:
1.strcpy的实现代码
char * strcpy(char * strDest,const char * strSrc)
{
if ((strDest==NULL)||(strSrc==NULL)) //[1]
throw "Invalid argument(s)"; //[2]
char * strDestCopy=strDest; //[3]
while ((*strDest++=*strSrc++)!=''); //[4]
return strDestCopy;
}
错误的做法:
[1]
(A)不检查指针的有效性,说明答题者不注重代码的健壮性。
(B)检查指针的有效性时使用((!strDest)||(!strSrc))或(!(strDest&&strSrc)),
说明答题者对C语言中类型的隐式转换没有深刻认识。在本例中char *转换为bool即是类
型隐式转换,这种功能虽然灵活,但更多的是导致出错概率增大和维护成本升高。所以
C++专门增加了bool、true、false三个关键字以提供更安全的条件表达式。
(C)检查指针的有效性时使用((strDest==0)||(strSrc==0)),说明答题者不知道使
用常量的好处。直接使用字面常量(如本例中的0)会减少程序的可维护性。0虽然简单
,但程序中可能出现很多处对指针的检查,万一出现笔误,编译器不能发现,生成的程
序内含逻辑错误,很难排除。而使用NULL代替0,如果出现拼写错误,编译器就会检查出
来。
[2]
(A)return new string("Invalid argument(s)");,说明答题者根本不知道返回值
的用途,并且他对内存泄漏也没有警惕心。从函数中返回函数体内分配的内存是十分危
险的做法,他把释放内存的义务抛给不知情的调用者,绝大多数情况下,调用者不会释
放内存,这导致内存泄漏。
(B)return 0;,说明答题者没有掌握异常机制。调用者有可能忘记检查返回值,调
用者还可能无法检查返回值(见后面的链式表达式)。妄想让返回值肩负返回正确值和
异常值的双重功能,其结果往往是两种功能都失效。应该以抛出异常来代替返回值,这
样可以减轻调用者的负担、使错误不会被忽略、增强程序的可维护性。
[3]
(A)忘记保存原始的strDest值,说明答题者逻辑思维不严密。
[4]
(A)循环写成while (*strDest++=*strSrc++);,同[1](B)。
(B)循环写成while (*strSrc!='') *strDest++=*strSrc++;,说明答题者对边界
条件的检查不力。循环体结束后,strDest字符串的末尾没有正确地加上''。
2.返回strDest的原始值使函数能够支持链式表达式,增加了函数的“附加值”。同
样功能的函数,如果能合理地提高的可用性,自然就更加理想。

char *strcpy(char *strDest, const char *strSrc)
{
if(strDest == NULL || strSrc == NULL)
{
return NULL;
}
char* temp = strDest;
while((*strDest++ = *strSrc++) != '');
return temp;
}
返回的指针是strDest的初始值
strDest在strcpy中会改变


Struts提供的HTML标签库

silver6 | 15 十月, 2005 12:01

继续学习Struts提供的HTML标签库。 by Budi Kurniawan 在本文系列的第一部分中我讲述了如何使用Struts提供的HTML标签库来配置一个Struts应用程序。我还介绍了该标签库中的一类标签:独立使用的标签。在第二部分中我将继续介绍第二类标签:与form相关的标签。 与form相关的标签包括 标签本身以及所有必须包含在其中的标签。比如,和标签就是和form相关的标签,因为如果不把它们放到一个form中它们就没有意义。 标签 标签用于生成一个HTML form。使用该标签时必须遵循许多规则。 首先,标签中必须包含一个action属性,它是这个标签中唯一必需的属性。如果不具备该属性则JSP页面会抛出一个异常。之后你必须给这个action属性指定一个有效值。一个有效值是指应用程序的Struts配置文件中元素里的任何一个子元素的访问路径。而且相应的元素中必须有一个name属性,它的值是form bean的名称。 例如,如果你有这样一个标签: 那么你的Struts配置文件的元素中必须有一个如下显示为粗体的元素: . . . 这就是说一个form标签是和form bean相关联的。 另一个要遵循的规则是:任何包含在

中用来接收用户输入的标签( 标签 标签用于显示一个单选按钮(radio button)。它必须包含“value”属性。比如这段代码: Mr. Ms. Dr. 会被转换成这样的HTML: Mr. Ms. Dr. 标签 标签用于显示checkbox类型的输入区域。比如: Please send me notification 会被转换成: Please send me notification 标签 标签用于生成提交类型(type submit)的输入区域。比如: 会被转换成: 标签 标签用于生成重置类型(type reset)的输入区域。比如: 会被转换成:

Intel笔试题

silver6 | 14 十月, 2005 08:59

原题如下: #include “stdafx.h” #include struct bit { int a:3; int b:2; int c:3; }; int main(int argc, char* argv[]) { bit s; char *c = (char*)&s; *c = 0x99; cout

MS 笔试题

silver6 | 14 十月, 2005 08:58

struct S { int i; int * p; }; void main() { S s; int * p = &s.i; p[0] = 4; p[1] = 3; s.p = p; s.p[1] = 1; s.p[0] = 2; } 问程序会在哪一行死掉。why 最后一行 记s.i的地址为a,s.p的地址为b, 即a = &s.i,b = &s.p, b = a+4 p = &s.i // 则 p = a; s.p = p // *b = p = a; s.p[1] = 1 // 即 *(*b + 4) = *(a+4) = *b = 1; s.p[0] = 2 // 即 **b = *(1) 对地址0x00000001赋值非法 呵呵 正解 ~ windows操作系统0x00000000-0x0000ffff是一段特殊内存, 禁止访问 ~ 这样不是更好看 struct S { int i; int * p; }; void main() { S s; int * x = &s.i; x[0] = 4; x[1] = 3; s.p = x; s.p[1] = 1; s.p[0] = 2; } 当然在C中象这样,在一个struct中的标拾符可以和外边的标拾符一样, 但在C++中就不能,因为它有严格的名字空间限制,当然这是为了解决C中当 代码膨胀引起的名字危机.

面试细节

silver6 | 11 十月, 2005 15:43

第一,人家约你几点,你最好就那个时间去,特别是接近上下班时间的情况,因为别人可能有什么安排,你去早了别人没空,你也只能干等。我就遇到一个,约的是下午1点半,他1点就来了,而我们公司是1点半上班的(因为大家中午都要休息一下),还好,我是一个不睡午觉的人,也就接待了他,但我不能影响其他同事休息啊,也免得让他干等,就把他叫到外面去面试(请他喝了一罐可乐,我抽我的烟,效果还不错,^_^)。这毕竟不好啊,万一我也要休息呢?你难道就在门口站着啊?也别迟到,原因跟上面差不多,也是人家可能有安排,更多的是一个尊重的问题。

第二,着装。不是一定要穿高档货,至少要整洁。比如衣服上有一块墨的那种,最好就算了,挑一件干净的衣服应该也不是什么难事。我毕业的时候,很多同学去买高档西服,2000多啊,反正我是买不起的。我觉得大家还是有选择一点比较好,比如去万科面试的话,最好穿西服打tie,他们就喜欢这个,大公司都喜欢这个,不管是男是女,也不管是应届还是N年工作经验,一身职业装给人的感觉就是很好。小公司的话,干净整洁的着装就OK了,但如果你要应聘的是一个高级职位,最好还是正式一点,虽然不一定要领带,但是衬衫、西裤、皮鞋、公文包一样别少(给一个小tips,这对“价格面议”有帮助哦)。

第三,形象。就算再怎么不修边幅,洗脸、刷牙、梳头还是要注意一下的。油脂分泌旺盛的,面试之前用面纸擦擦脸;喜欢抽烟的,面试之前嚼嚼口香糖。

第四,自信。你可以表现得很自信,但是不要表现得自负;你可以表现得很自谦,但是不要表现得很自卑。我去网易面试的时候,我开价1000,他问我为什么,我说:“首先我不是学销售的,虽然我做过,也做得很好,但您并不能了解这些,为了让贵公司放心,我先就要这么多,我相信如果我做得好的话,公司是会给我加薪的”,没想到他皱了一下眉头,说“你怎么说也是一个研究生,而且在IT行业也混得挺好,现在来我们公司做销售,不仅放弃了你最擅长的行业,而且月薪还只要求1000,你就不后悔吗?”(就这样,我没能去网易做市场策划,但我不死心,在现在的公司,我已经努力的往销售方面前进了,^_^

第五,姿势。这个不仅是礼节,也是自信(或者自负、自卑)的表现。面试的时候,不要靠着椅背,不要翘二郎腿,这样的人一般都不会录用,不是我们公司这样,谁都一样,连研究生入学面试都是这样,原因很简单,这样的人太傲,今后的合作多半不愉快。腿也别晃来晃去的,太紧张了。说话的时候看着对方的眼睛,不仅表现得你很自信,而且更是一种礼貌。平视前方的话,会给人呆板与不自信的感觉,忘着天说话就更不好了。手最好五指交叉放在桌子上,不仅好看,而且可以缓解紧张的心情。

第六,握手。面试完毕的时候,不要忘了握手,因为今后可能就是同事了,就算不当这是一种礼节,也当是拉关系吧。

还有就是多用“您”来称呼。我自己倒是会很尴尬(毕竟我还年轻,被别人这样称呼自然还是有些不好意思的),但是别人可能喜欢啊,这毕竟是礼节,还是用上吧,反正说说也无所谓。

最重要的,开价的时候,直接说出你的期望值就好了,犹豫对自己是没有好处的,因为你的犹豫很可能会让你开价更低。可能会跟你当场讨价还价,自己看着办就是了(我是不会讨价还价的,因为我在买东西的时候就是这样的了,^_^)。

可能会要你问一些问题,自己要先想好。问收入的问题要么别问,要么直接了当,不然给人的印象不好,我在找工的时候,学校有个讲座就是这样教我们的。多问公司的情况、自己的职责等,这样的问题质量会比较高的。

另外,在面试之前多看看关于这个公司的一些资料,baidugoogle或者公司网站都要看看的,在被问及“你觉得我们公司怎么样”之类的问题时才好对付,而且这也是一种自我保护。

面试的时间一般不会很长,10分钟以内吧,除非对你很感兴趣,或者是由boss来面试公司的高级主管,所以要把握一切能把握的时间。

好吧,就扯这么多吧。后面我会说说对于升职、加薪、跳槽的一些看法。


google的那道数1的面试题

silver6 | 11 十月, 2005 15:38

有一个整数n,写一个函数f(n),返回0到n之间出现的"1"的个数。比如f(13)=6,现在f(1)=1,问下一个最大的f(n)=n的n是什么?

为什么f(13)=6, 因为1,2,3,4,5,6,7,8,9,10,11,12,13.数数1的个数,正好是6.

请大家写出自己的算法,并统计一些在你机器上计算出1111111110的时间。为了不影响大家的思路,我最后贴上我的程序。
原贴http://community.csdn.net/expert/topic/4211/4211591.xml

对于用字符串s表示的整数z,小于等于它的数中包含多少个1可以简单的分析s的各个位上的数值来表示出来。方法如下:
取字符串为a0a1a2a3a4a5,数字表示下标,简要举6位作为示例。比如a3位,它右边a4a5,我的算法只考虑该位对于它右边各位的影响。
定义一个递归函数int CountOne(string s)求结果
若a3=0,则对右面的贡献为CountOne(a4a5);

若a3=1,则对右面的贡献为:a4a5的值+1+CountOne(a4a5)+CountOne(a3位的权值-1)。上式中a4a5的值+1表示从100-1a4a5这些数在a3所在的百位的1的个数,CountOne(a4a5)表示从100-1a4a5这些数中a3右边各位中1的个数,CountOne(a3位的权值-1)的值表示从000-099这些数中a3右边各位中含有的1的个数。

若a3>=2则对右边的贡献为:a3本位权值+CountOne(a4a5),+CountOne(a3位的权值-1)×a3的值。上式中本位权值表示从100-199这个100个数,CountOne(a4a5)表示从a300-a3a4a5这些数中a3右边各位中1的个数,CountOne(a3位的权值-1)×a3的值表示从000-(a300-1)这些数中a3右边各位中含有的1的个数。例如a3=4,则表示从000-099,100-199,200-299,300-399这400个数中各位和十位包含的1的个数。

例如求54321中千位4对右边各位的影响,则是case3,1000+CountOne(321)+CountOne(999)×4,结果我没有算,估计正确。我测试原题中1111111110,结果正确,时间为0.012秒,硬件为p43.0,512M内存,硬件较好,不过我觉得我的算法也不麻烦,大家评议。欢迎批评,qq83508052,msn:boylezhang@hotmail.com

代码:
using System;
using System.IO;
using System.Xml;
using System.Xml.XPath;
using System.Threading;
using System.Timers;

public class Sample
{
static void Main()
{
//Application.Run(new PagingSample());
string s="";
System.Console.Write("Input N:");
s = System.Console.ReadLine();

DateTime dt1 = DateTime.Now;

int count = CountOne(s);
System.Console.WriteLine("f("+s+")={0}",count);

DateTime dt2 = DateTime.Now;
TimeSpan ts = dt2.Subtract(dt1);
System.Console.WriteLine("{0:d}",ts.ToString());
System.Console.ReadLine();
}

public static void OnTimer(Object source, ElapsedEventArgs e)
{
Console.WriteLine("Hello World!");
}


public static int CountOne( string s )
{
s= TrimZeroAHead(s);
char[] array = s.ToCharArray();
int i=0,length=array.Length ;
int n = int.Parse(s);

if(n==0)
return 0;
if(n<10&&n>0)
return 1;

char c=array[length-1];
string sub="";

int count=0;

i=0;
sub=s.Substring(i+1);
c = array[i];
if(c=='0')
{
count+=CountOne(sub);
return 0;
}
else
{
if(c=='1')
{
int a = (int)Math.Pow(10,length-i-1)-1;
string temp = a.ToString();
count += 1+int.Parse(sub)+CountOne(sub)+CountOne(temp);
//return count;

}
else
{//c>=2
int multi = int.Parse(c.ToString());
int a = (int)Math.Pow(10,length-i-1)-1;
string temp = a.ToString();
count += (a+1)+CountOne(sub)+CountOne(temp)*multi;
//return count;
}
}
return count;
}

public static string TrimZeroAHead(string s)
{
int i=0;
for(i=0;i<s.Length-1;i++)
if(s[i]!='0')
break;
return s.Substring(i);
}
}


金蝶面试

silver6 | 14 九月, 2005 18:33

笔试分为五个部分,有九页纸:java基础,j2ee应用,java开发工具,数据库知识,还有一部分(一时忘了)... 均分为选择题(单选和多选在一起)和问答题(有两道程序题)......
简单说两个: 1.java的ide开发环境(列出常见的)
2. Eclispe的 特点(简述) :偶一直用Jbuilder
3.实现session bean时,首先要(继承还是)实现那些(类还是)接口? 是多选题
4.一张表如果数据量上千万后,查询速度会慢下来...如何优化?
5.一张表(oracle)能不能放在两个表空间中?
6.常用的管理源代码的工具:多选题(我知道VSS,CVS)
7.JMS是怎么传递消息的?简述它的两种实现方式
8.简述封装,继承,多态的基本概念(和用法)..等等吧

有的地方还是比较细的,但我记不清了:就不列了 知识点儿考的也比较全: Ejb的也不少,数据库的基础知识,如共享锁, 左连接,右连接等


IT从业人员必看的10个论坛

silver6 | 14 九月, 2005 18:32

IT方面的论坛太多了,有综合,有专业,有行业,在各个论坛里混了几年,体会颇深,
以前是论坛哪里人多,往哪里去,新浪论坛,网易是经常去的,人多啊,好几十万,去了
以后才发现没有意思,没有共同的语言,于是逛专业论坛,行业论坛,终于找到了共同语
言,总结一下论坛的经验:人不在多,有仙则灵,贴不在多,有精则行,逛了大半辈子,
一个IT人发展方向一定要除了技术外,业务,理论,思想一个都不能少,于是我推荐如下
这些论坛,或许真能帮助您,做论坛,都是赔本的买卖,不收费还帮助你学习,得向斑竹
们致敬啊。
  
    以下论坛排名不分先后,还有许多业界知名的论坛,主要有点偏门,这个不做概
述,呵呵。
  
    网络技术类
  
    正好论坛
  
    http://club.kingright.com/
  
    适合人员:网络工程师,尤其是正在学习思科、华为的产品及技术的工程师
  
    这个论坛的特色是有问必答,版主全部是double CCIE,网友提出的所有问题都会
得到版主的解答。另外还有很多很搞笑的笑话,在等待专家解答之余,可以轻松一下。

www.1000bbs.com
  
    适合人员:布线/网络工程师
  
    人气很旺,特色是版面比较紧凑,综合布线这一块很权威,很窄很专,时间非常
久了,颜色比较明快,就是太低端了,
  
    评价:不错,速度一般




IT技术开发综合类
  
    http://community.csdn.net/
  
    适合人群:只适合软件开发者
  
    技术开发最全面的论坛,里面可以遇到很多牛人,版面也很全,什么J2EE,.NET
啊,该有的全上,在这里基本上可以提出任何问题,人气也是最旺的,不过一般提出的意
见都有正方两面的,所以最终解决问题,还是靠自己。
  
    评价:专业,很牛逼,就是速度慢。
  
    www.itpub.net
  
    适合人群:数据库开发人员
  
    数据库方面是非常著名的,牛人不少,不过,现在比较杂,什么都做,网络,*作
系统,行业应用,到体育贴图,当然有些也不错,人气非常高,特别是灌水方面,^_*.

  
    评价:强,速度一般;
  
    http://bbs.chinaunix.net/forum/
  
    适合人员:系统工程师
  
    这里的特色就是操作系统方面在业界是最著名的,牛人不少,目前,在数据库,
网络方面也颇有建树,当然灌水方面也不赖,呵呵,属于温柔性
  
    评价:强,速度还可以
  
    bbs.chinajavaworld.com/
  
    适合人员:JAVA开发
  
    JAVA方面非常综合的论坛了,牛人也很多,是一个难得的JAVA论坛,涉及你想象
的关于JAVA目前任何技术。
  
    评论:强,速度还可以。
  
    http://www.huihoo.com/forum/
  
    适合人员:中间件开发者
  
    人气不错,版面风格独特,在开源,中间件,工作流方面非常不错,问题讨论都
非常深刻、也很专业。
  
    评价:很好,速度一般;
  
    IT售前技术顾问综合类
  
    http://www.sysvs.com/bbs
  
    适合人员:IT售前及技术顾问
  
    业界知名的售前技术顾问论坛,比较新异的知识点,各个IT行业版快划分也比较
好,也非常专业,绝对是我稀饭(喜欢)的风格,网站风格业内罕见,也有很多专业文章
,没有地方灌水,厉害。
  
    评价:很好,速度比较快
  
  
  
    IT营销管理类
  
    http://www.topren.net/forum/index.php
  
    适合人员:企业策划,CIO
  
    业界知名的知识站点"唐人社区",信息化管理顾问可以去看看,人也很多,可惜
,都是下载,实质性内容需要改观,我记得是非常专业的网站。
  
    评价:不错,速度也还可以。
  
    IT管理综合类
  
    http://club.amteam.org/
  
    适合人群:大多数,
  
    评论类比较多,基本上在其他媒体上看到的评论,这里都会有,要想了解IT发展
的情况,就来这里看看。
  
    评价:很好,休闲工作都可以看。


赴微软面试

silver6 | 13 九月, 2005 13:30

1.写一个实现对一段字符串翻转的方法,附加一些条件,如其中包括“,”、“.”,对其设计测试用 例 。

2.对一支纸杯设计测试用例(可以是广义的杯,不一定是某一支特定功能的杯)

开发语言概念题
3.什么是反射?
4.用Singleton如何写设计模式
5.C#中的垃圾回收机制是怎样的?
6.什么是Application Pool?
7.链表和数组的区别,各有什么优缺点.
8.Remoting在客户端服务器怎么实现 ?
9.什么是友元函数?
10.用标准C如何实现多态?
11.什么是虚函数?
12.什么是抽象函数?

13.什么是内存泄漏,怎样最简单的方法判断被存泄漏 ?

英语题
14.用英文介绍一下使用C#/C++做的项目,主要功能
15.如果要与美国开电话会议,会如何与美国的工程师沟通
16.如果老板认为你的技术落后,你会怎么回答

数据库知识题
17.使用什么工具来调用存储过程
18.SQL Server的两种索引是何形式?索引的作用?索引的优缺点?
19.触发器的作用

其它知识题及问题
20.什么是Web Service?
21.什么是XML?
22.Socket怎么实现?


C/C++ C语言 一道面试题

silver6 | 13 九月, 2005 13:28

int main()
{
int i,sum;

for( i=1;i<=3,i++) sum+=i;
printf("%d",sum);

}

1 i 是在 stack中 ,还是堆中,还是静态存储区中分配?
2 程序的输出是什么


hibernate的hello word

silver6 | 10 九月, 2005 14:20

我所给的只是我当初刚开始接触hibernate时候很想要的一个简单例子和设置方法。
一直没有找到,所以现在放到这里给大家看看,(只给想要入门的一个直观的感应,呵呵)

首先当然要新建一个项目

然后在Project Properties->Paths->Required Libraries->add->new 这里定义hibernate的类库 把hibernate的lib下面的所有jar包进去 当然还有hibernate2.jar也要
然后一路ok下去就可以了。

再来就是hibernate.properties
从hibernate的src下面找到
把它拷到你项目的src目录下
(什么,你的项目没有src目录,新建一个随便的类就有src目录了)

这样一个JB下面的hibernate的开发环境就好了

然后在hibernate.properties里面设置你的数据库连接
默认是HypersonicSQL

嗯 接下来的是你最想要做的事情了 其实很简单
新建一个类Message.java
代码如下

代码:
package hello;

import java.io.Serializable;

/**
* @author getdown
* @version 1.0
*/

public class Message implements Serializable {
private Long id;
private String text;
//定义一个简单链表 指向另外的一个Message
private Message nextMessage;
public Message() {}

public Message(Long id) {
this.id = id;
}

public Message(String text) {
this.text = text;
}

public Message(Long id, String text) {
this.id = id;
this.text = text;
}

public Long getId() {
return id;
}

private void setId(Long id) {
this.id = id;
}

public String getText() {
return text;
}

public void setText(String text) {
this.text = text;
}

public Message getNextMessage() {
return nextMessage;
}

public void setNextMessage(Message nextMessage) {
this.nextMessage = nextMessage;
}

}

接下来是这个类对应的hibernate的配置文件 Message.hbm.xml

代码:
<?xml version="1.0"?>

<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 2.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
<hibernate-mapping>
<!--定义类和表的对应-->
<class
name="hello.Message"
table="Messages"
>
<!--定义ID字段和生成ID的策略 这里采用identity-->
<id name="id"
column="MESSAGE_ID"
>
<generator class="identity"/>
</id>
<!--定义里面的text字段-->
<property
name="text"
type="string">
<!--定义text字段在数据库里面生成的方法-->
<column
name="TEXT"
length="100"
not-null="true"
/>
</property>
<!--定义对象关联之间的对应关系和关联的字段-->
<many-to-one
name="nextMessage"
cascade="all"
column="NEXT_MESSAGE_ID"
/>
</class>
</hibernate-mapping>

然后就是测试类

代码:
package hello;

import net.sf.hibernate.cfg.Configuration;
import net.sf.hibernate.SessionFactory;
import net.sf.hibernate.tool.hbm2ddl.SchemaExport;
import net.sf.hibernate.Session;
import net.sf.hibernate.Query;
import net.sf.hibernate.Hibernate;
import net.sf.hibernate.type.LongType;
import net.sf.hibernate.Transaction;



/**
* @author getdown
* @version 1.0
*/

public class Hello {
public Hello() {
}

public static void main(String[] args) throws Exception {
Configuration cfg = new Configuration().addClass(Message.class);

/** 顾名思义 构建表。。。第一次运行的时候运行下面语句可以在数据库生成表
* 之后可以把下面这句去掉
* */
// new SchemaExport(cfg).create(true, true);

//先生成sessionFactory
SessionFactory sessions = cfg.buildSessionFactory();
//再从sessionFactory得到一个session
Session session = sessions.openSession();
//开始对数据库的操作



/*----对数据库的创建操作--------*/
Message message = new Message("helloWorld");
//创建一条记录
session.save(message);
//存入记录
session.flush();


/*---对数据库的查询操作---------------*/
// Message message = new Message();
// Query q = session.createQuery("from Message as message where message.id=1");
// message = (Message) q.list().get(0);
// message.getNextMessage().setText("helloNext");
// session.flush();
// session.close();
// Long id = new Long(1);
// Message message = (Message) session.find("from Message as message where message.id=?", id, Hibernate.LONG).get(0);
// System.out.println(message.getText());


// /*-------事务的处理----------------*/
// Transaction tx = session.beginTransaction();
// try {
// Message message = new Message("hello");
// session.save(message);
// session.flush();
// message = new Message("hello");
// session.save(message);
// session.flush();
// tx.commit();
// }
// catch (HibernateException ex) {
// tx.rollback();
// }

/*-------添加1000条记录时间--------------*/
// Message message;
// long start = System.currentTimeMillis();
// for(int i = 0; i < 1000; i ++) {
// message = new Message("hello");
// session.save(message);
// session.flush();
// }
// long end = System.currentTimeMillis();
// System.out.println("添加1000条记录时间---" + (end-start)/1000 + "s");



session.close();


}

}

ok了 运行一下Hello看看出来什么吧
怎么样 比起CMP的持久 hibernate的持久是不是显得很轻量级。。
还可以试试看hibernate的性能 把Hello.java的最后一段注释去掉运行看看

当然hibernate最重要的还是它的原理,还有很多很好的,很有趣的功能和O/RM设计思想等着你自己发掘。
多看看它自己的文档,可以学到很多东西,它的文档真的非常好。

天乙社区代码分析(3)Hibernate篇

silver6 | 10 九月, 2005 14:13

天乙社区代码分析(3)Hibernate篇
天乙社区代码分析(3)
Struts+Hibernate+Spring
Hibernate篇
1、数据库和*.hbm.xml文件
数据库中共包含了76个数据表,其中75个表有*.hbm.xml文件,只有一个表BBSCS_TABLEID没有相应的文件。这个表是用户自己来维护的,没有用到hibernate的映射功能来维护。
2、关于BBSCS_TABLEID表
这个表是用来保存数据库中其他75张表中的ID字段当前值的。这个表有两个字段,其中ID字段是保存对应数据表的唯一信息(ID),这个值是2用户定义的,在*.hbm.xml文件中可以找到。IDValue字段是保存数据库中其他表的ID字段的当前数值的。
这个表的建表语句如下:
CREATE TABLE BBSCS_TABLEID (
ID int(4) NOT NULL default '0',
IDValue int(13) NOT NULL default '0',
PRIMARY KEY (ID)
) TYPE=MyISAM;
对于ID和IDValue的使用,看*.hbm.xml文件的ID的generate部分,参加天乙社区代码分析(2)的第一部分。
<id column="ID" length="13" name="id" type="long" unsaved-value="null">
<generator class="net.sf.hibernate.id.TableCustomGenerator"> /
<param name="table">BBSCS_TABLEID</param> //指定保存自定义ID信息的表BBSCS_TABLEID
<param name="column">IDValue</param> //其他数据表自定义ID当前最大值在BBSCS_TABLEID中的字段
<param name="id">12</param> //当前xml文件所映射的数据表在BBSCS_TABLEID中的ID数值
<param name="increment">15</param> //ID的自增大小为15
</generator>
</id>
3、hibernate的配置信息。
配置信息保存在init.properties文件中,参加天乙社区代码分析(1)的第9部分。
由于使用了spring框架,传统的hibernate.cfg.xml和hibernatesessionFactory不在使用了,spring中已经包含了这部分的内容,开发者只需要将相关的hibernate的配置参数定义好,通过applicationContext.xml中声明hibernate的参数配置文件,hibernate的数据库连接和数据表映射文件就可以了。参加天乙社区代码分析(1)的第15部分。
4、关于数据库的多用户访问和负载平衡的问题。
系统将用户访问量比较大的数据库分成了若干个字段相同的表,其中BookMark,Friend,GuestBook,Subscibe为10个表,而Forum为20个表。通过*Factory.java文件在保存数据的时候,动态决定将数据保存在那个表中。通过传递用户ID或者是Form.getBid参数,在通过sysUtil中的getForumClassName和getClassName函数,对传递进来的参数进行10或者20的取余处理,处理的结果加上对应的表明决定将数据保存在哪一个相对应的数据表中。
例如和Forum相关操作的几个类Post.java;VotePost.java;Move.java;通过向实例化的ForumFactory传入Form.getBid参数,在通过sysUtil中的getForumClassName函数,将Form.getBid进行20的取余处理,结果在结合Forum类,生成一个对应的类,通过这个对应的类进行保存数据的操作。当Form.getBid为10的时候,对应存储数据的数据表就是Forum_10。
对于数据读取,前面的4个是通过sysUtil.getTableID函数来实现获取相应的数据表的,而Forum数据则要复杂些了。
相关文件:com.laoer.bbscs.bean.*;com.laoer.bbscs.sys.sysUtil;com.laoer.bbscs.dao.hibernate.*

天乙社区代码分析(2)源代码结构篇

silver6 | 10 九月, 2005 14:11

8月31日
三国志系列码表与字库分析
还是van写的
三国志从3代开始自带字库,而且不断的增加字的数量,也修改过很少一部分的字形,其实它的码序与big5是基本一致的.到5代,big5字基本全了.虽然这些都是dos时代的技术,但是从9代来看,自己带字库对提升显示效果还是很有帮助的,特别是要支持多内码的时候.像magicwin的字库就远不如9代的好,而且9代还对字用了反走样(其实就是使用了16色且包含透明色的调色板),效果看上去很不错
下面简单介绍一下三3~5的字符编码
我想big5码大家都应该比较熟悉了,两字节编码.第一个字节范围是a1~fe,第二个字节范围是40~7f,a1~fe.不过三国志里没有直接使用big5编码,但是它的编码顺序是基本相同的.它的第一个字节从92开始,到b0有间断,第二个字节分成很多段,分别是48~56,65~90,97~121,128~254,一共使用了188个码位
下面的对应是从第一个汉字开始的
转换代码如下
For j = 0 To 7 Step 2
If t(j) = 0 Or t(j) = 32 Then Exit For
tt = t(j + 1)
If t(j) < 176 Then
p = 1 - 188 + (188 * (t(j) - &H92)) * 2
Else
p = 11619 + (188 * (t(j) - 176)) * 2
End If
If tt > 47 Then tt = tt - 48
If t(j + 1) > 64 Then tt = tt - 7
If t(j + 1) > 96 Then tt = tt - 6
If t(j + 1) > 127 Then tt = tt - 5
p = p + tt + tt
Get #2, p, t(j)
Get #2, p + 1, t(j + 1)
Next j
其中#2是码表文件.这里有一个我处理过的码表,改变了某些编码的次序.不过限于时间,只保证人名的对应关系是正确

顺带说一下三国的字库.
它是14*16而不是一般的16*16.格式就是magicwin的那种啦,一位一个像素.
字库文件的名称是ziku.16p.
三九的是f_font.s9,开头就是big5码列表。
至于三十和三九差不多,只不过像素是倒序存放的
8:50 | 固定链接 | 评论 (0) | 引用通告 (0) | 记录它 | 游戏
三国志系列图像文件格式浅析
琅琊的Van太守写的
最近在研究早期三国志的图片格式,发现其中头像的格式是完全一致的,介绍如下:
早期(san1~san5)的头像文件名基本上是kaodata,其中san1是picdata.dat,san2是kaodata.dat,san3就是kaodata.s3,san4里面有两个,一个是kaodatap.s4,另一个是kaodata2.s4(许多都是san3的,还有一些剧情人物),文件里没有任何格式信息,全部是头像数据。头像大小san1是32*40,san2是64*40(三2的显示模式里长宽比比较变态,实际的头像是扁的),san3~san5是64*80,也就是以后的标准大小。和三6等一样,读入的数据可以直接用stretchblt显示,只是需要预先处理一下。
大家知道,bmp格式只能处理2、4、16、256色等等,而在三国志里面是用8色的,所以是用每三个字节表示8个像素。比如说三个字节是11000000,11100001,00110101,则用相应位的三个组合在一起就可以得到实际的图像数据是6,6,3,1,0,1,0,3(注:三4加强版的头像文件的末尾还有附加字节,一共有701个字节(图片的总数目),表示头像是否被修改过)
下面是调色板(BGR十六进制)
san2:000000;ff5050;5050ff;ff50ff;50f850;fff850;50f8ff;fff8ff
san3:000000;ef3f00;004fef;cf4fef;4faf0f;efbf00;00dfef;efefef
san4:001f2f;7f3f1f;1f3faf;4f7fbf;1f6f3f;8f7f3f;7fafcf;afcfcf

早期三国的头像比较少,一般就两百多个,而且仔细看,其实许多就是一个模子里做出来的,光荣还特地把类似的头像放在一起,所以看上去特别明显^_^
因为san4有水浒人物,所以头像数大大提高,达到了700以上,看来光荣也很费了一番功夫,也算是一个飞跃吧,从此各代的规模也就大致如此了

三国志battlefield的头像在grp目录下,文件名是facedat.sog,它是沿用三8并对少数人物进行修改的基础上完成的,不过它的格式略有不同
与三国志系列不同,battlefield的头像用的是16位位图,不过前面的格式信息倒和三7没有分别
一开始4个字节是文件中的头像数,其后是头像数乘以16个字节的格式信息,接下来就是位图信息,2位一个象素
格式信息还是老样子,头4个是起始pos(第一个头像是0),然后四个是大小,接着就是宽和高
另外一个不同就是battlefield的头像文件里有空位,从1~520是三国人物的头像,接下来是一些8×8的填充字,然后才是诸如成吉思汗等的头像

hm*的格式(由浮生宛若寄研究出来的,我结合自己的处理谈一下)
此文件内没有任何附加信息,全部是图像数据。这里图片不是整张存放的,而是以48*48为单位分块存放,从左上角按行一直到右下角。其中每个小块都是倒放的,具体读取可参考下面的例程:
ReDim Color(48 * 48 - 1)
For i = 0 To Height - 1
For j = 0 To Width - 1
Get #1, , Color()
StretchDIBits Picture1.hDC, j * 48, (i + 1) * 48, 48, -48, 0, 0, 48, 48, Color(0), bi, 0, vbSrcCopy
Next j
Next i

三国志8中还是用256色位图,它专门将数据部分与描述部分分离.其中调色板文件存储在P_Main.s8中,而图像数据则在g_maindy.s8
1、描述部分
Public Type BITMAPFILEHEADER
bfType As Integer
bfSize As Long
bfReserved1 As Integer
bfReserved2 As Integer
bfOffBits As Long
End Type
Type BITMAPINFOHEADER
biSize As Long
biWidth As Long
biHeight As Long
biPlanes As Integer
biBitCount As Integer
biCompression As Long
biSizeImage As Long
biXPelsPerMeter As Long
biYPelsPerMeter As Long
biClrUsed As Long
biClrImportant As Long
End Type
Type RGBQUAD
rgbBlue As Byte
rgbGreen As Byte
rgbRed As Byte
rgbReserved As Byte
End Type
Type BITMAPINFO
bmiHeader As BITMAPINFOHEADER
bmiColors(0 To 255) As RGBQUAD
End Type

普通的256色位图是以BITMAPFILEHEADER和BITMAPINFO类型开头的,其中bmiColors就是调色板,在三八里,调色板有很多,其中和脸谱有关的有一个,和宝物图像有关的有3个,如下(数字为在P_Main.s8中的偏移地址,均为普通版):
头像(5701)
宝物1(337477)
宝物2(337477+1024)
宝物3(337477+1024*2)
注意:三八里的调色板的存放顺序是BGR,实际运用的时候还要换一下(windows默认的顺序是RGB)

2、数据部分
三八里面把数据存放在g_maindy.s8中,其中(数字为第一个数据的偏移地址)大头像(160*180)(普通:8265;加强:9393),小头像(64*80)(普通:21493065;加强:24374193),宝物(120*120)(普通:53022749;加强;?)。它是连续存放图像数据的,每一份数据的长度是Width*Height。
注意:1、与普通的位图不同,三八里是从图像尾自下而上存放图像数据的,所以显示时应该倒置一下。
2、因为宝物有三种调色板,所以要分情况显示。
3、宝物有80种,头像(普通746种;加强:846种)

例程:
获取调色板
Private Sub GetPutPal()
Dim i As Long, j As Long, r As Byte, t(1023) As Byte
Open SanPath.Caption & "P_Main.s8" For Binary As #1
Get #1, 337477 + 1024 * 2, t() '5701为提取头像调色板,这里提取第二个宝物调色板
Close #1
j = 0
For i = 0 To 255
r = t(j)
t(j) = t(j + 2)
t(j + 2) = r
j = j + 4
Next i
'假设table中已经有bmiHeader部分了
Open App.Path & "table3" For Binary As #1
Put #1, 55, t()
Close #1
End Sub
选择将不同的头描述部分(假设已经将调色板从P_Main.s8提取到table和table1~3文件中)加载到bi变量中,mode(0头像,1~3宝物)
Public Sub SetPic(Optional Mode As Long = 0)
Dim a As String
a = "table"
If Mode Then a = a & Mode
Open App.Path & a For Binary As #1
Get #1, 15, bi
Close #1
End Sub
显示图像
Function SetConstant(Mode As Integer)
Select Case Mode
Case Normal
ImageSmallStartPos = 21493065
ImageLargeStartPos = 8265
TotalImage = 746
Case Power
ImageSmallStartPos = 24374193
ImageLargeStartPos = 9393
TotalImage = 846
End Select
End Function

Sub LoadPic(Optional Mode As Long = 0)
Dim i As Long, Pos As Long, Step As Long, Width As Long, Height As Long
Dim Color() As Byte
Select Case Mode
Case 0
Width = 64: Height = 80
Pos = ImageSmallStartPos
Case 1
Width = 160: Height = 180
Pos = ImageLargeStartPos
Case 2
Width = 120: Height = 120
Pos = 53022749
End Select
Step = Width * Height
Pos = Pos + ImageIndex * Step
With bi.bmiHeader
.biHeight = Height
.biWidth = Width
End With
ReDim Color(Step - 1)
Open Form1.SanPath.Caption & "g_maindy.s8" For Binary As #1
Get #1, Pos, Color()
Close #1
With Form3
StretchDIBits .Picture1.hDC, 0, Height, Width, -Height, 0, 0, Width, Height, Color(0), bi, 0, vbSrcCopy
.Picture1.Refresh
.Label1.Caption = ImageIndex
End With
End Sub
输出图像
Sub OutputPic(OutputName As String, Optional Mode As Long = 0)
Dim i As Long, Pos As Long, Step As Long, Width As Long, Height As Long
Dim Color() As Byte
ReDim Color(1077)
Open App.Path & "table" For Binary As #1
Get #1, , Color()
Close #1
If Mode = 1 Then
Color(2) = 182
Color(3) = 116
Color(18) = 160
Color(22) = 180
End If
Open OutputName For Binary As #2
Put #2, , Color()
If Mode = 0 Then
Width = 64: Height = 80
Else
Width = 160: Height = 180
End If
Step = Width * Height
Pos = ImageLargeStartPos + ImageIndex * Step + Width * (Height - 1)
ReDim Color(Width - 1)
Open Form1.SanPath.Caption & "g_maindy.s8" For Binary As #1
For i = 1 To Height
Get #1, Pos, Color()
Put #2, , Color()
Pos = Pos - Width
Next i
Close #1, #2
End Sub

最近研究了一下三九的图像格式,发现它用了三种存储格式,弄的我花了好久才搞清楚.它的一部分调色板结合到图像文件中去了,而前两代广泛使用的带s*后缀的bmp文件也少了很多.
s9素材方面最大的变化,我想可能就是音频和视频都开始使用压缩格式了,不过最关键的图像它还是以前的256色,虽然存储的格式代代不同,但还是万变不离其宗.而且它专门为图像处理编了一个dll(用了mmx,应该不再使用GDI了),可能是为了更好的渲染效果吧.它也开始全面步入DirectX,虽然从36起,它就有一个dll是专门用DirectSound处理声音,不过好像游戏里面没有用

简要的介绍一下三9的图像文件格式,希望对想利用三9资源的朋友有一点帮助
调色版(P开头的)
第一个双字是调色版总数
之后每1064个字节是不同的调色版,其中前40个是相关的信息,可以忽略,之后即是调色版数据,仍然是bgr格式存放

图像文件(G开头的)
一共三种格式,但仍然没有存放所使用的调色版的信息
第一种(类似于以前的格式):第一个双字是图片总数,从第五个字节开始存放的是图像数据的起始pos,之后即是图像数据,每个图像均有16字节的前导信息,分别是图像数据的长度(包括16字节前导信息),宽,宽(宽存放了两次),高
第二种:第一个双字是该文件的总长度.之后即是图像数据,每个图像数据也有16字节前导信息,格式同上
第三种:同上,只是文件开头包括了调色版文件,接下来就是第二种的数据(但没有总长度那个双字)

一般图像的调色版是递增的,图像文件使用的调色版文件一般与其名字差不多,但不是很有规律.

一些参考
G_still:宝物事件图片
G_ikki:单挑的场景,小人等
G_lbuild:大地图上的建筑
G_units:大地图上的小士兵
8:48 | 固定链接 | 评论 (0) | 引用通告 (0) | 记录它
通用型游戏资源提取工具之介绍
游戏资源包括了游戏的图片、文字、音乐、动画和其他数据资源。虽然很多游戏的资源都是开放的或者采用通用格式压缩的,但也不少游戏是经特殊格式打包过了,要想得到这些资源可以寻找专用的资源提取工具。但并非所有游戏都有专门的提取工具。这时可以尝试寻找一些通用的游戏资源提取工具。一般来说这样的工具都能支持大量的游戏文件格式,而且有些工具还有一个强大的功能就是可以分析未知的压缩格式并提取出里面的图片、音乐、动画等资源。同时,一些工具提供的写入功能也能令许多玩家在制作MOD、汉化游戏时事半功倍。 在向大家介绍这些工具之前先说一下采用通用ZIP压缩资源的游戏,如有遗漏,欢迎补充。   游戏名              文件后缀名 18 Wheels Of Steel: Across America   ZIPFS 18 Wheels Of Steel: Pedal To The Metal ZIPFS Against Rome              DAT Alpha Black Zero             ABZ American McGee's Alice         PK3 Battlefield 2               ZIP Blitzkrieg                PAK Brothers Pilots 4             PAK Call of Duty               PK3 Cellblock Squadrons           BOX Civilization: Call To Power        CTP Deadly Dozen              ZA Deadly Dozen 2 Pacific Theater      ZIP Defiance                DAT Desperados: Wanted Dead or Alive    PAC Dethkarz                ZIP Duke Nukem Manhatten Project     ZIPFS El Airplane               ARH Empire Earth 2             ZIP Falcon 4                ZIP Fallout Tactics              BOS Far Cry                 PAK Fire Starter               ZIP Freedom Fighters            ZIP Freedom Force vs The 3rd Reich     FF Freelancer               FLMOD Great Battles of WWII - Stalingrad    PAK Hard Truck: 18 Wheels Of Steel     ZIPFS Heavy Metal FAKK 2           ZIP Hellhog XP               A Hitman Contracts            ZIP Hitman 2 Silent Assasin         ZIP Hot Rod American Street Drag      ROD Hunting Unlimited            ZIP Imperial Glory              ZIP Itch                  PSH Jedi Knight / JK Mysteries Of The Sith  ZIP Jedi Academy / Outcast         PK3 Law And Order 3            ZIP Lionheart               DAT Master of Orion 3            MOD Medal Of Honor: Allied Assult      PK3 Monte Christo             ZIP Outfront                PAK Packmania 2              ARF Perimeter                PAK Quake 3                PK3 Return To Castle Wolfenstein      PK3 Revenant                RVI RVM RVR Richard Burns Rally           RBZ Ricochet / Ricochet Xtreme       ZIP DAT Sabotain                ZIP Serious Sam              GRO Shadow Warrior            SHR Shark: Hunting The Great White     ZIPFS Soldier Of Fortune 2          PK3 Swarm                 DAT S.W.A.T 3               RES System Shock 2            CRF Terminator 3              POD The Fall - Last Days Of Gaia       UBN Thief: The Dark Age           CRF Thief 2: The Metal Age         CRF Transport Tycoon            001 Tribes 2                ZIP Uplink                 DAT Vietnam: Line Of Sight         ZA Vampire: The Masquerade       NOB Xpand Rally              PAK XS Mark                PK1 PK2 Zoo Tycoon              ZTD 以下就简单介绍一些通用的游戏资源提取工具。 1、Magic Extractor ——游戏资源提取工具。适用于Windows XP/98,支持将近200个游戏。界面直观,简便易用。要查询它所支持的游戏和文件格式请查询:http://magicteam.ag.ru/formats.html。它还有其他的配套工具如:Magic Viewer、Magic Packer。其中Magic Packer用来将游戏资源打包压缩回去。缺点就是Magic Packer支持的游戏比Magic Extractor少了很多,并且针对每个支持的游戏要下载专门的支持文件。 Magic Extractor的截图 2、MultiEx Commander ——游戏资源提取、编辑工具。适用于Windows XP/98,支持将近200个游戏,有图片、声音、文本的预览功能。要查询它所支持的游戏和文件格式请查询:http://multiex.xentax.com/gameslist.html。其中白色字体表示该游戏的资源可以被写入。 MultiEx Commander的截图 3、Game Extractor ——游戏资源提取、编辑工具。适用于Windows/Mac OS/Linux/Unix/Solaris等各种环境。运行时需要Java Runtime Environment的支持。该工具支持约800多个游戏,提供多种格式文件的预览。完全版还有写入功能,并提供了分析工具用于分析并提取未知格式的游戏文件中的图片、声音、动画等资源。要查询它所支持的游戏和文件格式请查询:http://www.watto.org/extract/games.html#games。 Game Extractor的截图 4、Dragon Unpacker ——游戏资源提取工具。适用于Windows XP/98,支持将近130个游戏。提供图片、声音的预览和转换(特殊格式转通用格式)。要查询它所支持的游戏和文件格式请查询:http://www.elberethzone.net/index.php?page...uage=en#formats。它同时提供了一个扫描分析工具用于分析未知格式的游戏文件中的图片、声音、动画等资源。该工具没有写入功能。 Dragon Unpacker的截图 5、Game Archive UnPacker ——游戏资源提取工具,用于Total Commander(类似于Windows资源管理器的工具)的插件。必须先安装Total Commander,网上有中文版,适用于Windows XP/98。安装时有些麻烦,实际上它的使用是最方便的。大家知道XP系统引入了ZIP压缩文件夹的功能,打开ZIP文件就像打开普通文件夹一样,且在ZIP文件夹里可以直接进行各种操作。比任何压缩软件都要方便。Game Archive UnPacker插件同样可以让Total Commander实现这种功能。打开游戏资源文件就像打开普通文件夹那样简单,要提取资源,只要像平常那样copy文件就可以了。该插件支持约120个游戏,要查询它所支持的游戏和文件格式请查询:http://forrox.narod.ru/gaup_en.htm#supform。对部分游戏该工具提供了文件格式转换的功能,例如将游戏特殊格式的图片转换为通用格式的图片。该工具没有写入功能。 6、Game File Explorer ——游戏资源提取工具,提供声音、图片的预览和图片转换功能,支持约70个游戏,没有什么突出的特点。相关信息请查询:http://www.geocities.com/TimesSquare/8271/index.html 7、Wombat Game Tools ——游戏资源提取、编辑工具。支持的游戏较少,只有约50个,主要是老游戏,较新的也只有《席德梅尔的海盗》。该工具算然有文件预览、写入功能。但仍然支持的不是很好。具体请查询:http://www.szevvy.com/content.php?content.1 * 要下载这些工具请到各自作者的主页,同时我的网络硬盘也收集了这些工具,欢迎下载(点击此处进入)。 * 以上有的工具提供了扫描分析未知游戏文件压缩格式的功能。但其并非万能,成百上千个游戏能自动分析出来10几个就很不错了。而且有时只能分析出文件的一部分而已。使用时不要抱太大期望。 * 有些工具可以很好的识别同一系列游戏文件的压缩格式。例如MultiEx Commander、Game Extractor和Dragon Unpacker都支持Port Royale(海商王)的.cpr文件,它们同样也能很好的支持游戏列表中没有的Port Royale 2的.cpr文件。但Magic Extractor就不行,它可以支持Port Royale,却不能很好的支持Port Royale 2(可以打开资源文件,但不能识别完整),因此选用时应注意。 * 不少人为以上的部分工具制作了非官方插件,有些插件能大量扩展原工具所支持的游戏数量。具体请查询各主页或其下属论坛。 * 这些工具都在不停的更新中,很多新游戏会不断被加入到其中。
8:28 | 固定链接 | 评论 (0) | 引用通告 (0) | 记录它 | 游戏
8月8日
Windows 2K克隆后竟然不能启动!郁闷
最后只好重新安装了。
9:39 | 固定链接 | 评论 (0) | 引用通告 (0) | 记录它
已知和清华紫光输入法冲突的软件
Deamon 3.44简体中文
eMule 0.45b VeryCD Builder 0214
MS Visual Studio 6.0

这些软件需要先于清华紫光输入法安装。
9:26 | 固定链接 | 评论 (0) | 引用通告 (0) | 记录它 | 计算机与 Internet
7月22日
天乙社区代码分析(3)Hibernate篇
天乙社区代码分析(3)
Struts+Hibernate+Spring
Hibernate篇
1、数据库和*.hbm.xml文件
数据库中共包含了76个数据表,其中75个表有*.hbm.xml文件,只有一个表BBSCS_TABLEID没有相应的文件。这个表是用户自己来维护的,没有用到hibernate的映射功能来维护。
2、关于BBSCS_TABLEID表
这个表是用来保存数据库中其他75张表中的ID字段当前值的。这个表有两个字段,其中ID字段是保存对应数据表的唯一信息(ID),这个值是2用户定义的,在*.hbm.xml文件中可以找到。IDValue字段是保存数据库中其他表的ID字段的当前数值的。
这个表的建表语句如下:
CREATE TABLE BBSCS_TABLEID (
ID int(4) NOT NULL default '0',
IDValue int(13) NOT NULL default '0',
PRIMARY KEY (ID)
) TYPE=MyISAM;
对于ID和IDValue的使用,看*.hbm.xml文件的ID的generate部分,参加天乙社区代码分析(2)的第一部分。
<id column="ID" length="13" name="id" type="long" unsaved-value="null">
<generator class="net.sf.hibernate.id.TableCustomGenerator"> /
<param name="table">BBSCS_TABLEID</param> //指定保存自定义ID信息的表BBSCS_TABLEID
<param name="column">IDValue</param> //其他数据表自定义ID当前最大值在BBSCS_TABLEID中的字段
<param name="id">12</param> //当前xml文件所映射的数据表在BBSCS_TABLEID中的ID数值
<param name="increment">15</param> //ID的自增大小为15
</generator>
</id>
3、hibernate的配置信息。
配置信息保存在init.properties文件中,参加天乙社区代码分析(1)的第9部分。
由于使用了spring框架,传统的hibernate.cfg.xml和hibernatesessionFactory不在使用了,spring中已经包含了这部分的内容,开发者只需要将相关的hibernate的配置参数定义好,通过applicationContext.xml中声明hibernate的参数配置文件,hibernate的数据库连接和数据表映射文件就可以了。参加天乙社区代码分析(1)的第15部分。
4、关于数据库的多用户访问和负载平衡的问题。
系统将用户访问量比较大的数据库分成了若干个字段相同的表,其中BookMark,Friend,GuestBook,Subscibe为10个表,而Forum为20个表。通过*Factory.java文件在保存数据的时候,动态决定将数据保存在那个表中。通过传递用户ID或者是Form.getBid参数,在通过sysUtil中的getForumClassName和getClassName函数,对传递进来的参数进行10或者20的取余处理,处理的结果加上对应的表明决定将数据保存在哪一个相对应的数据表中。
例如和Forum相关操作的几个类Post.java;VotePost.java;Move.java;通过向实例化的ForumFactory传入Form.getBid参数,在通过sysUtil中的getForumClassName函数,将Form.getBid进行20的取余处理,结果在结合Forum类,生成一个对应的类,通过这个对应的类进行保存数据的操作。当Form.getBid为10的时候,对应存储数据的数据表就是Forum_10。
对于数据读取,前面的4个是通过sysUtil.getTableID函数来实现获取相应的数据表的,而Forum数据则要复杂些了。
相关文件:com.laoer.bbscs.bean.*;com.laoer.bbscs.sys.sysUtil;com.laoer.bbscs.dao.hibernate.*
10:58 | 固定链接 | 评论 (0) | 引用通告 (0) | 记录它
天乙社区代码分析(2)源代码结构篇
天乙社区代码分析(2)
Struts+Hibernate+Spring
源代码结构篇
1、net.sf.hibernate.id.*
系统在关于hibernate的*.hbm.xml文件中的ID字段的配置的地方,在generator类声明的地方,没有使用普通的identity参数。而是使用了一个自定义的类TableCustomGenerator。用这个类来生成,更新hibernate所需要的类。这个自定义的ID增量是15。信息保存在BBSCS_TABLEID表中。
在*.hbm.xml中,ID字段的声明如下:
<id column="ID" length="13" name="id" type="long" unsaved-value="null">
<generator class="net.sf.hibernate.id.TableCustomGenerator"> //指定自定义的GeneratorID类
<param name="table">BBSCS_TABLEID</param> //指定保存自定义ID信息的表
<param name="column">IDValue</param> //自定义ID当前最大值在数据库的BBSCS_TABLEID中的字段
<param name="id">12</param> //当前xml文件所映射的数据表在的BBSCS_TABLEID中的ID数值
<param name="increment">15</param> //ID的自增大小为15
</generator>
</id>
同时使用了一个BBSCS_TABLEID表来保存当前的表的ID值。关于这个表的说明参加天乙社区代码分析(3)的第2部分。
1.1net.sf.hibernate.id.tableID
这个类主要是维护BBSCS_TABLEID这个数据表的,同时还有一些相关的操作。在对BBSCD_TABLEID这个表的维护,主要是getNextBlock函数来实现的。而nextID和setID则是对于IDValue这个字段数值的维护,和数据表的关系不是太大了。
1.2net.sf.hibernate.id.TableCustomGenerator
这个类主要是用于生成除BBSCS_TABLEID外的数据表中的ID字段的。类中的3个函数分别生成了一些SQL语句,这些函数的参数是通过*.hbm.xml文件中的id段的generator段的param属性来传递的。还有一个generate函数,应该是对应着<generator class="net.sf.hibernate.id.TableCustomGenerator">这句话的。在这个函数中,调用了TableID类的nextID函数来实现*.hbm.xml文件中所映射的数据表的ID字段的自增维护的,自增的大小是通过<param name="increment">15</param>这句来传递的。对应数据表在BBSCS_TABLEID表中的ID标识是通过<param name="id">12</param>这句来传递的。
这个类的格式,应该是hibernate所约定的,具体的可以参考hibernate的reference和源代码。
2 com.laoer.bbscs.bean.*
保存了和hibernate相关的一些文件
2.1 *.hbm.xml
保存了除BBSCS_TABLEID以外的75个数据库的映射
2.2 保存了和*.hbm.xml相对应的75个数据库基类文件。
2.3 BookMark.java是BookMark*.java的基类
2.4 Friend.java是Friend*.java的基类
2.5 Forum.java是Forum*.java的基类
2.6 GuestBook.java是GuestBook*.java的基类
2.7 Subscibe.java是Subscibe*.java的基类
2.8 *Factory.java这5个文件通过sysunit中的getForumClassName和getClassName函数来实现多用户并发访问的数据库分配和负载平衡的。参见天乙社区代码分析(3)的第4部分
3 com.laoer.bbscs.business.*和com.laoer.bbscs.business.service.*
3.1com.laoer.bbscs.business.*中的I*Service.java是com.laoer.bbscs.business.service.*的interface,只是声明了类的一些函数而已。
3.1.1这里面声明的函数是和com.laoer.bbscs.dao.*里面的函数相对应的。在com.laoer.bbscs.dao.*里面实现的是数据逻辑,这里面实现的是业务逻辑。而数据和业务逻辑的关联则是在applicationcontext.xml中实现的。
3.1.2其中UserInfoServiceImp.java文件中的UserInfoServiceImp类里面的代码使用了纯hibernate技术,没有使用spring的hibernate支持,而在
com.laoer.bbscs.business.service.UserInfoSeviceImp中类里面的代码使用了spring的hibernate支持。我想由于作者对代码维护的原因造成的。而在applicationcontext.xml中关于UserInfo类所引用的数据相关操作使用的是UserInfoSeviceImp,所以这个文件可以忽略它了。并没有在代码中起到实际的作用。
3.2com.laoer.bbscs.business.service.*
3.2.1这里面有3个jbx文件,可以不用管,觉得和jbuilder有关系的。
3.2.2*ServiceImp.java是从I*Service.java集成下来的,用来实现一些具体业务访问的类。
4 com.laoer.bbscs.dao.*和com.laoer.bbscs.dao.hibernate.*
4.1com.laoer.bbscs.dao.*中的I*DAO.java是com.laoer.bbscs.dao.hibernate.*的interface,只是声明了类的一些函数而已。这里面声明的函数将要实现一些数据逻辑。
4.2com.laoer.bbscs.dao.hibernate.*
主要实现了具体的数据逻辑访问
4.2.1数据保存
通过getHibernateTemplate().saveOrUpdate()函数来实现的。
4.2.2读取一条记录
通过getHibernateTemplate().get()函数来实现。
4.2.3查找一条记录
通过getHibernateTemplate().find()函数来实现的。
4.2.4删除一条记录
通过getHibernateTemplate().delete()函数来实现的。
4.2.5返回一个结果集
和一般的hibernate操作相同,通过CreateQuery()函数来返回一个list。
4.3相关的hibernate操作参加spring的API文档中org.springframework.orm.hibernate和org.springframework.orm.hibernate.support部分。
5 com.laoer.bbscs.lucene.*和com.laoer.bbscs.lucene.html.*
这里面的类定义应该都是来源于apache的一个工程的。主要是提供了一个全文检索的功能,不知道作者是不是改写了其中的部分源码。
5.1 com.laoer.bbscs.lucene.*
5.1.1 com.laoer.bbscs.lucene.IndexHTML在SysListener.java和IndexTimerTask.java两个类中用到的。
5.1.2 com.laoer.bbscs.lucene.HTMLDocument在com.laoer.bbscs.lucene.html.*中的很多类都用到了。
5.2 com.laoer.bbscs.lucene.html.*

6 com.laoer.bbscs.sys.*和com.laoer.bbscs.sys.mail.*
6.1com.laoer.bbscs.sys.*
一些通用的系统类
6.2com.laoer.bbscs.sys.mail.*
和邮件操作相关的类
7.com.laoer.bbscs.web.*
7.1com.laoer.bbscs.web.action.*
struts的action相关的文件
7.2com.laoer.bbscs.web.form.*
struts的form相关的文件
7.3com.laoer.bbscs.web.servlet.*
web.xml配置用到的相关文件
7.4com.laoer.bbscs.web.tag.*
taglib用到的相关文件
8 com.laoer.comm.*
一些作者写的通用的类文件。开发过程中可能会经常用到的。
8.1 com.laoer.comm.db.*
一些使用纯hibernate技术而不是用spring中的hibernate支持写的代码,在这个web程序中都没有用到。
8.2 com.laoer.comm.util.*
8.2.1 com.laoer.comm.util.FileIO
对文件的读写操作,程序中很多地方都用到了。主要是读取bbscs.xml等几个配置文件里面的信息。
8.2.2 com.laoer.comm.util.DES
DES加密算法,在com.laoer.bbscs.web.action.AdminBaseInfo中用到。
8.2.3 com.laoer.comm.util.message
字符串资源操作函数,在很多地方都用到的。
8.2.4 com.laoer.comm.util.SysProperties
在这个程序中没有用到
8.2.5 com.laoer.comm.util.Util
一些通用的函数,在很多地方用到了。比如Base64编码解码,一些字符串的操作函数。
8.3 com.laoer.comm.web.*
8.3.1 com.laoer.comm.web.EncodeingFilter
对于URL的编码函数,将ASCII转换成UTF-8编码。在web.xml中用到。
8.3.2 com.laoer.comm.web.pages和com.laoer.comm.web.PageList
对于返回一个数据集的分页操作函数

天乙社区代码分析(1)配置文件篇

silver6 | 10 九月, 2005 14:09

天乙社区代码分析(1)
Struts+Hibernate+Spring
配置文件篇
1、Web.xml
1.0路径:WEB-INF
1.1Web的配置文件
1.2声明Spring的接口: contextConfigLocation
1.3关于EncodingFilter:通过com.laoer.comm.web.EncodingFilter类,替换服务器默认的Filter容器,设置Filter编码为UTF-8,实现中文支持。相关代码com.laoer.comm.web.EncodingFilter
1.4listener,目前作用不详。应该和确定系统配置文件有关。相关代码com.laoer.bbscs.web.servlet.SysListener。
1.5servlet
1.5.1action,实现Struts接口支持
1.5.2sysloadservlet,目前作用不祥,感觉是加载board。相关代码com.laoer.bbscs.web.servlet.SysLoadServlet。
1.5.3authimg,生成用户登录页面认证码图片,相关代码com.laoer.bbscs.web.servlet.AuthImg。
1.5mapping,定义map的映射
1.6welcome-file-list,定义默认页面为index.jsp和indx.htm
1.7error-page,定义了5种错误返回的页面
1.8taglib,定义了struts所需要的taglib和一个用户自定义标签。
2、tiles-defs.xml
2.0路径:WEB-INF
2.1程序使用了tile技术。程序声明了若干个tile模板,在使用的时候调用。
3、validation.xml
3.0路径:WEB-INF
3.1程序使用了validation技术,对用户注册页面进行了校验。
3.2username:校验用户姓名的是否存在,掩码,最大和最小长度。
3.3nickname:校验用户昵称是否存在,最大和最小长度。
3.4email:校验电子邮箱是否存在,最大和最小长度。
3.5passwd:校验用户口令是否存在,最大和最小长度。
3.6repasswd:校验二次用户口令是否存在,最大和最小长度。
3.7question:校验用户问题是否存在,最大和最小长度。
3.8answer:校验用户问题答案是否存在,最大和最小长度。
3.9在多参数传递的时候,使用了arg0,arg1,arg2......这种方式,而不是arg position = 0这种方式,本质上是没有区别的。
3.10对于passwd和repasswd的相同校验,没有在validation中实现,目前还不知道使用的什么办法。
4、validator-rules.xml
4.0路径:WEB-INF
4.1由于程序使用struts1.1和validator1.0,所以在校验的声明及定义的方式上有所区别。这个文件应该是validator所自带的。
5、struts-config.xml
5.0路径:WEB-INF
5.1Struts的配置文件
5.2声明了4个global-forwards。
5.3声明了message-resources
5.4声明了tile和validator的插件接口
5.5关于form-beans和action-mappings没有过多的需要说明的地方。
6、bbscs.tld
6.0路径:WEB-INF
6.1用户自定义的JSP Tag Library,声明了一些标签。以后可能的话,在详细研究。标签所对应的代码保存路径:com.laoer.bbscs.web.tag.*
7、admininfo.properties
7.0路径:WEB-INFclasses
7.1保存管理员用户和口令的地方。在使用管理员功能的时候校验用户和口令的地方。
8、configpath.properties
8.0路径:WEB-INFclasses
8.1保存配置信息路径的地方。在Web.xml中声明listener的脚本中调用过一次。参加第1部分
8.2系统配置文件是bbscs.xml,参加第11部分
9、init.properties
9.0路径:WEB-INFclasses
9.1定义hibernate相关的参数,包括数据库连接等一些配置信息。
10、log4j.properties
10.0路径:WEB-INFclasses
10.1定义hibernate的配置信息。
11、bbscs.xml
11.0路径:WEB-INFclasses
11.1保存论坛的一些配置信息的地方。
12、forbid.xml
12.0路径:WEB-INFclasses,发布后保存在bbscs.jar中
12.1保存过滤IP和过滤关键词的地方。
13、oscache.properties
13.0路径:src,发布后保存在bbscs.jar中
13.1定义memory caching的地方
14、commons-logging.properties
14.0路径:src
14.1指定用log4j替换org.apache.commons.logging.Log
15、applicationContext.xml
15.0路径:src,发布后保存在bbscs.jar中
15.1spring的配置文件
15.2placeholderConfig,定义spring的初始化信息文件为/init.properties
15.3dataSource,读取init.properties中的数据库配置信息,同时声明并赋值数据库连接。
15.4mySessionFactory,定义数据库连接所对应的hibernate的数据表配置文件。是数据库和数据表关联。同时从init.properties中读取一些关于hibernate的配置信息,给hibernate赋值。
15.5后面是声明所有的业务逻辑的bean。
16、ApplicationResources.properties和AppMessage.properties
16.0路径:src,发布后保存在bbscs.jar中
16.1系统用到的字符串资源文件

学习Java的30个基本概念

silver6 | 10 九月, 2005 08:22

在我们学习Java的过程中,掌握其中的基本概念对我们的学习无论是J2SE,J2EE,J2ME都是很重要的,J2SE是Java的基础,所以有必要对其中的基本概念做以归纳,以便大家在以后的学习过程中更好的理解java的精髓,在此我总结了30条基本的概念.

  Java概述:
  目前Java主要应用于中间件的开发(middleware)---处理客户机于服务器之间的通信技术,早期的实践证明,Java不适合pc应用程序的开发,其发展逐渐变成在开发手持设备,互联网信息站,及车载计算机的开发.Java于其他语言所不同的是程序运行时提供了平台的独立性,称许可以在windows,solaris,linux其他操作系统上使用完全相同的代码.Java的语法与C++语法类似,C++/C程序员很容易掌握,而且Java是完全的彻底的面向对象的,其中提出了很好的GC(Garbage Collector)垃圾处理机制,防止内存溢出.
  Java的白皮书为我们提出了Java语言的11个关键特性.
  (1)Easy:Java的语法比C++的相对简单,另一个方面就是Java能使软件在很小的机器上运行,基础解释其和类库的支持的大小约为40kb,增加基本的标准库和线程支持的内存需要增加125kb.
  (2)分布式:Java带有很强大的TCP/IP协议族的例程库,Java应用程序能够通过URL来穿过网络来访问远程对象,由于servlet机制的出现,使Java编程非常的高效,现在许多的大的web server都支持servlet.
  (3)OO:面向对象设计是把重点放在对象及对象的接口上的一个编程技术.其面向对象和C++有很多不同,在与多重继承的处理及Java的原类模型.
  (4)健壮特性:Java采取了一个安全指针模型,能减小重写内存和数据崩溃的可能性。
  (5)安全:Java用来设计网路和分布系统,这带来了新的安全问题,Java可以用来构建防病毒和防攻击的System.事实证明Java在防毒这一方面做的比较好.
(6)中立体系结构:Java编译其生成体系结构中立的目标文件格式可以在很多处理器上执行,编译器产生的指令字节码(Javabytecode)实现此特性,此字节码可以在任何机器上解释执行.
  (7)可移植性:Java中对基本数据结构类型的大小和算法都有严格的规定所以可移植性很好.
  (8)多线程:Java处理多线程的过程很简单,Java把多线程实现交给底下操作系统或线程程序完成.所以多线程是Java作为服务器端开发语言的流行原因之一
  (9)Applet和servlet:能够在网页上执行的程序叫Applet,需要支持Java的浏览器很多,而applet支持动态的网页,这是很多其他语言所不能做到的.
  基本概念:
  1.OOP中唯一关系的是对象的接口是什么,就像计算机的销售商她不管电源内部结构是怎样的,他只关系能否给你提供电就行了,也就是只要知道can or not而不是how and why.所有的程序是由一定的属性和行为对象组成的,不同的对象的访问通过函数调用来完成,对象间所有的交流都是通过方法调用,通过对封装对象数据,很大限度上提高复用率.
  2.OOP中最重要的思想是类,类是模板是蓝图,从类中构造一个对象,即创建了这个类的一个实例(instance)
  3.封装:就是把数据和行为结合起在一个包中)并对对象使用者隐藏数据的实现过程,一个对象中的数据叫他的实例字段(instance field)
  4.通过扩展一个类来获得一个新类叫继承(inheritance),而所有的类都是由Object根超类扩展而得,根超类下文会做介绍.
  5.对象的3个主要特性
  behavior---说明这个对象能做什么.
  state---当对象施加方法时对象的反映.
  identity---与其他相似行为对象的区分标志.
  每个对象有唯一的indentity 而这3者之间相互影响.
6.类之间的关系:
  use-a :依赖关系
  has-a :聚合关系
  is-a :继承关系--例:A类继承了B类,此时A类不仅有了B类的方法,还有其自己的方法.(个性存在于共性中)
  7.构造对象使用构造器:构造器的提出,构造器是一种特殊的方法,构造对象并对其初始化.
  例:Data类的构造器叫Data
  new Data()---构造一个新对象,且初始化当前时间.
  Data happyday=new
  Data()---把一个对象赋值给一个变量happyday,从而使该对象能够多次使用,此处要声明的使变量与对象变量二者是不同的.new返回的值是一个引用.
  构造器特点:构造器可以有0个,一个或多个参数
  构造器和类有相同的名字
  一个类可以有多个构造器
  构造器没有返回值
  构造器总是和new运算符一起使用.
  8.重载:当多个方法具有相同的名字而含有不同的参数时,便发生重载.编译器必须挑选出调用哪个方法.
  9.包(package)Java允许把一个或多个类收集在一起成为一组,称作包,以便于组织任务,标准Java库分为许多包.java.lang java.util java,net等,包是分层次的所有的java包都在java和javax包层次内.
  10.继承思想:允许在已经存在的类的基础上构建新的类,当你继承一个已经存在的类时,那么你就复用了这个类的方法和字段,同时你可以在新类中添加新的方法和字段.
  11.扩展类:扩展类充分体现了is-a的继承关系. 形式为:class (子类) extends (基类).
  12.多态:在java中,对象变量是多态的.而java中不支持多重继承.
13.动态绑定:调用对象方法的机制.
  (1)编译器检查对象声明的类型和方法名.
  (2)编译器检查方法调用的参数类型.
  (3)静态绑定:若方法类型为priavte static final 编译器会准确知道该调用哪个方法.
  (4)当程序运行并且使用动态绑定来调用一个方法时,那么虚拟机必须调用x所指向的对象的实际类型相匹配的方法版本.
  (5)动态绑定:是很重要的特性,它能使程序变得可扩展而不需要重编译已存代码.
  14.final类:为防止他人从你的类上派生新类,此类是不可扩展的.
  15.动态调用比静态调用花费的时间要长,
  16.抽象类:规定一个或多个抽象方法的类本身必须定义为abstract例: public abstract string getDescripition
  17.Java中的每一个类都是从Object类扩展而来的.
  18.object类中的equal和toString方法.equal用于测试一个对象是否同另一个对象相等.toString返回一个代表该对象的字符串,几乎每一个类都会重载该方法,以便返回当前状态的正确表示.(toString 方法是一个很重要的方法)
  19.通用编程:任何类类型的所有值都可以同object类性的变量来代替.
  20.数组列表:ArrayList动态数组列表,是一个类库,定义在java.uitl包中,可自动调节数组的大小.
  21.class类 object类中的getclass方法返回ckass类型的一个实例,程序启动时包含在main方法的类会被加载,虚拟机要加载他需要的所有类,每一个加载的类都要加载它需要的类.
  22.class类为编写可动态操纵java代码的程序提供了强大的功能反射,这项功能为JavaBeans特别有用,使用反射Java能支持VB程序员习惯使用的工具.能够分析类能力的程序叫反射器,Java中提供此功能的包叫Java.lang.reflect反射机制十分强大.
  1.在运行时分析类的能力.
  2.在运行时探察类的对象.
  3.实现通用数组操纵代码.
  4.提供方法对象.
  而此机制主要针对是工具者而不是应用及程序.
  反射机制中的最重要的部分是允许你检查类的结构.用到的API有:
  java.lang.reflect.Field 返回字段.
  java.reflect.Method 返回方法.
  java.lang.reflect.Constructor 返回参数.
  方法指针:java没有方法指针,把一个方法的地址传给另一个方法,可以在后面调用它,而接口是更好的解决方案.
23.接口(Interface)说明类该做什么而不指定如何去做,一个类可以实现一个或多个interface.
  24.接口不是一个类,而是对符合接口要求的类的一套规范.若实现一个接口需要2个步骤:
  1.声明类需要实现的指定接口.
  2.提供接口中的所有方法的定义.
  声明一个类实现一个接口需要使用implements 关键字class actionB implements Comparable 其actionb需要提供CompareTo方法,接口不是类,不能用new实例化一个接口.
  25.一个类只有一个超类,但一个类能实现多个接口.Java中的一个重要接口Cloneable
  26.接口和回调.编程一个常用的模式是回调模式,在这种模式中你可以指定当一个特定时间发生时回调对象上的方法.例:ActionListener 接口监听.
  类似的API有:java.swing.JOptionPane
        java.swing.Timer
        java.awt.Tookit
  27.对象clone:clone方法是object一个保护方法,这意味着你的代码不能简单的调用它.
  28.内部类:一个内部类的定义是定义在另一个内部的类
  原因是:1.一个内部类的对象能够访问创建它的对象的实现,包括私有数据
  2.对于同一个包中的其他类来说,内部类能够隐藏起来.
  3.匿名内部类可以很方便的定义回调.
  4.使用内部类可以非常方便的编写事件驱动程序.
  29.代理类(proxy):1.指定接口要求所有代码 2.object类定义的所有的方法(toString equals)
  30.数据类型:Java是强调类型的语言,每个变量都必须先申明它都类型,java中总共有8个基本类型.4种是整型,2种是浮点型,一种是字符型,被用于Unicode编码中的字符,布尔型.

英语口语

silver6 | 09 九月, 2005 14:01

最常用的英语口语

1. I see. 我明白了。
2. I quit! 我不干了!
3. Let go! 放手!
4. Me too. 我也是。
5. My god! 天哪!
6. No way! 不行!
7. Come on. 来吧(赶快)
8. Hold on. 等一等。
9. I agree。 我同意。
10. Not bad. 还不错。
11. Not yet. 还没。
12. See you. 再见。
13. Shut up! 闭嘴!
14. So long. 再见。
15. Why not? 好呀! (为什么不呢?)
16. Allow me. 让我来。
17. Be quiet! 安静点!
18. Cheer up! 振作起来!
19. Good job! 做得好!
20. Have fun! 玩得开心!
21. How much? 多少钱?
22. I’m full. 我饱了。
23. I’m home. 我回来了。
24. I’m lost. 我迷路了。
25. My treat. 我请客。
26. So do I. 我也一样。
27. This way。 这边请。
28. After you. 您先。
29. Bless you! 祝福你!
30. Follow me. 跟我来。
31. Forget it! 休想! (算了!)
32. Good luck! 祝好运!
33. I decline! 我拒绝!
34. I promise. 我保证。
35. Of course! 当然了!
36. Slow down! 慢点!
37. Take care! 保重!
38. They hurt. (伤口)疼。
39. Try again. 再试试。
40. Watch out! 当心。
41. What’s up? 有什么事吗?
42. Be careful! 注意!
43. Bottoms up! 干杯(见底)!
44. Don’t move! 不许动!
45. Guess what? 猜猜看?
46. I doubt it 我怀疑。
47. I think so. 我也这么想。
48. I’m single. 我是单身贵族。
49. Keep it up! 坚持下去!
50. Let me see.让我想想。
51. Never mind.不要紧。
52. No problem! 没问题!
53. That’s all! 就这样!
54. Time is up. 时间快到了。
55. What’s new? 有什么新鲜事吗?
56. Count me on 算上我。
57. Don’t worry. 别担心。
58. Feel better? 好点了吗?
59. I love you! 我爱你!
60. I’m his fan。 我是他的影迷。
61. Is it yours? 这是你的吗?
62. That’s neat. 这很好。
63. Are you sure? 你肯定吗?
64. Do l have to 非做不可吗?
65. He is my age. 他和我同岁。
66. Here you are. 给你。
67. No one knows . 没有人知道。
68. Take it easy. 别紧张。
69. What a pity! 太遗憾了!
70. Any thing else? 还要别的吗?
71. To be careful! 一定要小心!
72. Do me a favor? 帮个忙,好吗?
73. Help yourself. 别客气。
74. I’m on a diet. 我在节食。
75. Keep in Touch. 保持联络。
76. Time is money. 时间就是金钱。
77. Who’s calling? 是哪一位?
78. You did right. 你做得对。
79. You set me up! 你出卖我!
80. Can I help you? 我能帮你吗?
81. Enjoy yourself! 祝你玩得开心!
82. Excuse me,Sir. 先生,对不起。
83. Give me a hand! 帮帮我!
84. How’s it going? 怎么样?
85. I have no idea. 我没有头绪。
86. I just made it! 我做到了!
87. I’ll see to it 我会留意的。
88. I’m in a hurry! 我在赶时间!
89. It’s her field. 这是她的本行。
90. It’s up to you. 由你决定。
91. Just wonderful! 简直太棒了!
92. What about you? 你呢?
93. You owe me one.你欠我一个人情。
94. You’re welcome. 不客气。
95. Any day will do. 哪一天都行夕
96. Are you kidding? 你在开玩笑吧!
97. Congratulations! 祝贺你!
98. T can’t help it. 我情不自禁。
99. I don’t mean it. 我不是故意的。
100. I’ll fix you Up. 我会帮你打点的.


1. I see. 我明白了。
2. I quit! 我不干了!
3. Let go! 放手!
4. Me too. 我也是。
5. My god! 天哪!
6. No way! 不行!
7. Come on. 来吧(赶快)
8. Hold on. 等一等。
9. I agree。 我同意。
10. Not bad. 还不错。
11. Not yet. 还没。
12. See you. 再见。
13. Shut up! 闭嘴!
14. So long. 再见。
15. Why not? 好呀! (为什么不呢?)
16. Allow me. 让我来。
17. Be quiet! 安静点!
18. Cheer up! 振作起来!
19. Good job! 做得好!
20. Have fun! 玩得开心!
21. How much? 多少钱?
22. I’m full. 我饱了。
23. I’m home. 我回来了。
24. I’m lost. 我迷路了。
25. My treat. 我请客。
26. So do I. 我也一样。
27. This way。 这边请。
28. After you. 您先。
29. Bless you! 祝福你!
30. Follow me. 跟我来。
31. Forget it! 休想! (算了!)
32. Good luck! 祝好运!
33. I decline! 我拒绝!
34. I promise. 我保证。
35. Of course! 当然了!
36. Slow down! 慢点!
37. Take care! 保重!
38. They hurt. (伤口)疼。
39. Try again. 再试试。
40. Watch out! 当心。
41. What’s up? 有什么事吗?
42. Be careful! 注意!
43. Bottoms up! 干杯(见底)!
44. Don’t move! 不许动!
45. Guess what? 猜猜看?
46. I doubt it 我怀疑。
47. I think so. 我也这么想。
48. I’m single. 我是单身贵族。
49. Keep it up! 坚持下去!
50. Let me see.让我想想。
51. Never mind.不要紧。
52. No problem! 没问题!
53. That’s all! 就这样!
54. Time is up. 时间快到了。
55. What’s new? 有什么新鲜事吗?
56. Count me on 算上我。
57. Don’t worry. 别担心。
58. Feel better? 好点了吗?
59. I love you! 我爱你!
60. I’m his fan。 我是他的影迷。
61. Is it yours? 这是你的吗?
62. That’s neat. 这很好。
63. Are you sure? 你肯定吗?
64. Do l have to 非做不可吗?
65. He is my age. 他和我同岁。
66. Here you are. 给你。
67. No one knows . 没有人知道。
68. Take it easy. 别紧张。
69. What a pity! 太遗憾了!
70. Any thing else? 还要别的吗?
71. To be careful! 一定要小心!
72. Do me a favor? 帮个忙,好吗?
73. Help yourself. 别客气。
74. I’m on a diet. 我在节食。
75. Keep in Touch. 保持联络。
76. Time is money. 时间就是金钱。
77. Who’s calling? 是哪一位?
78. You did right. 你做得对。
79. You set me up! 你出卖我!
80. Can I help you? 我能帮你吗?
81. Enjoy yourself! 祝你玩得开心!
82. Excuse me,Sir. 先生,对不起。
83. Give me a hand! 帮帮我!
84. How’s it going? 怎么样?
85. I have no idea. 我没有头绪。
86. I just made it! 我做到了!
87. I’ll see to it 我会留意的。
88. I’m in a hurry! 我在赶时间!
89. It’s her field. 这是她的本行。
90. It’s up to you. 由你决定。
91. Just wonderful! 简直太棒了!
92. What about you? 你呢?
93. You owe me one.你欠我一个人情。
94. You’re welcome. 不客气。
95. Any day will do. 哪一天都行夕
96. Are you kidding? 你在开玩笑吧!
97. Congratulations! 祝贺你!
98. T can’t help it. 我情不自禁。
99. I don’t mean it. 我不是故意的。
100. I’ll fix you Up. 我会帮你打点的.




101. It sounds great!. 听起来很不错。
102. It’s a fine day。 今天是个好天。
103. So far,So good. 目前还不错。
104. What time is it? 几点了?
105. You can make it! 你能做到!
106. Control yourself! 克制一下!
107. He came by train. 他乘火车来。
108. He is ill in bed. 他卧病在床。
109. He lacks courage. 他缺乏勇气。
110. How’s everything? 一切还好吧?
111. I have no choice. 我别无选择。
112. I like ice-cream. 我喜欢吃冰淇淋。
113. I love this game. 我钟爱这项运动。
114. I’ll try my best. 我尽力而为。
115. I’m On your side. 我全力支持你。
116. Long time no see! 好久不见!
117. No pain,no gain. 不劳无获。
118. Well,it depends 噢,这得看情况。
119. We’re all for it. 我们全都同意。
120. What a good deal! 真便宜!
121. What should I do? 我该怎么办?
122. You asked for it! 你自讨苦吃!
123. You have my word. 我保证。
124. Believe it or not! 信不信由你!
125. Don’t count on me.别指望我。
126. Don’t fall for it! 别上当!
127. Don’t let me down. 别让我失望。
128. Easy come easy go. 来得容易,去得快。
129. I beg your pardon. 请你原谅。
130. I beg your pardon? 请您再说一遍(我没有听清)。
131. I’ll be back soon. 我马上回来。
132. I’ll check it out. 我去查查看。
133. It’s a long story. 说来话长。
134. It’s Sunday today. 今天是星期天。
135. Just wait and see! 等着瞧!
136. Make up your mind. 做个决定吧。
137. That’s all I need. 我就要这些。
138. The view is great. 景色多么漂亮!
139. The wall has ears. 隔墙有耳。
140. There comes a bus. 汽车来了。
141. What day is today? 今天星期几?
142. What do you think? 你怎么认为?
143. Who told you that? 谁告诉你的?
144. Who’s kicking off? 现在是谁在开球?
145. Yes,I suppose So. 是的,我也这么认为。
146. You can’t miss it 你一定能找到的。
147. Any messages for me? 有我的留言吗?
148. Don’t be so modest. 别谦虚了。
149. Don’t give me that! 少来这套!
150. He is a smart boy. 他是个小机灵鬼。
151. He is just a child. 他只是个孩子。
152. I can’t follow you. 我不懂你说的。
153. I felt sort of ill. 我感觉有点不适。
154. I have a good idea! 我有一个好主意。
155. It is growing cool. 天气渐渐凉爽起来。
156. It seems all right. 看来这没问题。
157. It’s going too far. 太离谱了。
158. May I use your pen? 我可以用你的笔吗?
159. She had a bad cold. 她患了重感冒。
160. That’s a good idea. 这个主意真不错。
161. The answer is zero. 白忙了。
162. What does she like? 她喜欢什么?
163. As soon as possible! 越快越好!
164. He can hardly speak. 他几乎说不出话来。
165. He always talks big. 他总是吹牛。
166. He won an election. 他在选举中获胜。
167. I am a football fan. 我是个足球迷。
168. If only I could fly. 要是我能飞就好了。
169. I’ll be right there. 我马上就到。
170. I’ll see you at six. 我六点钟见你。
171. IS it true or false? 这是对的还是错的?
172. Just read it for me. 就读给我听好了。
173. Knowledge is power. 知识就是力量。
174. Move out of my way! 让开!
175. Time is running out. 没时间了。
176. We are good friends. 我们是好朋友。
177. What’s your trouble? 你哪儿不舒服?
178. You did fairly well! 你干得相当不错1
179. Clothes make the man. 人要衣装。
180. Did you miss the bus? 你错过公共汽车了?
181. Don’t lose your head。 不要惊慌失措。
182. He can’t take a joke. 他开不得玩笑。
183. He owes my uncle $100.他欠我叔叔100美元。
184. How are things going? 事情进展得怎样?
185. How are you recently? 最近怎么样?
186. I know all about it. 我知道有关它的一切。
187. It really takes time. 这样太耽误时间了。
188. It’s against the law. 这是违法的。
189. Love me,love my dog. (谚语)爱屋及乌。
190. My mouth is watering. 我要流口水了。
191. Speak louder,please. 说话请大声点儿。
192. This boy has no job. 这个男孩没有工作。
193. This house is my own. 这所房子是我自己的。
194. What happened to you? 你怎么了?
195. You are just in time. 你来得正是时候。
196. You need to workout. 你需要去运动锻炼一下。
197. Your hand feels cold. 你的手摸起来很冷。。
198. Don’t be so childish. 别这么孩子气。
199. Don’t trust to chance! 不要碰运气。
200. Fasten your seat belt. 系好你的安全带。



201. He has a large income. 他有很高的收入。
202. He looks very healthy. 他看来很健康。
203. He paused for a reply. 他停下来等着·回答。
204. He repaired his house. 他修理了他的房子。
205. He suggested a picnic. 他建议搞一次野餐。
206. Here’s a gift for you. 这里有个礼物送给你。
207. How much does it cost? 多少钱?
208. I caught the last bus. 我赶上了最后一班车。
209. I could hardly speak. 我简直说不出话来。
210. I’ll have to try that. 我得试试这么做。
211. I’m very proud of you. 我为你感到非常骄傲。
212. It doesn’t make sense. 这没有意义(不合常理)。
213. Make yourself at home. 请不要拘礼。
214. My car needs washing. 我的车需要洗一洗。
215. None of your business! 与你无关!
216. Not a sound was heard. 一点声音也没有。
217. That’s always the case. 习以为常了。
218. The road divides here. 这条路在这里分岔。
219. Those are watermelons. 那些是西瓜。
220. What a nice day it is! 今天天气真好!
221. What’s wrong with you? 你哪里不对劲?
222. You are a chicken. 你是个胆小鬼。
223. A lovely day,isn’t it? 好天气,是吗?
224. He is collecting money. 他在筹集资金。
225. He was born in New York. 他出生在纽约。
226. He was not a bit tired. 他一点也不累。
227. I will be more careful. 我会小心一些的,
228. I will never forget it. 我会记着的。
229. It is Just what I need. 这正是我所需要的。
230. It rather surprised me. 那事使我颇感惊讶。
231. Just around the comer. 就在附近。
232. Just for entertainment. 只是为了消遣一下。
233. Let bygones be bygones. 过去的,就让它过去吧。
234. Mother doesn’t make up. 妈妈不化妆。
235. Oh,you are kidding me. 哦,你别拿我开玩笑了。
236. She has been to school. 她上学去了。
237. Skating is interesting. 滑冰很有趣。
238. Supper is ready at six. 晚餐六点钟就好了。
239. That’s a terrific idea! 真是好主意!
240. What horrible weather! 这鬼天气!
241. Which would you prefer? 你要选哪个?
242. Does she like ice-cream? 她喜欢吃冰淇淋吗?
243. First come first served. 先到先得。
244. Great minds think alike. 英雄所见略同。
245. He has a sense of humor. 他有幽默感。
246. He is acting an old man. 他正扮演一个老人。
247. He is looking for a job. 他正在找工作。
248. He doesn’t care about me. 他并不在乎我。
249. I develop films myself. 我自己冲洗照片。
250. I felt no regret for it. 对这件事我不觉得后悔。
251. I get up at six o’clock. 我六点起床。
252. I meet the boss himself. 我见到了老板本人。
253. I owe you for my dinner. 我欠你晚餐的钱。
254. I really enjoyed myself. 我玩得很开心。
255. I’m fed up with my work! 我对工作烦死了!
256. It’s no use complaining. 发牢骚没什么用。
257. She’s under the weather. 她心情·不好。
258. The child sobbed sadly. 小孩伤心地抽泣着。
259. The rumor had no basis. 那谣言没有·根据。
260. They praised him highly. 他们大大地表扬了他。
261. Winter is a cold season. 冬天是一个,寒冷的季节。
262. You can call me any time. 你可以随时打电话给我。
263. 15 divided by3 equals 5. 15除以3等于5。
264. All for one,one for all. 我为人人,人人为我。
265. East,west,home is best. 金窝,银窝,不如自己的草窝。
266. He grasped both my hands. 他紧握住我的双手。
267. He is physically mature. 他身体己发育成熟。
268. I am so sorry about this. 对此我非常抱歉(遗憾)。
269. I can’t afford a new car. 我买不起一部新车。
270. I do want to see him now. 我现在确实很想去见他。
271. I have the right to know. 我有权知道。
272. I heard some one laughing. 我听见有人在笑。
273. I suppose you dance much. 我想你常常跳舞吧。
274. I walked across the park. 我穿过了公园。
275. I’ll just play it by ear. 我到时随机应变。
276. I’m not sure I can do it. 恐怕这事我干不了。
277. I’m not used to drinking. 我不习惯喝酒。
278. Is the cut still painful? 伤口还在痛吗?
279. It’s too good to be true! 好得难以置信。
280. Jean is a blue-eyed girl. 珍是个蓝眼睛的女孩。
281. Let’s not waste our time. 咱们别浪费时间了。
282. May I ask some questions? 我可以问几个问题吗?
283. Money is not everything. 金钱不是一切。
284. Neither of the men spoke. 两个人都没说过话。
285. Stop making such a noise. 别吵了。
286. That makes no difference. 没什么区别。
287. The price is reasonable. 价格还算合理。
288. They crowned him king. 他们拥立他为国王。
289. They’re in red and white. 他们穿着红白相间的衣服。
290. We all desire happiness. 我们都想要幸福。
291. We just caught the plane 我们刚好赶上了飞机。
292. What shall we do tonight? 我们今天晚上去干点儿什么呢?
293. What’s your goal in life 你的人生目标是什么?
294. When was the house built? 这幢房子是什么时候建造的?
295. Why did you stay at home? 为什么呆在家里?
296. Would you like some help? 今天真漂亮!
297. You mustn’t aim too high 你不可好高骛远。
298. You’re really killing me! 真是笑死我了!
299. You’ve got a point there. 你说得挺有道理的。
300. Being criticized is awful! 被人批评真是痛苦!




301. Did you enter the contest? 你参加比赛了吗?
302. Do you accept credit cards? 你们收信用卡吗?
303. Don’t cry over spilt milk. 不要做无益的后悔。
304. Don’t let chances pass by. 不要让机遇从我们身边溜走。
305. He owned himself defeated. 他承认自己失败了。
306. He seems at little nervous. 他显得有点紧张。
307. He strolls about the town. 他在镇上四处遛达。
308. Her tooth ached all night. 她牙疼了一整夜。
309. How about a drink tonight? 今晚喝一杯怎样?
310. I can do nothing but that. 我只会做那件事。
311. I get hold of you at last. 我终于找到你了。
312. I have a surprise for you. 我有一个意想不到的东西给你看。
313. I like all kinds of fruit. 我喜欢各种各样的水果。
314. I saw it with my own eyes. 我亲眼所见。
315. I will arrange everything. 我会安排一切的。
316. I wish I knew my neighbor. 我很想认识我的邻居。
317. I would like to check out. 我想结帐。
318. It has be come much cooler. 天气变得凉爽多了。
319. It’s time you went to bed. 你早就该睡觉了。
320. No spitting on the street. 禁止在大街上吐痰。
321. She was totally exhausted. 她累垮了。
322. Show your tickets,please. 请出示你的票。
323. Thank you for your advice. 谢谢你的建议。
324. That’s the latest fashion. 这是最流行的款式。
325. The train arrived on time. 火车准时到达。
326. There go the house lights. 剧院的灯光灭了。
327. They are paid by the hour. 他们按时取酬。
328. Things are getting better. 情况正在好转。
329. Wake me up at five thirty. 请在五点半叫醒我。
330. We are all busy with work. 我们都忙于工作。
331. Where do you want to meet? 你想在哪儿见面?
332. You can get what you want. 你能得到你想要的。
333. A barking dog doesn’t bite! 吠犬不咬人。
334. Are you free this Saturday? 你这个星期六有空吗?
335. Be careful not to fall ill. 注意不要生病了。
336. Being a mother is not easy. 做一个母亲是不容易的。
337. Brevity is the soul of wit. 简洁是智慧的精华。
338. Cancer is a deadly disease. 癌症是一种致命的疾病。
339. Did you fight with others? 你又和别人打架了吗?
340. Don’t dream away your time. 不要虚度光阴。
341. Don’t keep me waiting long. 不要让我等得太久。
342. He has a remarkable memory. 他有惊人的记忆力。
343. He has completed the task. 他完成了这个任务。
344. He has quite a few friends. 他有不少的朋友。
345. He is capable of any crime. 他什么样的坏事都能干得出来。
346. He walks with a quick pace. 他快步走路。
347. He was not a little tired. 他很累。
348. His looks are always funny. 他的样子总是滑稽可笑。
349. How about going to a movie? 去看场电影怎么样?
350. I think I’ve caught a cold. 我想我得了感冒。
351. I was taking care of Sally. 我在照顾萨莉。
352. I wish I lived in NEWYORK. 我希望住在纽约。
353. I’m very glad to hear that. 很高兴听你这样说。
354. I’m your lucky fellow then. 我就是你的幸运舞伴啦!
355. It’s none of your business! 这不关你的事儿!
356. No littering on the campus. 在校园内不准乱丢废物。
357. She is a good-looking girl. 她是一个漂亮女孩。
358. She mended the broken doll. 她修补了破了的洋娃娃。
359. So I just take what I want. 那么我只拿我所需要的东西。
360. Spring is a pretty season, 春天是一个好季节。
361. The figure seems all Right. 数目看起来是对的。
362. The stars are too far away. 星星太遥远了。
363. The whole world knows that. 全世界都知道。
364. Tomorrow will be a holiday. 明天放假。
365. We walk on the garden path. 我们走在花园小径上。
366. What you need is just rest. 你需要的就是休息。
367. What’s your favorite steps? 你最喜欢跳什么舞?
368. You’d better let her alone. 你们最好是让她一个人呆会儿。
369. A lost chance never returns. 错过的机会永不再来。
370. Don’t let this get you down. 不要为此灰心丧气。
371. He shot the lion with a gun. 他用枪把狮子打死了。
372. I don’t think you are right. 我认为你是不对的。
373. I have never seen the movie. 我从未看过那部电影。
374. I haven’t seen you for ages. 我好久没见到你了。
375. I was alone,but not lonely. 我独自一人,但并不觉得寂寞。
376. I went there three days ago. 我三天前去过那儿。
377. It’s a friendly competition. 这是一场友谊赛。
378. It’s very thoughtful of you. 你想得真周到。
379. May I speak to Lora,please? 我能和劳拉说话吗?
380. Mr.Wang is fixing his bike. 王先生在修他的自行车。
381. My brother is see king a job. 我弟弟正在找工作。
382. Nancy will retire next year. 南希明年就退休了。
383. Neither you nor he is wrong. 你没错,他也没错。
384. Opportunity knocks but once. 机不可失,时不再来。
385. She dressed herself hastily. 她匆忙穿上衣服。
386. She hired a car by the hour. 她租了一辆按钟点计费的汽车。
387. Someone is ringing the bell. 有人在按门铃。
388. The Smiths are my neighbors. 史密斯一家是我的邻居。
389. These shoes don’t fit right. 这双鞋不太合适。
390. This is only the first half. 这才是上半场呢。
391. This pen doesn’t write well. 这钢笔不好写。
392. Would you like a cup of tea? 你想喝杯茶吗?
393. You really look sharp today. 你今天真漂亮。
394. Another cat came to my house. 又有一只猫来到我家了。
395. Check your answers with mine. 把你的答案跟我的核对一下。
396. Don’t keep the truth from me. 别瞒着我事实真相。
397. Everything has its beginning. 凡事都有开端。
398. He came to the point at once. 他一下子就说到了点子上。
399. He fell behind with his work. 他工作落后了。
400. He is the happiest man alive. 他是世界上最快乐的人。



401. He neither smokes nor drinks. 他既不抽烟也不喝酒。
402. He ran his horse up the hill. 他策马跑上小山。
403. He reminds me of his brother. 他使我想起了他的弟弟。
404. He was efficient in his work. 他工作效率高。
405. He will do anything but work. 只要不是干活,他干什么都行。
406. His father runs a restaurant. 他的父亲经营一家餐馆。
407. I have something to tell you. 我有事要告诉你。
408. I smelled a smell of cooking. 我闻到了烧菜做饭的味道。
409. I want to see the film again. 我真想再看一遍。
410. I’ve got too much work to do. 我要做的工作太多了。
411. Let’s go for a walk,shall we? 咱们出去走走,好吗?
412. Please let me check the bill. 请让我核对一下帐单。
413. Plenty of sleep is healthful. 充足的睡眠有益于健康。
414. The sun comes up in the east. 太阳从东方升起。
415. This is because we feel pain. 这是因为我们能感到疼痛。
416. What do you desire me to do? 你想要我做什么?
417. What you said was quite true. 你所说的完全符合事实。
418. You can either stay or leave. 你或者留下或者离开。
419. Your life is your own affair. 你的生活是你自己的事。
420. All that glitters is not gold. 发闪光的不全是黄金。
421. Are you going to have a party? 你要举行聚会吗?
422. Aren’t you concerned about it? 难道你不担心吗?
423. Don’t forget to keep in touch. 别忘了保持联系。
424. He broke his words once again. 他又一次违背了诺言。
425. He is in his everyday clothes. 他穿着平常的衣服。
426. He is taller than I by ahead. 他比我高一头。
427. He led them down the mountain. 他带他们下山。
428. He was trained to be a lawyer. 他被培养成一名律师。
429. I am afraid that l have to go. 我要走了。
430. I don’t have any cash with me. 我身上没带现金。
431. I have been putting on weight. 我开始发胖了。
432. I have just finished the book. 我刚刚读完这本书。
433. I was late for work yesterday, 我昨天上班迟到了。
434. It appears to be a true story. 这故事似乎是真的。
435. I’ve got to start working out. 我必须开始做健身运动了。
436. Japan is to the east of China. 日本在中国的东部。
437. John asked Grace to marry him, 约翰向格雷斯求婚。
438. My watch is faster than yours. 我的表比你的表快。
439. New China was founded in l949. 1949年新中国成立。
440. Thanks for your flattering me. 多谢你的夸奖。
441. They charged the fault on him. 他们把过失归咎于他。
442. This car is in good condition. 这车性能很好。
443. This work itself is very easy. 这件工作本身很容易。
444. Truth is the daughter of time. 时间见真理。
445. We look forward to your visit. 期待您的光临。
446. What do you think of this one? 您觉得这个怎么样子
447. What’s the weather like to day? 今天天气怎么样?
448. A red tie will match that suit. 红领带会配那件衣服。
449. A wet road is usually slippery. 潮湿的路往往是滑的。
450. Example is better than precept。 身教胜于言传。
451. Go right back to the beginning. 直接回到起始位置。
452. He does everything without aim. 他做事都漫无目标。
453. He is respectful to his elders. 他对长辈很恭敬。
454. He knows English better than I. 他比我懂英语。
455. He resolved to give up smoking. 他决心戒烟。
456. His talk covered many subjects. 他的报告涉及很多课题。
457. I fear that he drinks too much. 我担心他喝的酒太多了。
458. I have my hair cut every month. 我每个月都理发。
459. I want to have a part-time job. 我想有一份兼职工作。
460. I’m sorry to have bothered you. 对不起,打扰你了。
461. It is not so easy as you think. 这事没有你想象的那么简单。
462. Keep your temper under control. 不要发脾气。 .
463. Lying and stealing are immoral. 说谎和偷窃都是不道德的。
464. My efforts resulted in nothing. 我的努力毫无结果。
465. My false teeth are stuck to it. 我的假牙还在上边呢!
466. She is a composer for the harp. 她是位写竖琴曲的作曲家
467. Take me to the airport,please. 请送我去机场。
468. Talking with you is a pleasure. 和你谈话很愉快
469. The eggs are sold by the dozen. 鸡蛋按打卖。
470. The price just covers the cost. 这个价格正好抵消成本。
471. The sweater is of good quality. 这件毛衣质地很好。
472. The teacher got a little angry. 老师有点生气了。
473. Think carefully before you act. 三思而后行。
474. Walt invented the steam engine. 瓦特发明了蒸汽机。
475. We are divided in our opinions. 我们意见分歧。
476. What ever I said,he’d disagree. 不论我说什么他都不同意。
477. Who ever comes will be welcomed. 来的人我们都欢迎。
478. You look as if you didn’t care. 你看上去好像满不在乎。
479. You should look at it yourself. 你应该亲自看看它。
480. Draw your chair up to the table. 把你的椅子拉到桌子旁边来。
481. He covered himself with a quilt. 他给自己盖上一条被。
482. He found my lecture interesting. 他觉得我讲课有趣。
483. He had a good many friends here. 他在这儿有很多朋友。
484. He is only about five feet high. 他大概只有五英尺高。
485. Her family are all music lovers. 她全家人都是音乐爱好者。
486. I am busy.How is your business? 我很忙。你的生意做得怎样?
487. I don’t think much of the movie. 我认为那电影不怎么样。
488. I feel like eating an ice-cream. 我想吃一个冰淇淋。
489. I found him seated on the bench. 我发现他在椅子上坐着
490. I gave much time to the old car. 我在这辆破车上花了不少时间。
491. I lost the door key about here. 我在这附近掉了门钥匙。
492. I’m not guessing,I really know. 我不是在猜想,我真的知道。
493. It’s time to tell her the truth. 是该告诉她真相的时候了。
494. Let’s watch TV with a candle on. 咱们点上蜡烛看电视吧。
495. Most games cost about that much. 大部分游戏差不多都是这个价钱。
496. My parents want me to go abroad. 我父母想让我出国。
497. She has been collecting stamps. 她一直收集邮票。
498. There are many stars in the sky. 天上有很多星星。
499. We get to London this afternoon. 我们是今天下午到达伦敦的。
500. What about having a pizza first? 先吃点比萨饼怎么样?



501. You’d better look before you leap. 你最好三思而后行。
502. You know what I’m talking about. 我想你知道我在说什么。
503. He has been sick for three weeks. 他已经病了几周了。
504. He inspected the car for defects. 他详细检查车子有无效障。
505. I count you as one of my friends 我把你算作我的一个朋友。
506. I go to school by bike every day. 我每天骑自行车上学。
507. I have a large collection of CDs. 我收集了很多唱片。
508. I won’t be able to see him today. 今天我不可能去看他。
509. I’ll call a taxi in case of need. 如果需要的话,我会叫出租车的。
510. Is there any sugar in the bottle 瓶子里还有糖吗
511. It’s a secret between you and me. 这是你我之间的秘密。
512. It’s very kind of you to help me. 你帮助我真是太好了。
513. Let’s divide the cake into three. 我们将蛋糕分成三份吧。
514. Patience is a mark of confidence. 耐心是自信心的一种表现。
515. Susan is going to finish college. 苏珊将完成大学学业。
516. That is my idea about friendship. 这是我关于友谊的看法。
517. The book you ask for is sold out. 你要的那本书已经售完了。
518. The boy was too nervous to speak. 那男孩紧张得说不出话来。
519. The play may begin at any moment. 戏随时都有可能开始。
520. The salve will heal slight burns. 这种药膏能治疗轻微烧伤。
521. The sea sparkled in the sunlight. 阳光下,大海波光粼粼。
522. The teacher tested us in English. 老师用英文考我们。
523. There is a bridge over the river. 河上有一座桥。
524. They rode their respective bikes. 他们各自骑着自己的自行车。
525. They will arrive in half an hour. 他们将于半小时之内到达。
526. Time is more valuable than money. 时间比金钱宝贵。
527. We are all in favor of this plan. 我们都赞同这项计划。
528. We reached London this afternoon. 我们是今天下午到达伦敦的。
529. We two finished a bottle of wine. 我俩喝完了一瓶酒。
530. what a lovely little girl she is! 她是一个多么可爱的小女孩耶!
531. Will you pick me up at my place 你能到我的住处来接我吗
532. You may choose whatever you like. 你可以喜欢什么就选什么。
533. You’re suffering from an allergy 你过敏吗
534. Beyond all questions you are right. 毫无疑问,你是对的。
535. But I plan to weed the yard today. 我计划今天除院子里的草。
536. But who will do all the house work 但是这些家务活谁来做呢
537. Close the door after you,please. 请随手关门。
538. Come to see me whenever you like。 你可以随时来见我。
539. Don’t pull the chairs about,boys! 不要把椅子拖来拖去,孩子们!
540. He drives more carefully than you. 他开车比你小心。
541. He invited me to dinner yesterday. 他昨天请我吃晚饭了。
542. He struck his attacker on the ear. 他打了那个攻击者一耳光。
543. He suddenly appeared in the party. 他突然在晚会上出现了。
544. Her handbag goes with her clothes. 她的手袋和她的衣服很搭配。
545. Here we are.Row M, seats l and 3. 哦,到了。M排,l号和3号。
546. His boss might get angry with him. 他的老板也许会生他的气。
547. I expect to be there this evening. 我打算今天晚上到那儿去。
548. I really need to lose some weight. 我真的需要减肥了。
549. I think you have the Wrong number. 我想你打错号码了。
550. I would rather stay at home alone. 我宁愿独自呆在家。
551. I’d like to look at some sweaters. 我想看看毛衣。
552. Its origin is still a mystery now. 它的起源至今仍是个谜。
553. Money is no more than our servant. 金钱不过是我们的仆人。
554. Once you begin,you must continue. 一旦开始,你就得继续。
555. She is poor but quite respectable. 她虽穷,人品却很端正。
556. She spent a lot of money on books. 她花了很多钱来买书。
557. The girl in red is his girlfriend. 穿红衣服的那个女孩是他的女朋友。
558. There is a chair below the window. 窗户下面有一把椅子。
559. They employed him as a consultant. 他们雇用他为顾问。
560. To be honest with you,I’m twenty. 老实说,我20岁。
561. We often call him by his nickname. 我们经常叫他的绰号。
562. Will you be free tomorrow evening 你明晚有空吗
563. Would you like to leave a message 你要留话吗
564. You can never turn the clock back. 时光不能倒流。
565. You may as well tell me the truth. 你还是把事实告诉我为好。
566. Are your grandparents still living 你的祖父母还在么
567. Can you recognize that woman,Mary 你能认出那个女人是谁了吗,玛丽
568. Do you have any suggestions for me 你对我有什么建议么
569. He is tough,but I am even tougher. 他是一个硬汉子,不过我要比他更硬。
570. He made his way through the forest. 他设法穿过了森林。
571. He suggests you leave here at once. 他建议你立刻离开这儿。
572. He was married to a friend of mine. 他和我的一个朋友结了婚。
573. He will blame you for carelessness. 他会责备你的粗心大意。
574. I can give you a number of excuses. 我可以给你说出很多韵理由。
575. I don’t doubt that he will help me. 我不怀疑他会援助我。
576. I hope you enjoy your stay with us. 希望您在这儿过的愉快。
577. I’d like to-repair our differences. 我愿意消除一下我们之间的分歧。
578. It’s nothing to be surprised about. 这事不值得大惊小怪。
579. It’s rude to stare at other people. 盯着别人看是不礼貌的。
580. Bob has always had a crush on Lucy. 鲍伯一直在爱着露茜。
581. Let’s take a short break for lunch. 让我们休息一会儿,去吃午饭。
582. Linda speaks as if she were a boss. 琳达说话总好象她是老板。
583. She became more and more beautiful. 她变得越来越漂亮了。
584. Suppose it rains,what shall we do 万一下雨,我们该怎么办
585. The book is protected by copyright. 该书受版权保护。
586. The ice is hard enough to skate on. 冰已经厚得可以划冰了。
587. The price includes postage charges. 价格包括邮资在内。
588. This is a little something for you. 这是我给你们的一点心意。
589. What he likes best is making jokes. 他最喜欢开玩笑。
590. Who but Jack would do such a thing 除了杰克谁会做这种事呢
591. You should have a mind of your own. 你必须有自己的主见。
592. You will soon get used to the work. 你很快就会习惯于这项工作的。
593. Columbus discovered America in l492. 哥伦布于1492年发现了美洲。
594. God helps those who he1p themse



701. His cake is three times bigger than mine.他的蛋糕比我的大三倍。
702. I am looking forward to your early reply. 希望早日得到你的答复。
703. I could say nothing but that I was sorry.我除了说“对不起”之外,什么也说不出来。
704. I don’t know how to express my gratitude. 我不知道怎样来表达我的感激之情。我要赶飞机
705. I have to catch a plane. Could you hurry?你能快点吗?我好久没有她的消息了。
706. I haven’t heard from her for a long time.我好久没有她的消息了。
707. I would like to wash the clothes for you. 我愿意帮你洗这些衣服。
708. Let me see your driver’s license, please. 请让我看看你的驾驶执照。
709. She goes to work every day except Sunday. 除星期天外,他每天去上班。
710. Take a seat please, make yourself at home.请坐,随便一点。
711. The damage was caused by external forces. 损害是由外力引起的。
712. The doctor advised me to give up smoking.医生建议我戒烟。
713. The flowers make the room more beautiful.花使房间变得更加美了。
714. There is a good restaurant on the street.那条大街上有一个很好的餐馆。
715. They covered 120 miles in a single night.他们仅一夜就走了120英里路。
716. Try to look on the bright side of things.尽量从好的方面看。
717. What’s your plan for the summer vacation?你暑假打算干什么?
718. You may pick whichever one you like best.你可以挑你最喜欢的。
719. You’re welcome to stay with us next time.欢迎您下次再光临我们的饭店。
720. There was a murder in London yesterday. 昨天伦敦发生了一起谋杀案。
721. They stared at the huge tiger with awe. 他们敬畏地看着那头巨虎。
722. He never misses a chance to see a movie.他从不错过看电影的机会。
723. I cannot put up with my noisy roommates.我受不了我那些吵闹的室友了。
724. I will be back by the end of next month.我下个月底会回来。
725. I’m good at freestyle and breast stroke.我擅长自由泳和蛙泳。
726. It was your turn to wash them yesterday. 昨天轮到你把它们洗干净。
727. Let’s go out to have a dinner, shall we?咱们出去吃饭吧,好吗?
728. Please push the ladder against the wall.请把梯子靠在墙壁上。
729. She is standing in the front of the bus.她站在公共汽车的前部。
730. The doctor asked me to watch what I eat.医生要我注意饮食。
731. The grass is moist early in the morning.清晨的草地湿漉漉的。
732. The test finished. We began our holiday.考试结束了,我们开始放假。
733. This question is too complicated for me.这个问题对我说来太复杂了。
734. Tony speaks English and he plays tennis.托尼会说英语,打网球。
735. What is worth doing is worth doing well.只要你觉得某事值得去做,就一定要把它做好。
736. Would you like to go to a party with me?你想不想和我一起去参加一个聚会?
737. All at once, a rabbit came out of a hole.突然,一只兔子从一个洞中跑了出来。
738. All characters in the book are imaginary.书中所有的人物都是虚构的。
739. Do you feel like going to that new disco? 你想去那个新开的迪厅
740. Ducks know how to swim when they are born.鸭子天生会游泳
741. He spent most of his life gathering money.他一生大部分时间用来积聚钱财。
742. He usually stays at home with his pet dog.他通常跟他的爱犬待在家里。
743. How peaceful and beautiful the country is!多么平静美丽的国家呀!
744. I am told that you dance wonderfully well.我听说你的舞跳得特棒。
745. I have had several conversations with him.我已经和他谈过几次了。
746. It is the best film that I have ever seen.这是我所看过的最好的电影。
747. It’s only a party in honor of my birthday.这只是为了庆祝我的生日而举行的晚会。
748. Learning English is like building a house.学英语象盖房子。
749. Listening with your heart is good for you.专心聆听别人说话对你有好处。
750. My grandpa died of hunger in the old days. 我爷爷在旧社会死于饥饿。
751. She feared staying alone in the farmhouse. 她害怕一个人留在农舍里。
752. She guided the tourists around the castle.她引导旅游者参观了这座城堡。
753. She runs everyday in order to lose weight.她每天都跑步是为了减肥。
754. She sang perfectly in the hall last night.她昨晚在大厅唱得非常好。
755. Somebody is always complaining to others.有人总是向别人抱怨。
756. They don’t often have a bad day this year.他们今年的运气还不错。
757. We regard the matter as nothing important. 我们认为这件事情不重要。
758. We’ll take our holiday sometime in August. 我们将在八月份的某个时候休假。
759. Could you direct me to the station, please?请问到车站怎么走?
760. Have you cleared your luggage with customs ?你的行李通关了吗?
761. He bothered me with a great many questions.他对我提了一大堆问题,真烦!
762. He does exercises every day in the morning.他每天早上锻练身体。
763. How do I control myself? I can’t calm down.我怎能控制我自己?我无法冷静下来。
764. I dig songs and I like pop music very much.我特别喜欢歌曲和流行音乐。
765. I’d like to cash a traveler’s check please.我想兑换旅行支票。
766. I’d like to pick sea shells this afternoon.今天下午我想去捡贝壳。
767. It’s odd that they didn’t reply our letter.他们没有给我们回信,这真奇怪。
768. John seldom gets together with his friends.约翰很少与朋友聚在一起。
769. Many people have been out of work recently.最近有许多人失业。
770. Please give my best regards to your family.请代我向你们全家致以最诚挚的问候。
771. Some people have compared books to friends.有些人把书比作朋友。
772. The bat together with the balls was stolen.球拍和球全被偷了。
773. The color of her dress suits her very well.她衣服的颜色很适合她。
774. The days get longer and the nights get shorter.白天变长了,黑夜变短了。
775. The dress doesn’t fit her. She is too thin.这件衣服不适合她,她太瘦了。
776. The examination put a lot of stress on him.那次考试给了他很大的压力。
777. The mother sat the child at a little table.母亲安排孩子坐到小桌旁。
778. There is some difference between the twins.这对双胞胎有点儿不一样。
779. They insisted on staying rather than going.他们坚持留下来,而不愿意走
780. Trust me, the game is really worth playing.相信我,这游戏确实值得一玩。
781. Unlike her friends, she never gave up hope.与她的朋友的不同之处是,她从不放弃希望。
782. Well done! You are always doing a good job!干得不错!你总是干得很出色!
783. We’re planning a tour to Italy this summer.我们计划今年夏天到意大利去旅行。
784. Were there any letters for me this morning?今天早上有我的信吗?
785. Why isn’t Mrs. Lee’s cat catching the mice?李太太的猫为何不在抓这些老鼠呢?
786. Your English is improving little by little.你的英语正在渐渐提高。
787. Could you tell me where I can wash my hands?请问洗手间怎么走?
788. Do you have any plans for the long weekend?你有办法打发这个漫长的周末吗?
789. He decided to bring a suit against his boss.他决定起诉他的老板。
790. He devoted his life to the study of science.他把毕生献给科学研究。
791. He had to choose between death and dishonor.他不得不在死亡和耻辱之间选择。
792. His previous attempts had been unsuccessful.他以前的尝试没有成功。
793. I determined that nothing should be changed.我决定什么都不改变。
794. I don’t think it will lead to a good result.我认为这事不会有什么好结果。
795. I have 4 books and 2 magazines to check out.我有4本书和2本杂志要借。
796. I think I’ve filled in everything correctly.我想各项都填对了。
797. I’m not sure whether I have locked the door.我没把握是否锁了门。
798. It took him a little time to fix that watch.他很快就把表修理好了。
799. My father is at home looking for the ticket.我爸爸正在家里找票呢!
800. Not until last week did I get a work permit.直到上周我才拿到工作许可证。
801. She intends to make teaching her profession.她想以教书为职业。
802. The letter "x" stands for an unknown number.字母x代表未知数。
803. The sight of the dead body scared him stiff.看到尸体把他吓僵了。
804. There are lots of huge buildings in Beijing.在北京有许多高大的建筑物。
805. There is an interesting film on Channel one.在一频道有一部有趣的电影。
806. They plan to immigrate to Finland next year.他们计划明年移居芬兰。
807. We enjoyed driving along the new expressway.我们喜欢沿着新建的高速公路开车。
808. We need to cooperate perfectly to win the game.要想赢得比赛,我们需要密切配合。
809. We need more than listening. We need action!我们需要的不光是听得进意见,我们要的是行动。
810. Yes. I wouldn’t go home early if I were you.是的,如果我是你,我不会早回家。
811. Your answer is satisfying. I feel satisfied.你的答案是令人满意的。我感到很满意。
812. Betty and Susan are talking on the telephone.贝蒂和苏珊正在通电话。
813. Great efforts ensure the success of our work.巨大的努力确保了我们工作的成功。
814. He has tasted the sweets and bitters of life.他已尝遍了人生的甜酸苦辣。
815. He said he was educated in the United States.他说他是在美国受的教育。
816. How do you like our English literature Prof.?你觉得我们的英国文学课的教授怎么样?
817. I am looking forward to your visit next week.我期待着你下周来访。
818. I feel I am the happiest person in the world.我觉得自己是世界上最幸福的人了。
819. I had to sit up all night writing the report.我不得不熬通宵写报告。
820. I hope we can see each other again some time.希望还能有相见的机会。
821. I saw him playing football on the playground.我看见他在操场上踢足球。
822. It is tomorrow that they will have a meeting.就在明天(而不是在别的某一天)他们要开会。
823. Let me tell you some details about clearance.让我告诉你一些通关的细节。
824. The brain needs a continuous supply of blood.大脑需要连续不断地供血。
825. The doctor’s words made him feel comfortable.医生的话让他感觉很舒服。
826. The truth is quite other than what you think.事实真相和你所想的完全不同。
827. They stopped talking when their boss came in.当老板进来的时候;他们停止了交谈。
828. They were glad of the examination being over.他们为考试结束了而高兴。
829. This is by far the largest cake in the world.这是目前世界上最大的蛋糕了。
830. Whichever you choose, you won’t be satisfied.不论你选择哪一个,你都不会满意。
831. Will you connect this wire to the television ?你把这根电线和电视机连上好吗?
832. His words are strongly impressed on my memory.他的话深深地铭记在我的心头。
833. Is this the fight bus for the Capital Library?这辆车到首都图书馆吗?
834. One third of this area is covered with forest.这一地区三分之一的地方都是森林。
835. They are arguing over who should pay the bill.他们为谁应该付款而争论不休。
836. Wait a moment, I’ll be with you in an instant.等一下,我立刻就来。
837. You’ll save time not waiting for the elevator.你可以节省等电梯的时间。
838. A clear conscience laughs at false accusation.只要问心无愧,无端的指责可以一笑置之。
839. I have a headache, and she has a stomachache.我头疼,她胃疼。
840. He glared at Bill, ready to teach him a lesson.他怒视着比尔,准备教训他一顿。
841. I assure you that you will feel no pain at all.我保证你根本不会觉得疼的。
842. I can’t afford to go to a restaurant every day.每天都去餐馆吃饭,我真是支付不起。
843. I left at 6:00 so that I could catch the train.我六点钟出门,以便赶上火车。
844. I’m afraid I have some rather bad news for you.我恐怕有些很坏的消息要告诉你。
845. Learn to say the fight thing at the fight time.学会在适当的时候说适当的话。
846. No wonder you can’t sleep when you eat so much.你吃这么多难怪睡不着。
847. Please ask her to call me back when she’s back.她回来时请让她给我回个电话。
848. There are a lot of people in the swimming pool.游泳池里挤满了人。
849. They have to work hard to support their family.他们必须努力工作来支持他们的家。
850. This way, he can kill two birds with one stone.这样他就能两全其美。
851. We are all taking medicine against the disease.我们都服药治疗疾病。
852. Would you please go to a dancing party with me?请你跟我一起去参加一个舞会好吗?
853. He usually drops in at my place on his way home.他常常在回家的路上顺便来看看我。
854. His vanity was hurt by their talking so frankly.他们坦率的谈话伤害了他的虚荣心。
855. How would you go to Beijing, by air or by train?你怎样去北京,是乘飞机还是坐火车?
856. I cannot express how glad I am to hear from him.我无法表达我接到他的信时有多高兴。
857. If Tom cannot keep his promise, he’ll lose face.如果汤姆不能信守诺言,他就会丢面子。
858. I’ll still love her even if she doesn’t love me.即使她不爱我,我还仍然爱她。
859. I received an invitation, but I did not accept it.我收到-份请帖,但没有接受。
860. If I were you, I would not be bothered by English.如果我是你,就不会为英语烦恼了。
861. If you don’t work, you will fail to pass the exam.如果你不学习,你考试就会不及格。
862. I’m thinking of hanging the lamp from the ceiling.我打算把灯吊在天花板上。
863. It is more important to be healthy than bony slim.健康永远比皮包骨头好。
864. Long ago, people believed that the world was flat.很久以前人们相信地球是平的。
865. Old tunes are sweetest and old friends are surest.老调最甜美,老友最可靠。
866. She makes it clear that she doesn’t like swimming.她明确地表示她不喜欢游泳。
867. The constitution guards the liberty of the people.宪法保护人民的自由。
868. The doctor examined the soldier’s wound carefully.大夫仔细检查了战士的伤口。
869. The harder I study, the better my English will be.我越努力,我的英语就会越好。
870. The sun was shining and the sky was crystal clear.阳光闪烁,天空湛蓝。
871. This cellar room is very damp in the rainy season.这间地下室在雨季非常潮湿。
872. Computers are becoming a part of our everyday life.电子计算机正渐渐成为我们日常生活的一部分。
873. Every man is fool sometimes, but none at all times.每个人都有愚蠢的时候,但是没有一个人永远愚蠢。
874. He dreamed of traveling to remote South Sea Islands.他曾梦想到遥远的南海诸岛去旅游。
875. How can I climb up that wall! I wish I were a bird!我怎么能够爬得上那堵墙?我要是一只鸟就好了!
876. However, Susan has not really made up her mind yet.然而,苏珊却还没有决定。
877. I really think a little exercise would do you good.我真的觉得做点运动对你有好处。
878. I will never forget the days that I spent with you.我永远都不会忘记和你一起度过的日子。
879. we got a bad headache, and my nose is running.我头痛得厉害,还流鼻涕。
880. Many young girls dream of being a fashion model.许多年轻女孩梦想成为时装模特儿。
881. Most of the earth’s surface is covered by water.大部分的地球表面被水覆盖着。
882. Somebody’s knocking at the door. I’ll answer it.有人在敲门,我去开。
883. The number 13 bus will take you to the hospital.13路车会带你去医院。
884. They celebrated his birthday with a dance party.也们举办舞会来祝贺他的生日。
885. They misplaced this book under other categories.他们把它错放到另一个类别去了。
886. They played a shameful part in the whole affair.他们在这一事件中扮演了可耻的角色。
887. As a matter of fact, he was pretending to be ill.实际上,他是在装病。
888. I will speak against anything I know to be wrong.我会对所有我认为不对的事情直言不讳。
889. In spite of the heavy rain, she went to the shop.尽管下着大雨,她还是去了商店。
890. No matter what happened, he would not say a word.不管发生什么事,他也不会说一句话。
891. No one knows the location of the hidden treasure.谁也不知道藏宝地点在哪里。
892. The old lady enjoys a quiet life with her family.老太太和她的家人安享宁静的生活。
893. The population of the city is close to a million.这个城市的人口接近一百万。
894. We are prohibited from smoking on school grounds.我们被禁止在校园内抽烟。
895. Growth, however, brings new problems and concerns.不过,发展也带来了新的问题和顾虑。
896. He appears to be your friend but I doubt if he is.他看上去像是你的朋友,但我怀疑他是否是真心的。
897. I am so full that I would burst with another bite.我吃得如此之饱,我感觉我再吃一口肚子就要胀破了。
898. I have two cats. One is white, the other is black.我有两只猫,一只是白猫,另一只是黑猫。
899. I’m sorry, these 2 books are 3 days overdue.小姐,对不起,这两本书已经过期3天了。
900. Jalu has forgotten falling off his bicycle.詹露早忘掉他从白行车上摔下来这件事了。

推技术聊天室的实现(下)

silver6 | 07 九月, 2005 08:44

下面我们来看看具体实现流程:

  聊天服务器的实现

  我们的服务器的核心部分是ThreadedChatHandle类,我们需要处理的数据主要包括两部分——在线列表和用户发言。在线列表可以直接使用大的对象数组,这是基于一个聊天室容量是有限制的考虑。而用户的发言直接发到管道里面就可以了。

  在线列表类的定义如下:

  class Chater
  { private static Double id;//这个ID作为区别号,同时
   private Double socketid; file://与聊天主帧对应的Socket相关联。
   private String nickname;// 用户昵称
   private String passwd;// 用户昵称
   private Int privilige;//
   private String[] filter;//某个用户的过滤列表
   private Double login_time;//记录登录时间,用以清除一些超时联接
   private String color;//用户聊天颜色
  ……//限于篇幅,省略了相关的方法。
  }

  注意:以上用户数据大部分是在login阶段,用户通过身份验证以后填入的。只有socketid要等到聊天主帧(一个普通的聊天界面包括聊天主帧,发言帧,在线列表帧三个部分)显示以后才得到。如果超过一定时间,socketid还是没有填入,说明浏览器取得主框架以后连接中断了,这时候就需要删除该用户数据。如果要实现象sohu那样的私聊的话,还应该增加用户IP地址的属性。

  用户发言类的定义如下:

  class Content
  { private Double timestamp;//时间戳
  private Double fromChaterid;//发言人id
  private Double toChaterid;//聊天对象id
  private Boolen isSecurity;//是否私聊标志
  private String theContent;//聊天内容,在构建器里处理过,已经包括表情等ht
ml文本。
  ……//限于篇幅,省略了相关的方法。
  }
  
  核心的ThreadedChatHandle类主要处理的工作是分析用户请求。客户端发送的请求的值,主要有login(验证身份,显示聊天室主框架)、joinchat(初始化聊天信息,如显示欢迎等,显示聊天内容显示帧,并保持连接,发送聊天信息。)、showtalk(显示发言的帧)、names(显示在线列表帧)、leave(用户点击按钮离开聊天室)等等。
假如我们使用GET方法传递数据而不是通过POST方法提交表单的话,用户数据输入都是在URL里传送,下面是几个url实例,结合后面客户端流程,可以更好地理解ThreadedChatHandle类的职能:

  这是一个用户名密码均为’aaa’的聊天用户登录系统,说了一句话“hello”,然后退出所产生的一系列请求:

  /login?name=aaa&passwd=aaa
  /joinchat?chaterid=555
  /showtalk?chaterid=555
  /names?chaterid=555
  /speak?chaterid=555
  /leave?chaterid=555
  ……

  以上是服务器程序流程,实际上我们参数的传递不能只传一个 chaterid,还需要有个对应的认证。而names传递一个chaterid是为了更新时间在线列表类内自己访问的时间,避免连接超时。下面我们从客户端看看具体登录过程。

  聊天界面由三个frame组成,其中joinchat帧是聊天内容显示部分;showtalk帧是用户输入部分,包括聊天内容输入、动作、过滤以及管理功能都在这一帧输入;names是在线名单显示部分,这一部分是定时刷新的。

  让我们从浏览器的角度来看看进入聊天室的过程。

  ◆首先浏览器请求页面

  http://host:8080/login?name=NAME&passwd=PWD

  此时一个ThreadedChatHandle出现(包括了一个socket连接),并发送了一行数据:

  GET /login?name=NAME&passwd=PWD HTTP/1.1

  ◆服务器生成一个session id,验证密码以后,发回:

  HTTP/1.1 200 OK

  <其他头信息>

  Content-TYPE: text/html

  <空行>

  <html>

  ……

  <frameset cols="*,170" rows="*" border="1" framespacing="1">

   <frameset rows="*,100,0" cols="*" border="0" framespacing="0">

    <frame src="/joinchat?chaterid=555" name="u" frameborder="NO" noresize>

    <frame src="/showtalk?chaterid=555" name="d" frameborder="NO" noresize>

   </frameset>

   <frame src="/names?chaterid=555" name="r" noresize>

  </frameset>

  ……

  </html>

  然后ThreadedChatHandle.start()退出,本子线程结束

  ◆浏览器收到以上html文件后,将会依次打开三个联接(其中的chaterid是需要传递的变量,555是个虚指):

  /joinchat?chaterid=555
  /showtalk?chaterid=555
  /names?chaterid=555

  这三个联接中的第一个联接joinchat在整个聊天过程中都是保持联接的,这样从浏览器角度来看,就是一个始终下载不完的大页面,显示效果上就是聊天内容不是靠刷新来更新,而是不断地向上滚动。通过察看html代码可以看到,只有<html><body>,然后就是不断增加的聊天内容,没有</body></html>。

  另外两个联接在页面发送完毕以后,处理这两个连接的线程就结束了。

  这样一次登录聊天室实际上有四个子线程响应,但登录完成以后,只有处理joinchat帧的线程依然存活,用于接收来自服务器的聊天信息,这是基于推技术聊天室的关键所在。

  当然,如果用户有其它操作的请求,例如用户注册、修改昵称、修改密码等操作都可以通过类的扩充得到相对应的响应。通过对类方法的重载还可以比较方便的根据需要修改用户认证机制与网站其它功能模块结合在一块。 查看全文

推技术聊天室的实现(上)

silver6 | 07 九月, 2005 08:39

基于推技术的聊天室在国内现在已经比较常见。这种聊天室最大的特点是不使用浏览器每格一段时间就刷新的方式,而让服务器不定时往客户端写聊天的内容。当有人发言时,屏幕上才会出现新聊天内容,而且聊天内容是不断向上滚动的,如果浏览器状态栏在的话,可以看到进度条始终处于下载页面状态。即使这种聊天室容纳上百人,性能不会明显的降低。而以往的CGI或活动服务器端脚本做的聊天室性能明显就不行了。

  推技术的聊天室聊天室基本原理是,不使用HTTPD服务器程序,由自己的Socket程序监听服务器的80端口,根据html规范,在接收到浏览器的请求以后,模仿www服务器的响应,将聊天内容发回浏览器。在浏览器看来就象浏览一个巨大的页面一样始终处于页面接收状态。也就是说,我们不再使用CGI等方式来处理聊天的内容,而采用我们自己的程序来处理所有的事务。实际上它就是一个专门的聊天服务器,即一个简化了的专门用于聊天的WWW服务器。

  在具体讨论程序的实现之前,我们先来解析一下相关的技术。

◆http请求和应答过程

  http协议是浏览器与WWW服务器之间通信的标准,Socket聊天服务器应当遵守这个协议。实际上,我们只需要使用其中的一小部分就可以了。

  http使用了C/S(客户/服务器)模式,其中浏览器是http客户,浏览某个页面实际上就是打开一个Socket连接,发送一个请求到WWW服务器,服务器根据所请求的资源发送应答给浏览器,然后关闭连接。客户和服务器之间的请求和应答有一定的格式要求,只要按照这个格式接收请求发送应答,浏览器就会正常的显示你所需要的的内容。

  请求和应答具有类似的结构,包括:

  · 一个初始行

  · 0个或多个header lines

  · 一个空行

  · 可选的信息

  我们看看一个浏览器发出的请求:

  当我们浏览网页http://www.somehost.com/path/file.html的时候,浏览器首先打开一个到主机www.somehost.com的80端口的socket,然后发送以下请求:

  GET /path/file.html HTTP/1.0

  From: someuser@somehost.com

  User-Agent: Mozilla/4.0 (compatible; MSIE 5.0; Windows NT 5.0; DigExt)

  [空行]

  第一行GET /path/file.html HTTP/1.0是我们需要处理的核心。由以空格分隔的三部分组成,方法(method):GET,请求资源:/path/file.html,http版本:HTTP/1.0。

  服务器将会通过同一个socket用以下信息回应:

  HTTP/1.0 200 OK

  Date: Fri, 31 Dec 1999 23:59:59 GMT

  Content-Type: text/html

  Content-Length: 1354

  <html>
  <body>
  <h1>Hello world!</h1>
(其他内容)...
  </body>
  </html>

  第一行同样也包括三部分:http版本,状态码,与状态码相关的描述。状态码200表示请求成功。
  发送完应答信息以后,服务器就会关闭socket。
◆服务器模型

  一般网络服务器主要分为两种:

  (1)循环服务器(iterative server):它是一个时刻只能处理一个请求的服务器,多个请求同时到来将会放在请求队列里。TCP套接字服务器一般很少采用循环方式,因为假如某个客户和服务器的连接出了问题,会导致整个服务器挂掉。它常为UDP套接字服务器所采用。

  (2)并发服务器(concurrent server):在每个请求到来以后分别产生一个新进程来处理这个请求所产生的连接。TCP的Socket服务器大多采用并发方式提供服务。

  并发服务器有多种实现方法:

  i 服务器和每个接收到的客户机进行连接,创建一个新的子进程处理这个客户机请求。

  ii 服务器预先创建多个子进程,由这个子进程处理客户机请求。这种方式被称为“预创建(prefork)”服务器。

  iii 服务器用函数select实现对多个客户机连接的多路复用。

  iv 超级服务器(inet)激活的服务器。

  并发服务器由于其算法而具有与生俱来的快速响应优势,而且当某一个用户与服务器通信死锁不会影响其他进程,但由于多个进程之间需要通过进程间通信实现信息交换,而且fork新进程所带来的开销随着用户数量的增加越来越大,因此原始的并发服务器并不一定是最好的选择。JAVA语言给我们带来的方便的线程机制,使我们可以用多线程来代替多进程,实现并发服务器,为我们进行快速的商业版本的聊天室的开发提供了优势。

  值得注意的是,在linux下,JAVA并没有实现真正的多线程,本质上仍然是多进程。

  ◆POST与GET

  提交form表单信息一般常用的有两种:POST或者GET。POST由于长度不受限制,而作为大多数form提交时使用的方法。GET方法通过URL来发送提交信息,由于URL被WWW服务器限制了长度,一般最长只能为1024字节,所以如果发送信息很长的话,就不能使用这种方法。
  由于我们对聊天内容有长度限制,不会太长,而且普通浏览页面使用GET方法,使用GET方法提交form表单可以简化处理过程,所以我们可以使用这种方法来提交聊天内容。

  我们感到美中不足的是GET方法将提交的内容简单的附在连接后边,我们如果能够将提交的内容进行HTML编码的话,就可以让客户舒服点了。
◆用JAVA实现并发SOCKET通信

  如果以前做过C的SOCKET编程,那么这一段对你来说将不是什么难事。利用JAVA的多线程机制我们可以非常方便的实现并发服务。

  每当我们知道服务器主程序创建一个新的套接字连接(即成功地调用了accept()方法)的时候,就启动一个新的线程来负责本服务器和该客户之间的连接,主程序将返回并等待下一个连接。为了实现这个方案,本服务器主循环应该采用如下形式:

  while(true)
  { Socket newjoin=s.accept();
  Tread t=new ThreadedChatHandle(newjoin);
  t.start();
  }

  ThreadedChatHandle类是从Thread类衍生出的处理聊天过程的子类,它的run()方法包括了服务器和客户的通信循环——判断客户的请求(例如登录、发言、刷新在线列表),处理发言数据,发送聊天信息等等。下面是一个服务器程序的例子,可以帮助初学者尽快理解。

  import java.io.*;
  import java.net.*;
  public class ChatServer
  { public static void main(String[] args)
  { int I=1;
  try
  {ServerSocket s=new ServerSocket(8080);
  /*创建一个监视8080端口的服务器套接字,如果需要,你可以改成80端口*/
  for(;;)
  { Socket newjoin=s.accept();
  /*等待一个连接。如果这个连接没有被创建,本方法阻塞当前线程。返回值是一个
Socket对象,服务器程序利用这个对象可以与连接的客户通信。*/
   System.out.println(“新连接”+i);
   new ThreadedChatHandle(newjoin,i).start();
  /* ThreadedChatHandle(Socket theS,int c)是我们自己定义的聊天服务类,这个
类在后边我们有进一步描述*/
       i++;
  }
  }
  catch(Exception e)
  { System.out.println(e);
  }
  }
  ……
  }

  多进程(线程)并发服务的一个关键问题是,如何实现进程(线程)间通信。每个客户的发言(包括表情和动作等选项)都需要放在一个公共的地方,让所有的输出线程都能够获得它。解决的方法有很多,比如说放在数据库里,放在大家都有权限的dat文件里,或直接用管道实现进程间通信。其中,对一个聊天室服务器来说,第一种方法是最傻的,太消耗系统资源,而且使程序执行效率变慢,可能出错环节增多。而使用管道通信的方式,把所有发言数据都保存在内存里,不但可以获得最高的执行效率,安全的执行过程,也不用考虑线程同步的问题。不要以为所有的发言数据会很多,其实服务器端只要保存最后100句就已经很了不起了,不是吗?

  JAVA里关于管道的API有:

  ●Java.io.PipedInputStream

  PipldInputStream():

  创建新的管道输入流,且它没有关联一个管道输出流。

  PipldInputStream(PipldOutputStream out):

  创建新的管道输入流,且从管道输出流out中读取数据。

  connect(PipldOutputStream out):

  关联一个管道输出流,且这个流读取数据。

  ●Java.io.PipedOutputStream

  PipldOutputStream():

  创建新的管道输出流,且它没有关联一个管道输入流。

  PipldOutputStream(PipldInputStream in):

  创建新的管道输出流,并输出数据到in。

  connect(PipldInputStream in):

  关联一个管道输入流,并输入数据到in。

  ◆Daemon的实现

  实际上,我还没有找到直接在JAVA中实现后台守护进程的方法。实现一个后台进程需要完成一系列的工作,包括:关闭所有的文件描述字;改变当前工作目录;重设文件存取屏蔽码(umask) ;在后台执行;脱离进程组;忽略终端I/O信号;脱离控制终端。

  JAVA中有一个叫Daemon Thread的东西,我没有使用过。据介绍,这种叫服务线程的东东唯一的目的就是为其它线程提供服务。而一个程序里如果只剩下服务线程的话,这个程序就会停止(和我们的初衷简直就是南辕北辙)。有兴趣的朋友可以看看相关的内容,在java.lang.Thread.setDaemon()。

  虽然我们不能用JAVA实现后台服务守护进程,不过我们还有JAVA的C接口,问题总有解决的办法。

  ◆异常处理

  在Socket通信过程中很容易出现一些意外情况,如果不加处理直接发送数据,就可能导致程序意外退出。例如,客户关闭了socket后,服务器继续发送数据,这就会导致异常。为避免这一情况的发生,我们必须对它进行处理,一般情况下,只需要简单地忽略这个信号就可以了。幸好,JAVA的异常处理机制还比较强壮。

  ◆用户断线判断和处理

  许多情况下,用户不是通过提交“离开”按钮离开聊天室,这时候就需要判断用户是否断线了。一般用户断线可能包括以下几种情况:方法是:当用户关闭浏览器,或者点击了浏览器stop按钮,或者跳转到其他网页的时候(如果用JAVASCRIPT弹出一个聊天窗口的话,那么这两种情况我们是能够避免的——大不了再禁止右键),相对应的socket将会变成可读状态,而此时读出的数据却是空字符串。

  利用这个原理,只要在某个可读的socket读取数据时,读到的却是空数据,那么我们就可以断定,与这个socket相对应的用户断线了。

  ◆防止连接超时断线

  如果浏览器在一段时间内没有接到任何数据,那么就会出现超时错误。要避免这一错误,必须在一定间隔内发送一些数据,在我们这个应用系统里,可以发送一些html注释。发送注释的工作可以直接插入聊天内容之间来完成。

亲身体验CORBA: 使用java和C++混合编程

silver6 | 07 九月, 2005 08:22

1. 前言

  现在很多人在对CORBA进行学习,大家都已经了解到CORBA是一个完全中间性的语言,可以使用接口定义语言(IDL)定义开发时使用接口的 Client 和实现接口的 Server 所需要的信息。Client 和 Server 的具体实现代码并不在IDL定义中编写,而是使用某种目标语言的IDL 编译器生成所需的代码存根及helper类,Client 和 Server再使用真正的编程语言来进行具体实现。

  为了保证在不同的 CORBA 产品基础之上构建的分布式对象可以相互通信,Client和Server通过ORB(对象请求代理)进行通信。一般的运行流程是Client把请求发送给ORB,ORB再把请求发送给Server,Server把返回结果发送ORB,ORB再把返回结果发送给Client。ORB可以说Client和Server之间的翻译者。即使Client和Server使用不同的编程语言编写,只要是符合相同的IDL定义,ORB也可以完成相互的通信。

  所有的文档在强调服务器及客户机可以是Java也可以是C++或其他语言(如:Delphi)进行编写,但在网站或书本是没有详细说如何应对多语言客户机的例子。《JAVA2核心技术》上面有些说明,但也只是介绍性的文章,故自己下载了omniORB304,进行了一次使用SUN的 tnameserv命名服务程序,服务器用JAVA编写,客户机分别用JAVA和C++(VC6+omniORB)编写的试验,希望通过一次编程的具体操作实例来体验或明了CORBA思想。

  总体的编写过程如下:

  用IDL定义一个接口文件,描绘要实现的功能,也可以说是定义一个要实现功能的一个模版(SysProp.idl)

  使用"IDL to Java"编译器(这里是IDLJ)将IDL文件转化为Java编程语言中编写的接口定义,生成所需的代码存根及helper类

  使用Java语言编写客户机和服务器的实现程序。

  使用"IDL to C++"编译器(这里是omniidl)将IDL文件转化为C++编程语言中编写的接口定义,生成所需的代码存根及helper类

  使用C++语言编写客户机实现程序(当然也可编写服务器程序,但本次试验没有进行)

  起动命名服务tnameserv

  起动Java编写的服务程序

  用Java和C++编写的客户机分别调用相应的服务

  2. 运行环境的设定:

  总体环境由jdk1.3+omniORB3.0(www.uk.research.att.comomniORBdoc3.0) +vc6 组成,下面说明具体的安装。

  2.1. 安装JDK1.3

  从SUN公司DOWN JDK1.3或者通过其他方式得到jdk1.3进行安装,再设定相应的环境变量,在本文测试用的电脑上是如下所示:

  CLASSPATH=.;
  JAVA_HOME=D:jdk130

  修改原来的PATH变量,添加"%JAVA_HOME%bin;",如下

  PTAH=%JAVA_HOME%bin;原变量

  注意:我在第一次使用jbuilder的jdk1.3时,服务器不能正常工作,我只是发觉这么一回事,具体原因与本文无关而没有进行了解,请谅。

  2.2. 安装VC6
  VC6按常规方式安装,注意的是:在本文测试用的电脑上安装在如下位置

  C:Program FilesMicrosoft Visual Studio

  2.3.安装omniORB

  从 www.uk.research.att.comomniORBdoc3.0 下载omniORB3.0 ( 本文测试所下载的文件是omniORB_304_x86_win32.zip )。

  用WINZIP进行解压omniORB_304_x86_win32.zip到omniORB_304_x86_win32目录,目录内存在omni目录,复制omni目录内的文件到你把想存放的位置。

  测试电脑安装在C:omni

  根据C:omniREADME.win32 文档进行设定,由于运行程序及命令行在控制台进行,所以本次测试并不根据文档要求去设定环境变量,而是编写了一个omni.bat,在使用控制台时,首先运行。

  本测试电脑omni.bat内容如下

set TOP=c:omni
set path=%TOP%binx86_win32;%path%
set LIB=%TOP%binx86_win32;%LIB%
set INCLUDE=%TOP%include;%INCLUDE%
set VcOsDir=
set VSCommonDir=

  如果你的电脑VC的环境变量已经设定在你的环境变量中,那么C:Program FilesMicrosoft Visual StudioVC98BinVCVARS32.BAT 就可以不运行。否则运行omni.bat前要首先运行VCVARS32.BAT。

3. 实践过程

  约定所有编写的文件保存在D:myworkt1中,omni.bat也在这个目录内

  3.1.编写SysProp.idl,功能是返回系统属性

interface SysProp
{ string getProperty(in string name);
};

  3.2. 编写JAVA的服务器

  3.2.1. 把IDL文件转化为JAVA编程语言代码存根类及helper类。

  执行如下命令

  idlj -fall SysProp.idl

  在正常的情况下D:myworkt1 目录内将生成以下文件,否则请检查你的执行程序及文件

SysProp.java

SysPropHelper.java

SysPropHolder.java

SysPropOperations.java

_SysPropImplBase.java

_SysPropStub.java

  3.2.2. 编写 SysPropServer.java

import org.omg.CosNaming.*;
import org.omg.CORBA.*;

//编写相对应的服务,一定要从 _类名ImplBase继承,并实现相应的方法
class SysPropS extends _SysPropImplBase //具体的服务实现

{ public String getProperty(String key)
{
System.out.println("调用"+key);
String S;
S=System.getProperty(key);
if (S==null) { S="null"; }
System.out.println(key+"="+S);
return S;
}
}
public class SysPropServer //起动服务的程序
{ public static void main(String args[])
{ try
{ System.out.println("创建和初始化 ORB ");
ORB orb = ORB.init(args, null);
System.out.println("创建服务对象并将其向 ORB 注册 ");
SysPropS impl = new SysPropS();
orb.connect(impl);
//打印IOR字符串
System.out.println(orb.object_to_string(impl));
org.omg.CORBA.Object namingContextObj =orb.resolve_initial_references("NameService");
NamingContext namingContext= NamingContextHelper.narrow(namingContextObj);
NameComponent[] path = {new NameComponent("SysProp", "")};
System.out.println("绑定服务...SysPropS");
namingContext.rebind(path, impl);
System.out.println("等待调用...SysPropS");
java.lang.Object sync = new java.lang.Object();
synchronized (sync)
{ sync.wait();
}
}
catch (Exception e)
{ System.err.println("Error: " + e);
e.printStackTrace(System.out);
}
}
}

  3.3. 编写JAVA的客户机

  3.3.1. 编写 SysPropClient.java 使用IOR字符串的方式

  注意在代码内有一段注解掉的代码,用"//使用ORB的方法的开始"开始,用"//使用ORB的方法的结束"结束。这段代码是使用ORB方法的代码,如果在代码中"//使用IOR的方法开始"前一行添加"/*",在"//使用IOR的方法结束"后一行添加"*/",而把"//使用ORB的方法的开始"前面的"/*"去掉,把"//使用ORB的方法的结束"后面的"*/"去掉,就是使用ORB方法的代码,程序运行时就是" SysPropClient [环境变量] "的方式。以下是具体代码:

import org.omg.CosNaming.*;
import org.omg.CORBA.*;
public class SysPropClient
{
public static void main(String args[])
{
try{
String SetInfo,ReturnInfo,ref;
org.omg.CORBA.Object objRef;
SysProp syspropRef;
ORB orb = ORB.init(args, null);
//使用IOR的方法开始
if (args.length>=1)
{
ref=args[0];
}
else
{
System.out.println("SysPropClient [环境变量]");
return;
}
objRef = orb.string_to_object(ref);
syspropRef = SysPropHelper.narrow(objRef);
//使用IOR的方法结束

/*
//使用ORB的方法的开始
objRef = orb.resolve_initial_references("NameService");
NamingContext ncRef = NamingContextHelper.narrow(objRef);
// 进行服务定位
NameComponent nc = new NameComponent("SysProp", "");
NameComponent path[] = {nc};
syspropRef = SysPropHelper.narrow(ncRef.resolve(path));
//使用ORB的方法的开始结束
*/
if (args.length>1)
{
SetInfo=args[1];
}
else
{
SetInfo="java.home";
}
System.out.println("开始调用");
ReturnInfo = syspropRef.getProperty(SetInfo);
System.out.println(SetInfo+"="+ReturnInfo);
} catch (Exception e) {
System.out.println("ERROR : " + e) ;
}
}
}

  3.3.2. 编译程序,在文件目录内执行如下命令

  jAVAC *.JAVA

  3.4. 进行测试

  第1控制台,执行

  tnameserv

  测试时如下所示

D:myworkt1>java tnameserv
Initial Naming Context:
IOR:000000000000002849444c3a6f6d672e6f72672f436f734e616d696e672f4e616d696e67436f
6e746578743a312e3000000000010000000000000054000101000000000c3139322e3136382e302e
31000ca6000000000018afabcafe00000002a999c474000000080000000000000000000000010000
0001000000140000000000010020000000000001010000000000
TransientNameServer: setting port for initial object references to: 900
Ready.

  第2控制台,执行

  java SysPropServer

  测试时如下所示

D:myworkt1>java SysPropServer
创建和初始化 ORB
创建服务对象并将其向 ORB 注册
IOR:000000000000001049444c3a53797350726f703a312e30000000000100000000000000540001
01000000000c3139322e3136382e302e31000ca7000000000018afabcafe00000002a999dbeb0000
00080000000000000000000000010000000100000014000000000001002000000000000101000000
0000
  绑定服务...SysPropS
  等待调用...SysPropS

  第3控制台,执行

  java SysPropClient IOR:XXX JAVA.HOME

  测试时如下所示

D:myworkt1>java SysPropClient IOR:000000000000001049444c3a53797350726f703a312e
3000000000010000000000000054000101000000000c3139322e3136382e302e31000ca700000000
0018afabcafe00000002a999dbeb0000000800000000000000000000000100000001000000140000
000000010020000000000001010000000000 java.home
开始调用
java.home=D:beajdk130jre

3.5. 编写C++的IOR客户机

  从实践来讲编写C++的客户机程序同JAVA没有多大的区别,只不过JAVA是用idlj生成代码存根类及helper类,而omni是用omniidl来生成代码存根类及helper类,而编程思想及编码过程非常相似。

  由于C++的程序要调用omni及VC6的相关文件,所以进入控制台后,如果VC没有进行环境变量设定,那么要先运行C:Program FilesMicrosoft Visual StudioVC98BinVCVARS32.BAT,再运行omni.bat,否则直接运行omni.bat后再编译程序及运行程序。

  3.5.1. 把IDL文件转化为C++编程语言代码存根类及helper类。

  执行如下命令

  omniidl -bcxx SysProp.idl

  在正常的情况下D:myworkt1 目录内将生成C++编程语言的代码存根类及helper类SysProp.hh和SysPropSK.cc。否则请检查你的执行程序及文件。

  3.5.2. 编写SysPropC.cc

#include
#include
int main(int argc, char** argv)
{
try {
CORBA::ORB_var orb = CORBA::ORB_init(argc, argv, "omniORB3");
if( argc < 2 || argc > 3 ) {
cout << "usage: SysPropC [环境变量名]" << endl;
return 1;
}
CORBA::Object_var obj = orb->string_to_object(argv[1]);
SysProp_ptr echoref = SysProp::_narrow(obj);
if( CORBA::is_nil(echoref) ) {
cerr << "没有对象" << endl;
return 1;
}
const char* message;
if (argc==3)
{
message=argv[2];
}
else
{
message="java.home";
}
CORBA::String_var dest = echoref->getProperty(message);
cout << (char*)message << "=" <<(char*)dest << endl;
orb->destroy();
}
catch(...) {
cerr << "Caught unknown exception." << endl;
}
return 0;
}

  3.5.3. 编写dirc.mak,如下所示

TOP = C:omni
OMNI_DYNAMIC_LIB = msvcstub.lib -NODEFAULTLIB:libcmt.lib -NODEFAULTLIB:libcmtd.lib
CORBA_CPPFLAGS = -D__WIN32__ -D__x86__ -D__NT__ -D__OSVERSION__=4
CORBA_LIB = omniORB304_rt.lib omnithread2_rt.lib
$(OMNI_DYNAMIC_LIB)
wsock32.lib advapi32.lib
-libpath:$(TOP)libx86_win32
CXXFLAGS = -O2 -MD -GX $(CORBA_CPPFLAGS) $(DIR_CPPFLAGS)
CXXLINKOPTIONS =
.SUFFIXES: .cc
.cc.obj:
cl /nologo /c $(CXXFLAGS) /Tp$<
all:: SysPropC.exe
SysPropC.exe: SysPropSK.obj SysPropC.obj
link -nologo $(CXXLINKOPTIONS) -out:$@ $** $(CORBA_LIB)
clean::
-del *.obj
-del *.exe
veryclean::
-del *.obj
-del echoSK.* echo.hh
-del *.exe
SysProp.hh SysPropSK.cc: SysProp.idl
$(TOP)binx86_win32omniidl -T -bcxx -Wbh=.hh -Wbs=SK.cc -Wbtp SysProp.idl

  3.5.4. 编译程序,执行如下命令

  nmake -f dirc.mak

  3.5.5. 测试 

  在第4控制台

  SysPropC IOR:XXX JAVA.HOME

  本测试如下所示

D:myworkt1>syspropc IOR:000000000000001049444c3a53797350726f703a312e3000000000
010000000000000054000101000000000c3139322e3136382e302e31000ca7000000000018afabca
fe00000002a999dbeb00000008000000000000000000000001000000010000001400000000000100
20000000000001010000000000 os.name
os.name=Windows 2000

  3.6. 编写C++的NAME方式客户机

  为了使用NANE方式,必须为OMNI软件设置注册表信息,要在注册表中建立如下数据项(regedit)HKEY_LOCAL_MACHINESOFTWAREORLomniORB2.0NAMESERVICE(字符串)。

  NAMESERVICE的值为tnameserv(jdk1.3bin内的程序)启动的IOR值(第一次设置时自行添加)。

  注意为了使用这种方式每次起动tnameserv后要用新IOR值换去旧的IOR值,我测试过用omini的omniNames.exe程序做服务器,IOR值是不变的,但服务器用JVAV编写就会出错。如果起动tnameserv,用 c编写的服务器及客户机就可以在上面运行。本例子如下所示

Initial Naming Context:
IOR:000000000000002849444c3a6f6d672e6f72672f436f734e616d696e672f4e616d696e67436f
6e746578743a312e3000000000010000000000000054000101000000000c3139322e3136382e302e
31000ca6000000000018afabcafe00000002a999c474000000080000000000000000000000010000
0001000000140000000000010020000000000001010000000000
TransientNameServer: setting port for initial object references to: 900
Ready.

  那么就要把从 IOR:开始(含IOR:)后面的字符串放进注册表。

  3.6.1.编写SysPropCC.cc

//使用NAME方式的客户机
#include
#include "SysProp.hh"
static CORBA::Object_ptr getObjectReference(CORBA::ORB_ptr orb);
int main (int argc, char **argv)
{
   if( argc != 2 ) {
     cout << "使用方法: SysPropCC <环境变量名>" << endl;
     return 1;
   }
try {
   CORBA::ORB_var orb = CORBA::ORB_init(argc, argv, "omniORB3");
   CORBA::Object_var obj = getObjectReference(orb);
   SysProp_ptr echoref = SysProp::_narrow(obj);
  const char* message;
  if (argc==2){message=argv[1];}
  else {message="java.home"; }
   CORBA::String_var dest = echoref->getProperty(message);
   cout << (char*)message << "=" <<(char*)dest << endl;
   orb->destroy();
  }
 catch(...) { cerr << "Caught unknown exception." << endl; }
 return 0;
}
//////////////////////////////////////////////////////////////////////
static CORBA::Object_ptr getObjectReference(CORBA::ORB_ptr orb)
{
 CosNaming::NamingContext_var rootContext;
 try {
   // 定位服务器:
   CORBA::Object_var obj;
   obj = orb->resolve_initial_references("NameService");
  // Narrow the reference returned.
   rootContext = CosNaming::NamingContext::_narrow(obj);
   if( CORBA::is_nil(rootContext) ) {
    cerr << " 初始化不成功." << endl;
    return CORBA::Object::_nil();
   }
 }
 catch(CORBA::ORB::InvalidName& ex) {
   cerr << " 没有找到服务" << endl;
   return CORBA::Object::_nil();
 }
 CosNaming::Name name;
  name.length(1);
  name[0].id = (const char*) "SysProp";
 name[0].kind = (const char*) "";
 try {
   // Resolve the name to an object reference.
   return rootContext->resolve(name);
}
catch(...) { cerr << "定位不成功." << endl;}
return CORBA::Object::_nil();
}

  3.6.2. 编写dircc.mak

TOP = C:omni
DIR_CPPFLAGS = -I. -I$(TOP)include
OMNI_DYNAMIC_LIB = msvcstub.lib -NODEFAULTLIB:libcmt.lib -NODEFAULTLIB:libcmtd.lib
CORBA_CPPFLAGS = -D__WIN32__ -D__x86__ -D__NT__ -D__OSVERSION__=4
CORBA_LIB = omniORB304_rt.lib omnithread2_rt.lib
              $(OMNI_DYNAMIC_LIB)
              wsock32.lib advapi32.lib
              -libpath:$(TOP)libx86_win32
CXXFLAGS      = -O2 -MD -GX $(CORBA_CPPFLAGS) $(DIR_CPPFLAGS)
CXXLINKOPTIONS =
.SUFFIXES: .cc
.cc.obj:
  cl /nologo /c $(CXXFLAGS) /Tp$<
all:: SysPropCc.exe
SysPropCc.exe: SysPropSK.obj SysPropCc.obj
  link -nologo $(CXXLINKOPTIONS) -out:$@ $** $(CORBA_LIB)
clean::
  -del *.obj
 -del *.exe
veryclean::
 -del *.obj
 -del echoSK.* echo.hh
 -del *.exe
SysProp.hh SysPropSK.cc: SysProp.idl
  $(TOP)binx86_win32omniidl -T -bcxx -Wbh=.hh -Wbs=SK.cc -Wbtp SysProp.idl

  3.6.3. 编译文件

  nmake -f dircc.mak

  3.6.4. 测试

  在第5控制台

  SysPropCC JAVA.HOME,测试结果如下所示

D:myworkt1>syspropcc java.home
java.home=D:beajdk130jre

  4. 小结

  另还使用了j2sdkee1.2.1进行测试,由于j2sdkee1.2.1起动时的nameserver的PORT是1050所以启动服务要加参数,对于本文中的程序运行时要如下所示:

 java SysPropServer -ORBInitialPort 1050

  如果用IOR的方式,也可以用omni的omniNames.exe程序做命名服务器,用C++编写服务器,客户机使用Java和C++编写,c++编写服务器的例子可见omni的文档。

  本次只是简单进行了测试,可以使大家了解一下,CORBA的这种特性,多种不同程序语言进行协作编程的具体运作过程,希望可以抛砖引玉。


下拉框的新特性

silver6 | 05 九月, 2005 08:59

http://www.baron.com.cn/javascript/zh/20021104zh2.htm

脚本说明:
第一步:把如下代码加入<body>区域中
<script language="JavaScript">
<!--
function catch_keydown(sel)
{
switch(event.keyCode)
{
case 13:
//Enter;
sel.options[sel.length] = new Option("","",false,true);
event.returnValue = false;
break;
case 27:
//Esc;
alert("text:" + sel.options[sel.selectedIndex].text + ", value:" + sel.options[sel.selectedIndex].value + ";");
event.returnValue = false;
break;
case 46:
//Delete;
if(confirm("删除当前选项!?"))
{
sel.options[sel.selectedIndex] = null;
if(sel.length>0)
{
sel.options[0].selected = true;
}
}
event.returnValue = false;
break;
case 8:
//Back Space;
var s = sel.options[sel.selectedIndex].text;
sel.options[sel.selectedIndex].text = s.substr(0,s.length-1);
event.returnValue = false;
break;
}

}
function catch_press(sel)
{
sel.options[sel.selectedIndex].text = sel.options[sel.selectedIndex].text + String.fromCharCode(event.keyCode);
event.returnValue = false;
}
//-->
</script>
<select name=s1 onkeydown="catch_keydown(this);" onkeypress="catch_press(this);" style="font-size:12px;"><option>---</option></select>

第二步:把<body>中的内容改为:
<body bgcolor="#fef4d9" onload="s1.focus();">


sql server 時間類型

silver6 | 03 九月, 2005 13:37

SUBSTRING(convert(char(8),日期字段,112),1,6)

csdn面試題

silver6 | 03 九月, 2005 08:26

1. public class text{
2. private static int j=0;
3.
4. private static boolean methodB(int k)(
5. j+=k;
6. return true;
6. ) // 这个括号用的是 ) 原题是这样的,不是我抄错.
7.
8. pvublic static void methodA(int i){
9. boolean b
10. b=i<10|methodB(4);
11. b=i<10||methodB(8);
12. )
13.
14. public static void main[String args[]} (
15. methodA(0); //上面的[} 原题是这样的,不是我抄错.
16. System.out.println(j);
17. )
18. ) // 这个括号用的是 ) 原题是这样的,不是我抄错.

what is the result ?
A.the program prints "0";
B.the program prints "4";
C.the program prints "8";
D.the program prints "12";
E.the code does not complate;

如果没抄错的话:选E
如果是下面这中情况:选A
public class text{
private static int j=0;
private static boolean methodB(int k){
j+=k;
return true;
}
public static void methodA(int i){
boolean b;
b=i<10||methodB(4);
b=i<10||methodB(8);
}

public static void main(String[] args){
methodA(0);
System.out.println(j);
}
}


JAVA生成JPG缩略图

silver6 | 02 九月, 2005 09:57

在任何一个综合性网站,我们往往需要上传一些图片资料。但随着高分辨率DC的普及,上传的图片容量会很大,比如300万象素DC出来的文件基本不下600K。为了管理方便,大家可能不愿意每次都用ACDsee修改它,而直接上传到服务器。但是这种做法在客户端看来就没有那么轻松了,对于拨号上网的用户简直是一场恶梦,虽然你可以在图片区域设置wide和high!

问题的解决之道来了!我们可以在类中处理一张大图,并缩小它。
前提是需要JDK1.4,这样才能进行处理。按以下方法做:

import java.io.File;
import java.io.FileOutputStream;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;

import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;

public class JpgTest {

public void JpgTset() throws Exception{
File _file = new File("/Order005-0001.jpg"); //读入文件
Image src = javax.imageio.ImageIO.read(_file); //构造Image对象
int wideth=src.getWidth(null); //得到源图宽
int height=src.getHeight(null); //得到源图长
BufferedImage tag = new BufferedImage(wideth/2,height/2,BufferedImage.TYPE_INT_RGB);
tag.getGraphics().drawImage(src,0,0,wideth/2,height/2,null); //绘制缩小后的图
FileOutputStream out=new FileOutputStream("newfile.jpg"); //输出到文件流
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
encoder.encode(tag); //近JPEG编码
//System.out.print(width+"*"+height);
out.close();
}
}

过程很简单,从本地磁盘读取文件Order005-0001.jpg(2032*1524),变成Image对象src,接着构造目标文件tag,设置tag的长宽为源图的一半,对tag进行编码,输出到文件流out,最后关闭文件流。

还有一些问题需要说明:
第一,目前只能支持JPG(JPEG)、GIF、PNG三种格式。
第二,对于源图的容量有限制,最好不要超过1M,否则会抛内存不足的错误,不过我试验过1.8M的源图,可以成功,但是也很容易抛内存不足。

引用一位前辈的话:图象运算本身是密集型运算,需要大量的内存存放象素值。我用VC试了一下,4M的图象也有问题,而且越是压缩比大的图片在内存中还原成BITMAP时需要的内存越大。解决的方法,可以重写编码类,先开一定的内存,然后一段一段编码写到临时文件中,输出的时候再一段一段读出来。或利用nio的内存映象来操作。JavaMail由于采用了Builder模式,先生成一个邮件的每一个部分,然后合并成一个完整的邮件对象,这样每个构件都要先生成到内存中,你如果发送一个上百兆的附件,那么在构造Part时肯定内存溢出,所以我就改写了BodyPart的构造,让他和一个临时文件关联,然后用临时文件保存Part而不是构造在内存中,这样任义大小的附件(硬盘能放得下为限)都可以发送了。

最后,如果大家对图像处理有更高的要求,不妨关注一下开源项目。比如JMagick,可以使用JMagick来实现图片的复制、信息获取、斜角、特效、组合、改变大小、加边框、旋转、切片、改变格式、去色等等功能。


com 入門

silver6 | 01 九月, 2005 15:14

本文的目的是为刚刚接触COM的程序员提供编程指南,并帮助他们理解COM的基本概念。
内容包括COM规范简介,重要的COM术语以及如何重用现有的COM组件。本文不包括如何编
写自己的COM对象和接口。
COM即组件对象模型,是Component Object Model 取前三个字母的缩写,这三个字母在
当今Windows的世界中随处可见。随时涌现出来的大把大把的新技术都以COM为基础。各
种文档中也充斥着诸如COM对象、接口、服务器之类的术语。因此,对于一个程序员来说
,不仅要掌握使用COM的方法,而且还要彻底熟悉COM的所有一切。
本文由浅入深描述COM的内在运行机制,教你如何使用第三方提供的COM对象(以Windows
外壳组件Shell为例)。读完本文后,你就能掌握如何使用Windows操作系统中内建的组
件和第三方提供的COM对象。
本文假设你精通C++语言。在例子代码中使用了一点MFC和ATL,如果你不熟悉MFC和ATL也
没关系,本文会对这些代码进行完全透彻的解释。
本文包括以下几个部分:
COM——到底是什么?——COM标准的要点介绍,它被设计用来解决什么问题?
基本元素的定义——COM术语以及这些术语的含义。
使用和处理COM对象——如何创建、使用和销毁COM对象。
基本接口——描述IUnknown基本接口及其方法。
掌握串的处理——在COM代码中如何处理串。
应用COM技术——例子代码,举例说明本文所讨论的所有概念。
处理HRESULT——HRESULT类型描述,如何监测错误及成功代码。

COM——到底是什么?
简单地说,COM是一种跨应用和语言共享二进制代码的方法。与C++不同,它提倡源代码
重用。ATL便是一个很好的例证。源码级重用虽然好,但只能用于C++。它还带来了名字
冲突的可能性,更不用说不断拷贝重用代码而导致工程膨胀和臃肿。
Windows使用DLLs在二进制级共享代码。这也是Windows程序运行的关键——重用kernel3
2.dll, user32.dll等。但DLLs是针对C接口而写的,它们只能被C或理解C调用规范的语
言使用。由编程语言来负责实现共享代码,而不是由DLLs本身。这样的话DLLs的使用受
到限制。
MFC引入了另外一种MFC扩展DLLs二进制共享机制。但它的使用仍受限制——只能在MFC程
序中使用。
COM通过定义二进制标准解决了这些问题,即COM明确指出二进制模块(DLLs和EXEs)必
须被编译成与指定的结构匹配。这个标准也确切规定了在内存中如何组织COM对象。COM
定义的二进制标准还必须独立于任何编程语言(如C++中的命名修饰)。一旦满足了这些
条件,就可以轻松地从任何编程语言中存取这些模块。由编译器负责所产生的二进制代
码与标准兼容。这样使后来的人就能更容易地使用这些二进制代码。
在内存中,COM对象的这种标准形式在C++虚函数中偶尔用到,所以这就是为什么许多COM
代码使用C++的原因。但是记住,编写模块所用的语言是无关的,因为结果二进制代码为
所有语言可用。
此外,COM不是Win32特有的。从理论上讲,它可以被移植到Unix或其它操作系统。但是
我好像还从来没有在Windows以外的地方听说过COM。
基本元素的定义
我们从下往上看。接口只不过是一组函数。这些函数被称为方法。接口名字以大写的I开
头,例如C++中的IShellLink,接口被设计成一个抽象基类,其中只有纯粹的虚拟函数。
接口可以从其它接口继承,这里所说的继承的原理就好像C++中的单继承。接口是不允许
多继承的。
coclass(简称组件对象类——component object class)被包含在DLL或EXE中,并且包
含着一个或者多个接口的代码。组件对象类(coclasss)实现这些接口。COM对象在内存
中表现为组件对象类(coclasss)的一个实例。注意COM“类”和C++“类”是不相同的
,尽管常常COM类实现的就是一个C++类。
COM服务器是包含了一个或多个coclass的二进制(DLL或EXE)。
注册(Registration)是创建注册表入口的一个过程,告诉Windows 操作系统COM服务器
放在什么位置。取消注册(Unregistration)则相反——从注册表删除这些注册入口。
GUID(谐音为“fluid”,意思是全球唯一标示符——globally unique identifier)是
个128位的数字。它是一种独立于COM编程语言的标示方法。每一个接口和coclass有一个
GUID。因为每一个GUID都是全球唯一的,所以避免了名字冲突(只要你用COM API创建它
们)。有时你还会碰到另一个术语UUID(意思也是全球唯一标示符——universally
unique identifier)。UUIDs和GUIDs在实际使用时的用途是一样的。
类ID或者CLSID是命名coclass的GUID。接口ID或者IID是命名接口的GUID。
在COM中广泛地使用GUID有两个理由:
1、GUIDs只是简单的数字,任何编程语言都可以对之进行处理。
2、GUIDs可以在任何机器上被任何人创建,一旦完成创建,它就是唯一的。因此,COM开
发人员可以创建自己特有的GUIDs而不会与其它开发人员所创建的GUIDs有冲突。这样就
消除了集中授权发布GUIDs的必要。
HRESULT是COM用来返回错误和成功代码的整型数字。除此之外,别无它意,虽然以H作前
缀,但没有句柄之意。下文会对它有更多的讨论。
最后,COM库是在你使用COM时与你交互的操作系统的一部分,它常常指的就是COM本身。
但是为了避免混淆才分开描述的。
使用和处理COM对象
每一种语言都有其自己处理对象的方式。例如,C++是在栈中创建对象,或者用new动态
分配。因为COM必须独立于语言,所以COM库为自己提供对象管理例程。下面是对COM对象
管理和C++对象管理所做的一个比较:
创建一个新对象
C++中,用new操作符,或者在栈中创建对象。
COM中,调用COM库中的API。
删除对象
C++中,用delete操作符,或将栈对象踢出。
COM中,所有的对象保持它们自己的引用计数。调用者必须通知对象什么时候用完这个对
象。当引用计数为零时,COM对象将自己从内存中释放。
由此可见,对象处理的两个阶段:创建和销毁,缺一不可。当创建COM对象时要通知COM
库使用哪一个接口。如果这个对象创建成功,COM库返回所请求接口的指针。然后通过这
个指针调用方法,就像使用常规C++对象指针一样。
创建COM对象
为了创建COM对象并从这个对象获得接口,必须调用COM库的API函数,CoCreateInstance
()。其原型如下:
HRESULT CoCreateInstance (
REFCLSID rclsid,
LPUNKNOWN pUnkOuter,
DWORD dwClsContext,
REFIID riid,
LPVOID* ppv );

以下是参数解释:
rclsid
coclass的CLSID,例如,可以传递CLSID_ShellLink创建一个COM对象来建立快捷方式。
pUnkOuter
这个参数只用于COM对象的聚合,利用它向现有的coclass添加新方法。参数值为null表
示不使用聚合。
dwClsContext
表示所使用COM服务器的种类。本文使用的是最简单的COM服务器,一个进程内(in-proc
ess)DLL,所以传递的参数值为CLSCTX_INPROC_SERVER。注意这里不要随意使用CLSCTX_
ALL(在ATL中,它是个缺省值),因为在没有安装DCOM的Windows95系统上会导致失败。

riid
请求接口的IID。例如,可以传递IID_IShellLink获得IShellLink接口指针。
ppv
接口指针的地址。COM库通过这个参数返回请求的接口。
当你调用CoCreateInstance()时,它负责在注册表中查找COM服务器的位置,将服务器加
载到内存,并创建你所请求的coclass实例。
以下是一个调用的例子,创建一个CLSID_ShellLink对象的实例并请求指向这个对象IShe
llLink接口指针。
HRESULT hr;
IShellLink* pISL;

hr = CoCreateInstance ( CLSID_ShellLink, // coclass 的CLSID
NULL, // 不是用聚合
CLSCTX_INPROC_SERVER, // 服务器类型
IID_IShellLink, // 接口的IID
(void**) &pISL ); // 指向接口的指针

if ( SUCCEEDED ( hr ) )
{
// 用pISL调用方法
}
else
{
// 不能创建COM对象,hr 为出错代码
}

首先声明一个接受CoCreateInstance()返回值的HRESULT和IShellLink指针。调用CoCrea
teInstance()来创建新的COM对象。如果hr接受到一个表示成功的代码,则SUCCEEDED宏
返回TRUE,否则返回FALSE。FAILED是一个与SUCCEEDED对应的宏用来检查失败代码。
删除COM对象
前面说过,你不用释放COM对象,只要告诉它们你已经用完对象。IUnknown是每一个COM
对象必须实现的接口,它有一个方法,Release()。调用这个方法通知COM对象你不再需
要对象。一旦调用了这个方法之后,就不能再次使用这个接口,因为这个COM对象可能从
此就从内存中消失了。
如果你的应用程序使用许多不同的COM对象,因此在用完某个接口后调用Release()就显
得非常重要。如果你不释放接口,这个COM对象(包含代码的DLLs)将保留在内存中,这
会增加不必要的开销。如果你的应用程序要长时间运行,就应该在应用程序处于空闲期
间调用CoFreeUnusedLibraries() API。这个API将卸载任何没有明显引用的COM服务器,
因此这也降低了应用程序使用的内存开销。
继续用上面的例子来说明如何使用Release():
// 像上面一样创建COM 对象, 然后,

if ( SUCCEEDED ( hr ) )
{
// 用pISL调用方法

// 通知COM 对象不再使用它
pISL->Release();
}

接下来将详细讨论IUnknown接口。
基本接口——IUnknown
每一个COM接口都派生于IUnknown。这个名字有点误导人,其中没有未知(Unknown)接
口的意思。它的原意是如果有一个指向某COM对象的IUnknown指针,就不用知道潜在的对
象是什么,因为每个COM对象都实现IUnknown。

IUnknown 有三个方法:

AddRef() – 通知COM对象增加它的引用计数。如果你进行了一次接口指针的拷贝,就必
须调用一次这个方法,并且原始的值和拷贝的值两者都要用到。在本文的例子中没有用
到AddRef()方法。
Release() – 通知COM对象减少它的引用计数。参见前面的Release()示例代码段。
QueryInterface() – 从COM对象请求一个接口指针。当coclass实现一个以上的接口时
,就要用到这个方法。
前面已经看到了Release()的使用,但如何使用QueryInterface()呢?当你用CoCreateIns
tance()创建对象的时候,你得到一个返回的接口指针。如果这个COM对象实现一个以上
的接口(不包括IUnknown),你就必须用QueryInterface()方法来获得任何你需要的附
加的接口指针。QueryInterface()的原型如下:
HRESULT IUnknown::QueryInterface (
REFIID iid,
void** ppv );


以下是参数解释:
iid
所请求的接口的IID。
ppv
接口指针的地址,QueryInterface()通过这个参数在成功时返回这个接口。
让我们继续外壳链接的例子。它实现了IShellLink 和IPersistFile接口。如果你已经有
一个IShellLink指针,pISL,可以从COM对象请求IPersistFile接口:
HRESULT hr;
IPersistFile* pIPF;
hr = pISL->QueryInterface ( IID_IPersistFile, (void**) &pIPF );

然后使用SUCCEEDED宏检查hr的值以确定QueryInterface()的调用情况,如果成功的话你
就可以象使用其它接口指针那样使用新的接口指针,pIPF。但必须记住调用pIPF->Relea
se()通知COM对象已经用完这个接口。
仔细做好串处理
这一部分将花点时间来讨论如何在COM代码中处理串。如果你熟悉Unicode 和ANSI,并知
道如何对它们进行转换的话,你就可以跳过这一部分,否则还是读一下这一部分的内容

不管什么时候,只要COM方法返回一个串,这个串都是Unicode串(这里指的是写入COM规
范的所有方法)。Unicode是一种字符编码集,类似ASCII,但用两个字节表示一个字符
。如果你想更好地控制或操作串的话,应该将它转换成TCHAR类型串。
TCHAR和以_t开头的函数(如_tcscpy())被设计用来让你用相同的源代码处理Unicode和
ANSI串。在大多数情况下编写的代码都是用来处理ANSI串和ANSI WindowsAPIs,所以在
下文中,除非另外说明,我所说的字符/串都是指TCHAR类型。你应该熟练掌握TCHAR类型
,尤其是当你阅读其他人写的有关代码时,要特别注意TCHAR类型。
当你从某个COM方法返回得到一个Unicode串时,可以用下列几种方法之一将它转换成cha
r类型串:

1、调用 WideCharToMultiByte() API。
2、调用CRT 函数wcstombs()。
3、使用CString 构造器或赋值操作(仅用于MFC )。
4、使用ATL 串转换宏。
WideCharToMultiByte()
你可以用WideCharToMultiByte()将一个Unicode串转换成一个ANSI串。此函数的原型如
下:
int WideCharToMultiByte (
UINT CodePage,
DWORD dwFlags,
LPCWSTR lpWideCharStr,
int cchWideChar,
LPSTR lpMultiByteStr,
int cbMultiByte,
LPCSTR lpDefaultChar,
LPBOOL lpUsedDefaultChar );


以下是参数解释:
CodePage
Unicode字符转换成的代码页。你可以传递CP_ACP来使用当前的ANSI代码页。代码页是25
6个字符集。字符0——127与ANSI编码一样。字符128——255与ANSI字符不同,它可以包
含图形字符或者读音符号。每一种语言或地区都有其自己的代码页,所以使用正确的代
码页对于正确地显示重音字符很重要。
dwFlags
dwFlags 确定Windows如何处理“复合” Unicode字符,它是一种后面带读音符号的字符
。如è就是一个复合字符。如果这些字符在CodePage参数指定的代码页中,不会出什么
事。否则,Windows必须对之进行转换。
传递WC_COMPOSITECHECK使得这个API检查非映射复合字符。
传递WC_SEPCHARS使得Windows将字符分为两段,即字符加读音,如e`。
传递WC_DISCARDNS使得Windows丢弃读音符号。
传递WC_DEFAULTCHAR使得Windows用lpDefaultChar参数中说明的缺省字符替代复合字符

缺省行为是WC_SEPCHARS。
lpWideCharStr
要转换的Unicode串。
cchWideChar
lpWideCharStr在Unicode 字符中的长度。通常传递-1,表示这个串是以0x00结尾。
lpMultiByteStr
接受转换的串的字符缓冲
cbMultiByte
lpMultiByteStr的字节大小。
lpDefaultChar
可选——当dwFlags包含WC_COMPOSITECHECK | WC_DEFAULTCHAR并且某个Unicode字符不
能被映射到同等的ANSI串时所传递的一个单字符ANSI串,包含被插入的“缺省”字符。
可以传递NULL,让API使用系统缺省字符(一种写法是一个问号)。
lpUsedDefaultChar
可选——指向BOOL类型的一个指针,设置它来表示是否缺省字符曾被插入ANSI串。可以
传递NULL来忽略这个参数。
我自己都有点晕菜了……!,万事开头难啊……,不搞清楚这些东西就很难搞清楚COM的
串处理。何况文档中列出的比实际应用的要复杂得多。下面就给出了如何使用这个API的
例子:
// 假设已经有了一个Unicode 串 wszSomeString...
char szANSIString [MAX_PATH];

WideCharToMultiByte ( CP_ACP, // ANSI 代码页
WC_COMPOSITECHECK, // 检查重音字符
wszSomeString, // 原Unicode 串
-1, // -1 意思是串以0x00结尾
szANSIString, // 目的char字符串
sizeof(szANSIString), // 缓冲大小
NULL, // 肥缺省字符串
NULL ); // 忽略这个参数
调用这个函数后,szANSIString将包含Unicode串的ANSI版本。

wcstombs()
这个CRT函数wcstombs()是个简化版,但它终结了WideCharToMultiByte()的调用,所以
最终结果是一样的。其原型如下:
size_t wcstombs (
char* mbstr,
const wchar_t* wcstr,
size_t count );

以下是参数解释:
mbstr
接受结果ANSI串的字符(char)缓冲。
wcstr
要转换的Unicode串。
count
mbstr参数所指的缓冲大小。

wcstombs()在它对WideCharToMultiByte()的调用中使用WC_COMPOSITECHECK |
WC_SEPCHARS标志。用wcstombs()转换前面例子中的Unicode串,结果一样:

wcstombs ( szANSIString, wszSomeString, sizeof(szANSIString) );
CString
MFC中的CString包含有构造函数和接受Unicode串的赋值操作,所以你可以用CString来
实现转换。例如:

// 假设有一个Unicode串wszSomeString...

CString str1 ( wszSomeString ); // 用构造器转换
CString str2;

str2 = wszSomeString; // 用赋值操作转换

ATL宏
ATL有一组很方便的宏用于串的转换。W2A()用于将Unicode串转换为ANSI串(记忆方法是
“wide to ANSI”——宽字符到ANSI)。实际上使用OLE2A()更精确,“OLE”表示的意
思是COM串或者OLE串。下面是使用这些宏的例子:

#include

// 还是假设有一个Unicode串wszSomeString...

{
char szANSIString [MAX_PATH];
USES_CONVERSION; // 声明这个宏要使用的局部变量

lstrcpy ( szANSIString, OLE2A(wszSomeString) );
}

OLE2A()宏“返回”转换的串的指针,但转换的串被存储在某个临时栈变量中,所以要用
lstrcpy()来获得自己的拷贝。其它的几个宏是W2T()(Unicode 到 TCHAR)以及W2CT()
(Unicode到常量TCHAR串)。
有个宏是OLE2CA()(Unicode到常量char串),可以被用到上面的例子中,OLE2CA()实际
上是个更正宏,因为lstrcpy()的第二个参数是一个常量char*,关于这个问题本文将在
以后作详细讨论。
另一方面,如果你不想做以上复杂的串处理,尽管让它还保持为Unicode串,如果编写的
是控制台应用程序,输出/显示Unicode串时应该用全程变量std::wcout,如:

wcout << wszSomeString;

但是要记住,std::wcout只认Unicode,所以你要是“正常”串的话,还得用std::cout
输出/显示。对于Unicode串文字量,要使用前缀L标示,如:

wcout << L"The Oracle says..." << endl << wszOracleResponse;

如果保持串为Unicode,编程时有两个限制:

—— 必须使用wcsXXX() Unicode串处理函数,如wcslen()。
—— 在Windows 9x环境中不能在Windows API中传递Unicode串。要想编写能在9x和NT上
都能运行的应用,必须使用TCHAR类型,详情请参考MSDN。

用例子代码总结上述内容
下面用两个例子演示本文所讲的COM概念。代码中还包含了本文的例子工程。
使用单接口COM对象
第一个例子展示的是单接口COM对象。这可能是你碰到得最简单的例子。它使用外壳中的
活动桌面组件对象类(CLSID_ActiveDesktop)来获得当前桌面墙纸的文件名。请确认系
统中安装了活动桌面(Active Desktop)。

以下是编程步骤:

初始化COM库。 (Initialize)
创建一个与活动桌面交互的COM对象,并取得IActiveDesktop接口。
调用COM对象的GetWallpaper()方法。
如果GetWallpaper()成功,则输出/显示墙纸文件名。
释放接口(Release())。
收回COM库(Uninitialize)。

WCHAR wszWallpaper [MAX_PATH];
CString strPath;
HRESULT hr;
IActiveDesktop* pIAD;

// 1. 初始化COM库(让Windows加载DLLs)。通常是在程序的InitInstance()中调

// CoInitialize ( NULL )或其它启动代码。MFC程序使用AfxOleInit()。

CoInitialize ( NULL );

// 2. 使用外壳提供的活动桌面组件对象类创建COM对象。
// 第四个参数通知COM需要什么接口(这里是IActiveDesktop).

hr = CoCreateInstance ( CLSID_ActiveDesktop,
NULL,
CLSCTX_INPROC_SERVER,
IID_IActiveDesktop,
(void**) &pIAD );

if ( SUCCEEDED(hr) )
{
// 3. 如果COM对象被创建成功,则调用这个对象的GetWallpaper() 方法。
hr = pIAD->GetWallpaper ( wszWallpaper, MAX_PATH, 0 );

if ( SUCCEEDED(hr) )
{
// 4. 如果 GetWallpaper() 成功,则输出它返回的文件名字。
// 注意这里使用wcout 来显示Unicode 串wszWallpaper. wcout 是
// Unicode 专用,功能与cout.相同。
wcout << L"Wallpaper path is:n " << wszWallpaper << endl <<
endl;
}
else
{
cout << _T("GetWallpaper() failed.") << endl << endl;
}

// 5. 释放接口。
pIAD->Release();
}
else
{
cout << _T("CoCreateInstance() failed.") << endl << endl;
}

// 6. 收回COM库。MFC 程序不用这一步,它自动完成。
CoUninitialize();

在这个例子中,输出/显示Unicode 串 wszWallpaper用的是std::wcout。

使用多接口的COM对象
第二个例子展示了如何使用一个提供单接口的COM对象QueryInterface()函数。其中的代
码用外壳的Shell Link组件对象类创建我们在第一个例子中获得的墙纸文件的快捷方式

以下是编程步骤:

初始化COM 库。
创建一个用于建立快捷方式的COM 对象并取得IShellLink 接口。
调用IShellLink 接口的SetPath()方法
调用对象的QueryInterface()函数并取得IPersistFile接口。
调用IPersistFile 接口的Save()方法。
释放接口
收回COM库

CString sWallpaper = wszWallpaper; // 将墙纸路径转换为ANSI
IShellLink* pISL;
IPersistFile* pIPF;

// 1. 初始化COM库(让Windows 加载DLLs). 通常在InitInstance()中调用
// CoInitialize ( NULL )或其它启动代码。MFC 程序使用AfxOleInit() 。

CoInitialize ( NULL );

// 2. 使用外壳提供的Shell Link组件对象类创建COM对象。.
// 第四个参数通知COM 需要什么接口(这里是IShellLink)。

hr = CoCreateInstance ( CLSID_ShellLink,
NULL,
CLSCTX_INPROC_SERVER,
IID_IShellLink,
(void**) &pISL );

if ( SUCCEEDED(hr) )
{
// 3. 设置快捷方式目标(墙纸文件)的路径。
hr = pISL->SetPath ( sWallpaper );

if ( SUCCEEDED(hr) )
{
// 4. 获取这个对象的第二个接口(IPersistFile)。
hr = pISL->QueryInterface ( IID_IPersistFile, (void**) &pIPF );

if ( SUCCEEDED(hr) )
{
// 5. 调用Save() 方法保存某个文件得快捷方式。第一个参数是
// Unicode 串。
hr = pIPF->Save ( L"C:wallpaper.lnk", FALSE );

// 6a. 释放IPersistFile 接口。
pIPF->Release();
}
}

// 6. 释放IShellLink 接口。
pISL->Release();
}

// 输出错误信息部分这里省略。

// 7. 收回COM 库。MFC 程序不用这一步,它自动完成。
CoUninitialize();

处理HRESULT
这一部分准备用SUCCEEDED 和 FAILED宏进行一些简单的出错处理。主要是深入研究从CO
M方法返回的HRESULT,以便达到完全理解和熟练应用。
HRESULT是个32位符号整数,其非负值表示成功,负值表示失败。HRESULT有三个域:程
度位(表示成功或失败),功能码和状态码。功能码表示HRESULT来自什么组件或程序。
微软给不同的组件多赋予功能码,如:COM、任务调度程序等都有功能码。功能码是个16
位的值,仅此而已,没有其它内在含义;它在数字和意义之间是随意关联的;类似GetLa
stError()返回的值。
如果你在winerror.h头文件中查找错误代码,会看到许多按照[功能]_[程度]_[描述]命
名规范列出的HRESULT值,由组件返回的通用的HRESULT(类似E_OUTOFMEMORY)在名字中
没有功能码。如,
REGDB_E_READREGDB: 功能码 = REGDB, 指“注册表数据库(registry database)”;
程度 = E 意思是错误(error);描述 = READREGDB 是对错误的描述(意思是不能读注
册表数据库)。
S_OK: 没有功能码——通用(generic)HRESULT;程度=S;表示成功(success);OK
是状态描述表示一切都好(everything''s OK)。
好在有一种比察看winerror.h文件更容易的方法来确定HRESULT的意思。使用VC提供的错
误查找工具(Error Lookup)可以轻松查到为HRESULT内建功能码。例如,假设你在CoCr
eateInstance()之前忘了调用CoInitialize()。CoCreateInstance()返回的值是0x80040
1F0。你只要将这个值输入到错误查找工具按“Look Up”按钮,便可以看到错误信息描
述“尚未调用CoInitialize”如下图所示:

另外一种查找HRESULT描述的方法是在调试器中。假设有一个HRESULT变量是hres。在Wat
ch窗口的左边框中输入“hres,hr”,表示想要看的值,“hr”便会通知VC显示HRESULT
所描述的值。如下图所示:


通过以上的讨论,想必你对COM编程有了初步的认识,本文第二部分将探讨COM的内部机
制。教你如何用C++编写自己的接口。

导出数据到Excel概述

silver6 | 01 九月, 2005 10:13

This stored procedure can be used to insert the result set of the
particular select statement into Excel file (c:ImportToExcel.xls,
by default).
You can pass the server name, user name, user password, the select
statement to execute, and the file name to store the results set,
as in the example below:

EXEC ExportToExcel @server = '.',
@uname = 'sa',
@QueryText = 'SELECT au_fname FROM pubs..authors',
@filename = 'c:ImportToExcel.xls'

/*
Version: SQL Server 7.0/2000
Created by: Alexander Chigrik
- all about MS SQL
(SQL Server Articles, FAQ, Scripts, Tips and Test Exams).

This stored procedure can be used to insert the result set of the
particular select statement into Excel file (c:ImportToExcel.xls,
by default).
You can pass the server name, user name, user password, the select
statement to execute, and the file name to store the results set,
as in the example below:

EXEC ExportToExcel @server = '.',
@uname = 'sa',
@QueryText = 'SELECT au_fname FROM pubs..authors',
@filename = 'c:ImportToExcel.xls'
*/

IF OBJECT_ID('ExportToExcel') IS NOT NULL DROP PROC ExportToExcel
GO

CREATE PROCEDURE ExportToExcel (
@server sysname = null,
@uname sysname = null,
@pwd sysname = null,
@QueryText varchar(200) = null,
@filename varchar(200) = 'c:ImportToExcel.xls'
)
AS
DECLARE @SQLServer int,
@QueryResults int,
@CurrentResultSet int,
@object int,
@WorkBooks int,
@WorkBook int,
@Range int,
@hr int,
@Columns int,
@Rows int,
@indColumn int,
@indRow int,
@off_Column int,
@off_Row int,
@code_str varchar(100),
@result_str varchar(255)

IF @QueryText IS NULL
BEGIN
PRINT 'Set the query string'
RETURN
END

-- Sets the server to the local server
IF @server IS NULL SELECT @server = @@servername

-- Sets the username to the current user name
IF @uname IS NULL SELECT @uname = SYSTEM_USER

SET NOCOUNT ON

EXEC @hr = sp_OACreate 'SQLDMO.SQLServer', @SQLServer OUT
IF @hr <> 0
BEGIN
PRINT 'error create SQLDMO.SQLServer'
RETURN
END

-- Connect to the SQL Server
IF @pwd IS NULL
BEGIN
EXEC @hr = sp_OAMethod @SQLServer, 'Connect', null, @server, @uname
IF @hr <> 0
BEGIN
PRINT 'error Connect'
RETURN
END
END
ELSE
BEGIN
EXEC @hr = sp_OAMethod @SQLServer, 'Connect', null, @server, @uname, @pwd
IF @hr <> 0
BEGIN
PRINT 'error Connect'
RETURN
END
END

SELECT @result_str = 'ExecuteWithResults("' + @QueryText + '")'
EXEC @hr = sp_OAMethod @SQLServer, @result_str, @QueryResults OUT
IF @hr <> 0
BEGIN
PRINT 'error with method ExecuteWithResults'
RETURN
END

EXEC @hr = sp_OAMethod @QueryResults, 'CurrentResultSet', @CurrentResultSet OUT
IF @hr <> 0
BEGIN
PRINT 'error get CurrentResultSet'
RETURN
END

EXEC @hr = sp_OAMethod @QueryResults, 'Columns', @Columns OUT
IF @hr <> 0
BEGIN
PRINT 'error get Columns'
RETURN
END

EXEC @hr = sp_OAMethod @QueryResults, 'Rows', @Rows OUT
IF @hr <> 0
BEGIN
PRINT 'error get Rows'
RETURN
END

EXEC @hr = sp_OACreate 'Excel.Application', @object OUT
IF @hr <> 0
BEGIN
PRINT 'error create Excel.Application'
RETURN
END

EXEC @hr = sp_OAGetProperty @object, 'WorkBooks', @WorkBooks OUT
IF @hr <> 0
BEGIN
PRINT 'error create WorkBooks'
RETURN
END

EXEC @hr = sp_OAGetProperty @WorkBooks, 'Add', @WorkBook OUT
IF @hr <> 0
BEGIN
PRINT 'error with method Add'
RETURN
END

EXEC @hr = sp_OAGetProperty @object, 'Range("A1")', @Range OUT
IF @hr <> 0
BEGIN
PRINT 'error create Range'
RETURN
END

SELECT @indRow = 1
SELECT @off_Row = 0
SELECT @off_Column = 1

WHILE (@indRow <= @Rows)
BEGIN
SELECT @indColumn = 1

WHILE (@indColumn <= @Columns)
BEGIN

EXEC @hr = sp_OAMethod @QueryResults, 'GetColumnString', @result_str OUT, @indRow, @indColumn
IF @hr <> 0
BEGIN
PRINT 'error get GetColumnString'
RETURN
END

EXEC @hr = sp_OASetProperty @Range, 'value', @result_str
IF @hr <> 0
BEGIN
PRINT 'error set value'
RETURN
END

EXEC @hr = sp_OAGetProperty @Range, 'Offset', @Range OUT, @off_Row, @off_Column
IF @hr <> 0
BEGIN
PRINT 'error get Offset'
RETURN
END

SELECT @indColumn = @indColumn + 1

END

SELECT @indRow = @indRow + 1
SELECT @code_str = 'Range("A' + LTRIM(str(@indRow)) + '")'
EXEC @hr = sp_OAGetProperty @object, @code_str, @Range OUT
IF @hr <> 0
BEGIN
PRINT 'error create Range'
RETURN
END

END

SELECT @result_str = 'exec master..xp_cmdshell ''del ' + @filename + ''', no_output'
EXEC(@result_str)
SELECT @result_str = 'SaveAs("' + @filename + '")'
EXEC @hr = sp_OAMethod @WorkBook, @result_str
IF @hr <> 0
BEGIN
PRINT 'error with method SaveAs'
RETURN
END

EXEC @hr = sp_OAMethod @WorkBook, 'Close'
IF @hr <> 0
BEGIN
PRINT 'error with method Close'
RETURN
END

EXEC @hr = sp_OADestroy @object
IF @hr <> 0
BEGIN
PRINT 'error destroy Excel.Application'
RETURN
END

EXEC @hr = sp_OADestroy @SQLServer
IF @hr <> 0
BEGIN
PRINT 'error destroy SQLDMO.SQLServer'
RETURN
END
GO

 查看全文

extremeTable 中文说明

silver6 | 30 八月, 2005 18:43

1、何为 extremeTable,又一个开源taglib
extremeTable,开源的jsp 自定义标签,以表格的形式显示数据,当前最新版本为 1.0.1-M1.
它是一个类似display tag,valueList 等开源产品.
homepage: http://extremecomponents.org/
download: http://sourceforge.net/projects/extremecomp/

开源产品作者:
Jeff Johnston ,现居住美国,圣路易斯.
六年web应用软件开发经验,eXtremeComponents最初的创建者. 负责设计及大部分的编码。

其它还包括Paul Horn ,eXtremeTree的技术设计, 以及大部分的编码;
Dave Goodin,Brad Parks等.

主要特色
1、导出EXCEL以及pdf无需再另写jsp(这个基本与valuelist作比较,因为以前用valueList的时候每写一个table都要再写一个excel.jsp)
2、扩展性比较强,基本上想怎样改就怎样改,对jar影响比较少。
3、另外据官方声称有以下四点

  • Fast ( 本人曾小测一次,三千纪录情况下,效率基本与valuelist持平)
  • Efficient
  • Easy ( 得确很容易使用与理解加扩展)
  • Reliable

    安装要求
    1、Servlet 2.3 或更高
    2、 JDK 1.3.1 或更高

    最小的Jars需求
    1、commons-beanutils 1.6
    2、commons-collections 3.0
    3、 commons-lang 2.0
    4、 commons-logging 1.0.4
    5、 standard 1.0.2

    PDF 导出要用到的包:
    1、 avalon-framework 4.0
    2、batik 1.5-fop-0.20-5
    3、 fop 0.20.5
    4、 xalan 2.5.1
    5、 xercesImpl 2.6.1
    6、 xml-apis 2.0.2
    XLS 导出要用到的包:
    1、 poi-2.5.1.jar

    2、安装与测试

    下载解压到的主要文件包括

    [1]src源文件
    [2]extremecomponents.jar以及其它所依赖的包

    [3]tld文件
    extremecomponents.tld

    [4]一组默认样式及图片
    extremecomponents.css

    [5]用以校验安装的测试页面
    test.jsp

    [6]doc文档,比较详细

    快速配置安装
    web app目录结构
    /ROOT
      /WEB-INF/web.xml
     /tld/extremecomponents.tld
    /lib
    /classes/extremecomponents.properties
    [extremecomponents.properties文件可到sourceorgextremecomponentstablecore中得到]
     /images/*.jpg [一组默认样式及图片]
     /css/extremecomponents.css
     /test.jsp
     /index.jsp [用于学习以及扩展测试用代码请见下]

    web.xml 配置
    包括taglib uri 定义以及导出文件filter,由于只是手板功夫,这里就略过了,相关代码如下:

    <taglib>
    <taglib-uri>/tld/extremecomponentstaglib-uri>
    <taglib-location>/WEB-INF/tld/extremecomponents.tldtaglib-location>
    taglib>

    <filter>
    <filter-name>eXtremeExportfilter-name>
    <filter-class>org.extremecomponents.table.filter.ExportFilterfilter-class>
    filter>
    <filter-mapping>
    <filter-name>eXtremeExportfilter-name>
    <url-pattern>/*url-pattern>
    filter-mapping>


    配置好所有后,开tomcat,测试浏览http://your_web_app/test.jsp,看到

    Congratulations!! You have successfully configured eXtremeTable!
    恭喜你,这表示安装成功!


    3、动手学习这个taglib
    建index.jsp页面,修改代码如下

    @ page contentType="text/html;charset=GBK"
    @ page import="java.util.*"
    @ taglib uri="/tld/extremecomponents" prefix="ec"
    在本页要用到jstl-->
    @ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"
    使用include的方式-->
    <link rel="stylesheet" type="text/css" href=""/extremecomponents.css"/>">


    List goodss
    = new ArrayList();
    for (int i = 1; i 10; i++)
    {
    Map goods
    = new java.util.HashMap();
    goods.put(
    "code", "A00"+i);
    goods.put(
    "name", "面包"+i);
    goods.put(
    "status", "A:valid");
    goods.put(
    "born", new Date());
    goodss.add(goods);
    }

    request.setAttribute(
    "goodss", goodss);

    <ec:table
    collection
    ="goodss"
    action
    ="${pageContext.request.contextPath}/test.jsp"
    imagePath
    ="${pageContext.request.contextPath}/images/*.gif"
    cellpadding
    ="1"
    title
    ="my bread">
    <ec:column property="code"/>
    <ec:column property="name"/>
    <ec:column property="status"/>
    <ec:column property="born" cell="date" format="yyyy-MM-dd"/>
    ec:table>



    效果如下:
    ec1.jpg


    [1] 1.0.1-M1 版支持国际化
    修改web.xml文件增加

    <context-param>
    <param-name>extremecomponentsResourceBundleLocationparam-name>
    <param-value>com.itorgan.tags.extreme.extremetableResourceBundleparam-value>
    context-param>



    意指到 com.itorgan.tags.extreme 下找 extremetableResourceBundle_[language]_[country].properties 文件

    extremetableResourceBundle_en_US.properties代码如下
    table.statusbar.resultsFound={0} results found, displaying {1} to {2}
    table.statusbar.noResultsFound=There were no results found.
    table.toolbar.showAll=Show All

    extremetableResourceBundle_zh_CN.properties如下.
    table.statusbar.resultsFound={0} u6761u7EAAu5F55u7B26u5408u6761u4EF6, u73B0u5728u662Fu7B2C {1} u81F3 {2} u6761u7EAAu5F55
    table.statusbar.noResultsFound=u6CA1u6709u8981u67E5u8BE2u7684u7EAAu5F55u3002
    table.toolbar.showAll=u6240 u6709

    补充:中文 - > Unicode编码 可通过反编译class文件或用native2ascii命令得到 。

    然后在table标签中增加locale属性即可切换


    [3] 样式修改
    基本的HTML结构
    [7] 解决excel中文问题
    继承XlsView.java
    ec另一亮点就帮我们写好了form ,如上代码:
    设置form name以及action
  • <ec:table
    ………………
    ………………
    ………………
    locale
    ="en_US"
    >

    <ec:table
    ………………
    ………………
    ………………
    locale
    ="zh_CN"
    >


    [2] 保留table的上一次状态
    是指,不管跳转到另一个后再返回,extremeTable会将之前的Filter,Sort参数保存到session中,以至返回看到的页面还是之前的状态.

    实现操作方法:
    修改extremecomponents.properties文件
    table.useSessionFilterSortParam=foo
    saveFilterSort="true" 注意:saveFilterSort="true"不能在properties文件中配置,只能在页面中设

     <ec:table
    ……………………
    saveFilterSort
    ="true"
    /ec:table>
    <a href="1.jsp">跳到a>

    新建一页面用于跳转的页面 1.jsp
    代码为

    <a href="test.jsp?foo=true">Backa>

    <div class="eXtremeTable" >
    <table border="0" cellpadding="0" cellspacing="0" width="100%" >
    <tr>
    <td class="title" ><span>标题-->span>td>
    <td align="right" >
    <table border="0" cellpadding="0" cellspacing="1" class="toolbar" >
    <tr>
    <form name="pres_toolbar" action="/extremesite/public/demo/presidents.jsp" >
    工具栏,包括上一页,下一页以及导出-->
    tr>
    <tr>
    form>
    tr>
    table>
    td>
    tr>
    table>

    <table id="pres" border="0" cellspacing="2" cellpadding="0" width="100%" class="tableRegion" >
    <tr>
    <td colspan="6" >
    <table border="0" cellpadding="0" cellspacing="0" width="100%" >
    <tr>
    <td class="statusBar" >43 results found, displaying 1 to 12 td>
    <td class="filterButtons" >td>
    tr>
    table>
    td>
    tr>

    <form name="pres_filter" action="/extremesite/public/demo/presidents.jsp" >
    <tr class="filter" id="filter" >
    -->
    tr>
    form>
    <tr>
    tableHead-->
    tr>
    <tbody class="tableBody" >
    <tr>
    column-->
    tr>
    tbody>
    table>
    div>


    extremeTable支持样式快速切换.可自定的样式包括column 的td以及table的一些属性,例如cellpadding等,
    另本人发现,在properties中如下设置tableHeader的样式是不行的.不知道是否一个BUG
    table.headerClass=itoTableHeader
    table.headerSortClass=itoTableHeaderSort

    只能继承一个HeaderCell

    public class HeaderCell extends org.extremecomponents.table.cell.HeaderCell
    {
    public final static String TABLE_HEADER = "itoTableHeader";
    public final static String TABLE_HEADER_SORT = "itoTableHeaderSort";

    新的样式代码:

    <LINK REL="stylesheet" HREF=""/style.css"/>" TYPE="text/css">
    collection="goodss"
    action="${pageContext.request.contextPath}/test.jsp"
    imagePath="${pageContext.request.contextPath}/images/*.gif"
    cellpadding="1"
    title="my bread"
    saveFilterSort="true"
    locale="zh_CN"
    >



    效果见下:
    ec[2].jpg

    [4] 实现 table width 自动累加
    原来的extremeTable 宽度要自己set。不会自动能过下面的column累加。
    本人作了个修改以达到自动累加,省得自己加写上去:
    查看htmlView.java 两处地方 
    toolbarPlacement
    tableStart可见两处地方要修改的


    [5] custom cell
    在properties文件中我们可观察到:

    table.cell_=display
    table.cell_currency=org.extremecomponents.table.cell.NumberCell
    table.cell_number=org.extremecomponents.table.cell.NumberCell
    table.cell_display=org.extremecomponents.table.cell.DisplayCell
    table.cell_date=org.extremecomponents.table.cell.DateCell

    当 column 默认使用org.extremecomponents.table.cell.DisplayCell

    public class DisplayCell extends BaseCell {

    public String html() {
    HtmlBuilder html
    = new HtmlBuilder();

    html.append(startTD());

    Object value
    = column.getValue();
    if (value != null && StringUtils.isNotEmpty(value.toString())) {
    html.append(value);
    }
    else {
    html.append(
    " ");
    }


    html.append(endTD());

    return html.toString();
    }

    }


    ec已其它cell
    日期格式化: cell = " date " format = " yyyy-MM-dd "
    数字格式化: cell="currency" format="###,###,##0.00"


    另外,extremeTable支持自定义cell
    在这里我以一个简单的例子[以input框的形式出现] 说明如何实现这一方便的扩展

    public class DemoInput extends BaseCell
    {
    public String html()
    {
    Integer rowNum
    = rowcount;
    HtmlBuilder html
    = new HtmlBuilder();
    html.append(startTD());
    Object value
    = column.getValue();
    HtmlBuilder input
    = new HtmlBuilder();
    input.input(
    "text");
    input.name(column.getProperty()
    + "_" + rowNum);
    input.value(value.toString());
    input.close();
    html.append(input.toString());
    html.append(endTD());
    return html.toString();
    }

    }


    properties文件增加

    table.cell_demoInput =org.extremecomponents.table.cell.DemoInput

    jsp代码

    <ec:column property="code" title="编号" width="100" cell="demoInput" styleClass="GridTd"/>

    效果显示为
    当然这只是一个简单的demo以说明如何自定义cell
    如上面你可以简单的实现同样功能

    <ec:column property="code" title="编号" width="100" styleClass="GridTd">
    <input type="text" value="${goodss.code}" name="code_${ROWCOUNT}">
    ec:column>



    [6]Extended Attributes
    新版本支持Extended Attributes,方便了用户扩展,记得0.9版本时还要我修改N个地方,现在为table,column增加attribute方便多了.
    为table增加一个height的属性

    public class TableTag extends org.extremecomponents.table.tag.TableTag
    {
    //div 的高度
    private String height;

    一般分类 :: 评论 (0) :: 静态链接网址 :: 引用 (0)

    一篇关于web.xml配置的详细说明

    silver6 | 01 一月, 2000 00:00

    1 定义头和根元素

    部署描述符文件就像所有XML文件一样,必须以一个XML头开始。这个头声明可以使用的XML版本并给出文件的字符编码。
    DOCYTPE声明必须立即出现在此头之后。这个声明告诉服务器适用的servlet规范的版本(如2.2或2.3)并指定管理此文件其余部分内容的语法的DTD(Document Type Definition,文档类型定义)。
    所有部署描述符文件的顶层(根)元素为web-app。请注意,XML元素不像HTML,他们是大小写敏感的。因此,web-App和WEB-APP都是不合法的,web-app必须用小写。

    2 部署描述符文件内的元素次序

    XML 元素不仅是大小写敏感的,而且它们还对出现在其他元素中的次序敏感。例如,XML头必须是文件中的第一项,DOCTYPE声明必须是第二项,而web- app元素必须是第三项。在web-app元素内,元素的次序也很重要。服务器不一定强制要求这种次序,但它们允许(实际上有些服务器就是这样做的)完全拒绝执行含有次序不正确的元素的Web应用。这表示使用非标准元素次序的web.xml文件是不可移植的。
    下面的列表给出了所有可直接出现在web-app元素内的合法元素所必需的次序。例如,此列表说明servlet元素必须出现在所有servlet-mapping元素之前。请注意,所有这些元素都是可选的。因此,可以省略掉某一元素,但不能把它放于不正确的位置。
    l icon icon元素指出IDE和GUI工具用来表示Web应用的一个和两个图像文件的位置。
    l display-name display-name元素提供GUI工具可能会用来标记这个特定的Web应用的一个名称。
    l description description元素给出与此有关的说明性文本。
    l context-param context-param元素声明应用范围内的初始化参数。
    l filter 过滤器元素将一个名字与一个实现javax.servlet.Filter接口的类相关联。
    l filter-mapping 一旦命名了一个过滤器,就要利用filter-mapping元素把它与一个或多个servlet或JSP页面相关联。
    l listener servlet API的版本2.3增加了对事件监听程序的支持,事件监听程序在建立、修改和删除会话或servlet环境时得到通知。Listener元素指出事件监听程序类。
    l servlet 在向servlet或JSP页面制定初始化参数或定制URL时,必须首先命名servlet或JSP页面。Servlet元素就是用来完成此项任务的。
    l servlet-mapping 服务器一般为servlet提供一个缺省的URL:
    http://host/webAppPrefix/servlet/ServletName。但是,常常会更改这个URL,以便servlet可以访问初始化参数或更容易地处理相对URL。在更改缺省URL时,使用servlet-mapping元素。
    l session-config 如果某个会话在一定时间内未被访问,服务器可以抛弃它以节省内存。可通过使用HttpSession的setMaxInactiveInterval方法明确设置单个会话对象的超时值,或者可利用session-config元素制定缺省超时值。
    l mime-mapping 如果Web应用具有想到特殊的文件,希望能保证给他们分配特定的MIME类型,则mime-mapping元素提供这种保证。
    l welcom-file-list welcome-file-list元素指示服务器在收到引用一个目录名而不是文件名的URL时,使用哪个文件。
    l error-page error-page元素使得在返回特定HTTP状态代码时,或者特定类型的异常被抛出时,能够制定将要显示的页面。
    l taglib taglib元素对标记库描述符文件(Tag Libraryu Descriptor file)指定别名。此功能使你能够更改TLD文件的位置,而不用编辑使用这些文件的JSP页面。
    l resource-env-ref resource-env-ref元素声明与资源相关的一个管理对象。
    l resource-ref resource-ref元素声明一个资源工厂使用的外部资源。
    l security-constraint security-constraint元素制定应该保护的URL。它与login-config元素联合使用
    l login-config 用login-config元素来指定服务器应该怎样给试图访问受保护页面的用户授权。它与sercurity-constraint元素联合使用。
    l security-role security-role元素给出安全角色的一个列表,这些角色将出现在servlet元素内的security-role-ref元素的role-name子元素中。分别地声明角色可使高级IDE处理安全信息更为容易。
    l env-entry env-entry元素声明Web应用的环境项。
    l ejb-ref ejb-ref元素声明一个EJB的主目录的引用。
    l ejb-local-ref ejb-local-ref元素声明一个EJB的本地主目录的应用。

    3 分配名称和定制的UL

    在web.xml中完成的一个最常见的任务是对servlet或JSP页面给出名称和定制的URL。用servlet元素分配名称,使用servlet-mapping元素将定制的URL与刚分配的名称相关联。
    3.1 分配名称
    为了提供初始化参数,对servlet或JSP页面定义一个定制URL或分配一个安全角色,必须首先给servlet或JSP页面一个名称。可通过 servlet元素分配一个名称。最常见的格式包括servlet-name和servlet-class子元素(在web-app元素内),如下所示:

    Test
    moreservlets.TestServlet

    这表示位于WEB-INF/classes/moreservlets/TestServlet的servlet已经得到了注册名Test。给 servlet一个名称具有两个主要的含义。首先,初始化参数、定制的URL模式以及其他定制通过此注册名而不是类名引用此servlet。其次,可在 URL而不是类名中使用此名称。因此,利用刚才给出的定义,URL
    http://host/webAppPrefix/servlet/Test 可用于 http://host/webAppPrefix/servlet/moreservlets.TestServlet 的场所。
    请记住:XML元素不仅是大小写敏感的,而且定义它们的次序也很重要。例如,web-app元素内所有servlet元素必须位于所有servlet- mapping元素(下一小节介绍)之前,而且还要位于5.6节和5.11节讨论的与过滤器或文档相关的元素(如果有的话)之前。类似地,servlet 的servlet-name子元素也必须出现在servlet-class之前。5.2节"部署描述符文件内的元素次序"将详细介绍这种必需的次序。
    例如,程序清单5-1给出了一个名为TestServlet的简单servlet,它驻留在moreservlets程序包中。因为此servlet是扎根在一个名为deployDemo的目录中的Web应用的组成部分,所以TestServlet.class放在deployDemo/WEB- INF/classes/moreservlets中。程序清单5-2给出将放置在deployDemo/WEB-INF/内的web.xml文件的一部分。此web.xml文件使用servlet-name和servlet-class元素将名称Test与TestServlet.class相关联。图 5-1和图5-2分别显示利用缺省URL和注册名调用TestServlet时的结果。

    程序清单5-1 TestServlet.java
    package moreservlets;

    import java.io.*;
    import javax.servlet.*;
    import javax.servlet.http.*;

    /** Simple servlet used to illustrate servlet naming
    * and custom URLs.
    *


    * Taken from More Servlets and JavaServer Pages
    * from Prentice Hall and Sun Microsystems Press,
    *

    URI: " + uri + "

    n" +
    "");
    }
    }


    程序清单5-2 web.xml(说明servlet名称的摘录)

    PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
    "
    http://www.moreservlets.com/.
    * © 2002 Marty Hall; may be freely used or adapted.
    */

    public class TestServlet extends HttpServlet {
    public void doGet(HttpServletRequest request,
    HttpServletResponse response)
    throws ServletException, IOException {
    response.setContentType("text/html");
    PrintWriter out = response.getWriter();
    String uri = request.getRequestURI();
    out.println(ServletUtilities.headWithTitle("Test Servlet") +
    "n" +
    "
    http://java.sun.com/dtd/web-app_2_3.dtd">




    Test
    moreservlets.TestServlet




    3.2 定义定制的URL
    大多数服务器具有一个缺省的serlvet URL:
    http://host/webAppPrefix/servlet/packageName.ServletName。虽然在开发中使用这个URL很方便,但是我们常常会希望另一个URL用于部署。例如,可能会需要一个出现在Web应用顶层的URL(如,http: //host/webAppPrefix/Anyname),并且在此URL中没有servlet项。位于顶层的URL简化了相对URL的使用。此外,对许多开发人员来说,顶层URL看上去比更长更麻烦的缺省URL更简短。
    事实上,有时需要使用定制的URL。比如,你可能想关闭缺省URL映射,以便更好地强制实施安全限制或防止用户意外地访问无初始化参数的servlet。如果你禁止了缺省的URL,那么你怎样访问servlet呢?这时只有使用定制的URL了。
    为了分配一个定制的URL,可使用servlet-mapping元素及其servlet-name和url-pattern子元素。Servlet- name元素提供了一个任意名称,可利用此名称引用相应的servlet;url-pattern描述了相对于Web应用的根目录的URL。url- pattern元素的值必须以斜杠(/)起始。
    下面给出一个简单的web.xml摘录,它允许使用URL
    http://host/webAppPrefix/UrlTest而不是http://host/webAppPrefix/servlet/Test
    http: //host/webAppPrefix/servlet/moreservlets.TestServlet。请注意,仍然需要XML头、 DOCTYPE声明以及web-app封闭元素。此外,可回忆一下,XML元素出现地次序不是随意的。特别是,需要把所有servlet元素放在所有 servlet-mapping元素之前。

    Test
    moreservlets.TestServlet



    Test
    /UrlTest

    URL模式还可以包含通配符。例如,下面的小程序指示服务器发送所有以Web应用的URL前缀开始,以..asp结束的请求到名为BashMS的servlet。

    BashMS
    msUtils.ASPTranslator



    BashMS
    /*.asp

    3.3 命名JSP页面
    因为JSP页面要转换成sevlet,自然希望就像命名servlet一样命名JSP页面。毕竟,JSP页面可能会从初始化参数、安全设置或定制的URL中受益,正如普通的serlvet那样。虽然JSP页面的后台实际上是servlet这句话是正确的,但存在一个关键的猜疑:即,你不知道JSP页面的实际类名(因为系统自己挑选这个名字)。因此,为了命名JSP页面,可将jsp-file元素替换为servlet-calss元素,如下所示:

    Test
    /TestPage.jsp

    命名JSP页面的原因与命名servlet的原因完全相同:即为了提供一个与定制设置(如,初始化参数和安全设置)一起使用的名称,并且,以便能更改激活 JSP页面的URL(比方说,以便多个URL通过相同页面得以处理,或者从URL中去掉.jsp扩展名)。但是,在设置初始化参数时,应该注意,JSP页面是利用jspInit方法,而不是init方法读取初始化参数的。
    例如,程序清单5-3给出一个名为TestPage.jsp的简单JSP页面,它的工作只是打印出用来激活它的URL的本地部分。TestPage.jsp放置在deployDemo应用的顶层。程序清单5-4给出了用来分配一个注册名PageName,然后将此注册名与
    http://host/webAppPrefix/UrlTest2/anything 形式的URL相关联的web.xml文件(即,deployDemo/WEB-INF/web.xml)的一部分。

    程序清单5-3 TestPage.jsp






    URI:






    程序清单5-4 web.xml(说明JSP页命名的摘录)

    PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
    "
    http://java.sun.com/dtd/web-app_2_3.dtd">




    PageName
    /TestPage.jsp



    PageName
    /UrlTest2/*





    4 禁止激活器servlet

    对servlet或JSP页面建立定制URL的一个原因是,这样做可以注册从 init(servlet)或jspInit(JSP页面)方法中读取得初始化参数。但是,初始化参数只在是利用定制URL模式或注册名访问 servlet或JSP页面时可以使用,用缺省URL
    http://host/webAppPrefix/servlet/ServletName 访问时不能使用。因此,你可能会希望关闭缺省URL,这样就不会有人意外地调用初始化servlet了。这个过程有时称为禁止激活器servlet,因为多数服务器具有一个用缺省的servlet URL注册的标准servlet,并激活缺省的URL应用的实际servlet。
    有两种禁止此缺省URL的主要方法:
    l 在每个Web应用中重新映射/servlet/模式。
    l 全局关闭激活器servlet。
    重要的是应该注意到,虽然重新映射每个Web应用中的/servlet/模式比彻底禁止激活servlet所做的工作更多,但重新映射可以用一种完全可移植的方式来完成。相反,全局禁止激活器servlet完全是针对具体机器的,事实上有的服务器(如ServletExec)没有这样的选择。下面的讨论对每个Web应用重新映射/servlet/ URL模式的策略。后面提供在Tomcat中全局禁止激活器servlet的详细内容。
    4.1 重新映射/servlet/URL模式
    在一个特定的Web应用中禁止以
    http://host/webAppPrefix/servlet/ 开始的URL的处理非常简单。所需做的事情就是建立一个错误消息servlet,并使用前一节讨论的url-pattern元素将所有匹配请求转向该 servlet。只要简单地使用:
    /servlet/*
    作为servlet-mapping元素中的模式即可。
    例如,程序清单5-5给出了将SorryServlet servlet(程序清单5-6)与所有以
    http://host/webAppPrefix/servlet/ 开头的URL相关联的部署描述符文件的一部分。

    程序清单5-5 web.xml(说明JSP页命名的摘录)

    PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
    "
    http://java.sun.com/dtd/web-app_2_3.dtd">




    Sorry
    moreservlets.SorryServlet



    Sorry
    /servlet/*





    程序清单5-6 SorryServlet.java
    package moreservlets;

    import java.io.*;
    import javax.servlet.*;
    import javax.servlet.http.*;

    /** Simple servlet used to give error messages to
    * users who try to access default servlet URLs
    * (i.e.,
    http://host/webAppPrefix/servlet/ServletName)
    * in Web applications that have disabled this
    * behavior.
    *


    * Taken from More Servlets and JavaServer Pages
    * from Prentice Hall and Sun Microsystems Press,
    *

    " + title + "

    n" +
    "Sorry, access to servlets by means ofn" +
    "URLs that begin withn" +
    "
    http://www.moreservlets.com/.
    * © 2002 Marty Hall; may be freely used or adapted.
    */

    public class SorryServlet extends HttpServlet {
    public void doGet(HttpServletRequest request,
    HttpServletResponse response)
    throws ServletException, IOException {
    response.setContentType("text/html");
    PrintWriter out = response.getWriter();
    String title = "Invoker Servlet Disabled.";
    out.println(ServletUtilities.headWithTitle(title) +
    "n" +
    "
    http://host/webAppPrefix/servlet/n" +
    "has been disabled.n" +
    "");
    }

    public void doPost(HttpServletRequest request,
    HttpServletResponse response)
    throws ServletException, IOException {
    doGet(request, response);
    }
    }


    4.2 全局禁止激活器:Tomcat
    Tomcat 4中用来关闭缺省URL的方法与Tomcat 3中所用的很不相同。下面介绍这两种方法:
    1.禁止激活器: Tomcat 4
    Tomcat 4用与前面相同的方法关闭激活器servlet,即利用web.xml中的url-mapping元素进行关闭。不同之处在于Tomcat使用了放在 install_dir/conf中的一个服务器专用的全局web.xml文件,而前面使用的是存放在每个Web应用的WEB-INF目录中的标准 web.xml文件。
    因此,为了在Tomcat 4中关闭激活器servlet,只需在install_dir/conf/web.xml中简单地注释出/servlet/* URL映射项即可,如下所示:

    invoker
    /servlet/*

    -->
    再次提醒,应该注意这个项是位于存放在install_dir/conf的Tomcat专用的web.xml文件中的,此文件不是存放在每个Web应用的WEB-INF目录中的标准web.xml。
    2.禁止激活器:Tomcat3
    在Apache Tomcat的版本3中,通过在install_dir/conf/server.xml中注释出InvokerInterceptor项全局禁止缺省 servlet URL。例如,下面是禁止使用缺省servlet URL的server.xml文件的一部分。
    className="org.apache.tomcat.request.InvokerInterceptor"
    debug="0" prefix="/servlet/" />
    -->

    5 初始化和预装载servlet与JSP页面

    这里讨论控制servlet和JSP页面的启动行为的方法。特别是,说明了怎样分配初始化参数以及怎样更改服务器生存期中装载servlet和JSP页面的时刻。
    5.1 分配servlet初始化参数
    利用init-param元素向servlet提供初始化参数,init-param元素具有param-name和param-value子元素。例如,在下面的例子中,如果initServlet servlet是利用它的注册名(InitTest)访问的,它将能够从其方法中调用getServletConfig(). getInitParameter("param1")获得"Value 1",调用getServletConfig().getInitParameter("param2")获得"2"。

    InitTest
    moreservlets.InitServlet

    param1
    value1


    param2
    2


    在涉及初始化参数时,有几点需要注意:
    l 返回值。GetInitParameter的返回值总是一个String。因此,在前一个例子中,可对param2使用Integer.parseInt获得一个int。
    l JSP中的初始化。JSP页面使用jspInit而不是init。JSP页面还需要使用jsp-file元素代替servlet-class。
    l 缺省URL。初始化参数只在通过它们的注册名或与它们注册名相关的定制URL模式访问Servlet时可以使用。因此,在这个例子中,param1和 param2初始化参数将能够在使用URL
    http://host/webAppPrefix/servlet/InitTest 时可用,但在使用URL http://host/webAppPrefix/servlet/myPackage.InitServlet 时不能使用。
    例如,程序清单5-7给出一个名为InitServlet的简单servlet,它使用init方法设置firstName和emailAddress字段。程序清单5-8给出分配名称InitTest给servlet的web.xml文件。
    程序清单5-7 InitServlet.java
    package moreservlets;

    import java.io.*;
    import javax.servlet.*;
    import javax.servlet.http.*;

    /** Simple servlet used to illustrate servlet
    * initialization parameters.
    *


    * Taken from More Servlets and JavaServer Pages
    * from Prentice Hall and Sun Microsystems Press,
    *

    Init Parameters:

    n" +
    "
      n" +
      "
    • First name: " + firstName + "n" +
      "
    • Email address: " + emailAddress + "n" +
      "
    n" +
    "");
    }
    }


    程序清单5-8 web.xml(说明初始化参数的摘录)

    PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
    "
    http://www.moreservlets.com/.
    * © 2002 Marty Hall; may be freely used or adapted.
    */

    public class InitServlet extends HttpServlet {
    private String firstName, emailAddress;

    public void init() {
    ServletConfig config = getServletConfig();
    firstName = config.getInitParameter("firstName");
    emailAddress = config.getInitParameter("emailAddress");
    }

    public void doGet(HttpServletRequest request,
    HttpServletResponse response)
    throws ServletException, IOException {
    response.setContentType("text/html");
    PrintWriter out = response.getWriter();
    String uri = request.getRequestURI();
    out.println(ServletUtilities.headWithTitle("Init Servlet") +
    "n" +
    "
    http://java.sun.com/dtd/web-app_2_3.dtd">




    InitTest
    moreservlets.InitServlet

    firstName
    Larry


    emailAddress
    Ellison@Microsoft.com





    5.2 分配JSP初始化参数
    给JSP页面提供初始化参数在三个方面不同于给servlet提供初始化参数。
    1)使用jsp-file而不是servlet-class。因此,WEB-INF/web.xml文件的servlet元素如下所示:

    PageName
    /RealPage.jsp

    ...
    ...

    ...

    2) 几乎总是分配一个明确的URL模式。对servlet,一般相应地使用以
    http://host/webAppPrefix/servlet/ 开始的缺省URL。只需记住,使用注册名而不是原名称即可。这对于JSP页面在技术上也是合法的。例如,在上面给出的例子中,可用URL http://host/webAppPrefix/servlet/PageName 访问RealPage.jsp的对初始化参数具有访问权的版本。但在用于JSP页面时,许多用户似乎不喜欢应用常规的servlet的URL。此外,如果 JSP页面位于服务器为其提供了目录清单的目录中(如,一个既没有index.html也没有index.jsp文件的目录),则用户可能会连接到此 JSP页面,单击它,从而意外地激活未初始化的页面。因此,好的办法是使用url-pattern(5.3节)将JSP页面的原URL与注册的 servlet名相关联。这样,客户机可使用JSP页面的普通名称,但仍然激活定制的版本。例如,给定来自项目1的servlet定义,可使用下面的 servlet-mapping定义:

    PageName
    /RealPage.jsp

    3)JSP页使用jspInit而不是init。自动从JSP页面建立的servlet或许已经使用了inti方法。因此,使用JSP声明提供一个init方法是不合法的,必须制定jspInit方法。
    为了说明初始化JSP页面的过程,程序清单5-9给出了一个名为InitPage.jsp的JSP页面,它包含一个jspInit方法且放置于 deployDemo Web应用层次结构的顶层。一般,
    http://host/deployDemo/InitPage.jsp 形式的URL将激活此页面的不具有初始化参数访问权的版本,从而将对firstName和emailAddress变量显示null。但是, web.xml文件(程序清单5-10)分配了一个注册名,然后将该注册名与URL模式/InitPage.jsp相关联。

    程序清单5-9 InitPage.jsp




    Init Parameters:



    • First name:
    • Email address:


    private String firstName, emailAddress;

    public void jspInit() {
    ServletConfig config = getServletConfig();
    firstName = config.getInitParameter("firstName");
    emailAddress = config.getInitParameter("emailAddress");
    }



    程序清单5-10 web.xml(说明JSP页面的init参数的摘录)

    PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
    "
    http://java.sun.com/dtd/web-app_2_3.dtd">




    InitPage
    /InitPage.jsp

    firstName
    Bill


    emailAddress
    gates@oracle.com




    InitPage
    /InitPage.jsp





    5.3 提供应用范围内的初始化参数
    一般,对单个地servlet或JSP页面分配初始化参数。指定的servlet或JSP页面利用ServletConfig的getInitParameter方法读取这些参数。但是,在某些情形下,希望提供可由任意servlet或JSP页面借助ServletContext的getInitParameter方法读取的系统范围内的初始化参数。
    可利用context-param元素声明这些系统范围内的初始化值。context-param元素应该包含param-name、param-value以及可选的description子元素,如下所示:

    support-email
    blackhole@mycompany.com

    可回忆一下,为了保证可移植性,web.xml内的元素必须以正确的次序声明。但这里应该注意,context-param元素必须出现任意与文档有关的元素(icon、display-name或description)之后及filter、filter-mapping、listener或 servlet元素之前。
    5.4 在服务器启动时装载servlet
    假如servlet或JSP页面有一个要花很长时间执行的init (servlet)或jspInit(JSP)方法。例如,假如init或jspInit方法从某个数据库或ResourceBundle查找产量。这种情况下,在第一个客户机请求时装载servlet的缺省行为将对第一个客户机产生较长时间的延迟。因此,可利用servlet的load-on- startup元素规定服务器在第一次启动时装载servlet。下面是一个例子。





    可以为此元素体提供一个整数而不是使用一个空的load-on-startup。想法是服务器应该在装载较大数目的servlet或JSP页面之前装载较少数目的servlet或JSP页面。例如,下面的servlet项(放置在Web应用的WEB-INF目录下的web.xml文件中的web-app元素内)将指示服务器首先装载和初始化SearchServlet,然后装载和初始化由位于Web应用的result目录中的index.jsp文件产生的 servlet。

    Search
    myPackage.SearchServlet
    1


    Results
    /results/index.jsp
    2


    6 声明过滤器

    servlet版本2.3引入了过滤器的概念。虽然所有支持servlet API版本2.3的服务器都支持过滤器,但为了使用与过滤器有关的元素,必须在web.xml中使用版本2.3的DTD。
    过滤器可截取和修改进入一个servlet或JSP页面的请求或从一个servlet或JSP页面发出的相应。在执行一个servlet或JSP页面之前,必须执行第一个相关的过滤器的doFilter方法。在该过滤器对其FilterChain对象调用doFilter时,执行链中的下一个过滤器。如果没有其他过滤器,servlet或JSP页面被执行。过滤器具有对到来的ServletRequest对象的全部访问权,因此,它们可以查看客户机名、查找到来的cookie等。为了访问servlet或JSP页面的输出,过滤器可将响应对象包裹在一个替身对象(stand-in object)中,比方说把输出累加到一个缓冲区。在调用FilterChain对象的doFilter方法之后,过滤器可检查缓冲区,如有必要,就对它进行修改,然后传送到客户机。
    例如,程序清单5-11帝国难以了一个简单的过滤器,只要访问相关的servlet或JSP页面,它就截取请求并在标准输出上打印一个报告(开发过程中在桌面系统上运行时,大多数服务器都可以使用这个过滤器)。

    程序清单5-11 ReportFilter.java
    package moreservlets;

    import java.io.*;
    import javax.servlet.*;
    import javax.servlet.http.*;
    import java.util.*;

    /** Simple filter that prints a report on the standard output
    * whenever the associated servlet or JSP page is accessed.
    *


    * Taken from More Servlets and JavaServer Pages
    * from Prentice Hall and Sun Microsystems Press,
    *


    * Taken from More Servlets and JavaServer Pages
    * from Prentice Hall and Sun Microsystems Press,
    *

    http://www.moreservlets.com/.
    * © 2002 Marty Hall; may be freely used or adapted.
    */

    public class ReportFilter implements Filter {
    public void doFilter(ServletRequest request,
    ServletResponse response,
    FilterChain chain)
    throws ServletException, IOException {
    HttpServletRequest req = (HttpServletRequest)request;
    System.out.println(req.getRemoteHost() +
    " tried to access " +
    req.getRequestURL() +
    " on " + new Date() + ".");
    chain.doFilter(request,response);
    }

    public void init(FilterConfig config)
    throws ServletException {
    }

    public void destroy() {}
    }

    一旦建立了一个过滤器,可以在web.xml中利用filter元素以及filter-name(任意名称)、file-class(完全限定的类名)和(可选的)init-params子元素声明它。请注意,元素在web.xml的web-app元素中出现的次序不是任意的;允许服务器(但不是必需的)强制所需的次序,并且实际中有些服务器也是这样做的。但这里要注意,所有filter元素必须出现在任意filter-mapping元素之前, filter-mapping元素又必须出现在所有servlet或servlet-mapping元素之前。
    例如,给定上述的ReportFilter类,可在web.xml中作出下面的filter声明。它把名称Reporter与实际的类ReportFilter(位于moreservlets程序包中)相关联。

    Reporter
    moresevlets.ReportFilter

    一旦命名了一个过滤器,可利用filter-mapping元素把它与一个或多个servlet或JSP页面相关联。关于此项工作有两种选择。
    首先,可使用filter-name和servlet-name子元素把此过滤器与一个特定的servlet名(此servlet名必须稍后在相同的 web.xml文件中使用servlet元素声明)关联。例如,下面的程序片断指示系统只要利用一个定制的URL访问名为SomeServletName 的servlet或JSP页面,就运行名为Reporter的过滤器。

    Reporter
    SomeServletName

    其次,可利用filter-name和url-pattern子元素将过滤器与一组servlet、JSP页面或静态内容相关联。例如,相面的程序片段指示系统只要访问Web应用中的任意URL,就运行名为Reporter的过滤器。

    Reporter
    /*

    例如,程序清单5-12给出了将ReportFilter过滤器与名为PageName的servlet相关联的web.xml文件的一部分。名字 PageName依次又与一个名为TestPage.jsp的JSP页面以及以模式http: //host/webAppPrefix/UrlTest2/ 开头的URL相关联。TestPage.jsp的源代码已经JSP页面命名的谈论在前面的3节"分配名称和定制的URL"中给出。事实上,程序清单5- 12中的servlet和servlet-name项从该节原封不动地拿过来的。给定这些web.xml项,可看到下面的标准输出形式的调试报告(换行是为了容易阅读)。
    audit.irs.gov tried to access
    http://mycompany.com/deployDemo/UrlTest2/business/tax-plan.html
    on Tue Dec 25 13:12:29 EDT 2001.

    程序清单5-12 Web.xml(说明filter用法的摘录)

    PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
    "
    http://java.sun.com/dtd/web-app_2_3.dtd">



    Reporter
    moresevlets.ReportFilter



    Reporter
    PageName



    PageName
    /RealPage.jsp



    PageName
    /UrlTest2/*





    7 指定欢迎页

    假如用户提供了一个像http: //host/webAppPrefix/directoryName/ 这样的包含一个目录名但没有包含文件名的URL,会发生什么事情呢?用户能得到一个目录表?一个错误?还是标准文件的内容?如果得到标准文件内容,是 index.html、index.jsp、default.html、default.htm或别的什么东西呢?
    Welcome-file-list 元素及其辅助的welcome-file元素解决了这个模糊的问题。例如,下面的web.xml项指出,如果一个URL给出一个目录名但未给出文件名,服务器应该首先试用index.jsp,然后再试用index.html。如果两者都没有找到,则结果有赖于所用的服务器(如一个目录列表)。

    index.jsp
    index.html

    虽然许多服务器缺省遵循这种行为,但不一定必须这样。因此,明确地使用welcom-file-list保证可移植性是一种良好的习惯。

    8 指定处理错误的页面

    现在我了解到,你在开发servlet和JSP页面时从不会犯错误,而且你的所有页面是那样的清晰,一般的程序员都不会被它们的搞糊涂。但是,是人总会犯错误的,用户可能会提供不合规定的参数,使用不正确的URL或者不能提供必需的表单字段值。除此之外,其它开发人员可能不那么细心,他们应该有些工具来克服自己的不足。
    error-page元素就是用来克服这些问题的。它有两个可能的子元素,分别是:error-code和exception- type。第一个子元素error-code指出在给定的HTTP错误代码出现时使用的URL。第二个子元素excpetion-type指出在出现某个给定的Java异常但未捕捉到时使用的URL。error-code和exception-type都利用location元素指出相应的URL。此 URL必须以/开始。location所指出的位置处的页面可通过查找HttpServletRequest对象的两个专门的属性来访问关于错误的信息,这两个属性分别是:javax.servlet.error.status_code和javax.servlet.error.message。
    可回忆一下,在web.xml内以正确的次序声明web-app的子元素很重要。这里只要记住,error-page出现在web.xml文件的末尾附近,servlet、servlet-name和welcome-file-list之后即可。

    8.1 error-code元素
    为了更好地了解error-code元素的值,可考虑一下如果不正确地输入文件名,大多数站点会作出什么反映。这样做一般会出现一个404错误信息,它表示不能找到该文件,但几乎没提供更多有用的信息。另一方面,可以试一下在
    www.microsoft.comwww.ibm.com 处或者特别是在www.bea.com 处输出未知的文件名。这是会得出有用的消息,这些消息提供可选择的位置,以便查找感兴趣的页面。提供这样有用的错误页面对于Web应用来说是很有价值得。事实上rm-error-page子元素)。由form-login-page给出的HTML表单必须具有一个j_security_check的 ACTION属性、一个名为j_username的用户名文本字段以及一个名为j_password的口令字段。
    例如,程序清单5-19指示服务器使用基于表单的验证。Web应用的顶层目录中的一个名为login.jsp的页面将收集用户名和口令,并且失败的登陆将由相同目录中名为login-error.jsp的页面报告。

    程序清单5-19 web.xml(说明login-config的摘录)

    PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
    "
    http://java.sun.com/dtd/web-app_2_3.dtd">



    ...

    FORM

    /login.jsp
    /login-error.jsp






    9.2 限制对Web资源的访问
    现在,可以指示服务器使用何种验证方法了。"了不起,"你说道,"除非我能指定一个来收到保护的 URL,否则没有多大用处。"没错。指出这些URL并说明他们应该得到何种保护正是security-constriaint元素的用途。此元素在 web.xml中应该出现在login-config的紧前面。它包含是个可能的子元素,分别是:web-resource-collection、 auth-constraint、user-data-constraint和display-name。下面各小节对它们进行介绍。
    l web-resource-collection
    此元素确定应该保护的资源。所有security-constraint元素都必须包含至少一个web-resource-collection项。此元素由一个给出任意标识名称的web-resource-name元素、一个确定应该保护的URL的url-pattern元素、一个指出此保护所适用的 HTTP命令(GET、POST等,缺省为所有方法)的http-method元素和一个提供资料的可选description元素组成。例如,下面的 Web-resource-collection项(在security-constratint元素内)指出Web应用的proprietary目录中所有文档应该受到保护。


    Proprietary
    /propritary/*



    重要的是应该注意到,url-pattern仅适用于直接访问这些资源的客户机。特别是,它不适合于通过MVC体系结构利用 RequestDispatcher来访问的页面,或者不适合于利用类似jsp:forward的手段来访问的页面。这种不匀称如果利用得当的话很有好处。例如,servlet可利用MVC体系结构查找数据,把它放到bean中,发送请求到从bean中提取数据的JSP页面并显示它。我们希望保证决不直接访问受保护的JSP页面,而只是通过建立该页面将使用的bean的servlet来访问它。url-pattern和auth-contraint元素可通过声明不允许任何用户直接访问JSP页面来提供这种保证。但是,这种不匀称的行为可能让开发人员放松警惕,使他们偶然对应受保护的资源提供不受限制的访问。
    l auth-constraint
    尽管web-resource-collention元素质出了哪些URL应该受到保护,但是auth-constraint元素却指出哪些用户应该具有受保护资源的访问权。此元素应该包含一个或多个标识具有访问权限的用户类别role- name元素,以及包含(可选)一个描述角色的description元素。例如,下面web.xml中的security-constraint元素部门规定只有指定为Administrator或Big Kahuna(或两者)的用户具有指定资源的访问权。

    ...

    administrator
    kahuna


    重要的是认识到,到此为止,这个过程的可移植部分结束了。服务器怎样确定哪些用户处于任何角色以及它怎样存放用户的口令,完全有赖于具体的系统。
    例如,Tomcat使用install_dir/conf/tomcat-users.xml将用户名与角色名和口令相关联,正如下面例子中所示,它指出用户joe(口令bigshot)和jane(口令enaj)属于administrator和kahuna角色。




    l user-data-constraint
    这个可选的元素指出在访问相关资源时使用任何传输层保护。它必须包含一个transport-guarantee子元素(合法值为NONE、 INTEGRAL或CONFIDENTIAL),并且可选地包含一个description元素。transport-guarantee为NONE值将对所用的通讯协议不加限制。INTEGRAL值表示数据必须以一种防止截取它的人阅读它的方式传送。虽然原理上(并且在未来的HTTP版本中),在 INTEGRAL和CONFIDENTIAL之间可能会有差别,但在当前实践中,他们都只是简单地要求用SSL。例如,下面指示服务器只允许对相关资源做 HTTPS连接:



    CONFIDENTIAL


    l display-name
    security-constraint的这个很少使用的子元素给予可能由GUI工具使用的安全约束项一个名称。
    9.3 分配角色名
    迄今为止,讨论已经集中到完全由容器(服务器)处理的安全问题之上了。但servlet以及JSP页面也能够处理它们自己的安全问题。
    例如,容器可能允许用户从bigwig或bigcheese角色访问一个显示主管人员额外紧贴的页面,但只允许bigwig用户修改此页面的参数。完成这种更细致的控制的一种常见方法是调用HttpServletRequset的isUserInRole方法,并据此修改访问。
    Servlet的 security-role-ref子元素提供出现在服务器专用口令文件中的安全角色名的一个别名。例如,假如编写了一个调用 request.isUserInRole("boss")的servlet,但后来该servlet被用在了一个其口令文件调用角色manager而不是boss的服务器中。下面的程序段使该servlet能够使用这两个名称中的任何一个。



    boss
    manager


    也可以在web-app内利用security-role元素提供将出现在role-name元素中的所有安全角色的一个全局列表。分别地生命角色使高级IDE容易处理安全信息。

    10 控制会话超时

    如果某个会话在一定的时间内未被访问,服务器可把它扔掉以节约内存。可利用HttpSession的setMaxInactiveInterval方法直接设置个别会话对象的超时值。如果不采用这种方法,则缺省的超时值由具体的服务器决定。但可利用session-config和session- timeout元素来给出一个适用于所有服务器的明确的超时值。超时值的单位为分钟,因此,下面的例子设置缺省会话超时值为三个小时(180分钟)。

    180


    11 Web应用的文档化

    越来越多的开发环境开始提供servlet和JSP的直接支持。例子有Borland Jbuilder Enterprise Edition、Macromedia UltraDev、Allaire JRun Studio(写此文时,已被Macromedia收购)以及IBM VisuaAge for Java等。
    大量的web.xml元素不仅是为服务器设计的,而且还是为可视开发环境设计的。它们包括icon、display-name和discription等。
    可回忆一下,在web.xml内以适当地次序声明web-app子元素很重要。不过,这里只要记住icon、display-name和description是web.xml的web-app元素内的前三个合法元素即可。
    l icon
    icon元素指出GUI工具可用来代表Web应用的一个和两个图像文件。可利用small-icon元素指定一幅16 x 16的GIF或JPEG图像,用large-icon元素指定一幅32 x 32的图像。下面举一个例子:

    /images/small-book.gif
    /images/tome.jpg

    l display-name
    display-name元素提供GUI工具可能会用来标记此Web应用的一个名称。下面是个例子。
    Rare Books
    l description
    description元素提供解释性文本,如下所示:

    This Web application represents the store developed for
    rare-books.com, an online bookstore specializing in rare
    and limited-edition books.


    12 关联文件与MIME类型

    服务器一般都具有一种让Web站点管理员将文件扩展名与媒体相关联的方法。例如,将会自动给予名为mom.jpg的文件一个image/jpeg的MIME 类型。但是,假如你的Web应用具有几个不寻常的文件,你希望保证它们在发送到客户机时分配为某种MIME类型。mime-mapping元素(具有 extension和mime-type子元素)可提供这种保证。例如,下面的代码指示服务器将application/x-fubar的MIME类型分配给所有以.foo结尾的文件。

    foo
    application/x-fubar

    或许,你的Web应用希望重载(override)标准的映射。例如,下面的代码将告诉服务器在发送到客户机时指定.ps文件作为纯文本(text/plain)而不是作为PostScript(application/postscript)。

    ps
    application/postscript



    13 定位TLD

    JSP taglib元素具有一个必要的uri属性,它给出一个TLD(Tag Library Descriptor)文件相对于Web应用的根的位置。TLD文件的实际名称在发布新的标签库版本时可能会改变,但我们希望避免更改所有现有JSP页面。此外,可能还希望使用保持taglib元素的简练性的一个简短的uri。这就是部署描述符文件的taglib元素派用场的所在了。Taglib包含两个子元素:taglib-uri和taglib-location。taglib-uri元素应该与用于JSP taglib元素的uri属性的东西相匹配。Taglib-location元素给出TLD文件的实际位置。例如,假如你将文件chart-tags- 1.3beta.tld放在WebApp/WEB-INF/tlds中。现在,假如web.xml在web-app元素内包含下列内容。

    /charts.tld

    /WEB-INF/tlds/chart-tags-1.3beta.tld


    给出这个说明后,JSP页面可通过下面的简化形式使用标签库。


    14 指定应用事件监听程序

    应用事件监听器程序是建立或修改servlet环境或会话对象时通知的类。它们是servlet规范的版本2.3中的新内容。这里只简单地说明用来向Web应用注册一个监听程序的web.xml的用法。
    注册一个监听程序涉及在web.xml的web-app元素内放置一个listener元素。在listener元素内,listener-class元素列出监听程序的完整的限定类名,如下所示:

    package.ListenerClass

    虽然listener元素的结构很简单,但请不要忘记,必须正确地给出web-app元素内的子元素的次序。listener元素位于所有的servlet 元素之前以及所有filter-mapping元素之后。此外,因为应用生存期监听程序是serlvet规范的2.3版本中的新内容,所以必须使用 web.xml DTD的2.3版本,而不是2.2版本。
    例如,程序清单5-20给出一个名为ContextReporter的简单的监听程序,只要Web应用的Servlet-Context建立(如装载Web应用)或消除(如服务器关闭)时,它就在标准输出上显示一条消息。程序清单5-21给出此监听程序注册所需要的web.xml文件的一部分。

    程序清单5-20 ContextReporterjava
    package moreservlets;

    import javax.servlet.*;
    import java.util.*;

    /** Simple listener that prints a report on the standard output
    * when the ServletContext is created or destroyed.
    *
    http://www.moreservlets.com/.
    * © 2002 Marty Hall; may be freely used or adapted.
    */

    public class ContextReporter implements ServletContextListener {
    public void contextInitialized(ServletContextEvent event) {
    System.out.println("Context created on " +
    new Date() + ".");
    }

    public void contextDestroyed(ServletContextEvent event) {
    System.out.println("Context destroyed on " +
    new Date() + ".");
    }
    }


    程序清单5-21 web.xml(声明一个监听程序的摘录)

    PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
    "
    http://java.sun.com/dtd/web-app_2_3.dtd">





    package.ListenerClass

    ...




    15 J2EE元素

    本节描述用作J2EE环境组成部分的Web应用的web.xml元素。这里将提供一个简明的介绍,详细内容可以参阅
    http://java.sun.com/j2ee/j2ee-1_3-fr-spec.pdf的Java 2 Plantform Enterprise Edition版本1.3规范的第5章。
    l distributable
    distributable 元素指出,Web应用是以这样的方式编程的:即,支持集群的服务器可安全地在多个服务器上分布Web应用。例如,一个可分布的应用必须只使用 Serializable对象作为其HttpSession对象的属性,而且必须避免用实例变量(字段)来实现持续性。distributable元素直接出现在discription元素之后,并且不包含子元素或数据,它只是一个如下的标志。

    l resource-env-ref
    resource -env-ref元素声明一个与某个资源有关的管理对象。此元素由一个可选的description元素、一个resource-env-ref- name元素(一个相对于java:comp/env环境的JNDI名)以及一个resource-env-type元素(指定资源类型的完全限定的类),如下所示:


    jms/StockQueue


    javax.jms.Queue


    l env-entry
    env -entry元素声明Web应用的环境项。它由一个可选的description元素、一个env-entry-name元素(一个相对于java: comp/env环境JNDI名)、一个env-entry-value元素(项值)以及一个env-entry-type元素(java.lang程序包中一个类型的完全限定类名,java.lang.Boolean、java.lang.String等)组成。下面是一个例子:

    minAmout
    100.00
    minAmout

    l ejb-ref
    ejb -ref元素声明对一个EJB的主目录的应用。它由一个可选的description元素、一个ejb-ref-name元素(相对于java: comp/env的EJB应用)、一个ejb-ref-type元素(bean的类型,Entity或Session)、一个home元素(bean的主目录接口的完全限定名)、一个remote元素(bean的远程接口的完全限定名)以及一个可选的ejb-link元素(当前bean链接的另一个 bean的名称)组成。
    l ejb-local-ref
    ejb-local-ref元素声明一个EJB的本地主目录的引用。除了用local-home代替home外,此元素具有与ejb-ref元素相同的属性并以相同的方式使用。






    17:42 | 固定链接 | 评论 (0) | 引用通告 (0) | 记录它 | 计算机与 Internet


    固定链接 关闭
    http://spaces.msn.com/members/tsfy/Blog/cns!1pFtRRZqZXTCdE5YlUjqVIcQ!116.entry







    4月14日



    给你的session加个监听器


    今天一个学生问我怎么实现在网页里显示在线用户的名称——他已经使用了session,但是无法处理用户离开的情况,然后导致在线用户列表的无限增大。跟他说了自己在application中进行超时检查,更新application的时候就比较当前所有列表中的session是否超过自己指定的时间间隔。后来想了想,又给他提了使用给session加监听器的方法。但是提的时候自己也没有做过,所以只是说这种方式很复杂,建议他还是自己进行超时检查。刚才又看了看资料,发现实际上给session加监听器的方式很简单,不禁觉得自己有点误人子弟了,现在将方法写在这,借以告诫自己以后要严谨。
    首先写一个SessionBinder类,它实现了HttpSessionBindingListener接口的valueBound方法和valueUnbound方法,示例代码如下:
    public class SessionBinder implements HttpSessionBindingListener {
    public void valueBound(HttpSessionBindingEvent event){
    //you can do anything you want!this method will be called when this binder is bind with any session.
    }

    public void valueUnbound(HttpSessionBindingEvent event) {
    //you can do something while this session is invalidate
    }
    }
    现在写好了SessionBinder,我们现在选择在一个servlet中向session中加入这个监听器——在jsp中的代码书写与此相同
    //省略前面的代码,此操作可能发生在servlet的doGet方法中,也可能是doPost方法中
    HttpSession session = req.getSession(true);//首先获得需要加入监听器的session对象,req是HttpRequest对象
    SessionBinder sb = new SessionBinder();//建立一个监听器对象
    session.putValue("BinderObject",sb);//将监听器加入此session中,从此时开始执行sb的valueBound方法
    //省略后面的代码
    随后,如果整个session超时或者被用户中止之后,sb的valueUnbound自动执行
    呵呵,以上代码以供参考

    Valid XHTML 1.0 Strict and CSS.
    Powered by pLog
    Design by Book of Styles