首页 > 其他分享 >【TinyWebServer】13踩坑和面试题

【TinyWebServer】13踩坑和面试题

时间:2023-10-06 21:38:14浏览次数:29  
标签:面试题 temp iov TinyWebServer 13 send iv bytes 线程

踩坑

在此项目中遇到的一些比较有意义的问题

大文件传输

先看下游双书上发送逻辑这块的代码,发送数据只调用了writev函数,并对其返回值是否异常做了处理。

bool http_conn::write()
{
	int temp = 0;
	int byte_have_send = 0;   
	int byte_to_send = m_write_idx;  

	if(byte_to_send == 0)
	{
		modfd(m_epollfd,m_sockfd,EPOLLIN);
		init();
		return true;
	}

	while(1)
	{
		temp = writev(m_sockfd,m_iv,m_iv_count);
		if(temp <= -1)
		{
			if(errno == EAGAIN)
			{
				modfd(m_epollfd,m_sockfd,EPOLLOUT);
				return true;
			}
			unmap();
			return false;
		}
		byte_to_send -= temp;
		byte_have_send += temp;
		if(byte_to_send <= bytes_have_send)
		{
			unmap();
			if(m_linger)
			{
				init();
				modfd(m_epollfd,m_sockfd,EPOLLIN);
				return true;
			}
			else
			{
				modfd(m_epollfd,m_sockfd,EPOLLIN);
				return false;
			}
		}
	}
}

在实际测试中发现,当请求小文件,也就是调用一次writev函数就可以将数据全部发送出去的时候,不会报错,此时不会再次进入while循环。

一旦请求服务器文件较大文件时,需要多次调用writev函数,便会出现问题,不是文件显示不全,就是无法显示。

对数据传输过程分析后,定位到writev的m_iv结构体成员有问题,每次传输后不会自动偏移文件指针和传输长度,还会按照原有指针和原有长度发送数据。

根据前面的基础API分析,我们知道writev以顺序iov[0],iov[1]至iov[iovcnt-1]从缓冲区中聚集输出数据。项目中,申请了2个iov,其中iov[0]为存储报文状态行的缓冲区,iov[1]指向资源文件指针。

对上述代码做了修改如下:

  • 由于报文消息报头较小,第一次传输后,需要更新m_iv[1].iov_base和iov_len,m_iv[0].iov_len置成0,只传输文件,不用传输响应消息头
  • 每次传输后都要更新下次传输的文件起始位置和长度

更新后,大文件传输得到了解决。

bool http_conn::write()
{
    int temp = 0;

    int newadd = 0;

    if (bytes_to_send == 0)
    {
        modfd(m_epollfd, m_sockfd, EPOLLIN, m_TRIGMode);
        init();
        return true;
    }

    while (1)
    {
        temp = writev(m_sockfd, m_iv, m_iv_count);

        if (temp >= 0)
        {
            bytes_have_send += temp;
            newadd = bytes_have_send - m_write_idx;
        }
        else
        {
            if (errno == EAGAIN)
            {
                if (bytes_have_send >= m_iv[0].iov_len)
                {
                    m_iv[0].iov_len = 0;
                    m_iv[1].iov_base = m_file_address + newadd;
                    m_iv[1].iov_len = bytes_to_send;
                }
                else
                {
                    m_iv[0].iov_base = m_write_buf + bytes_have_send;
                    m_iv[0].iov_len = m_iv[0].iov_len - bytes_have_send;
                }
                modfd(m_epollfd, m_sockfd, EPOLLOUT, m_TRIGMode);
                return true;
            }
            unmap();
            return false;
        }
        bytes_to_send -= temp;
        if (bytes_to_send <= 0)

        {
            unmap();
            modfd(m_epollfd, m_sockfd, EPOLLIN, m_TRIGMode);

            if (m_linger)
            {
                init();
                return true;
            }
            else
            {
                return false;
            }
        }
    }
}

面试点

包括项目介绍,线程池相关,并发模型相关,HTTP报文解析相关,定时器相关,日志相关,压测相关,综合能力等。

项目介绍

  • 为什么要做这样一个项目?
  • 介绍下你的项目

线程池相关

  • 手写线程池
  • 线程的同步机制有哪些?
  • 线程池中的工作线程是一直等待吗?
  • 你的线程池工作线程处理完一个任务后的状态是什么?
  • 如果同时1000个客户端进行访问请求,线程数不多,怎么能及时响应处理每一个呢?
  • 如果一个客户请求需要占用线程很久的时间,会不会影响接下来的客户请求呢,有什么好的策略呢?

并发模型相关

  • 简单说一下服务器使用的并发模型?
  • reactor、proactor、主从reactor模型的区别?
  • 你用了epoll,说一下为什么用epoll,还有其他复用方式吗?区别是什么?

HTTP报文解析相关

  • 用了状态机啊,为什么要用状态机?
  • 状态机的转移图画一下
  • https协议为什么安全?
  • https的ssl连接过程
  • GET和POST的区别

数据库登录注册相关

  • 登录说一下?
  • 你这个保存状态了吗?如果要保存,你会怎么做?(cookie和session)
  • 登录中的用户名和密码你是load到本地,然后使用map匹配的,如果有10亿数据,即使load到本地后hash,也是很耗时的,你要怎么优化?
  • 用的mysql啊,redis了解吗?用过吗?

定时器相关

  • 为什么要用定时器?
  • 说一下定时器的工作原理
  • 双向链表啊,删除和添加的时间复杂度说一下?还可以优化吗?
  • 最小堆优化?说一下时间复杂度和工作原理

日志相关

  • 说下你的日志系统的运行机制?
  • 为什么要异步?和同步的区别是什么?
  • 现在你要监控一台服务器的状态,输出监控日志,请问如何将该日志分发到不同的机器上?(消息队列)

压测相关

  • 服务器并发量测试过吗?怎么测试的?
  • webbench是什么?介绍一下原理
  • 测试的时候有没有遇到问题?

综合能力

  • 你的项目解决了哪些其他同类项目没有解决的问题?
  • 说一下前端发送请求后,服务器处理的过程,中间涉及哪些协议?

转载文章:

最新版Web服务器项目详解 - 13 踩坑和面试题 (qq.com)

标签:面试题,temp,iov,TinyWebServer,13,send,iv,bytes,线程
From: https://www.cnblogs.com/Wangzx000/p/17745041.html

相关文章

  • 【TinyWebServer】12注册登录
    整体概述本项目中,使用数据库连接池实现服务器访问数据库的功能,使用POST请求完成注册和登录的校验工作。本文内容本篇将介绍同步实现注册登录功能,具体的涉及到流程图,载入数据库表,提取用户名和密码,注册登录流程与页面跳转的的代码实现。流程图具体的,描述了GET和POST请求下的页......
  • 39-13
    假设有两个按元素值递减次序排列的线性表,均以单链表的形式存储,编写算法,将这两个单链表合成一个按值递减的单链表,使用原链表的结点。没啥好说的,这个有手就行#include<stdio.h>#include<stdlib.h>typedefstructnode{intdata;structnode*next;}LNode,*LinkLi......
  • CF131D Subway 题解
    题目传送门前置知识强连通分量|最短路解法考虑用Tarjan进行缩点,然后跑最短路。缩点:本题的缩点有些特殊,基于有向图缩点修改而得,因为是无向图,所以在Tarjan过程中要额外记录一下从何处转移过来,防止在同一处一直循环。基环树上找环还有其他方法,这里仅讲解使用Tarjan求......
  • 2023-2024-1 学号20231315《计算机基础与程序设计》第二周学习总结
    学期:2023-2024-1学号:20231315《计算机基础与程序设计》第二周学习总结作业信息这个作业属于哪个课程2023-2024-1《计算机基础与程序设计》这个作业要求在哪里2023-2024-1《计算机基础与程序设计》这个作业的目标学习计算机科学概论第1章和《C语言程序设计》第1......
  • 升级Lync Server 2013到Skype for Business 2019(二)
    写在前面从本章开始,将进入到整个LyncServer2013升级到SkypeforBusiness2019升级项目的详细实施部分。本章将介绍SkypeforBusiness2019前端服务器安装。前端服务器安装先决条件安装打开WindowsPowerShell。确保已插入WindowsServer2019安装介质。运行以下命令Add-Window......
  • 面试题:Redis和MySQL的事务区别是什么?
    大家好,我是小米!今天我要和大家聊聊一个在技术面试中经常被问到的问题:“Redis和MySQL的事务区别是什么?”这个问题看似简单,但实际上涉及到了数据库和缓存两个不同领域的知识,让我们一起来深入了解一下吧!什么是事务?首先,我们需要明确什么是事务。事务是数据库中的一个重要概念,它是一组数......
  • 大数据面试题:MapReduce压缩方式
    可回答:1)Hadoop常见的压缩算法有哪些?问过的一些公司:网易云音乐(2022.11),阿里(2020.08)参考答案:1、MapReduce支持的压缩方式压缩格式hadoop自带?算法文件扩展名是否可切分换成压缩格式后,原来的程序是否需要修改DEFLATE是,直接使用DEFLATE.deflate否和文本处理一样,不需要修改Gzip是,直接......
  • Linux常见面试题,应对面试分享
    操作系统基础1.cpu占⽤率太⾼了怎么办?排查思路是什么,怎么定位这个问题,处理流程其他程序:1.通过top命令按照CPU使⽤率排序找出占⽤资源最⾼的进程2.lsof查看这个进程在使⽤什么⽂件或者有哪些线程3.询问开发或者⽼⼤,是什么业务在使⽤这个进程4.是否可以将这台机器隔离,不影响......
  • P4133 [BJOI2012]最多的方案 题解
    P4133双倍经验发现斐波那契数列增长极快,不到\(100\)项就超过了\(10^{18}\),搜索树也极为稀疏,可以考虑搜索。爆搜肯定会超时,考虑优化:可行性剪枝。记忆化,去除重复的计算。改变搜索的顺序,因为先考虑小元素的话,会有较多的无用的搜索,且小元素较灵活,更容易凑到\(x\),故可......
  • Luogu CF1133B 题解
    这道题其实很简单要让两数和为\(k\)的倍数,需要满足以下两条件之一:两数都是\(k\)的倍数两数的余数和为\(k\)因此,我们可以先统计出余数再按上述条件算出共有多少组,即可得到答案注意:当\(k\)为偶数时,余数为\(k/2\)的数要两两配对,不要多算这里统计的是组数,......