0%

命名规则

需要从可读性、方便识别、减少码字时间和能准确表达含义等方面来考虑

项目命名

视情况挑选以下三种方式的其中一种:

  • Link-Cooperation

  • StarUI

  • starui

文件夹(模块)命名

使用小写英文,拆分子文件夹来分层级

Examples:

Text
1
2
3
4
fs/afs
fs/efs
fs/exfat
...

源文件和头文件命名

阅读全文 »

投资、风险与回报

ROI(Return On Investment):投资回报率,指通过投资而应返回的价值,具有时效性。可以理解为转化率,计算公式:年利润(或年均利润)/ 投资总额 * 100%

GTV(Gross Transaction Volume):交易成交总额,一般中介性质的服务平台用其作为评价指标,比如美团。计算公式:成交总额 + 退货订单总额(一般不会扣除) + 其它一些抵减项(即使用原价)。GTV的含金量比GMV高,但是要注意的是,对于美团这样的平台,GTV并不是其实际收入,因为商品是商家提供的,客户支付给商家而中介赚取的是抽成部分

GMV(Gross Merchandise Volume):商品销售总额(一段时间内),即流水,一般把取消的订单也算进去,所以导致流水是有水分的。一般是电商平台(比如京东商城.,其包括了未支付或取消的订单)用于衡量平台竞争力(市场占有率)的核心指标,计算公式:成交总额 + 取消订单总额 + 拒收订单总额 + 退货订单总额 + 未支付订单总额。GMV相比GTV更具实时性,可用来研究客户的购买意向

ARPU(Average Revenue Per User):每用户平均收益,指一个时期内(通常为月或年),平均每个用户贡献的业务收入。计算公式:总收入 / 总用户数,注意总用户数包括了未付费的用户

ARPPU(Average Revenue Per Paying User):每付费用户平均收益,类似ARPU,但ARPPU只统计时间内的所有付费用户。计算公式:总收入 / 总付费用户

流量指标

PV(Page View):页面访问量,每打开一个页面记录一次

PVPU(Page Views Per User):每个访问者的页面访问量

DV(Site Visit Depth):页面访问深度,访问者在一次完整的站点访问过程中所浏览的页面数,可用于衡量用户粘性

阅读全文 »

定义并注册Callback class

以下Callback是在非Python所创建的线程中回调Python中的方法,所以在执行任何Python相关的调用前,最好先调用PyGILState_Ensure,另外使用boost::python::call_method来调用Python对象中的方法。

非Python创建的线程

PyGILState_Ensure

call_method

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
/**
* Callback
* @brief 在非Python创建的线程中执行回调
*/
class Callback
{
public:
Callback()
: m_self(nullptr)
{
}

explicit Callback(PyObject* self)
: m_self(self)
{
}

Callback(const Callback& other) noexcept
: m_self(other.m_self)
{
incref();
}

Callback(Callback&& other) noexcept
{
m_self = other.m_self;
other.m_self = nullptr;
}

Callback& operator=(const Callback& other) noexcept
{
m_self = other.m_self;
incref();
return *this;
}

Callback& operator=(Callback&& other) noexcept
{
m_self = other.m_self;
other.m_self = nullptr;
return *this;
}

virtual ~Callback()
{
decref();
}

void incref()
{
if (!m_self) {
return;
}

PyGILState_STATE state = PyGILState_Ensure();
Py_INCREF(m_self);
PyGILState_Release(state);
}

void decref()
{
if (!m_self || !Py_REFCNT(m_self)) {
return;
}

PyGILState_STATE state = PyGILState_Ensure();
Py_DECREF(m_self);
PyGILState_Release(state);
}

void dispatch(const std::string message)
{
if (!m_self) {
return;
}

PyGILState_STATE state = PyGILState_Ensure();
try {
call_method<void>(m_self, "event", std::string(message), boost::python::object());
}
catch (const boost::python::error_already_set&) {
boost::python::handle_exception();
}
catch (const std::exception&) {
boost::python::handle_exception();
}
PyGILState_Release(state);
}

void dispatch(const std::string message, boost::python::dict& data)
{
if (!m_self) {
return;
}

PyGILState_STATE state = PyGILState_Ensure();
try {
call_method<void>(m_self, "event", std::string(message), data.copy());
}
catch (const boost::python::error_already_set&) {
boost::python::handle_exception();
}
catch (const std::exception&) {
boost::python::handle_exception();
}
PyGILState_Release(state);
}

protected:
PyObject* m_self;
};
1
2
3
4
BOOST_PYTHON_MODULE(FooModule)
{
class_<Callback, boost::noncopyable>("Callback", init<PyObject*>());
}

补充注册回调方法

下面这个例子会在注册回调函数时启动一个C/C++运行时线程,休眠一秒后执行回调。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
void register_callback(Callback& callback)
{
std::thread([](Callback callback) {
std::this_thread::sleep_for(std::chrono::milliseconds(1000));

callback.dispatch("message_one");

PyGILState_STATE state = PyGILState_Ensure();
{
boost::python::dict data;
data["key"] = "ten";
data["value"] = 10;
callback.dispatch("message_two", data);
}
PyGILState_Release(state);

std::this_thread::sleep_for(std::chrono::milliseconds(1000));
}, callback).detach();
}
1
2
3
4
5
6
BOOST_PYTHON_MODULE(FooModule)
{
class_<Callback, boost::noncopyable>("Callback", init<PyObject*>());

def("register_callback", register_callback);
}

Python测试代码

阅读全文 »