三、综合题
1、有一颗结构如下的树,对其做镜像反转后如下,请写出能实现该功能的代码。注意:请勿对该树做任何假设,它不一定是平衡树,也不一定有序。
1 1
/ | \ / | \
2 3 4 4 3 2
/|\ /\ | | / \ / | \
6 5 7 8 9 10 10 9 8 7 5 6
答:以孩子、兄弟的存储结构来存储这棵树,使之成为一颗二叉树,然后对二叉树进行链表的转换。
[cpp] view plaincopytypedef struct TreeNode
{
int data;
struct TreeNode *firstchild;
struct TreeNode *nextsibling;
}TreeNode,*Tree;
void MirrorTree(Tree root)
{
if(!root)
return ;
if(root->firstchild)
{
Tree p=root->firstchild;
Tree cur=p->nextsibling;
p->nextsibling=NULL;
while(cur)
{
Tree curnext=cur->nextsibling;
cur->nextsibling=p;
if(p->firstchild)
MirrorTree(p);
p=cur;
cur=curnext;
}
root->firstchild=p;
}
}
int main(void)
{
TreeNode *root=(TreeNode *)malloc(sizeof(TreeNode));
Init();
MirrorTree(root);
OutPut();
}
2、假设某个网站每天有超过10亿次的页面访问量,出于安全考虑,网站会记录访问客户端访问的ip地址和对应的时间,如果现在已经记录了1000亿条数据,想统计一个指定时间段内的区域ip地址访问量,那么这些数据应该按照何种方式来组织,才能尽快满足上面的统计需求呢,设计完方案后,并指出该方案的优缺点,比如在什么情况下,可能会非常慢?
答:用B+树来组织,非叶子节点存储(某个时间点,页面访问量),叶子节点是访问的IP地址。这个方案的优点是查询某个时间段内的IP访问量很快,但是要统计某个IP的访问次数或是上次访问时间就不得不遍历整个树的叶子节点。答:
或者可以建立二级索引,分别是时间和地点来建立索引。
四、附加题
1、写出C语言的地址对齐宏ALIGN(PALGNBYTES),其中P是要对齐的地址,ALIGNBYTES是要对齐的字节数(2的N次方),比如说:ALIGN(13,16)=16
[cpp] view plaincopyALIGN(P,ALIGNBYTES) ( (void*)( ((unsigned long)P+ALIGNBYTES-1)&~(ALIGNBYTES-1) ) )
2、在高性能服务器的代码中经常会看到类似这样的代码:
typedef union
{
erts_smp_rwmtx_t rwmtx;
byte cache_line_align_[ERTS_ALC_CACHE_LINE_ALIGN_SIZE(sizeof(erts_smp_rwmtx_t))];
}erts_meta_main_tab_lock_t;
erts_meta_main_tab_lock_t main_tab_lock[16];
请问其中用来填充的cache_line_align的作用是?
3、在现代web服务系统的设计中,为了减轻源站的压力,通常采用分布式缓存技术,其原理如下图所示,前端的分配器将针对不同内容的用户请求分配给不同的缓存服务器向用户提供服务。
分配器
/ | \
缓存 缓存 ...缓存
服务器1 服务器2 ...服务器n
1)请问如何设置分配策略,可以保证充分利用每个缓存服务器的存储空间(每个内容只在一个缓存服务器有副本)
2)当部分缓存服务器故障,或是因为系统扩容,导致缓存服务器的数量动态减少或增加时,你的分配策略是否可以保证较小的缓存文件重分配的开销,如果不能,如何改进?
3)当各个缓存服务器的存储空间存在差异时(如有4个缓存服务器,存储空间比为4:9:15:7),如何改进你的策略,按照如上的比例将内容调度到缓存服务器?