第一轮 编码分配——TCP发送方-接收方通信,处理重复和无序数据包。
场景:应用程序从网络上的服务器接收数据包。每个数据包都属于一个特定的信道,并且也由一个唯一的序列号来标识。请注意,每个通道都有自己的序列号系列。因此,如果服务器正在为10个通道发送数据,那么您应该看到这10个通道中的每个通道都以序号1开头的数据包。
网络是这样的,在离开服务器但到达应用程序之前,这些数据包可能会被删除
- 重新订购;或
- 复制;但是
- 从未完全放弃。
应用程序的目标是始终按照(特定于通道的)序列号的顺序应用数据包数据,并且没有任何间隙。当然,在现实世界中,还有更多的工作要做,但我们现在将忽略它。
你必须 实现函数re_sequence_和_apply() .
您可以使用任何数据结构来实现这个目的,包括来自C++ STL的任何内容。如果您编写自己的数据结构,请在解决方案中提供该数据结构的完整定义。
此外,您还必须实现event_源代码接口,以便以您希望的任何方式测试代码。您的解决方案将根据正确性以及空间和时间复杂性进行评估。
代码片段
#include <stdint.h> #include <iostream> struct event { uint8_t channel_id; uint32_t sequence_number; uint8_t *pkt_data; uint32_t pkt_len; }; classevent_source { public : virtual event* get_next() = 0; virtual void release_event(event* ev) = 0; }; void apply_pkt_data( int8_t channel_id, uint32_t sequence_number, uint8_t* pkt_data, uint32_t pkt_len) { std::cout<< "(" <<( int )channel_id<< "," <<sequence_number << "," <<*( char *)pkt_data<< ") " ; } void re_sequence_and_apply( int8_t channel_id, uint32_t sequence_number, uint8_t* pkt_data, uint32_t pkt_len) { /* This is the function that you need to code. It should apply the data in sequence for each channel for which data is received. Once your code figures out which packet to apply next, it should call apply_pkt_data() as defined above */ } // Driver program int main () { // Instantiate your own implementation of event_source // here for testing. event_source* event_q; event* ev; while ((ev = event_q->get_next()) != NULL) { re_sequence_and_apply(ev->channel_id, ev->sequence_number, ev->pkt_data, ev->pkt_len); event_q->release_event(ev); } return 0; } |
第二轮(约35-40分钟)
1.什么是用户模式和内核模式?
—-> 内核模式
在内核模式下,执行代码可以完全且不受限制地访问底层硬件。它可以执行任何CPU指令并引用任何内存地址。内核模式通常为操作系统的最低级别、最受信任的功能保留。内核模式下的崩溃是灾难性的;他们将停止整个电脑。 用户模式
在用户模式下,执行代码无法直接访问硬件或参考内存。在用户模式下运行的代码必须委托给系统API才能访问硬件或内存。由于这种隔离提供了保护,用户模式下的崩溃总是可以恢复的。计算机上运行的大多数代码将在用户模式下执行。
2.单用户系统为什么需要内核模式?
->从硬件资源和I/O资源分配的角度考虑,陷阱、系统调用和中断都发生在内核模式下。为了执行原语和敏感指令,内核模式是必要的。
3.为什么内核模式的操作不能在用户模式下执行?
4.两个进程能否生成相同的虚拟地址?如果是,那么物理地址会不同还是相同?为什么相同或不同?
5.什么是陷阱?什么是中断?中断类型?它们有什么不同?所有陷阱都需要在模式之间切换吗?
6.具有不同堆栈的进程线程如何共享资源?线程将如何通信?
7.在多核情况下,如果T1在核1上运行,T2在核2上运行,它们将如何同步和通信?
8、给出了C++中的一些代码段,其中P1和P2进程生成一些地址。P1生成的地址使用解引用进行初始化。P2可以取消引用吗?
9.关于堆栈指针的问题。
10.代码片段在打印纸上给出。询问代码将输出什么。答案中大多是seg错误。
11.编写了一些syscalls代码,但她非常耐心地向我解释了该代码,然后问错误在哪里?我不记得密码了。
问我想不想问什么。我问了2-3个关于公司的问题,我该怎么办?被问及工作和个人资料,以及公司实际做什么?
她回答得很有趣。我喜欢。
第三轮(约1小时)
面试官太棒了。在这一轮中,我一秒钟也不觉得不舒服。讨论一直在继续。根据我个人的经验,这真是太棒了。
1.完成编码作业的讨论。使用的策略和数据结构。
2.如果内存有限,设计数据结构以保存大量传入数据包。
3.在线程执行中,您将把调度器、编译器、调度器和MMU放在哪里?详细解释一切。
4.你知道汇编代码吗?你在线程库中使用的汇编代码?这将如何调用调度程序?
5.如果您试图访问地址1(按堆栈指针递增,如SP=SP+1),可能会出现分段错误?如果是,为什么?如果没有,原因是什么?
6.高级计算机网络课程讨论:新TCP协议:维加斯、雷诺、无线韦斯特伍德等
7.设计一个数据结构(可以使用STL)来捕获数据包,如果传入数据的速度非常快,请记住无序交付和重复数据包。在处理所有案件方面效率很高。
->处理过程中的延迟应该是最小的
->能够管理超过10000个无序数据包。
8.解释三方握手。如果SYN被删除,如果SYN+ACK被删除,如果ACK被删除,会发生什么?在丢弃最后一个ACK时,发送方仍然可以通过通道发送数据吗?它可靠吗?
9.关于pthread库实现的问题-CSP分配。关于调度程序、编译器以及调度程序如何在线程调度中工作。完整解释循环调度程序。
10.给出了一个代码:
int *f1( int a) { int *c = &a; *c = *c*10; return &c; } int *f2( int *b) { int c = *b*10; return &c; } int main() { int a = 10; int *add1=f1(a); int *add2=f2(add1); print (*add2); } |
这段代码可以编译吗?如果是,输出是什么?如果没有,为什么?
堆栈上的内存分配和释放将如何工作?
关于分段错误的长期讨论。如果是,为什么?如果没有,是吗?当函数返回或局部变量的值仍然存在时,除非下一个函数重写,否则内存将从堆栈空间中交换。到底发生了什么?
在我离开的时候让我运行代码。我问我能带上这段代码吗?他说不,我不能透露问题,他笑了。然后,我说没关系。这个问题在我脑海里。我一定会执行的。
如果你喜欢Geeksforgek,并想贡献自己的力量,你也可以写一篇文章,然后把你的文章发到contribute@geeksforgeeks.org.看到你的文章出现在Geeksforgeks主页上,并帮助其他极客。