准备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
买呢? (还是该问你读这本书的心得)
这本书对於考试以及实际工作上的价值在那?
谢谢你的分享
作者: gitaman 发布时间: 2004-08-04
您好,那么请问一下Habibit这本书你觉得值不值得
买呢? (还是该问你读这本书的心得)
这本书对於考试以及实际工作上的价值在那?
谢谢你的分享
如果你打算考SCJD的话,Habibi这本书值得买,但如果不考的话,
而你需要写一些Swing App的话,也还是有一定的参考价值,
尤其是threading部分.
我以前都是搞J2EE (JSP/Servlet/EJ,对於SWING/Threading/RMI这些东西
是很陌生的,经由SCJD的考试确实会对这些主题的基本观念清楚很多.
这本书对於要考SCJD的人是有帮助的,对於实际工作的帮助的话,
要看你的实际工作是否有用到用J2SE写应用程式囉.
现在似乎web比较流行,所以考SCWCD的人比较多......
作者: systempanic 发布时间: 2004-08-04
建议版主将此篇文章放入 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
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
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
作者: 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
我所谓的tricky,指的不是用复杂难懂的设计来达成目的,我用一套更简单的方法来达成locking&RMI的目的,原因是因为我觉得SCJD的应考者几乎把Habibi的书当作圣经在读,一遇到疑问就比照书上的方法办理,近几年来javaranch上更是所有讨论一面倒都是以这种方法来设计,但试问为了达成locking的issue就一定要照著11与13点去做吗? 这样的架构真的好懂吗? 这样的设计绝对是正确的,因为已经有成千上万的人,都照本宣科的拿到了这张证照,但这是不是最好的解决方案,就是未知数了....
想说的是在SCJD考试中,locking是一个issue,为了达成这个issue,所有的应考者都应该要尝试想一套自己的方式来解决问题,而不是直接把书上与讨论区上的东西当成是自己的solution,如果是这样的话这张SCJD证照对应考者来说,充其量不过是SCJP partII
作者: systempanic 发布时间: 2004-09-18
以高分考过scjd,谢谢你的经验分享~
还有几点想请教一下:
请问一下,
(1)assignment实作的时间,你大概花了多久时间
作者: gitaman 发布时间: 2004-09-20
恭禧∼systempanic兄
以高分考过scjd,谢谢你的经验分享~
还有几点想请教一下:
请问一下,
(1)assignment实作的时间,你大概花了多久时间
作者: systempanic 发布时间: 2004-09-20
作者: anc 发布时间: 2004-10-13
Sun的规定,所以我post出来,有兴趣的人自行参考即可,不一定要照我的方法做~
1 |
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
SCJD 真的不好考, its specification and question are very vague and had to state a lot of assumptions
作者: btsai 发布时间: 2005-01-01
作者: gitaman 发布时间: 2005-01-04
再次阅读systempanic前辈的心得之后,我又有些疑问?烦请解惑一下
作者: systempanic 发布时间: 2005-01-04
作者: gitaman 发布时间: 2005-01-04
Systempanic前辈
作者: systempanic 发布时间: 2005-01-04
作者: gitaman 发布时间: 2005-01-05
作者: cvc 发布时间: 2006-08-20
请问 essay 是问答题吗? 是否要用英文回答...?
yes
yes
作者: systempanic 发布时间: 2006-10-21
作者: LKK388 发布时间: 2011-09-09
热门阅读
-
office 2019专业增强版最新2021版激活秘钥/序列号/激活码推荐 附激活工具
阅读:74
-
如何安装mysql8.0
阅读:31
-
Word快速设置标题样式步骤详解
阅读:28
-
20+道必知必会的Vue面试题(附答案解析)
阅读:37
-
HTML如何制作表单
阅读:22
-
百词斩可以改天数吗?当然可以,4个步骤轻松修改天数!
阅读:31
-
ET文件格式和XLS格式文件之间如何转化?
阅读:24
-
react和vue的区别及优缺点是什么
阅读:121
-
支付宝人脸识别如何关闭?
阅读:21
-
腾讯微云怎么修改照片或视频备份路径?
阅读:28