n个数,对这个数组任意次以下操作:
如果 a i + a j a_i+a_j ai+aj为奇,那么就可交换这两个数
求出能通过若干次操作后得到的数组中
输入 7 3 5 1 输出 7 3 5 1
输入
53941 38641 31525 75864 29026 12199 83522 58200 64784 80987
输出
12199 29026 31525 38641 53941 58200 64784 75864 80987 83522
#include
#include
#include
#include
#include
const int N = 1e5 + 10;
int a[N];
using namespace std;
int main()
{
int n;
cin >> n;
int odd = 0,even = 0;
for(int i=0;i<n;i++)
{
cin>>a[i];
if(a[i]%2==0)
even++;
else
odd++;
}
if(even>0 && odd>0)
sort(a,a+n);
for(int i=0;i<n;i++)
{
printf("%d%c", a[i], i == n - 1 ? '\n' : ' ');
}
return 0;
}
给定表达式,1*2+3/5+7,操作符只有加减乘除,没括号,
数字是非负。
编写一个程序输出表达式的结果。
符号栈和数字栈
读新符号
最后把符号栈里剩余的符号依照出栈的顺序进行运算即可。
python的eval可直接解析表达式并得出结果:
exp=input()
print(eval(exp))
广州对外地车牌实行开四停四,
实现一个算法,根据以往若干天的行驶情况,判断它在哪几天违章。
开四停四是指你最长的连续开车间隔不能超过4天,
题目本身很简单,但理解这个规则还是需要逻辑清晰点的。
__func__和__LINE__的实现机制是怎么样的?
__func__是C++11里的一个预定义变量,__LINE__是一个宏,__LINE__在预处理阶段展开,而__func__在编译期做完词法分析后获得AST后可以很轻易的展开(应该是在语义分析阶段)
解释一下TCP的流量控制和拥塞控制有什么不同?具体机制是怎么样的?
这个非常基础了,流量控制是用来防止接收方缓存不够的情况的,由接收窗口rwnd控制,如果发送方检测到rwnd=0,那么就会发送一个空数据包并停止继续发送数据而拥塞控制是用来防止由于网络拥堵导致丢包的情况,由拥塞窗口cwnd控制,拥塞控制有三个模式:慢启动,拥塞避免和快速恢复。(剩下还回答了好多细节,这里就不贴了)
简述一下TCP的三次握手机制?
emmm这个太简单了,不讲
https的加密机制了解吗?
https的加密既使用了对称加密也使用了非对称加密。首先,服务器生成非对称加密算法所需的公钥和私钥,将公钥明文传给客户机,客户机在本机上生成对称加密所使用的通讯密钥,用公钥加密发送给服务器,由于公钥加密后的密文只能通过私钥解开,因此传输节点无法得知通讯密钥内容。这样后续交流双方只需要使用通讯密钥加密信息就可以实现安全通信了。
但是如果传输过程中存在一个中间人,他把服务器的公钥换成自己的公钥传递给客户机,这样客户机发送通讯密钥的时候中间人就能通过自己的密钥解开,得到通讯密钥,再用服务器的公钥加密后传回给服务器。此时,中间人就在客户机和服务器没有察觉的情况下成功窃听到了信息。为了防止这样的情况发生,我们需要验证公钥是否真的来自于服务器。
这时候我们想到可以找一个受信的第三方(也就是CA),把公钥,域名,第三方机构等信息放在一起做一次hash(做hash的目的是把这些信息变成定长的比特串,降低非对称加密所需的时间,因为如果内容很长的话加密时间也会很长),再用CA的私钥加密,得到一个对内容的签名,由于中间人无法得到CA的信任,因此即使中间人可以伪造证书,也无法伪造签名。
现在,服务器直接发送证书和证书签名,当客户机收到证书和签名时,他首先找到是哪个CA发行了证书,再用CA的公钥解密签名,与客户机自己对证书生成的hash对比,如果一致就说明这个公钥是可行的,可以确定是服务器传过来的公钥了!(证书)
https的握手机制?
客户机发出hello连接请求,附上自己支持的安全协议的版本,能够使用的加密套件的列表等相关信息。
服务器回应hello请求,根据本机上能使用的加密套件,发送此次握手使用的协议版本,哪种加密套件以及自己的证书。
客户机收到信息后,验证证书真伪,如果通过验证就在本地生成通讯密钥,通过公钥加密发送给服务器
服务器收到信息后,通过私钥解密获得通讯密钥
后续通讯均通过通讯密钥加密进行
了解epoll吗?
linux下有五种OS模型,分别是:阻塞型,非阻塞型,IO多路复用型,信号驱动型,异步IO型。大部分socket接口都是阻塞型的,但有一个巨大的缺点就是如果要读取的socket未就绪进程就会阻塞,这导致一个进程同时处理一个socket,如果同时有多个访问就要对每个访问单独开一个进程处理,这会占用大量的系统资源。而使用IO多路复用则是由一个进程同时监视多个socket,当这些socket中的一个准备就绪后进程对此进行处理,这样就节省了内存资源。IO多路复用比较适合于处理连接数较多,但活跃连接数较少的情况,比如提供web服务。在linux下常用的多路复用函数有select,poll和epoll。select和poll查询socket是否就绪使用的是轮询法,效率是,而epoll由内核直接支持,通过callback直接将对应的文件标识符加入就绪队列,从而达到的时间复杂度。epoll实际上是一组函数,包括epoll_create,epoll_ctl和epoll_wait。
在触发方式上,epoll有ET(边缘触发)和LT(水平触发)两种模式,在ET模式下,仅当socket刚刚就绪时会触发epoll,epoll告诉我们该socket就绪。如果没有及时处理,epoll不会再次告知我们。
C++
void func(int arr[]){
cout<<sizeof(arr)<<endl;//输出4
}
linux下有哪些进程间通信的方法?哪一种最快?
这个问题一面也问到了,这里不再重复。进程间通信最快的方法是共享内存法,因为并不需要拷贝,直接通过某些手段把同一段内存映射到两个进程的地址空间中。
linux中进程的内存布局是怎么样的?
又是内存布局……我依然不会,只能随便扯了一点和虚拟内存相关的东西。这里附上一个知乎答案里的图来解释:
假设在linux下,有一个程序首先读入一个文件,修改了其中的内容,再写入原文件中,请你谈谈在这个过程中OS做了哪些工作。
这个问题一下就问到很底层的知识了,只能很浅显的说了一些我会的,如果大家会这道题可以帮我补充一下。。
数据库
了解mySQL中的存储引擎吗?
这个以前上实验课的时候了解过,但是好久没看不记得了……mySQL的两个最主流的储存引擎是MyISAM 和 InnoDB,通常我们使用的是InnoDB。他们的差别:
InnoDB支持事务,MyISAM不支持。
InnoDB支持外键,MyISAM不支持。
InnoDB是聚集索引,MyISAM是非聚集索引。
InnoDB不保存表的具体行数,MyISAM保存了表的具体行数
InnoDB最小的锁粒度是行锁,MyISAM是表锁。
通常来说,InnoDB适合增删改多,且需要事务支持的情况,而myismp支持高效率查找,适合读比较多的情况。
事实上,mySQL的储存引擎还有MEMORY,ARCHIVE等,他们各有各自的优缺点。但主流的还是上面提到的两个储存引擎。
如何优化SQL的查询速度?
这个不知道怎么回答……我说了可以建立索引,分页,缓存部分内容到内存(比如redis就是类似的原理)三个方法,也不知道对不对。
这个问题可以转化成求一个点是否在一个多边形内部。我们首先可以进行一个简单测试,先取得这些像素点的最大和最小x,y坐标,构成一个恰好将闭合区域包裹在里面的四边形,看看这个点是否在该四边形里面,如果不在那么肯定不在多边形内部。接下来我们采用射线法:过给定点做一条与x轴平行的射线,这条射线会和多边形形成一系列交点,如果交点数量是奇数,那么就说明在多边形内部,否则就在外部。当然这样是没有考虑一些特殊情况的,更加详细的解答可以参考这个链接。
这个问题很简单,用tarjan跑一遍就出来了。不懂的同学可以学一下求LCA的tarjan算法。