最右技术问答的一点个人见解
Posted 痕迹天涯119
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了最右技术问答的一点个人见解相关的知识,希望对你有一定的参考价值。
题目一:服务日志分析
需求:分析服务接口的调用次数和平均响应时长待分析的服务日志:http://www.izuiyou.com/download/server_access.log.tgz下载并解压,解压后有一个文件server_access.log, 文件每一行记录一次服务接口的调用信息,日志格式如下:
15/Nov/2016:03:20:01 /post/httpapi/get_member_like_data 0.004
该行包含三个字段,字段间以空格区分, 第一个字段是访问时间,第二个字段是接口名字,第三个字段是调用的响应时长(单位毫秒)。
请做如下分析:
1.计算每个接口的访问次数,并按次数的倒序排序
答:
该问关键点有两个:
1)对于重复接口字符串的判定
这里我想到两种方案,一是通过直接对比两个接口的字符串来对比是否是同一接口,二是通过哈希算法为每个接口生成唯一的标记位然后存储到类集合中
建立接口对象
public static class XCInterface
String mName;
String visitTime;
double responseTime;
public XCInterface(String mName, String visitTime, Double responseTime)
this.mName = mName;
this.visitTime = visitTime;
this.responseTime = responseTime;
第一种方案的实现及复杂度:
建立对象数组A,遍历日志文件,若接口的字串S不被包含在数组A中则向A中添加字串S对应的接口Node,否则仅在访问次数上+1即可。
for("遍历获取接口字符串值")
int k=0;
//mName接口字串,visitTime 访问时间,responseTime响应时间,visitNumber 访问累计次数
if("对象数组A中没有接口s对应的接口Node")
xcInterfaces[k] = new XCInterface(mName,visitTime,responseTime,0);
k+=1;
else
xcInterfaces["匹配位置"].visitNumber+=1;
假设m:不同接口字串的总数 n:日志总数 x:所有接口字串个数的平均数
该方案最差情况下n中的每个日志每轮都需要与m中的所有已积累字串进行对比,且每次都要对比x次,那么该方案的复杂度是O(m*n*x)即O(mnx)。
第二种方案的实现及复杂度:
对n个日志进行一轮遍历,在遍历的过程中通过预先设定好的hash函数为每个不同的接口字串生成在数组中唯一的标记值
//这里假设共有1000个以内的访问接口
XCInterface[] xcInterfaces = new XCInterface[1000];
for ("遍历获取接口字符串值")
//mName接口字串,visitTime 访问时间,responseTime响应时间
if(xcInterfaces["生成唯一的hash值"] !=null)//这一步省去了接口字符的对比过程,较少m倍
xcInterfaces["生成唯一的hash值"].visitNumber+=1;
else
xcInterfaces["生成唯一的hash值"] = new XCInterface(mName, visitTime, responseTime,0);
2)判定后数据的存取及排序
这里把前面所有非null的值提取到ArrayList中进行排序操作
private static void quick_sort(ArrayList<XCInterface> mList,int l,int r)
if(l<r)
int i=l,j=r;
double temp = mList.get(0).responseTime;
while(i<j)
while(i<j&&mList.get(i).responseTime<=temp)
j--;
if(i<j)
mList.get(i++).responseTime = mList.get(j).responseTime;
while(i<j&&mList.get(i).responseTime>=temp)
i++;
if(i<j)
mList.get(j--).responseTime = mList.get(i).responseTime;
mList.get(i).responseTime = temp;
quick_sort(mList,l,i-1);
quick_sort(mList,i+1,r);
OK,对于每个接口的倒序排列就搞定了
2.计算每个接口的平均响应时长
这里O(N)即可实现,在原有的对象中添加一个totalTime属性
public static class XCInterface
//省略...
int totalTime;
public XCInterface(String mName, String visitTime, Double responseTime, int visitNumber ,int totalTime)
this.totalTime = totalTime;
//省略...
平均响应时长 = totalTime/visitNumber;
3.计算每个接口响应时长超过100ms的次数
同样的添加一个属性overTimeCount累计个数即可,复杂度O(N),不再过多叙说
最后,我们完全可以把这么大的数据量划分为多个文件,并通过多线程来并发实现计算,最后对结果统一处理即可。
题目二:设计帖子的排序算法
最右App的核心操作之一就是通过刷新推荐出帖子进行消费,每时每刻都有大量的新帖子产生,而每次刷新能推荐给你的帖子数是非常有限的(比如一次刷新推荐12条帖子),那么此时就需要在服务器端对于待推荐的帖子进行排序,排在前面的帖子会优先被推荐出来,用户通过刷新显示到最右APP中。
那么问题来了,如何对这些待推荐的帖子进行排序呢?
1.帖子排序依赖于每个帖子的权重值(Rank)
2.帖子权重和很多因素有关,例如发帖时间,帖子类型,帖子得到的行为等
3.帖子得到的行为有查看、赞、踩,分享等,你可以通过使用最右App了解更多的用户行为。
4.甚至你的算法可以针对不同的用户给出完全不同的排序结果(最终给出的算法中可以不考虑这一点)。
最后,给出你的算法思路和描述,最好能给出伪码实现。
++关于这个问题啊,,貌似更像是产品同学的问题吧,既然有此一问,这里给出琢磨的思路及其实现。++
对于帖子的推荐顺序在确定每个帖子针对每个用户的权重之后还是比较简单的,而权重的获取大致可以参考faceBook的edgerank算法。
EdgeRank 用于当某个用户查看他的新鲜事时,决定这些新鲜事先后顺序的一个排序算法. 算法核心是每个事件对这个用户而言的权重 E, 其计算公式是 E = u*w*d, 其中
u, 事件生产者和观察者之间的亲密度
w, 边权重 (主要是事件的类型)
d, 时间衰减因子
我个人的看法是针对实际应用涉及到的每一项会影响用户对帖子感觉的因素设定不同的值用以表示该因素对整体权重产生的影响(可能的因素特别多,比如帖子类型,点赞,亲密度,被举报等等),然后通过累加累减变动的产生的一个针对具体用户的帖子权重值,根据该值响应用户的数据获取请求即可。
大体上就是这样了,希望没有白忙活吧,哈哈
以上是关于最右技术问答的一点个人见解的主要内容,如果未能解决你的问题,请参考以下文章