每日刷题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的主要内容,如果未能解决你的问题,请参考以下文章