解题思路 : 先用map去统计次数, 然后用multimap根据次数排序, 返回前K个高频的即可
题目链接 力扣347
class Solution {
public:
vector<int> topKFrequent(vector<int>& nums, int k)
{
map<int, int> m1; //统计次数
for(auto e : nums)
m1[e]++;
multimap<int, int, greater<int>> m2; //根据次数降序排序,次数可能相同
for(auto e : m1)
{
m2.insert({e.second, e.first});
}
vector<int> v;
for(auto e : m2)
{
if(k == 0)
break;
k--;
v.push_back(e.second);
}
return v;
}
};
ll , ls , mkdir, mv, netstat, grep, cp, cd, rm, chmod, ln, ,
netstat -nltp | grep a //找到对应的pid
ll /proc/pid/exe
netstat -nltp | grep IP + 端口号 | head -5
1,对于经常被查询或用于排序或者连表查询的字段, 应该建立索引。
2, 多建立联合索引而不是单列索引,多个单列搜索比一个联合索引更浪费空间。
3, 尽量利用索引, 尽量避免 前置% 和 后置%的一起使用。
4, 尽量避免使用 select * from 表名, 应该需要哪些字段就查询哪些字段。
1, websock是一个基于tcp协议的长连接协议,它是全双工通信。
首先客户端发送http请求, 经过和服务端的3次握手后,建立链接。
然后服务端收到客户端的握手请求后,同样也采用HTTP协议发送回数据。 然后他们就可以直接通信
1,协程是一种比线程更加轻量级的存在。
2,一个线程就是执行一个子程序,子程序的调用是一个入口,一次返回,调用顺序明确。
而协程在子程序内部可以中断,然后去执行别的子程序,然后合适的时候返回继续执行。
3, 协程极高的执行效率,因为子程序的切换并不是线程切换,没有线程切换的开销,它完全由用户程
序控制。
4, 协程是不需要加锁, 因为只有一个线程,所以控制共享资源的时候只用判断状态就可以。
有一个数字n,现在想把这个数字拆成两个非负整数a和b,使得a + b=n,对于每一种方案,我们定义
一个价值val=s(a) + s(b);
其中s(x)代表x的数位和,例如数字×= 1234,那么s(x)= 1+2+3+4 = 10。
现在想让你求可以选择的方案中val值最大的为多少?
例如输入 35 输出 17
//这个题的核心思路 : 把35拆分成两个数a, b , 使得 a + b = 35
//然后取出 a, b中每一个数字即可。 这里借用字符串要方便一些。
#include
#include
#include
using namespace std;
int main()
{
int T = 0;
cin >> T;
while (T--)
{
int n = 0;
cin >> n;
int value = 0;
for (int i = 0; i <= n; i++)
{
for (int j = 0; j <= n; j++)
{
if (i + j == n)
{
string s1 = to_string(i);
string s2 = to_string(j);
int num = 0;
for (int i = 0; i < s1.size(); i++)
{
num += s1[i] - '0';
}
for (int i = 0; i < s2.size(); i++)
{
num += s2[i] - '0';
}
value = max(value, num);
}
}
}
cout << value << endl;
}
return 0;
}
不能, 因为虚函数表指针是在构造函数初始化列表阶段初始化的。
底层实现 : 数组,链表, 红黑树
什么是迭代器失效 :
1 迭代器指向了释放的空间 (野指针)
2,迭代器的意义变了 (例如在下标0位置插入1, 迭代器之前指向的是元素变成了1)
vector的插入删除操作 : 会导致当前和以后位置的迭代器是失效 (因为是需要罗董元素的)
list的插入删除操作 : 会导致当前位置的迭代器失效 (因为是链表)
map的插入删除操作 : 当前位置的迭代器失效
可以通过加互斥锁,信号量,条件变量让多线程进行同步访问临界资源, 实质上是让并行运行的线程变成串行。
1, 减少锁持有时间,它有助于降低锁冲突的可能,提高系统的并发能力。
2, 减少锁的粒度, 实质上就是减少加锁的范围,这样也有助于降低锁冲突。
3, 用读写分离锁来替代独占锁, 在读多写少的情况下。
协程是比线程更加轻量化的存在。
一个线程就是一段子程序的执行,一个入口, 一个返回值。
而协程可以在执行一个子程序的时候,切换去执行另一个子程序,在合适的时候再切换回来。
协程间的切换不同于线程间的切换, 不需要将从CPU剥离下来,也就是没有线程切换的开销,而且它完
全由用户程序控制。
另外的话, 协程不需要加锁,因为只有一个线程,在访问共享资源的时候就比较简单
1, 每次调用select的时候,都需要手动设置fd_set集合,意味着每次调用都需要从用户向内核拷贝大量数
据,而 epoll只需要在合适的时候通过epoll_ctr添加fd即可。
2,由于fd_set是一个位图结构,select关心的fd有限制, epoll无上限。
3,select中的内核检测fd就绪的时候是通过轮询遍历的方式,O(N),而epoll的底层是通过就绪队列
直接获取的O(1)。
4,select上的每一个fd没有分开监视的事件和发生的事件, 而epoll做到了参数分离
对于poll呢? 在select的基础上进行了优化 : 1 fd上的输入输出参数分离 2 文件描述符无上限
ll, ls, mkdir, cp, mv, cd 。
top : 查看cpu
free: 查看内存使用
df: 产看磁盘分区可以使用的磁盘空间
du : 产看每个文件和目录的使用空间
出现在主动断开tcp链接的第三次挥手中。
当客户端的某一些用户不活跃的时候, 服务端就会主动断开连接 :
服务端就有可能处于这个状态,会导致由于没有完全断开链接,而每一个链接就会占用一个通信5元组
(源IP, 目的IP, 目的端口, 源端口,协议)。 而服务端的ip和端口又是固定的,如果这个时候有客户端来链接的ip和端口与time_wait占用的链接重复, 就会出现问题。
如何解决 :通过函数 setsockopt() , 允许创建多个fd, 他们的ip不同, 但是共享一个相同的端口号
我记得第一个技术难点就是在下载好的一个html文档里面,它的内容变成了一个string,既有大写也有
小写。 如何查找出与关键字相邻的前50个字符和后50个字符拼接,关键字又是全部小写的,我们是不需
要区分大小写,而string的find函数是区分大小写的。如何编写精简和高效的代码。 所以这里借助了标
准命名空间std::searcher函数加以利用lambda表达式来解决。
第二个难点就是之前运行起来很慢很卡,原因是在建立正排和倒排索引的时候,我每次都是拷贝一份结构体
DocInfo,然后那一份存在的结构体出作用域销毁,后来引入了std::move()函数,它可以将结构体的资
源窃取过来不需要重新拷贝。