标签:b+树 oid shmdt sort out cto -- 模式 redis
老题,方法有:
代码:
#include <map>
#include <vector>
#include <cmath>
#include <algorithm>
#include <stdio.h>
#include <iostream>
#include <string>
#include <unordered_map>
using namespace std;
// 1 先排序,后取中位数
template <typename T>
T solve_by_sort(vector<T> src)
{
sort(src.begin(), src.end());
size_t len = src.size();
if (len & 0x01)
{
return src[len / 2 + 1];
}
else
{
return (src[len / 2 - 1] + src[len / 2]) / 2;
}
}
// 利用堆排序,如果是偶数,那么需要维持两个堆
// 或是如果是偶数,维持一个大根堆,大小为 len/2+1 ,
// 取出一个后,再建堆一次.貌似这样比较快
template <typename T>
T solve_by_heap(vector<T> src)
{
size_t len = src.size();
if (len & 0x01)
{
vector<T> tmp;
for (size_t i = 0; i < len; i++)
{
if (tmp.size() != len / 2 + 1)
{
tmp.push_back(src[i]);
}
else
{
cout << tmp[0] << endl;
// 大根堆留小的那个 堆顶是最大的
tmp[0] = min(tmp[0], src[i]);
}
// 大根堆
make_heap(tmp.begin(), tmp.end(), [](T v1, T v2) {
return v2 > v1;
});
}
return tmp[0];
}
else
{
vector<T> min_heap;
vector<T> max_heap;
for (size_t i = 0; i < len; i++)
{
if (min_heap.size() != len / 2)
{
min_heap.push_back(src[i]);
}
else
{
if (min_heap[0] < src[i])
{
max_heap.push_back(min_heap[0]);
min_heap[0] = src[i];
}
else
{
max_heap.push_back(src[i]);
}
}
make_heap(min_heap.begin(), min_heap.end(), [](T v1, T v2) {
return v1 > v2;
});
make_heap(max_heap.begin(), max_heap.end(), [](T v1, T v2) {
return v2 > v1;
});
}
cout << endl;
return (min_heap[0] + max_heap[0]) / 2;
}
}
// 3 快排的变体
// 主要是在拿到 partion 的返回值以后,只排序靠近k的位置
// 当partion 返回的下标是k的时候,那么就是第k个了
template <typename T>
T solve_by_qsort_aux_partion(T start, T end)
{
if (start > end)
{
return start;
}
T l = start;
T r = start;
while (r != end - 1)
{
if (*r < *(end - 1))
{
iter_swap(r, l);
l++;
r++;
}
else
{
r++;
}
}
iter_swap(end - 1, l);
return l;
}
template <typename T>
T qsort(T start, T end)
{
if (start != end)
{
T part = solve_by_qsort_aux_partion(start, end);
qsort(start, part);
qsort(part + 1, end);
}
}
template <typename T>
T solve_by_qsort_aux(T start, T end, T flag, int k)
{
if (start != end)
{
T part = solve_by_qsort_aux_partion(start, end);
// 主要是这一部分,向第k个判断
if (part - flag != k)
{
if (part - flag > k)
{
solve_by_qsort_aux(start, part, flag, k);
}
else
{
solve_by_qsort_aux(part + 1, end, flag, k);
}
}
else
{
return part;
}
}
}
template <typename T>
T solve_by_qsort(vector<T> src)
{
size_t len = src.size();
if (len & 0x01)
{
return *solve_by_qsort_aux(src.begin(), src.end(), src.begin(), len / 2 + 1);
}
else
{
T tmp1=(*solve_by_qsort_aux(src.begin(), src.end(), src.begin(), len / 2));
T tmp2=(*solve_by_qsort_aux(src.begin(), src.end(), src.begin(), len / 2-1));
return (tmp1+tmp2)/2;
}
}
int main()
{
vector<double> src = {5, 3, 2, 1, 4, 6};
cout << "solve_by_heap: " << solve_by_heap(src) << endl;
cout << "solve_by_sort: " << solve_by_sort(src) << endl;
qsort(src.begin(), src.end());
for (auto t : src)
{
cout << t << " ";
}
cout << endl;
cout << "solve_by_sort: " << solve_by_qsort(src) << endl;
}
因为没有改变double的值,因此,可以直接判断
建堆相关的函数:
make_heap
建堆,最后是二叉堆:接受两个迭代器,对迭代器之间的进行排序[)
区间,第三个参数是compare
函数
[](T v1,T v2){return v1>v2}
,v1>v2
是降序,v2>v1
是升序
sort_heap
堆排序,最后是排序结果:同上
is_heap
判断是否是一个二叉堆:同上
pop_heap
:进行排序,每次排一个,也就是说,将堆顶的元素,放入尾部,每次一个.
类priority_queue 使用了二叉堆.默认最大堆.
priority_queue<int,vector<int>,std::greater<int>> pq;
最小堆
priority_queue<int,vector<int>,std::less<int>> pq;
最大堆(默认)
快排编写时候,最主要的是判断,边界.
和上一个题是同一个题
快排最好的情况是,每次正好中分,复杂度为O(nlogn)。最差情况,复杂度为O(n^2),退化成冒泡排序
初始化建堆的时间复杂度为O(n),排序重建堆的时间复杂度为nlog(n)
宏内核和微内核,开源闭源
df命令参数功能:检查文件系统的磁盘空间占用情况。可以利用该命令来获取硬盘被占用了多少空间,目前还剩下多少空间等信息。 df命令是显示文件系统,磁盘级别上.无论在哪个目录下运行,基本都是下面的信息(window子系统)
du命令是对文件和目录磁盘使用的空间的查看 ,是文件夹级别的.
一般加上--max-depth=数字
表示递归多少层,否则,du命令会在当前目录下每个子文件夹都展示出来
int shmget( key_t shmkey , int shmsiz , int flag );
void *shmat( int shmid , char *shmaddr , int shmflag );
int shmctl( int shmid , int cmd , struct shmid_ds *buf );
int shmdt( char *shmaddr );
shmget()
key_t shmkey 是这块共享内存的标识符。如果是父子关系的进程间通信的话,这个标识符用IPC_PRIVATE来代替。但是刚才我们的两个进程没有任何关系,所以就用ftok()算出来一个标识符使用了。 int shmsiz 是这块内存的大小. int flag 是这块内存的模式(mode)以及权限标识。 模式可取如下值: 新建:IPC_CREAT 使用已开辟的内存:IPC_ALLOC 如果标识符以存在,则返回错误值:IPC_EXCL 然后将“模式” 和“权限标识”进行“或”运算,做为第三个参数。 如: IPC_CREAT | IPC_EXCL | 0666 这个函数成功时返回共享内存的ID,失败时返回-1。
shmat()
是用来允许本进程访问一块共享内存的函数。 int shmid是那块共享内存的ID。 char *shmaddr是共享内存的起始地址 int shmflag是本进程对该内存的操作模式。如果是SHM_RDONLY的话,就是只读模式。其它的是读写模式 成功时,这个函数返回共享内存的起始地址。失败时返回-1。
int shmctl( int shmid , int cmd , struct?shmid_ds *buf );
int shmid是共享内存的ID。 int cmd是控制命令,可取值如下: IPC_STAT 得到共享内存的状态 IPC_SET 改变共享内存的状态 IPC_RMID 删除共享内存 struct shmid_ds *buf是一个结构体指针。IPC_STAT的时候,取得的状态放在这个结构体中。如果要改变共享内存的状态,用这个结构体指定。 返回值:?成功:0 失败:-1
索引的实现,innodb的索引,b+树索引是怎么实现的,为什么用b+树做索引节点,一个节点存了多少数据,怎么规定大小,与磁盘页对应
如果Redis有1亿个key,使用keys命令是否会影响线上服务,我说会,因为是单线程模型,可以部署多个节点
持久化方式
Redis的list是怎么实现
sortedset怎么实现
不知道,AVL看的都累
kafka,zookeep
为什么迅雷下载是基于UDP的,我说FTP是基于TCP,而迅雷是p2p不需要TCP那么可靠的传输保证。
产生死锁的四个必要条件:
四个条件是死锁的必要条件,只要系统发生死锁,这些条件必然成立,而只要上述条件之一不满足,就不会发生死锁。
最近未使用
大致的思路是这样的:
两个数据结构的节点都指向LruNode.
template <class K, class T>
struct LruNode
{
LruNode(K k, T t)
: key(k), data(t),
prev(nullptr), next(nullptr)
{
}
K key;
T data;
LruNode *prev, *next;
};
template <typename K,typename T>
class Lru
{
public:
Lru(size_t max_size = 10)
: m_max(max_size),
root(nullptr),
end(nullptr)
{
}
T get(K k)
{
if (m_hash.find(k) != m_hash.end())
{
LruNode<K,T>* target = m_hash[k];
if (target != end)
{
target->next->prev = target->prev;
}
else if (target != root)
{
end = target->prev;
target->prev->next = nullptr;
}
if (target != root)
{
target->prev->next = target->next;
target->next = root;
target->prev = nullptr;
root = target;
}
return target->data;
}
else
{
return T();
}
}
void push(K k, T t)
{
LruNode<K,T> *target = new LruNode<K,T>(k, t);
if (root != nullptr)
{
target->next = root;
root->prev=target;
root = target;
}
else
{
root = target;
end = target;
}
m_hash[k] = target;
if (m_hash.size() > m_max)
{
LruNode<K,T> *trash = end;
end = end->prev;
end->next=nullptr;
delete trash;
}
}
size_t size()
{
return m_hash.size();
}
private:
size_t m_max;
LruNode<K,T> *root;
LruNode<K,T> *end;
unordered_map<K, LruNode<K,T> *> m_hash;
};
标签:b+树 oid shmdt sort out cto -- 模式 redis
原文地址:https://www.cnblogs.com/perfy576/p/9486350.html