ARTS挑战第十八周

Algorithm

【三指针】88. 合并两个有序数组

​ 解法一:直接拼接再排序,然后放入结果中。时间复杂度O((m+n)long(m+n)), 空间复杂度O(m+n);

​ 解法二:使用三指针,从头到尾合并到新的数组中。时间复杂度O(m+n), 空间复杂度O(m+n);

​ 解法三:使用逆向三指针,从尾到头合并到nums1数组中,不会覆盖不该覆盖的元素。

【动态规划】887. 鸡蛋掉落

dp[i][j]表示剩余i枚鸡蛋,共有j层楼的最坏情况下的最小操作次数

​ base case: dp[i][0] =0, dp[0][j]=n 取n表示不可能

​ 选择:则第i枚鸡蛋可以从1~j层楼任意层楼m扔下(暴力枚举)

​ 状态转移:dp[i][j] = min(dp[i][j],max(dp[i][j-m],dp[i-1][m-1])+1)

​ 没碎 碎了

dp[i][j] 默认取j,表示从一楼线性往上扫描(最慢的方式)

【数组去重】316. 去除重复字母

​ |–使用一个数组count统计所有字符出现的次数

​ |–使用另一个数组exist来标记当前集合已经出现过的字母

​ |–使用一个vector记录当前结果集中的元素

​ |–遍历所有字符

​ |–count[c]–;

​ |–如果当前字符出现过,continue

​ |–否则考虑将当前字符加入vector中:

​ |–while vector末尾元素大于当前元素并且末尾元素后面还会出现:

​ |–将末尾元素删除,并且将该元素标记为当前集合未出现过

​ |–将当前字符放入vector,并标记为出现过

​ |–将vector转换成string返回

【优先级队列+hash表|链表数组+hash表】895. 最大频率栈

类似LFU算法,但又有不同。具体看我的这篇文章,提供了两种解法,一种是优先级队列+hash表,一种是链表数组+hash表。

Review

SYN Flood 攻击及防御方法

TCP第二次握手阶段,服务器收到SYN会创建一个TCB放到半连接队列里面,系统的半连接队列大小是有限的,从而导致其它正常请求不能得到响应。
常用解决方案:

  1. SYN Cache:这种方式服务器收到SYN不会马上创建TCB,而是在一个Hash表中保存这个半连接信息,等到收到第三次握手信息才创建TCB。这种方法需要防止自己的sequence number被对方猜到,需要使用一些空间保存己方生成的Sequence Number信息
  2. SYN Cookie:Syn Cookie技术则完全不使用任何存储资源,这种方法比较巧妙,它使用一种特殊的算法生成Sequence Number,这种算法考虑到了对方的IP、端口、己方IP、端口的固定信息,以及对方无法知道而己方比较固定的一些信息,如MSS(Maximum Segment Size,最大报文段大小,指的是TCP报文的最大数据报长度,其中不包括TCP首部长度。)、时间等,在收到对方 的ACK报文后,重新计算一遍,看其是否与对方回应报文中的(Sequence Number-1)相同,从而决定是否分配TCB资源。

循环引用中的shared_ptr和weak_ptr

share_ptr demo版实现

#include <iostream>
#include <memory>
using namespace std;

template<typename T>
class SharedPtr {
    
    
public:
    int* counter;  // 引用计数,用指针表示,多个SharedPtr之间可以同步修改
    T* resource;  // 裸指针

    SharedPtr(T* resc = nullptr) {
    
      // 构造函数
        cout << __PRETTY_FUNCTION__ << endl;
        counter = new int(1);
        resource = resc;
    }

    SharedPtr(const SharedPtr& rhs) {
    
      // 拷贝构造函数
        cout << __PRETTY_FUNCTION__ << endl;
        resource = rhs.resource;
        counter = rhs.counter;
        ++*counter;
    }

    SharedPtr& operator=(const SharedPtr& rhs) {
    
      // 拷贝赋值函数
        cout << __PRETTY_FUNCTION__ << endl;
        --*counter;  // 原来指向的资源的引用计数减1
        if (*counter == 0) {
    
    
            delete counter;
            delete resource;
        }

        resource = rhs.resource;
        counter = rhs.counter;
        ++*counter;  // 新指向的资源的引用计数加1
    }

    ~SharedPtr() {
    
      // 析构函数
        cout << __PRETTY_FUNCTION__ << endl;
        --*counter;
        if (*counter == 0) {
    
    
            delete counter;
            delete resource;
        }
    }

    int use_count() {
    
    
        return *counter;
    }
};

Tips

  1. linux 开启syncookies方法: Linux中的/proc/sys/net/ipv4/tcp_syncookies是内核中的SYN Cookies开关,0表示关闭SYN Cookies1表示在新连接压力比较大时启用SYN Cookies,2表示始终使用SYN Cookies
  2. const是如何保证不被修改的?:局部变量都是编译器检查发现的,全局变量通过让系统的内存只读权限的保护能力进行实现
  3. 【c++】函数输出参数使用指针而不是引用的好处:可读性更强
  4. 【c++】传入参数有什么是指针能办到而引用不行的:传入空指针,例如树的前序遍历
  5. 【c++】share_ptr如何实现的?引用计数
  6. 【c++】share_ptr循环引用如何解决?weak_ptr
  7. 【c++】智能指针的是线程安全的吗?智能指针的引用计数是原子操作,是线程安全的。但是在进行赋值操作时,资源指针赋值与引用计数这两个并不是在一个原子操作里面,因此从这个角度上来说是线程不安全的。
  8. 【python】 psutil模块可以用来监控系统各种指标,包括io、带宽、cpu、内存等
  9. 【python】dir方法可以查看一个对象包含的所有方法
  10. 【docker】清除所有的已经停止的容器:docker system prune
  11. 【网络】tcp字节流与udp数据包传输区别:字节流会粘包,多次传输可以一次接受。udp传输几个包就得调用几次recvfrom函数

Share

【动态规划】鸡蛋掉落

[TCP SYN cookie的作用、原理、缺陷](https://blog.csdn.net/Fei20140908/article/details/119808739)

895. 最大频率栈

猜你喜欢

转载自blog.csdn.net/Fei20140908/article/details/119840461