+ -
当前位置:首页 → 问答吧 → 准备SCJD的一些心得

准备SCJD的一些心得

时间:2004-07-27

来源:互联网

声明: 以下只是个人心得经验,仅供参考,不一定是唯一方法.

本来版上已经许多人考过SCJD,应该轮不到我出来讲,但我正在应考中,印象较深,而且所述若有错误,已考过SCJD的先进也可帮忙指正,让我能即时修正

1.跟SCJD认证相关的书较为大家推荐的是Mehran Habibi, et al所写的书,个人也是参考这本书,但是光看这本书可能还是会有一大堆的疑问,最重要的解答来源在www.javaranch.com,在这里可以找到很多有用的"提示".

2.SCJD的题型大致上有四种左右,而每一种又有版本上的小差异(主要是interface的不同),
但是所强调的重点都是类似,亦即: Threading/Locking, RMI/Socket Networking, SWING GUI, MVC Design Pattern.

3.我拿到的题目是UrlyBird 1.3.1,是关於旅馆房间订位问题,题目要求你必须使用原来旧系统的资料库档案,然后给你一个DBMain interface,要求你写Data.java而且必须implements DBMain

4.我第一个碰到的问题是,Habibi书上写的是使用serialization object来代表data record,每一个record即是一个档案,但在SCJD试题中你必须使用一个现有的资料档. 所以我就参考ranch上大部分人的做法,即使用RandomAccessFile(RAF)来读写档案. 档案格式是前面一段为meta data,后面为一笔接一笔固定长度的资料.

5.所以我就在Data.java中把DBMain.java所定义的所有method,利用RAF给实作出来,但这里我定义一个Room JavaBean来holding data record的每个栏位. 另外定义一个Hashtable RoomCol来存放所有没有被delete的Room javabean. 另外定义一个HashSet存放资料档中被mark为delete的资料编号(record number),因为试题要求必须重复利用被delete的资料空间.

6.我使用ant+junit来帮助我不断作test & refactoring,并利用java.util.logging package来纪录辅助debug (SCJD要求不能在提交的程式中使用3rd party library,所以不能使用log4j)

7. 再来是重头戏threading and locking, 我的题目只需使用server-side lock (没有client cookie), 但是参考ranch上的讨论后发现有两派做法,一派是把Data实作成singleton,亦即每一个来request的client都给同一个Data instance; 另一派做法是每一个来request的client都给不同的Data instance. 使用singleton的好处是所有client都共用同一个RAF instance,但performance会比较差;使用multiple Data instance的话,也是共用同一个RAF instance,但是必须对RAF synchronized (file level locking). (我使用multiple Data instances,若使用Data Singleton的话,可能在DataAdapter需要对Data object作synchronized)

8. 在我的Data.java中有四个静态成员(class variable),一个是DataSchema (singleton),一个是lockedRecord Vector,一个是bookings Hashtable,一个是reusableRecNos HashSet; 在Data.java中我利用static block来作一次性初始化; 在DataSchema中存有RAF reference,和一些db metadata info.; lockedRecord是在作logical record locking时用来存放锁定的record number,这个跟Habibi书上讲的是一样的用法; 在update/delete/create这些方法中,我自订锁定顺序来锁定RAF,bookings,reusableRecNos等物件,以避免dead lock.

9.我另定义一个Wrapper for Data object,即DataAdapter,在DataAdapter中使用data.lock/db operation(delete/update/create)/data.unlock顺序,但在read/find方法则不使用lock/unlock,即允许dirty read,但可大幅提升performance. 另外在DataAdapter中的方法回传值/传入参数,改成Booking Object或是Collection,以符合OO设计(在Data.java中是int[]/String[])

10.完成DataAdapter之后必须用力测试,可spawn一堆thread然后对同一record number作booking/delete动作,观察log资讯看看是否符合预期

11.网路方面可选择Socket或RMI,我个人当然选择较简单的RMI啦,大致上follow Habibi的书上应可完成,但若是选择使用multiple Data instances的话可能需要写一个ConnectionFactory,把这一个ConnectionFactory object bind到rmi registry,然后每一个client request进来时都产生一个新的DataAdapter object给client. (注: DataAdapter和Data的关系是1:1)

12.记得RMI client自RMI server得到的是object interface stubs,不是 implementation stubs, 弄错了会有ClassCastException.

13. 由於RMI server thread pooling机制有可能会使用同一个thread来服务不同的client,所以在unlock方法中可能需要使用client id来判断该client是否是之前锁定同一recNo的client (唉,这是我刚在ranch上发现我没注意到的....),另外可能还要考虑万一client当机或网路断线时如何release locked recNo. 在ranch上有一长篇文章讨论(题目是:Single table / Simple Locking - WeakHashMap vs WeakReferences),我打算这两天就利用这方法来改进我的locking mechanism (done)

14. 再来剩下GUI部分,个人觉得这部分是最简单的,大致上follow Habibit书上的做法使用MVC pattern,View方面用JTable+AbstractTableModel, Controller负责delegate UI action和Model<->TableModel Conversion,Model则由RMI remote object取得.....

--The End

作者: systempanic   发布时间: 2004-07-27

您好,那么请问一下Habibit这本书你觉得值不值得
买呢? (还是该问你读这本书的心得)
这本书对於考试以及实际工作上的价值在那?

谢谢你的分享

作者: gitaman   发布时间: 2004-08-04

gitaman wrote:
您好,那么请问一下Habibit这本书你觉得值不值得
买呢? (还是该问你读这本书的心得)
这本书对於考试以及实际工作上的价值在那?

谢谢你的分享


如果你打算考SCJD的话,Habibi这本书值得买,但如果不考的话,
而你需要写一些Swing App的话,也还是有一定的参考价值,
尤其是threading部分.

我以前都是搞J2EE (JSP/Servlet/EJ,对於SWING/Threading/RMI这些东西
是很陌生的,经由SCJD的考试确实会对这些主题的基本观念清楚很多.

这本书对於要考SCJD的人是有帮助的,对於实际工作的帮助的话,
要看你的实际工作是否有用到用J2SE写应用程式囉.

现在似乎web比较流行,所以考SCWCD的人比较多......

作者: systempanic   发布时间: 2004-08-04

小弟现在也正要准备 SCJD, 这是一篇很棒的分享, 谢谢 systempanic.
建议版主将此篇文章放入 SCJD 的精华区. 谢谢.

作者: RogerY2k   发布时间: 2004-09-16

帮原作补充几点:

15. 请务必彻底看通题目, 题目大概有六七页吧, 字字珠玑...
若是觉得有疑义的地方, javaranch大都有前人讨论过了, 去那边看看
一定会有收获,我自己从头到尾看了这份文件起码30次以上... 发现了很多诡
异的地方, 要是没有发现这些东西, 到现在我可能还在coding....

16. 看完javaranch后, 会发现很多人都用同一种方法来解问题, 但不一定要照著
前人的脚步走, 只要符合题目的"must"条件, 高兴怎么去实做都行, 我自己
就以身试法, 用比较tricky方法来实做, 可以省个几百行程式码, 我这个人很
懒, 但又很有种, 所以就采用这种方法, 没问题~~
照样高分过.(如果你因此被fail了, 可以写信去请他们列举出你被fail的原因
, 如果没有违反"must"条件, 且达到题目所要求的目标, 可以尝试要求他们
重新审核你的专案, 据我所知就有两例是这样起死回生的...))

17. 专案与笔试考完后, 写信到[email protected]请他们确认是否有收
到你的考试资料, 不然你可能专案没有upload成功, 然后一直痴痴的等结
果.

18. 专案与笔试都考完后, 才会开始计分, 评分过程约2~6周(sun的说法是4~6
周, 但prometric是说2~4周, 所以我取2~6周), 评分时间长短跟你会fail或
pass无关(有人等了六周, 结果是automatic failure, 也有人一周就收到
automatic failure的通知)

19. 考试结果会公布於
http://www.certmanager.net/sun_assignment/
http://www.certmanager.net/sun
第一个网址公布的最快, 升阳不会以其他任何的形式告知你考试结果.

作者: EdwardC   发布时间: 2004-09-16

成绩终於出来了,380分,Passed.

This report shows the total number of points awarded for each section. The maximum number of poins is 400, to pass you need a score of 320. Section Summary: Section Max Actual Points Points General Con: 100 90, Documentation: 70 70, OOD: 30 30, GUI: 40 30, Locking: 80 80, Network Server: 40 40, Data Store: 40 40, Total: 400 380

我的UI比较阳春,但应该有满足spec要求,只能搜寻hotel name和location.
有些可能发生的例外没有去考虑,例如启动rmi server失败时,我是出现个错误讯息对话框后,直接结束程式,没有给User更正的机会,这可能会扣些分(我承认我偷懒)

作者: systempanic   发布时间: 2004-09-18

EdwardC wrote:
16. 看完javaranch后, 会发现很多人都用同一种方法来解问题, 但不一定要照著
前人的脚步走, 只要符合题目的"must"条件, 高兴怎么去实做都行, 我自己
就以身试法, 用比较tricky方法来实做, 可以省个几百行程式码, 我这个人很
懒, 但又很有种, 所以就采用这种方法, 没问题~~
照样高分过.(如果你因此被fail了, 可以写信去请他们列举出你被fail的原因
, 如果没有违反"must"条件, 且达到题目所要求的目标, 可以尝试要求他们
重新审核你的专案, 据我所知就有两例是这样起死回生的...))

在spec中有说明,你的设计或程式即使给novice level developer看应容易了解,所以最好是以简单易懂的做法为主,避免smart hacks.

Quoted from spec: A clear design, such as will be readily understood by junior programmers, will be preferred to a complex one, even if the complex one is a little more efficient.

作者: systempanic   发布时间: 2004-09-18

恭喜systempanic, 这是一篇很棒的心得分享, 多谢

作者: dtaun   发布时间: 2004-09-18


systempanic wrote:
11.网路方面可选择Socket或RMI,我个人当然选择较简单的RMI啦,大致上follow Habibi的书上应可完成,但若是选择使用multiple Data instances的话可能需要写一个ConnectionFactory,把这一个ConnectionFactory object bind到rmi registry,然后每一个client request进来时都产生一个新的DataAdapter object给client. (注: DataAdapter和Data的关系是1:1)

13. 由於RMI server thread pooling机制有可能会使用同一个thread来服务不同的client,所以在unlock方法中可能需要使用client id来判断该client是否是之前锁定同一recNo的client (唉,这是我刚在ranch上发现我没注意到的....),另外可能还要考虑万一client当机或网路断线时如何release locked recNo. 在ranch上有一长篇文章讨论(题目是:Single table / Simple Locking - WeakHashMap vs WeakReferences),我打算这两天就利用这方法来改进我的locking mechanism (done)

在spec中有说明,你的设计或程式即使给novice level developer看应容易了解,所以最好是以简单易懂的做法为主,避免smart hacks.

Quoted from spec: A clear design, such as will be readily understood by junior programmers, will be preferred to a complex one, even if the complex one is a little more efficient.


我所谓的tricky,指的不是用复杂难懂的设计来达成目的,我用一套更简单的方法来达成locking&RMI的目的,原因是因为我觉得SCJD的应考者几乎把Habibi的书当作圣经在读,一遇到疑问就比照书上的方法办理,近几年来javaranch上更是所有讨论一面倒都是以这种方法来设计,但试问为了达成locking的issue就一定要照著11与13点去做吗? 这样的架构真的好懂吗? 这样的设计绝对是正确的,因为已经有成千上万的人,都照本宣科的拿到了这张证照,但这是不是最好的解决方案,就是未知数了....

想说的是在SCJD考试中,locking是一个issue,为了达成这个issue,所有的应考者都应该要尝试想一套自己的方式来解决问题,而不是直接把书上与讨论区上的东西当成是自己的solution,如果是这样的话这张SCJD证照对应考者来说,充其量不过是SCJP partII

作者: EdwardC   发布时间: 2004-09-18

EdwardC wrote:
我所谓的tricky,指的不是用复杂难懂的设计来达成目的,我用一套更简单的方法来达成locking&RMI的目的,原因是因为我觉得SCJD的应考者几乎把Habibi的书当作圣经在读,一遇到疑问就比照书上的方法办理,近几年来javaranch上更是所有讨论一面倒都是以这种方法来设计,但试问为了达成locking的issue就一定要照著11与13点去做吗? 这样的架构真的好懂吗? 这样的设计绝对是正确的,因为已经有成千上万的人,都照本宣科的拿到了这张证照,但这是不是最好的解决方案,就是未知数了....

想说的是在SCJD考试中,locking是一个issue,为了达成这个issue,所有的应考者都应该要尝试想一套自己的方式来解决问题,而不是直接把书上与讨论区上的东西当成是自己的solution,如果是这样的话这张SCJD证照对应考者来说,充其量不过是SCJP partII

作者: systempanic   发布时间: 2004-09-18

恭禧∼systempanic兄

以高分考过scjd,谢谢你的经验分享~
还有几点想请教一下:
请问一下,

(1)assignment实作的时间,你大概花了多久时间

作者: gitaman   发布时间: 2004-09-20

gitaman wrote:
恭禧∼systempanic兄

以高分考过scjd,谢谢你的经验分享~
还有几点想请教一下:
请问一下,

(1)assignment实作的时间,你大概花了多久时间

作者: systempanic   发布时间: 2004-09-20

systempanic 恭喜了! 我还记得两年多前我用JUnit的多执行绪测我的SCJD作业,捉到一些bugs,也学到了不少好的观念,至今受用无穷!

作者: anc   发布时间: 2004-10-13

有网友对我的测试thread/locking方式有兴趣,我评估这个应该没有违背
Sun的规定,所以我post出来,有兴趣的人自行参考即可,不一定要照我的方法做~

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
package suncertify.test;
 
import junit.framework.*;
import java.io.*;
import java.util.*;
 
import suncertify.db.*;
 
public class DataAdapterClient { public static void main(String[] args) throws Exception { DataAdapter da1 = new DataAdapter(); DataAdapter da2 = new DataAdapter(); DataAdapter da3 = new DataAdapter(); String s1 = "00000001"; String s2 = "00000002"; String s3 = "00000003"; String s4 = "00000004"; String s5 = "00000005"; String s6 = "00000006"; String[] s7 = {"My Name S7","My Location S7","15","Y","$100.00","2004/12/12","MyOwner7"}; String[] s8 = {"My Name S8","My Location S8","15","Y","$100.00","2004/12/12","MyOwner8"}; String[] s9 = {"My Name S9","My Location S9","15","Y","$100.00","2004/12/12","MyOwner9"}; String[] s10 = {"My Name SX","My Location SX","15","Y","$100.00","2004/12/12","MyOwnerX"}; DataAdapterClient dac = new DataAdapterClient();   RunnerBooking rb1= dac.new RunnerBooking(da1, 0, s1); RunnerBooking rb2= dac.new RunnerBooking(da2, 0, s2); RunnerBooking rb3= dac.new RunnerBooking(da3, 0, s3); RunnerBooking rb4= dac.new RunnerBooking(da1, 0, s4); RunnerBooking rb5= dac.new RunnerBooking(da2, 0, s5); RunnerBooking rb6= dac.new RunnerBooking(da1, 0, s6);
  RunnerBooking rb7= dac.new RunnerBooking(da1, 6, s1); RunnerBooking rb8= dac.new RunnerBooking(da2, 6, s2); RunnerBooking rb9= dac.new RunnerBooking(da3, 6, s3); RunnerBooking rb10= dac.new RunnerBooking(da1, 6, s4); RunnerBooking rb11= dac.new RunnerBooking(da2, 6, s5); RunnerBooking rb12= dac.new RunnerBooking(da1, 6, s6);
  RunnerDelete rd1 = dac.new RunnerDelete(da2, 7); RunnerDelete rd2 = dac.new RunnerDelete(da3, 21); RunnerCreate rc1 = dac.new RunnerCreate(da1, s7); RunnerCreate rc2 = dac.new RunnerCreate(da2, s8); RunnerCreate rc3 = dac.new RunnerCreate(da1, s9); RunnerCreate rc4 = dac.new RunnerCreate(da3, s10);
  rb7.start(); rb8.start(); rb9.start(); rb10.start(); rb11.start(); rb12.start(); rd1.start(); rd2.start(); rc1.start(); rc2.start(); rc3.start(); rc4.start(); rb1.start(); rb2.start(); rb3.start(); rb4.start(); rb5.start(); rb6.start(); }   class RunnerBooking extends Thread { private DataAdapter da; private String customerId; private int recNo; public RunnerBooking() {} public RunnerBooking(DataAdapter da, int recNo, String customerId) { super(); this.da = da; this.recNo = recNo; this.customerId = customerId; } public void run(){ //System.out.println("Thread: " + this); try { da.book(recNo,customerId); } catch (RoomAlreadyBookedException e) { System.out.println("The room is already booked for recNo="+recNo); } catch (Exception e) { e.printStackTrace(); } } }   class RunnerDelete extends Thread { private DataAdapter da; private int recNo; public RunnerDelete() {} public RunnerDelete(DataAdapter da, int recNo) { super(); this.da = da; this.recNo = recNo; } public void run(){ //System.out.println("Thread: " + this); try { da.delete(recNo); } catch (Exception e) { e.printStackTrace(); } } }   class RunnerCreate extends Thread { private DataAdapter da; private String[] s; public RunnerCreate() {} public RunnerCreate(DataAdapter da, String[] s) { super(); this.da = da; this.s = s; } public void run(){ //System.out.println("Thread: " + this); try { int recNo = da.create(s); System.out.println("New Record created, recNo="+ recNo); } catch (Exception e) { e.printStackTrace(); } } }   }
 

作者: systempanic   发布时间: 2004-12-29

congratulations
SCJD 真的不好考, its specification and question are very vague and had to state a lot of assumptions

作者: btsai   发布时间: 2005-01-01

再次阅读systempanic前辈的心得之后,我又有些疑问?烦请解惑一下

作者: gitaman   发布时间: 2005-01-04

gitaman wrote:
再次阅读systempanic前辈的心得之后,我又有些疑问?烦请解惑一下

作者: systempanic   发布时间: 2005-01-04

Systempanic前辈

作者: gitaman   发布时间: 2005-01-04

gitaman wrote:
Systempanic前辈

作者: systempanic   发布时间: 2005-01-04

谢谢您的回答,获益良多!

作者: gitaman   发布时间: 2005-01-05

请问 essay 是问答题吗? 是否要用英文回答...?

作者: cvc   发布时间: 2006-08-20

cvc wrote:
请问 essay 是问答题吗? 是否要用英文回答...?


yes

yes

作者: systempanic   发布时间: 2006-10-21

结果你拿到SCJD的认证了吗? 看起来很难.

作者: LKK388   发布时间: 2011-09-09

热门下载

更多