ARTS-WEEK3

"ARTS打卡记录"

Posted by Simon on June 14, 2020

“Better code, better life. ”

ARTS打卡第三周

Algorithm

[题目]转变数组后最接近目标值的数组和

[题解]

//
// Created by Simon on 2020/3/28.
//

#include <iostream>

#include <map>

#include <vector>

#include <stack>

#include <algorithm>

using namespace std;


class Solution {
public:

    int findBestValue(vector<int> &arr, int target) {
        int size = arr.size();
        sort(arr.begin(), arr.end());
        int def = target / size;
        if ((def + 1) * size - target < target - def * size) {
            def += 1;
        }
        int sum = 0, diff = 0, i = 0;
        for (; i < size; ++i) {
            if (i == 0) {
                if (arr[i] * size > target)
                    return def;
                else {
                    diff = target - arr[i] * size;
                    sum = arr[i];
                }
                continue;
            }
            int cur_diff = target - sum - arr[i] * (size - i);
            if (cur_diff < 0) {
                def = (target - sum) / (size - i);
                if ((def + 1) * (size - i) - (target - sum)  < (target - sum) - def * (size - i)) {
                    return def + 1;
                }
                return def;
            }
            if (cur_diff > diff) {
                return arr[i - 1];
            }
            sum += arr[i];
            diff = cur_diff;
        }
        return arr[i - 1];
    }
};

int main() {
    vector<int> arr{1547, 83230, 57084, 93444, 70879};
    Solution s;
    cout << s.findBestValue(arr, 71237) << endl;
}

Review

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

[笔记] :

libevent事件循环

在完成事件的创建和注册以后,就可以开始事件循环了,libevent提供了以下接口


#define EVLOOP_ONCE             0x01
#define EVLOOP_NONBLOCK         0x02
#define EVLOOP_NO_EXIT_ON_EMPTY 0x04

int event_base_loop(struct event_base *base, int flags);

默认形况下,event_base_loop()会一直运行,直到所有注册过的事件都执行完毕。该函数会一直轮询所有注册过的事件是否被触发,一旦有事件被触发,该事件会被标记为active,然后执行注册的回调函数。

对于event_base_loop的几种模式的说明:

  • EVLOOP_ONCE模式下,事件循环会阻塞到有事件被触发,执行完触发事件的回调函数后即退出。
  • EVLOOP_NONBLOCK模式下,事件循环会忽略事件触发的过程,只检查那些已经就绪的,可以立即被回调的事件。
  • 通常情况下,事件循环会在事件队列为空时退出,而通过EVLOOP_NO_EXIT_ON_EMPTY标志位,你可以指定**当事件队列为空时libevent的行为。 **

下面是event_base_loop的伪代码:

while (any events are registered with the loop,
        or EVLOOP_NO_EXIT_ON_EMPTY was set) {

    if (EVLOOP_NONBLOCK was set, or any events are already active)
        If any registered events have triggered, mark them active.
    else
        Wait until at least one event has triggered, and mark it active.

    for (p = 0; p < n_priorities; ++p) {
       if (any event with priority of p is active) {
          Run all active events with priority of p.
          break; /* Do not run any events of a less important priority */
       }
    }

    if (EVLOOP_ONCE was set or EVLOOP_NONBLOCK was set)
       break;

主动退出事件循环

libevent提供了以下接口,可以让一个正在运行的事件循环停止:

int event_base_loopexit(struct event_base *base,
                        const struct timeval *tv);
int event_base_loopbreak(struct event_base *base);

其中event_base_loopexit可以通过传入一个timeval变量的方式实现定时停止,如果tvnullptr,则立即停止。

event_base_loopbreak底层其实就是调用了event_base_loopexit(base, nullptr);

【注意】以上两个函数都不会让事件循环终止执行中的回调函数,事件循环会在左右执行中的回调函数返回后才会推出!!

Tips

GTest 对私有方法做单元测试

最近两周,因为工作的原因,一直在学习GoogleTest框架,中间遇到了一个问题:如何使用GTest对类的私有方法做单元测试?在这里分享一下解决方案。

  • 使用Friend fixture

定义一个Test Fixuture类,并将其设置为待测试类的友元类。举例:

class Foo{
	friend class Foo_TEST    
private:
    int add(int a, int b);
}

class Foo_TEST : public ::testing::Test{
protected:
	int add(int a, int b){
        foo.add(a, b);
    }   
private:
    Foo foo;
}
  • 使用Friend Test

直接再待测试类中定义TEST方法;

class Foo{
private:
    FRIEND_TEST(Foo, barReturnsZero);
    int bar(...);
}

TEST(Foo, barReturnsZero){
    Foo foo;
    EXPECT_EQ(foo.bar(...), 0);
}

Share

本周依然是GTest的分享