迅雷面试题

来源:互联网 发布:gb12348-2008标准数据 编辑:程序博客网 时间:2024/05/29 19:52

一、实现一个高性能的文件缓存系统,先写好思路,再编码实现。
    A. 这个题目。。。考虑分布式文件系统,比如googleGFS?全系统由一到多个中心服务器和多台外围服务器组成,外围服务器用来存放文件,中心服务器用来查询,备份等操作。当中心服务器收到文件请求后,进行查找把请求分发给外围服务器。冗余机制。大文件分拆。优化效率。需要相当长的时间来作这个,可能面试的时间不够。
    B.使用hash相关算法如md5把需要缓冲的记录生成唯一的缓冲文件ID保存,缓冲文件目录深度可以根据实际需要设定。以后访问相关记录可以直接访问缓冲的文件服务器了。

C.文件缓存系统,我的理解就是为了让文件访问时,减少磁盘IO次数,而尽量从缓存中读取(这里只考虑读取的加速)。我的解法是先开辟一块内存做为文件内容总缓存(设为SizeT),其中可以放多个文件的内容,每个文件的缓存大小是固定的(设为SizeP),所以总缓存中可缓存的文件个数也就是一定的(为SizeT/SizeP)。然后再建立一个用于索引的hash表,hash表的key为文件的全路径。hash表中每一项的内容可以定义为类似

这样的一个结构:

struct SFileCacheIndex          //文件内容缓存索引

{

 char pszFile[MAX_PATH];      //文件全路径

 long long llStartOffset;         //缓存中文件内容在文件中的起始偏移

 long long llEndOffSet;          //缓存中文件内容在文件中的结束偏移

 void* pCachePos;                //本本件内容缓存在总缓存中的起始位置

 int nAcitveFactor;                 //本文件的活跃系数,初始为1

};

初始时,hash表为空。

所以,这里需要这些数据:一个索引的hash表,一个用于实际存放文件内容缓存的内存块(总缓存),还有一个标志,用于标示某轮读取是否命中缓存。

 

索引更新策略:当收到一个读文件请求时,先在hash表中查找,看有否本文件的缓存索引,如果有则将本索引的活跃系数加1,设置命中标志位;否则看总缓存中还有没有剩余的空间用来容纳新的文件缓存,如果有空间则新建一个索引结构,然后设置命中标志位,如果总缓存已满,则将依次将现有hash表中的索引的活跃系数减1,如果某个索引的活跃系数减1后等于1的话,则认为该索引的已经过期,然后将该索引设置为新的文件索引,然后设置命中标志位,如果没有过期索引,则本轮读取没有命中cache,清除命中标志位。

 

文件读取策略:看当前的要读取的内容是否在缓存中,如果全部在则从缓存中读取,如果部分在,则在的部分从缓存中读取,其余的从磁盘读取,如果没有则全部从文件中读取。

 

cache更新策略:如果命中标志被设置且有磁盘读取发生的话,则将当前请求读取内容的结束位置后的SizeP个字节的文件内容放入缓存进行更新。

 

上面就是大致的思路,觉得主要缺陷有:1.缓存大小是固定的,不够灵活。2.对于顺序性文件读取可能有效,但是随机读取文件的话可能就没什么效果了(需要设置不同的策略)。3.每次只能处理一个读请求,并发性不好。

--------------------------------------------------------------------------------------------------------

D.就是参考linux文件系统缓存机制


二、实现一个高效率的程序(包括所需程序代码),以尽量短的时间,将用户信息表中150张按照时间hash的表(每张表的数据量为100万,数据字段包含《最近修改时间戳/username/nickname/出生地/所在地/年龄/性别/自我介绍》),转换成按照username hash100张表。转换过程方法和过程需要考虑:
a)尽可能短的时间中断用户服务;
b)尽可能少的使用机器内存。

   
stringhash算法

三、迅雷进行一个活动,这个活动需要客户端访问我们服务器。但活动为了限制访问量,做了如下规定,那就是每一个帐户在3600秒内只能参加不多于5次。请实现类c_user_enabled,完成此限制功能。
类接口定义:
Class c_user_enabled
{
Public:
Bool init();
Bool is_user_enabled(string user_name);// user_name表示用户帐户标识
Bool destroy();
};

附:
需要考虑线程安全
可以使用stl.
可以使用如下的一个hash函数:
Unsigned str_hash(string str);
可以使用如下锁:
Class c_lock
{
Public:
Void lock();
Void unlock();
Private:
…;
};
A服务器socketIOCP,epoll)多线程处理,线程加锁接口都有了,呵呵。
用户名Unsigned str_hash(string str); string hash算法也提供了,剩下就是用vectormap去保存用户hash ID和访问次数了
B感觉似乎相对简单一点,建立一个所有用户的表,把3600秒视为一个用户的访问周期。表中的每条记录中都有该用户本周期的起始时间及已经访问的次数,那么用户访问到来时,先看看当前时间是否在前一个周期内,如果不在的话,则将周期起始时间设为当前时间,再将访问次数设为1。如果当前时间还在前一个周期内,那么就看看次数是否超过5次,如果超过就拒绝访问,否则将次数加1,允许访问。为了保证并发性,可以对每个用户单独加锁。而不是对整个表加锁。

http://topic.csdn.net/u/20090212/12/bd6217fd-4df3-4eae-a5b4-2b26f104f6a7.html

原创粉丝点击