面试题: java面试经历 已看1 抢红包如何分配每个人抢到的钱 有用 难点的面试题

面试题: java面试经历  已看1 抢红包如何分配每个人抢到的钱  有用 难点的面试题

2018.03.09 深圳乐唯科技

我看了下感觉这公司貌似挺不错的,面试官人也挺好的,氛围应该很不错,可惜我实力不足,唉,接续努力,下面把面试中印象较深的三个问题写一下。


面试问题1:数据库删除重复数据,多条重复的数据中只保留一条 
表名 t

a b c
1 222 333
2 222 333
3 222 333

如果a字段的数据每行都不同的话SQL如下:( 保留a字段数据最小的那条,如果要保留大的就讲min(a)换成max(a) )

DELETE FROM tt WHERE NOT EXISTS(
    SELECT * FROM (
        SELECT *, MIN(a) AS id FROM tt GROUP BY b HAVING COUNT(*) >= 1
    ) e WHERE e.id = tt.a
)
  • 1
  • 2
  • 3
  • 4
  • 5

ps: 上面是MySQL的用法 
下面还有一种其他数据库的用法,下面这条SQL放到MySQL中运行会报错,貌似只有MySQL会报错,报错信息为:[Err] 1093 - You can’t specify target table ‘tt’ for update in FROM clause 错误的意思是说,不能先select出同一表中的某些值,再update这个表(在同一语句中),我本来想讲select出来的外面再套一层select,但是这条语句的逻辑好像不能套一层select,套了之后会有语法错误;

DELETE FROM tt WHERE b IN(
    SELECT b FROM tt GROUP BY b HAVING COUNT(*) >1
) AND a NOT IN (
    SELECT MIN(a) FROM tt GROUP BY b HAVING COUNT(*)>1
)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

上面是a的值不同的情况,如果每行a的值都相同呢?貌似可以用行号来标记,具体还需要在研究研究,未完待续~


面试问题2:抢红包如何分配每个人抢到的钱(抢红包算法)

@param total 红包余额
@param rest 红包剩余个数 - 1(先减去本次的个数)
private long nextMoney(long total, long rest){
    if(rest < 0 || total < 0){
        //如果rest或者total小于0,抛出一个异常,可以自己写一个异常处理类继承RuntimeException
        throw ......
    }
    //如果rest为0,说明这是最后一个红包,直接返回余额
    if(rest == 0){
        return total;
    }
    //取余额平均数(要加上本次的个数)
    long per = total/(rest + 1);
    //取1至余额平均数的*2的随机数(数学期望值?)
    long result = RandomUtils.nextLong(1, per * 2);
    //如果result取大了,不能满足剩下的个数每个最小值1的要求,就留下最低余额,剩下的返回
    if(total - result < rest){
        result = total - rest;
    }
    return result;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

面试问题3:为什么要用bean,有什么好处或优势? 
我回答的是什么解耦啊、使用更灵活啊、、, Σ( ° △ °|||)︴,看到面试官在无奈的摇头,,,, ╥﹏╥… 
后来我在网上找了找,表示没有找到这个问题的答案,汗,我会继续找的。