每日刷题3.125道算法+15道面试 - 阿V

Posted V鸦_阿V

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了每日刷题3.125道算法+15道面试 - 阿V相关的知识,希望对你有一定的参考价值。

感觉算法太占时间了,而且刷的差不多了,现在开始专攻面试!加油~明天阿里笔试。

面试题 (一面-项目介绍+基础面)

1. 自我介绍 (游戏测试工程师)

看了多篇文章,说自我介绍不能太短,最好是三分钟,哈哈哈,我尽力描述。


HR你们好,我叫zzw,21岁,来面试游戏测试工程师的,就读于广东工业大学数字媒体技术专业,是一名热爱玩游戏又热爱开发游戏的网瘾少年,学校课程里的游戏开发大作业,都是完全负责程序代码方面,当然我也喜欢参与策划,课外也热爱自己捣鼓游戏开发,自己开发过几款游戏demo,都剪成视频上传到了B站,最满意的一款demo就是雷霆战机,播放量过万,在开发的过程中,遇到过许许多多的bug和问题,没系统学过怎么测试,都是自己摸索出bug的源头并修复。现在使用最频繁的是C++,因为最近半年刷算法都是用C++。

当然除了虚拟游戏,现实中我非常热爱运动,因为没有健康的体魄就玩不了游戏了,每天都会去跑步健身,之前爱好街舞,大二还担任了一年的舞蹈俱乐部社长,举办过不少活动,荣获四星级社团。乐于与人交往,在与人交往的过程中,学习如何做人,如何更好的与人配合。

之所以选择游戏测试工程师这个职业,因为很想从事游戏相关的职业,而所有职业中游戏测试工程师是最符合的,测试游戏可以令游戏质量上升,因为是一名游戏玩家,舒服的游戏体验是每个玩家都希望的,而测试游戏的过程中,可以学习到很多游戏开发的知识,这也是我渴望的。所以我想带着兴趣和梦想来担任这份工作,以上就是我的自我介绍,谢谢大家。

2. 介绍项目

雷霆战机项目:

游戏玩法:驾驶飞机躲避弹幕,吃比自己体型小的敌机进行升级,类似于大鱼吃小鱼的玩法。

遇到难题(对于当时的我来说):

1. 飞机类型与子弹类型如何做到同时匹配,解决办法是:将飞机类型和子弹类型用字典存储在一起,修改飞机的时候同时修改子弹。

2.飞机升级,子弹数量增加要如何增加,就是如何均匀地分布在飞机周围,解决办法是:在飞机周围提前创建好空对象,位置和编号都自己设定好,子弹增加时,获取对应编号的位置添加上去就行。

从中学习到了什么:

了解了飞行类游戏的玩法,相关设计模式的原理,例如:观察者模式。以及子弹的规则生成,敌机属性与AI的搭建。

3. TCP和UDP的联系和区别

 TCP(传输控制协议),是面向连接,可靠,基于字节流的传输协议,只支持单播,可以全双工通信,拥有拥塞控制,流量控制。建立连接使用三报文握手,断开连接使用四报文挥手。

UDP(用户数据报协议),是无连接,不可靠,基于报文流的传输协议,支持单播、多播、广播,不可以全双工通信。

4.  设计一个可靠的UDP协议应该怎么做?

 首先思考UDP怎么不可靠?UDP在传输过程中会出现丢包、数据不完整、乱序等问题。根据这些问题一一解决。

防止丢包:加入确认和重传机制,类似于TCP的Ack机制

数据不完整:加个16或32位的CRC验证字段

乱序:加个数据包序列号SEQ

5. 微信是使用TCP还是UDP

 根据TCP和UDP的原理,微信的视频通话,语音通话应该使用了速度更加的UDP,而文本消息等使用TCP确保信息准确。

但网上了解到,微信登陆验证等采用HTTP,而文本消息,视频通话等使用了TCP长连接,通过心跳包来维护长连接,300s一个心跳。

6. 进程和线程的联系和区别

 进程是表示资源分配的基本单位,线程是进程中执行运算和调度的最小单位。

1. 一个线程只能属于一个进程,而一个进程可以拥有多个线程。

2. 资源分配给进程,同一进程的所有线程共享该进程的所有资源。

3. 进程拥有独立的地址空间,进程都是建立在虚拟内存的基础上,而线程没有独立的地址空间。

4. 进程比线程健壮,一个进程崩溃不会影响其他进程,而一个线程崩溃会导致整个进程崩溃。

5. 进程执行开销大,而线程依附于进程,执行开销小。

7.  单例模式

 首先什么是单例模式?因程序需要,有时某个类只需要一个对象,例如:设备管理器,数据池等。

单例模式特点:1. 全局只有一个实例,禁止赋值和拷贝  2.用户通过接口获取实例

实现单例的几种方式;

1. 懒汉式(Lazy-Initialization)的方法是直到使用时才实例化对象,问题:

        1.线程安全问题,不同线程同时创建该类,可能导致多个实例出现,解决办法加锁。

        2.内存泄漏,由于static申请在静态存储区,无法直接delete,只能靠系统自己处理。

#include <iostream>
// version1:
// with problems below:
// 1. thread is not safe
// 2. memory leak

class Singleton
private:
    Singleton() //修改默认构造函数
        std::cout<<"constructor called!"<<std::endl;
    
    Singleton(Singleton&)=delete; //删除拷贝构造函数
    Singleton& operator=(const Singleton&)=delete; //删除赋值运算符函数
    static Singleton* m_instance_ptr; //创建静态对象
public:
    ~Singleton() //修改析构函数
        std::cout<<"destructor called!"<<std::endl;
    
    static Singleton* get_instance() //创建对象
        if(m_instance_ptr==nullptr)
              m_instance_ptr = new Singleton;
        
        return m_instance_ptr;
    
    void use() const  std::cout << "in use" << std::endl;  //const放函数后面表示该函数一切都不可修改
;

Singleton* Singleton::m_instance_ptr = nullptr; //初始化单例对象为空

int main()
    Singleton* instance = Singleton::get_instance();
    Singleton* instance_2 = Singleton::get_instance();
    return 0;


2. 线程安全、内存安全的懒汉式单例 (智能指针,锁)

#include <iostream>
#include <memory> // shared_ptr
#include <mutex>  // mutex

// version 2:
// with problems below fixed:
// 1. thread is safe now
// 2. memory doesn't leak

class Singleton 
public:
	typedef std::shared_ptr<Singleton> Ptr; //使用智能指针

	~Singleton() 
		std::cout << "destructor called!" << std::endl;
	

	Singleton(Singleton&) = delete; //禁止拷贝构造函数
	Singleton& operator=(const Singleton&) = delete; //赋值运算符操作

	static Ptr get_instance() 

		// "double checked lock"
		if (m_instance_ptr == nullptr) 
			std::lock_guard<std::mutex> lk(m_mutex); //线程加锁
			if (m_instance_ptr == nullptr) 
				m_instance_ptr = Ptr(new Singleton);
			
		
		return m_instance_ptr;
	


private:
	Singleton() 
		std::cout << "constructor called!" << std::endl;
	

	static Ptr m_instance_ptr; //创建静态对象
	static std::mutex m_mutex;
;

// initialization static variables out of class
Singleton::Ptr Singleton::m_instance_ptr = nullptr;
std::mutex Singleton::m_mutex;

int main() 
	Singleton::Ptr instance = Singleton::get_instance();
	Singleton::Ptr instance2 = Singleton::get_instance();
	return 0;


3. 最推荐的懒汉式单例(magic static )——局部静态变量

#include <iostream>

class Singleton

public:
    ~Singleton()
        std::cout<<"destructor called!"<<std::endl;
    

    Singleton(const Singleton&)=delete;
    Singleton& operator=(const Singleton&)=delete;

    static Singleton& get_instance()
        static Singleton instance;
        return instance;
    
private:
    Singleton()
        std::cout<<"constructor called!"<<std::endl;
    
;

int main(int argc, char *argv[])

    Singleton& instance_1 = Singleton::get_instance();
    Singleton& instance_2 = Singleton::get_instance();
    return 0;


 8.  C++ STL是什么

 STL:标准模板库,一些容器、算法和其他一些组件的集合,容器包括vector、list、set、map等

有什么作用呢?使用 STL 可以更加方便灵活地处理数据

9. 常见的数据结构

 数组、队列、堆、栈、树、图、链表等

 10. C++内存分配的方式

 有三种:静态存储区分配、栈上分配内存和堆上分配内存。、

静态存储区分配内存:在程序编译时就分配好了,程序的整个运行期间都存在,例如全局变量,static变量。

栈上分配内存:系统自动分配,例如函数内部的局部变量,随着函数结束而删除。

堆上分配内存:动态分配内存,例如new、malloc。

11.  malloc/free和new/delete的区别

 共同点:都是从堆上申请空间,并且需要用户手动释放。

不同点:

1. malloc和free是函数,new和delete是操作符

2. malloc申请的空间不会初始化,new可以初始化。

3. malloc申请空间要手动计算空间大小,new只需在其后输入空间类型即可。

4. malloc的返回值是void*,new返回空间类型。

5. malloc申请空间失败,返回NULL,new申请失败,抛出异常。

12.  C++ vector 容器

 什么是vector?vector是一个封装了动态大小数组的顺序容器

特性:

1. 容器内元素按严格的线性顺序排序,查找的时间复杂度为O(1)。

2. 添加元素时会进行动态分配内存,使其快速增删。

常用函数:push_back(),pop_back(),empty() ,sort()等。

13. HTTPS是什么?

想了解HTTPS是什么?就要先了解HTTP? 就要了解TLS/SSL 工作原理及握手过程。

传输层安全性协议 TLS(Transport Layer Security),及其前身安全套接层 SSL(Secure Sockets Layer)是一种安全协议,目的是为互联网通信提供安全及数据完整性保障。

HTTP超文本传输协议(HTTP,HyperText Transfer Protocol)是互联网上应用最为广泛的一种网络协议

HTTPS:是以安全为目标的 HTTP 通道,是 HTTP 的安全版。HTTPS 的安全基础是 SSL。SSL 协议位于 TCP/IP 协议与各种应用层协议之间,为数据通讯提供安全支持。

14.  HTTP的请求有哪几种?各有什么用?

1.GET:请求指定的页面信息,并返回实体主体。

2. HEAD:类似于get请求,只不过返回的响应中没有具体的内容,用于获取报头。

3. POST:向指定资源提交数据进行处理请求。

4. PUT:从客户端向服务器传送的数据取代指定的文档内容。

5. DELETE:请求服务器删除指定的页面。

6. CONNECT:将连接改为管道方式的代理服务器。

7. OPTIONS:允许客户端查看服务器性能

8. TRACE:回显服务器收到的请求,主要用于测试。

算法题

1. 两个数对之间的最大乘积差

 贪心算法。


代码详情:

class Solution 
public:
    int maxProductDifference(vector<int>& nums) 
        sort(nums.begin(), nums.end()); //排序数组

        return ((nums[nums.size()-1] * nums[nums.size()-2]) - (nums[0] * nums[1]));
    
;

 通过情况:

 2. 数组拆分 I

 贪心算法。


代码详情:

class Solution 
public:
    int arrayPairSum(vector<int>& nums) 
        sort(nums.begin(), nums.end()); //数组排序
        int n = nums.size();
        if (n == 1) return nums[0]; //边界判断

        int res = 0; //存储最终答案
        for (int i = n - 2; i >= 0; i -= 2) //贪心算法,每次选最后两个的前一个为最小
            res += nums[i];
        

        return res;
    
;

明天晚上就阿里笔试啦!!!加油~

每日刷题3.155道算法+15道面试 - 阿V

今天4399面试啦!!!加油。

面试题(计算机网络)

1. TCP三报文握手 / 能否只两次握手

能否只两次握手呢?答案是不能的:

1.如果客户端有一条失效了很久的请求连接报文段,因为网络滞留导致连接结束了才到达服务端,如果只两次握手,那么这时服务端就会直接建立连接,而服务端发送的确认报文段也无客户端响应,导致服务端浪费资源,一直等待客户端响应。

2.如果直接两次握手,只能说明客户端与服务端建立了正常通信,却不能说明服务端与客户端建立正常通信。

2. TCP四报文挥手

 close-wait这段时间是等待服务器将剩下的数据处理完。

3. TCP如何保证可靠性

1. 防止数据丢包的确认应答机制,以及丢包后的超时重传。

2. 防止数据乱序的序列号。

3. 滑动窗口动态控制数据的传输速度,也就是流量控制。

4. 防止网络瘫痪的拥塞控制。

4.  HTTP和HTTPS的区别,以及HTTPS的优缺点

 区别:

1. HTTP协议以明文的方式在网络中传输数据,HTTPS是在HTTP的基础上将数据进行TLS/SSL加密。

2. HTTPS在TCP三次握手的基础上加个SSL握手。

3. HTTPS协议需要在服务器申请证书,客户端安装对应的根证书。‘

4. HTTP协议端口号为80,HTTPS端口号为443。

HTTPS优点:

1. 安全性高

2. 确保数据发送对象正确。

缺点:

1. 建立连接的握手延时高,由于多一次安全握手

2. 部署成本高,占用CPU资源多。

5. IP地址的作用,以及MAC地址的作用

 MAC地址是硬件地址,定义网络设备位置,由数据链路层负责。IP地址由IP协议提供的统一的地址格式,为互联网的每一个网络和主机分配一个逻辑地址,来抵消物理地址的差异。

6. 用户从输入URL到显示页面整个过程 

 DNS解析URL,接着传输层的TCP建立连接,发送HTTP请求,服务器处理并返回HTTP报文,浏览器解析并渲染页面。

7. TCP拥塞控制?以及达到什么情况的时候开始减慢增长速度 

 什么是拥塞控制?拥塞控制是为了防止过多的数据注入网络,从而使网络中的路由器或者链路过载,是全局网络流量整体性的控制,连接的双方都有一个拥塞窗口(cwnd)。

1. 慢开始:最开始发送方的拥塞窗口为一,由小到大递增。每经过一个传输轮次,拥塞窗口cwnd加倍,当cwnd超过慢开始门限,使用拥塞避免算法。

2. 拥塞避免算法:当cwnd超过慢开始门限,每经过一个往返时间RTT,cwnd+1。一旦发现网络拥塞,就将慢开始门限设置为当前值的一半,并重新设置cwnd为1,重新慢开始。

3. 快重传:接收方每收到一个失序的报文段就立即发出重复确认,发送方只要收到3个重复确认就立即重传。

4. 快恢复:当发送方连续收到三个重复确认,就将慢开始门限减半,将当前窗口设置为慢开始门限,并采用拥塞避免算法。

8. TCP/IP数据链路层的交互过程

 网络层等到数据链路层用MAC地址作为通信目标,数据包到达网络准备往数据链路层发送时,首先会去自己的arp缓存表(ip-mac对应关系)查找目标ip的mac地址,查到就将目标ip的mac地址封装到链路层数据包的包头。如果没找到,则广播寻找目标mac地址。

9.  TCP四次挥手的时候,先发起方为什么会有一个TIME_WAIT状态,它的作用是什么?

 为了能够确保发起方的最后一次报文能到达,如果中途丢包,可以接收到对方的重传报文段进行超时重传。

10. GET和POST的区别 

 GET请求:获取指定页面信息

POST请求:向指定资源提交数据进行修改

区别:

1. get参数通过url传递,post在request body中。

2. get请求在URL中传递参数有长度限制,post没有。

3. get比post更不安全,因为参数都暴露在url中。

4. get请求只能进行url编码,而post支持多种编码方式。

5. get请求会被浏览器主动cache,post不会。

6. get请求会完整保留在浏览历史记录里,而post中的参数不会。

7. get产生一个TCP数据包,而post产生两个数据包。

11. 阻塞,非阻塞,同步,异步

 阻塞:调用者在事件没有发生的时候,一直等待事件发生,不能处理其他任务。

非阻塞:调用者在事件没有发生时,可以处理事务。

同步:调用者循环查看事件发生情况。

异步:调用者无需查看事件发生情况,而是等待注册在时间上的回调函数通知。

12.  简单说一下http协议

 HTTP协议是基于TCP/IP通信协议来传递数据,属于应用层的面向对象的协议。HTTP协议工作于客户端-服务端架构之上。

优点:

1. 简单快速,发送请求只需传送请求方法和路径。

2. 灵活:允许传输任何类型的数据对象。

3. 无连接:每次连接只处理一个请求。

4. 无状态:处理请求无记忆功能。

面试题(操作系统)

13. 进程间的通信的几种方式

1. 管道(pipe)和命名管道(named pipe):管道可用于具有亲缘关系的父子进程间的通信,有名管道除了具有管道所具有的功能外,还允许无亲缘关系进程间的通信。

2. 信号(signal):信号是一种比较复杂的通信方式,用于通知接收进程事件发生。

3. 消息队列:消息队列是消息的链接表,克服上两种通信方式信号量有限的缺点,具有写权限的进程可以向消息队列添加消息,具有读权限的进程可以从消息队列读取信息。

4. 共享内存:最有用的进程间通信方式。可以使多个进程访问同一块内存空间,不同进程可以及时看到对方进程中对共享数据的更新。

5. 信号量:主要作为进程之间及同一种进程的不同线程之间的同步和互斥手段。

6. 套接字:用于网络不同机器之间的进程通信。

14. 线程同步的方式

1. 互斥量:采用互斥对象机制,只有拥有互斥对象的线程才有访问公共资源的权限。

2. 信号量:允许同一时刻多个线程访问同一资源,需要控制同一时刻访问此资源的最大线程数量。

3. 事件(信号):通过通知操作的方式来保持多线程同步,方便实现多线程优先级的比较操作。

今天的4399面试感觉还不错,有一些基础知识不扎实没答出来,收拾一下心情继续努力,星期四有网易笔试,星期五有阿里笔试,之前的游戏测试觉得真不适合就拒绝了,没想到他帮我转到了 游戏开发,太神奇了,加油加油!!!

以上是关于每日刷题3.125道算法+15道面试 - 阿V的主要内容,如果未能解决你的问题,请参考以下文章

每日刷题3.135道算法+15道面试 - 阿V

python每日经典算法题5(基础题)+1(中难题)

算法如何刷题

Java实习生每日10道面试题打卡!

Java实习生每日10道面试题打卡!

数据结构与算法面试题80道(14)