ARTS-WEEK4

"ARTS打卡记录"

Posted by Simon on June 20, 2020

“Better code, better life. ”

ARTS打卡第四周

Algorithm

[题目] :https://leetcode-cn.com/problems/permutation-in-string/

[题解]

这是一道典型的滑动窗口题目,直接双指针解决:

class Solution {
public:

    static bool isCover(const unordered_map<char, int> &s1, unordered_map<char, int> &s2) {
        for (const auto &p:s1) {
            if (s2[p.first] != p.second) {
                return false;
            }
        }
        return true;
    }

    bool checkInclusion(string s1, string s2) {
        unordered_map<char, int> m_1, m_2;
        for (const auto &c:s1) {
            m_1[c]++;
        }
        for (int left = 0, right = 0; right < s2.size();) {
            if (m_1.count(s2[right])) {
                m_2[s2[right]]++;
                if (right - left + 1 == s1.size()) {
                    if (isCover(m_1, m_2)) {
                        return true;
                    } else {
                        m_2[s2[left]]--;
                        ++left;
                    }
                }
                ++right;
            } else {
                m_2.clear();
                ++right;
                left = right;
            }
        }
        return false;
    }
};

Review

[文章链接] :http://www.wangafu.net/~nickm/libevent-book/Ref4_event.html

[笔记] :

Libevent最基本的组件就是事件。每一个事件都是一系列状态的集合,包括:

  • 准备读/写的文件描述符
  • 就绪的文件描述符(仅适用于边缘触发)
  • 超时时间
  • 信号
  • 被用户触发的事件

创建一个事件

Libevent提供了以下接口来创建事件

//超时时间到达后会触发
#define EV_TIMEOUT      0x01
//文件描述符可读时事件触发
#define EV_READ         0x02
//文件描述符可写时事件触发
#define EV_WRITE        0x04
//需要实现信号探测方法
#define EV_SIGNAL       0x08
//事件触发后,会被改为appending状态,而不会删除
#define EV_PERSIST      0x10
//边缘触发模式
#define EV_ET           0x20

typedef void (*event_callback_fn)(evutil_socket_t, short, void *);

struct event *event_new(struct event_base *base, evutil_socket_t fd,
    short what, event_callback_fn cb,
    void *arg);

void event_free(struct event *event);

event_new函数会创建一个新的event对象,第一个参数是新事件要注册的event_base,第二个参数是事件关注的文件描述符,第三个是文件描述符上关注的事件类型,后面两个是回调函数和对应的参数。

下面对于事件触发的几种类型做更细致的说明。

关于EV_PERSIST

默认情况下,一个事件触发后其状态会被修改为non-pending,再事件回调函数结束后,可以通过调用event_add来重新把它变成pending状态。如果设置了EV_PERSIST标志位,其默认行为会改变为:一个事件触发后,仍然是pending状态。可以再回调函数中调用event_del来删除该事件

关于EV_SIGNAL

Libevent支持POSIX风格的信号量。我们可以使用以下接口来创建一个关心信号量的事件:

#define evsignal_new(base, signum, cb, arg) \
    event_new(base, signum, EV_SIGNAL|EV_PERSIST, cb, arg)

举个例子:

struct event *hup_event;
struct event_base *base = event_base_new();

/* call sighup_function on a HUP signal */
hup_event = evsignal_new(base, SIGHUP, sighup_function, NULL);

Tips

可执行文件都有哪些段

  • .text段:编译后的机器代码
  • .rodata:只读数据,比如printf语句中的格式串和开关语句的跳转表
  • .data:已初始化的全局和静态C变量
  • .bss:未初始化的全局变量和静态C变量
  • .symtab:符号表,存放程序中定义和引用的函数和全局变量的信息。

Share

这周是Redis源码解析第一篇

Redis数据结构-字符串