java 新建对象时,保证全局唯一ID

很久之前见到的一道面试题,答题过程有点捞,记录一下。

 

一、答题过程

(1)UUID的简单用法

面试官:“现在我想新建一些monster对象,对象有一个id字段。我希望生成的每个monster对象都有其唯一id,要如何解决这个问题呢?”

我:“这好办,用UUID。”

TestUUID.java

运行结果:

(2)去掉“-”

面试官:“一般id里面是不会带-的,能不能把这个-去掉呢?”

我:“这好办,简单用一下String提供的replaceAll就行了”。

testUUID.java

运行结果:

(3)id改为integer(错误示范)

面试官:“现在我需要把id改为整型,怎么做?”

我:“多捞哦这个需求!你家数据库的id主键都是number吗!为什么不能用String!”(当然不敢这样直接说)

TestUUID.java

面试官:“这段代码能正常运行吗?”

我review了一遍之后:“不能,Interger存不下,长度肯定溢出了”。

(4)原子类

面试官:“用integer做id确实不太合理。但是如果我坚持要这样做,要怎么解决这个问题呢?”

我:“mmp,用原子类试一下”。

Test.java

面试官:“但是这样一来,id还是存在着数量限制啊?”

我:“是你叫我用Integer的,你告诉我怎么弄好了。”

面试官:“…”

(5)不同服的重复id

面试官:“那么问题来了,游戏里面经常存在跨服玩法。按照上面的原子类方法,在两个不同的服务器内可能存在相同id。要如何避免这种情况?”

我:“那就RPC调用咯。先设置一个中心服,所有游戏服统一向中心服拿id,就可以避免了。”

面试官:“假如我现在禁止使用RPC,要如何保证id唯一?”

我:“mmp,虽然这种解决方法很sb,只能加入游戏服的不同特征了!”

“假设存在游戏一服和游戏二服,游戏一服的id为1,游戏二服的id为2。首先我们约定monster的id必须为10位长度的integer(这里要注意整型的范围:-2^31(-2,147,483,648)到2^31-1(2,147,483,647))。”

“约定前三位为游戏服id,比如1服为001,二服为002。当然,这样出来的整型可能会少前面两位,但是我们可以知道整个integer的长度,不足的补0就可以了。”

“约定后七位为monsterid,一样按照原子类的方法生成。总id为:游戏服id * 10^7 + monsterid。”

我:“你觉得这样可取吗?”

面试官:“其实你应该一早就告诉我,integer不适用于做id…”

我:“你是失了智!”

二、总结

面试过程没有我写的那么有戏剧性,但是这道题真的出得不好,有点莫名其妙。

1 对 “java 新建对象时,保证全局唯一ID”的想法;

  1. 不是可以去使用数据库获取唯一id吗?取一个范围在内存中自增,然后大道阈值了就去数据库再取一个,就这样

发表评论

电子邮件地址不会被公开。 必填项已用*标注