您的位置:首页 > 职场人生

一道关于优化的面试题,一家互联网公司的面试题

2017-04-14 11:44 375 查看
近期遇到一个有意思的面试题,关于优化的。

系统中有一个方法func,每10秒钟就会调用一次,性能有问题,请优化一下。主要考虑执行效率。

方法例如以下。

LinkedList<Date> dates = new LinkedList<Date>();

……

public String func(String bits)

{

Random random = new Random(System.currentTimeMillis());

String str = "";

for(int i = 0; i < (bits.length() > 1000 ? bits.length() : 1000); ++i)

{

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

str += sdf.format(dates.get(i));

}

return str;

}

能够看到,这种方法的作用就是将dates的元素依照List的顺序以一定的格式拼接在一起,拼接的元素总数以bits.length() > 1000 ? bits.length() : 1000得到。

我的优化方案:因为for循环里总是在做String的链接,这样会产生非常多小的对象,而循环次数也不少,easy导致垃圾回收。String改为StringBuffer,这样就能避免产生小对象。看代码。

public String func1(String bits)

{

StringBuffer sb = new StringBuffer();

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

for(int i = 0; i < (bits.length() > 1000 ?

bits.length() : 1000); ++i)

{

sb.append(sdf.format(dates.get(i)));

}

return sb.toString();

}

上面的就是我的面试答案。哎,仅仅有更好,没有最好啊。

进一步,循环至少迭代1000次。那么,在某个步骤准备好一个字符串(datemat1000)。

可假设dates发生变化,比方remove前面的对象。就会导致结果不对。

再进一步,假设考虑到了remove的时候,变化这个datamat1000。那结果就正确。

有没有更好的方案呢,假设bits非常长(对应的。dates肯定也长),还是会迭代非常多次,效率还会有问题。

啊哈,灵光一闪。是否能预先将dates全部的元素预先拼接在一起。在dates add和remove的时候将拼接的StringBuffer做出对应变化,在func里依据bits的长度从StringBuffer里复制字符串来。

这样就不会再每10秒执行的func里有太多动作。

缺点:remove(object o)这种方法里须要又一次构建字符串。


请看代码:

MyLinkedList dates = new MyLinkedList();

// ……

public String func2(String bits)

{

int bitlen = bits.length() > 1000 ? bits.length() : 1000;

return dates.getDatesSb().substring(0, bitlen * dates.SDF_LEN);

}

class MyLinkedList<Date> extends LinkedList<Date>{

private StringBuffer datesSb = new StringBuffer();

private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

public final int SDF_LEN = 19;

@Override

public boolean add(Date date)

{

boolean isok = super.add(date);

if(!isok)

return isok;

dateSb.append(sdf.format(date));

return isok;

}

private void reInit()

{

StringBuffer sb = new StringBuffer();

for(int i = 0; i < super.size(); i++)

{

sb.append(sdf.format(super.get(i)));

}

dateSb = sb;

}

@Override

public boolean remove(Object o)

{

boolean isok = super.remove(o);

if(!isok)

return isok;

reInit();

return isok;

}

@Override

public Date remove(int index)

{

Date date = super.remove(index);

if(date != null)

{

dateSb.delete(index* SDF_LEN, (index + 1) * SDF_LEN);

}

return date;

}

//……

public StringBuffer getDatesSb() {

return datesSb;

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: