这是小题目的系列之四之一:http://topic.csdn.net/u/20070828/10/7aa61fbc-8575-4212-85c4-582c08f81535.html
之二:http://topic.csdn.net/u/20070917/10/928cdd3b-0ec6-4236-a89d-7c3ddba8eaba.html
之三:http://topic.csdn.net/u/20080130/17/7fdd8b93-bdd6-467a-863e-fc3c9731bc52.html做题规则:老规矩,不允许上机操作,全部完成后可以将代码复制自行检测一下,需采用 JDK 5.0 或以上版本1,诡异的 Set看看下面的这段程序,输出的是_____。A. 4
B. 5
C. 6
D. 以上都不是import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashSet;
import java.util.Set;public class Test1 {
private static final String[] URL_NAMES = {
"http://javapuzzlers.com",
"http://apache2-snort.skybar.dreamhost.com",
"http://www.google.com",
"http://javapuzzlers.com",
"http://findbugs.sourceforge.net",
"http://www.cs.umd.edu"
}; public static void main(String[] args) throws MalformedURLException {
Set<URL> favorites = new HashSet<URL>();
for (String urlName : URL_NAMES)
favorites.add(new URL(urlName));
System.out.println(favorites.size());
}
}=====★===我===是===题===目===间===的===小===分===隔===符===★=====2,Number 惹的祸下面是一个三目运算符的小题目,看看程序运行后,在控制台上会输出_____。A. 3
B. 1.0
C. 抛出异常
D. 以上都不是import java.util.Random;public class Test2 {
public static void main(String[] args) {
Random rnd = new Random();
boolean toBe = rnd.nextBoolean();
Number result = (toBe || !toBe) ?
new Integer(3) : new Float(1);
System.out.println(result);
}
}到目前为止,我们就结束带有迷惑性质的题目,包括前三期我们共有 19 道此类性质的题目了。=====★===我===是===题===目===间===的===小===分===隔===符===★=====接下来是一些有趣而偏向于实用的题目,需要自行来动手设计,可以看看您对面向对象、Java 语言,以
及 JDK 类库的了解程度。下面的题目也没有什么统一标准的答案(因为条条大路通罗马呗),请大家各抒己见,结帖前我会贴一些
代码以供参考。以下题目在没有 JDK 版本要求时,均采用 JDK 5.0。3,限定参数范围某个方法有一个参数,这个参数只能接受 1~10 之间的值(含 1 和 10),在此范围之外的参数都被视
为非法。现在需要设计一个方法,在传入非法参数时在编译期报错。注意:要求在编译期报错,而不是在运行期。JDK 版本限定为 1.4。=====★===我===是===题===目===间===的===小===分===隔===符===★=====4,对象复制现在需要设计一个这样的工具方法,使用这个方法来复制一个对象字段中的值到别外一个对象中去,基本
的方法签名:public static void copyFields(Object src, Object dist); 但是这样的方法不
是很健壮,经不起考验。我们知道要拷贝对象属性时 src 和 dist 应该具有相同的类型,或者是 dist 是 src 的子类型这样做
才有意义。现在要重新对这个方法进行设计,并能满足上面的要求,在 src 和 dist 不是同一类型时,需
要在编译期报错。5,懒人的提议在一般实体类对应的 DAO 中都有 CRUD 操作,也就是最基本的四个增查改删。以 StudentDao 为例,可能会有以下五个最基本的方法:public Student get(Serializable id) {
return (Student)getHibernateTemplate().load(Student.class, id);
}
public List<Student> getAll() {
return (List<Student>)getHibernateTemplate().loadAll(Student.class);
}
public void save(Student stu) {
getHibernateTemplate().saveOrUpdate(stu);
}
public void remove(Student stu) {
getHibernateTemplate().delete(stu);
}
public void update(Student stu) {
getHibernateTemplate().update(stu);
}但在 TeacherDao 中,也要会有这几个方法,只是传入的参数不同而已。如果在每个 DAO 里都写上
这么几个方法就显示很拖杳,重复的代码就会很多。以大家常用的 Spring + Hibernate 组合来说,Spring 提供了一个操作 Hibernate 的抽象类
——HiernateDaoSupport,只要继承它就可以很方便地实现一些 DAO 操作,通常采用 Hibernate
实现类的签名为:public StudentHibernateDao extends HibernateSupportDao implements StudentDao; +-------------------------------+
class of Spring --> | <<abstract>> |
| HibernateDaoSupport |
+-------------------------------+
A
| |
<------ DAO Interface Package ------->|<- Hibernate Impleme|ntation Package ->
| |
+-------------------------------+ | +-------------------------------+
| <<interface>> | | | |
| StudentDao | | | StudentHibernateDao |
+-------------------------------+ | +-------------------------------+
| + get(Serializable) : Student | | | + get(Serializable) : Student |
| + getAll() : List<Student> |<- - - - -| + getAll() : List<Student> |
| + save(Student) : void | | | + save(Student) : void |
| + remove(Student) : void | | | + remove(Student) : void |
| + update(Student) : void | | | + update(Student) : void |
| + method1() | | | + method1() |
| + method2() | | | + method2() |
| + ... | | | + ... |
+-------------------------------+ | +-------------------------------+
|<- - - - 表示实现接口(不表示依赖哦,因为在半角状态下我找了好久都没找到向左的空心三角啦,
将究着看看,不要要求太高哈)A
| 表示继承(就把 A 的两个脚去掉,看成向上的空心三角哈)
|这样我们只要在客户端配置一下具体的实现类,采用 StudentDao 进行面向接口的编程就可以完成
DAO 操作了,从而大大降低了耦合程度。但是这样做,HibernateSupportDao 中并没有提供那几个基本的 CRUD 操作,在这种情况下这个
类的签名并不能满足我们的要求,需要重新进行设计(仍然需要 HibernateSupportDao 提供的功
能),不改变客户端的行为(与普通的实现采用同样的配置、同样的调用),在实现时不需要每个
DAO 里重复劳动地去写那几个方法,以降低 DAO 层的工作量。你该如何进行设计?当然了,这里仅仅只是举一个以 Spring + Hibernate 为代表的例子,这样的设计也可以用于其
他方面。=====★===我===是===题===目===间===的===小===分===隔===符===★=====6,如何关闭?我们都使用过数据库连接池,即在连接池中保存了多个数据库连接 Connection 对象,需要连接数
据库时从池中取出一个 Connection 对象进行操作,用完后将这个对象归还到池中。一般来说连接
池采用一个集合来存放这些连接对象,在调用 getConnection 方法时从集合中取中一个,用完后
采用 con.close() 把这个连接归还到池中。嘿嘿,现在问题来了,我们都知道 con.close() 是关闭与数据库之间的连接,但是在连接池的状态
下我们并不能真正地将其关闭掉(如果真的关掉的话,这个连接就不能再重用了)。现在有个办法,
就是不调用 con.close(),同样地也就不让连接关闭,在使用完后用 releaseConnection(Connection con)
的方法将其归还到池中。但是这样做问题又来了,Connection 中的 close() 方法是公开的,我们
并不能阻止使用者调用它。现在我们要设计这个连接池,不采用 releaseConnection 的方法,我们
要改变原有 con.close() 中的行为,不让其关闭,而是把它归还到池中。当然了,这只是连接池中一个很小的问题,要设计一个功能完善的连接池,至少还需要连接参数的可配
置化、连接异常的检测和处理等,而且问题远不止这些,问题可能会多得超出我所能想到的 :(这里并不是需要大家去实现一个连接池,只是提出一个小问题,拓展一下思路,发表一下您对这个问题
的看法,或者是您将会怎么做?解决这个问题的话,我们就可以自己实现一个很很简单的连接池哦 :)注意:Connection 仅仅是个接口曾经看过一些网友实现的连接池,基本上都是采用 releaseConnection 的形式来将连接归还到池中去
的,并没有解决 con.close() 的问题,使用者的行为我们是无法加以干涉的,如果使用者不习惯去调用
releaseConnection,而是照常用的习惯去调用 con.close() 的话,这个连接池就是形同虚设,因为这
样一个连接都得不到重用。=======================================================PS-1:帖子的字数比较多,感谢大家耐心地把它看完。(羞羞羞,某种果子怎么不说自己表达能力差,尽是废话呢?)
PS-2:如有描述不清之处,请在回复中指出,我会负责说明和解释的。(嘿嘿,某种果子承认自己表达能力差了吧!)
PS-3:这次大多数都是动手题,为了回报大家的付出我会再加 100 分的。(果子也没加过分,果子好像在哪里看到过最多只能加 100 分的,到时再说吧,果子能多加就多加)
PS-4:本帖非散分帖,谢谢配合。(不要拿烂番茄扔果子哦,果子最不喜欢洗衣服了。嗯~~~ 实在要扔的话,就拿好的小番茄直接扔到果子嘴里吧,嘻嘻~~~)
之二:http://topic.csdn.net/u/20070917/10/928cdd3b-0ec6-4236-a89d-7c3ddba8eaba.html
之三:http://topic.csdn.net/u/20080130/17/7fdd8b93-bdd6-467a-863e-fc3c9731bc52.html做题规则:老规矩,不允许上机操作,全部完成后可以将代码复制自行检测一下,需采用 JDK 5.0 或以上版本1,诡异的 Set看看下面的这段程序,输出的是_____。A. 4
B. 5
C. 6
D. 以上都不是import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashSet;
import java.util.Set;public class Test1 {
private static final String[] URL_NAMES = {
"http://javapuzzlers.com",
"http://apache2-snort.skybar.dreamhost.com",
"http://www.google.com",
"http://javapuzzlers.com",
"http://findbugs.sourceforge.net",
"http://www.cs.umd.edu"
}; public static void main(String[] args) throws MalformedURLException {
Set<URL> favorites = new HashSet<URL>();
for (String urlName : URL_NAMES)
favorites.add(new URL(urlName));
System.out.println(favorites.size());
}
}=====★===我===是===题===目===间===的===小===分===隔===符===★=====2,Number 惹的祸下面是一个三目运算符的小题目,看看程序运行后,在控制台上会输出_____。A. 3
B. 1.0
C. 抛出异常
D. 以上都不是import java.util.Random;public class Test2 {
public static void main(String[] args) {
Random rnd = new Random();
boolean toBe = rnd.nextBoolean();
Number result = (toBe || !toBe) ?
new Integer(3) : new Float(1);
System.out.println(result);
}
}到目前为止,我们就结束带有迷惑性质的题目,包括前三期我们共有 19 道此类性质的题目了。=====★===我===是===题===目===间===的===小===分===隔===符===★=====接下来是一些有趣而偏向于实用的题目,需要自行来动手设计,可以看看您对面向对象、Java 语言,以
及 JDK 类库的了解程度。下面的题目也没有什么统一标准的答案(因为条条大路通罗马呗),请大家各抒己见,结帖前我会贴一些
代码以供参考。以下题目在没有 JDK 版本要求时,均采用 JDK 5.0。3,限定参数范围某个方法有一个参数,这个参数只能接受 1~10 之间的值(含 1 和 10),在此范围之外的参数都被视
为非法。现在需要设计一个方法,在传入非法参数时在编译期报错。注意:要求在编译期报错,而不是在运行期。JDK 版本限定为 1.4。=====★===我===是===题===目===间===的===小===分===隔===符===★=====4,对象复制现在需要设计一个这样的工具方法,使用这个方法来复制一个对象字段中的值到别外一个对象中去,基本
的方法签名:public static void copyFields(Object src, Object dist); 但是这样的方法不
是很健壮,经不起考验。我们知道要拷贝对象属性时 src 和 dist 应该具有相同的类型,或者是 dist 是 src 的子类型这样做
才有意义。现在要重新对这个方法进行设计,并能满足上面的要求,在 src 和 dist 不是同一类型时,需
要在编译期报错。5,懒人的提议在一般实体类对应的 DAO 中都有 CRUD 操作,也就是最基本的四个增查改删。以 StudentDao 为例,可能会有以下五个最基本的方法:public Student get(Serializable id) {
return (Student)getHibernateTemplate().load(Student.class, id);
}
public List<Student> getAll() {
return (List<Student>)getHibernateTemplate().loadAll(Student.class);
}
public void save(Student stu) {
getHibernateTemplate().saveOrUpdate(stu);
}
public void remove(Student stu) {
getHibernateTemplate().delete(stu);
}
public void update(Student stu) {
getHibernateTemplate().update(stu);
}但在 TeacherDao 中,也要会有这几个方法,只是传入的参数不同而已。如果在每个 DAO 里都写上
这么几个方法就显示很拖杳,重复的代码就会很多。以大家常用的 Spring + Hibernate 组合来说,Spring 提供了一个操作 Hibernate 的抽象类
——HiernateDaoSupport,只要继承它就可以很方便地实现一些 DAO 操作,通常采用 Hibernate
实现类的签名为:public StudentHibernateDao extends HibernateSupportDao implements StudentDao; +-------------------------------+
class of Spring --> | <<abstract>> |
| HibernateDaoSupport |
+-------------------------------+
A
| |
<------ DAO Interface Package ------->|<- Hibernate Impleme|ntation Package ->
| |
+-------------------------------+ | +-------------------------------+
| <<interface>> | | | |
| StudentDao | | | StudentHibernateDao |
+-------------------------------+ | +-------------------------------+
| + get(Serializable) : Student | | | + get(Serializable) : Student |
| + getAll() : List<Student> |<- - - - -| + getAll() : List<Student> |
| + save(Student) : void | | | + save(Student) : void |
| + remove(Student) : void | | | + remove(Student) : void |
| + update(Student) : void | | | + update(Student) : void |
| + method1() | | | + method1() |
| + method2() | | | + method2() |
| + ... | | | + ... |
+-------------------------------+ | +-------------------------------+
|<- - - - 表示实现接口(不表示依赖哦,因为在半角状态下我找了好久都没找到向左的空心三角啦,
将究着看看,不要要求太高哈)A
| 表示继承(就把 A 的两个脚去掉,看成向上的空心三角哈)
|这样我们只要在客户端配置一下具体的实现类,采用 StudentDao 进行面向接口的编程就可以完成
DAO 操作了,从而大大降低了耦合程度。但是这样做,HibernateSupportDao 中并没有提供那几个基本的 CRUD 操作,在这种情况下这个
类的签名并不能满足我们的要求,需要重新进行设计(仍然需要 HibernateSupportDao 提供的功
能),不改变客户端的行为(与普通的实现采用同样的配置、同样的调用),在实现时不需要每个
DAO 里重复劳动地去写那几个方法,以降低 DAO 层的工作量。你该如何进行设计?当然了,这里仅仅只是举一个以 Spring + Hibernate 为代表的例子,这样的设计也可以用于其
他方面。=====★===我===是===题===目===间===的===小===分===隔===符===★=====6,如何关闭?我们都使用过数据库连接池,即在连接池中保存了多个数据库连接 Connection 对象,需要连接数
据库时从池中取出一个 Connection 对象进行操作,用完后将这个对象归还到池中。一般来说连接
池采用一个集合来存放这些连接对象,在调用 getConnection 方法时从集合中取中一个,用完后
采用 con.close() 把这个连接归还到池中。嘿嘿,现在问题来了,我们都知道 con.close() 是关闭与数据库之间的连接,但是在连接池的状态
下我们并不能真正地将其关闭掉(如果真的关掉的话,这个连接就不能再重用了)。现在有个办法,
就是不调用 con.close(),同样地也就不让连接关闭,在使用完后用 releaseConnection(Connection con)
的方法将其归还到池中。但是这样做问题又来了,Connection 中的 close() 方法是公开的,我们
并不能阻止使用者调用它。现在我们要设计这个连接池,不采用 releaseConnection 的方法,我们
要改变原有 con.close() 中的行为,不让其关闭,而是把它归还到池中。当然了,这只是连接池中一个很小的问题,要设计一个功能完善的连接池,至少还需要连接参数的可配
置化、连接异常的检测和处理等,而且问题远不止这些,问题可能会多得超出我所能想到的 :(这里并不是需要大家去实现一个连接池,只是提出一个小问题,拓展一下思路,发表一下您对这个问题
的看法,或者是您将会怎么做?解决这个问题的话,我们就可以自己实现一个很很简单的连接池哦 :)注意:Connection 仅仅是个接口曾经看过一些网友实现的连接池,基本上都是采用 releaseConnection 的形式来将连接归还到池中去
的,并没有解决 con.close() 的问题,使用者的行为我们是无法加以干涉的,如果使用者不习惯去调用
releaseConnection,而是照常用的习惯去调用 con.close() 的话,这个连接池就是形同虚设,因为这
样一个连接都得不到重用。=======================================================PS-1:帖子的字数比较多,感谢大家耐心地把它看完。(羞羞羞,某种果子怎么不说自己表达能力差,尽是废话呢?)
PS-2:如有描述不清之处,请在回复中指出,我会负责说明和解释的。(嘿嘿,某种果子承认自己表达能力差了吧!)
PS-3:这次大多数都是动手题,为了回报大家的付出我会再加 100 分的。(果子也没加过分,果子好像在哪里看到过最多只能加 100 分的,到时再说吧,果子能多加就多加)
PS-4:本帖非散分帖,谢谢配合。(不要拿烂番茄扔果子哦,果子最不喜欢洗衣服了。嗯~~~ 实在要扔的话,就拿好的小番茄直接扔到果子嘴里吧,嘻嘻~~~)
4.
public static<S,D extends S> void copyFields(S src, D dist)
======================================
本贴第一题从目前的代码看不出答案的,关键看你的URL类中是否重写了equals和hashCode方法,以及怎样重写的。
例如:public class Test1 {
private static final String[] URL_NAMES = {
"http://javapuzzlers.com",
"http://apache2-snort.skybar.dreamhost.com",
"http://www.google.com",
"http://javapuzzlers.com",
"http://findbugs.sourceforge.net",
"http://www.cs.umd.edu",
"http://www.cs.umd.edu",
"http://www.cs.umd.edu"
};
public static void main(String[] args) throws MalformedURLException {
Set<URL> favorites = new HashSet<URL>();
for (String urlName : URL_NAMES)
favorites.add(new URL(urlName));
System.out.println(favorites.size());
}
private static class URL
{
private String urlName = "";
private URL(String strURLName)
{
this.urlName = strURLName;
}
public boolean equals(Object obj)
{
return true;
}
public int hashCode()
{
int result = 17;
return result;
}
}
}这样set里永远只有一个,把equals修改下(hashCode也应该修改,此处略)
public boolean equals(Object obj)
{
URL url = (URL)obj; //被修改
return this.urlName==url.urlName;
}
对于本例返回4
DNumber result = (toBe || !toBe) ?new Integer(3) : new Float(1);
它的规则应该和
result = 3i+1f;
是一样的
你说你的URL里重写了equals()我们又看不到,怎么知道你怎么重写的
private static final String[] URL_NAMES = {
"http://javapuzzlers.com",
"http://apache2-snort.skybar.dreamhost.com",
"http://www.google.com",
"http://javapuzzlers.com",
"http://findbugs.sourceforge.net",
};
且条件满足了binary numeric promotion of either operand
最终结果是一个Float
如果第二个操作数是一个可以用第一操作数表示的数 且本身为常量
则不会进行此种promotion操作
URL 里重写的 equals 和 hashCode 又不是我实现的,类库中本身就实现的啊。
A但我觉得题目应该是“诡异的 URL ”呵呵,
因为应该是 URL类中的
public boolean equals(Object obj);
public int hashCode();
暂时没搞清楚是pug还是它这样本身是合理的
有兴趣可以看一下java.net.URLStreamHandler类
因为URL hashCode方法用的是父类的.
帖点给大家看
int h = 0; // Generate the protocol part.
String protocol = u.getProtocol();
if (protocol != null)
h += protocol.hashCode(); // Generate the host part.
InetAddress addr = getHostAddress(u);
if (addr != null) {
h += addr.hashCode();
} else {
String host = u.getHost();
if (host != null)
h += host.toLowerCase().hashCode();
} // Generate the file part.
String file = u.getFile();
if (file != null)
h += file.hashCode(); // Generate the port part.
if (u.getPort() == -1)
h += getDefaultPort();
else
h += u.getPort(); // Generate the ref part.
String ref = u.getRef();
if (ref != null)
h += ref.hashCode(); return h;
是不是pug你们自己说咯,呵呵
URL类重写了equals方法...其比对过程非常之猥琐咩咩...
只有5个非重复的URL
且能构成合法可用的只有4个 apache的那个service unavailable
如果断网的话 就等不出结果了但我居然有一次运行出了结果5
我怎么可能会把大家当傻子呢,而且这个题目也不是我出的,前两题都是来自于:
Joshua Bloch 在 2007 JavaOne 会议上关于 Java Puzzlers 的演讲所出的题目。如果直接选输出是 4 的话,那是很不严谨的,因为大家现在都是联网的吧。
解析,但两个主机名相等(不区分大小写),或者两个主机名都为 null,则也认为这
两个主机相同。也就是说,如果两个 URL 的 IP 地址是相同的,那么这两个 URL 就是相等的。可能大家会没注意到:http://javapuzzlers.com
http://apache2-snort.skybar.dreamhost.com第一和第二个的 IP 地址是相同的,都是 208.97.154.9 ,所以在 Set 时都把它们当成同一个了。如果在没有网络的条件,这些都是无法解析成为 IP 地址的,这时就判断 URL 的名字了,仅认为名字
相同时才是相同的 URL。这道题告诉我们,不要把 URL 应用于 Set 和 Map 的 key 中,可以使用 URI 来代替,这样就不存在
有无网络的问题了。
我的API里怎么没有个说明,
我也只是看了源码以后才知道,也没说url与uri的这点区别,
不要长期不说话哦~
论坛建设中...
老大,你不会直接去JDK下打开那个类库源码看的
2个或2个以上无法解析的地址也会只认一个
URL是URI的子集 但不定位即无解析
"http://apache2-snort.skybar.dreamhost.com",在IE里打开都不同,竟然是相同的URL,完全无语。
测试环境:eclipse3.2.1
A,B一定有一个答案是对的吧,
如果说答案是D,那是在什么情况下的呢,
有两情况,要么有网络,要么没网络,难道是说情况不能确定就选D吗,
呵呵,有意思。
实际上这个题目出出来也不是为了那个答案这个题主要让我们看看 URL#equals 的工作方式,以及在使用时需要注意些什么。
由于Number result = (toBe || !toBe) ?new Integer(3) : new Float(1);
这个判断选择语句选择了new Float(3)int i =(Integer)result;
Exception in thread "main" java.lang.ClassCastException: java.lang.Float cannot be cast to java.lang.Integer
at 疑惑.Test1.main(Test1.java:32)
BigDecimal, BigInteger, Byte, Double, Float, Integer, Long, and Short.还真没注意过Integer的继承关系。我选的答案是 3 而不是 3.0呵呵!
为什么要考虑继承关系呢,toBe || !toBe 不是衡为真吗,那不就应该是 new Integer(3)吗,那不就应该输出3吗,我不太懂,呵呵
127.0.0.1 www.cs.umd.edu
127.0.0.1 findbugs.sourceforge.net
127.0.0.1 javapuzzlers.com
127.0.0.1 www.google.com
127.0.0.1 apache2-snort.skybar.dreamhost.com 我的结果是1
在5.0jdk下,应该是认为int型和float在运算,结果为float型