/* Include the best multiplexing layer supported by this system. * The following should be ordered by performances, descending. */ #ifdef HAVE_EVPORT #include "ae_evport.c" #else #ifdef HAVE_EPOLL #include "ae_epoll.c" #else #ifdef HAVE_KQUEUE #include "ae_kqueue.c" #else #include "ae_select.c" #endif #endif #endif
Redis根据所处系统的不同,包含不同的IO多路复用实现代码。每种IO多路复用都实现了以下的接口:
1 2 3 4 5 6 7 8
struct aeApiState; static int aeApiCreate(aeEventLoop *eventLoop); static int aeApiResize(aeEventLoop *eventLoop, int setsize); static void aeApiFree(aeEventLoop *eventLoop); static int aeApiAddEvent(aeEventLoop *eventLoop, int fd, int mask); static void aeApiDelEvent(aeEventLoop *eventLoop, int fd, int mask); static int aeApiPoll(aeEventLoop *eventLoop, struct timeval *tvp); static char *aeApiName(void);
typedef void aeFileProc(struct aeEventLoop *eventLoop, int fd, void *clientData, int mask);
/* File event structure */ typedef struct aeFileEvent { int mask; /* one of AE_(READABLE|WRITABLE) */ aeFileProc *rfileProc; aeFileProc *wfileProc; void *clientData; } aeFileEvent;
int aeCreateFileEvent(aeEventLoop *eventLoop, int fd, int mask, aeFileProc *proc, void *clientData); void aeDeleteFileEvent(aeEventLoop *eventLoop, int fd, int mask);
定时器事件
与定时器事件相关的定义和接口有:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
typedef int aeTimeProc(struct aeEventLoop *eventLoop, long long id, void *clientData); typedef void aeEventFinalizerProc(struct aeEventLoop *eventLoop, void *clientData);
/* Time event structure */ typedef struct aeTimeEvent { long long id; /* time event identifier. */ long when_sec; /* seconds */ long when_ms; /* milliseconds */ aeTimeProc *timeProc; aeEventFinalizerProc *finalizerProc; void *clientData; struct aeTimeEvent *next; } aeTimeEvent;
long long aeCreateTimeEvent(aeEventLoop *eventLoop, long long milliseconds, aeTimeProc *proc, void *clientData, aeEventFinalizerProc *finalizerProc); int aeDeleteTimeEvent(aeEventLoop *eventLoop, long long id);
/* Search the first timer to fire. * This operation is useful to know how many time the select can be * put in sleep without to delay any event. * If there are no timers NULL is returned. * * Note that's O(N) since time events are unsorted. * Possible optimizations (not needed by Redis so far, but...): * 1) Insert the event in order, so that the nearest is just the head. * Much better but still insertion or deletion of timers is O(N). * 2) Use a skiplist to have this operation as O(1) and insertion as O(log(N)). */
#file: cython_person_info.pyx from libc.stdlib cimport malloc, free cdef extern from "person_info.h": struct person_info_t: int age char *gender ctypedef person_info_t person_info
$ make $ python test_person_info.py Traceback (most recent call last): File "test_person_info.py", line 7, in <module> info_wrap.gender = 'mmmale' File "cython_person_info.pyx", line 39, in cython_person_info.person_info_wrap.gender.__set__ self.ptr.gender = value File "stringsource", line 93, in carray.from_py.__Pyx_carray_from_py_char IndexError: not enough values found during array assignment, expected 16, got 6
cython转换和make时候是没有报错的,运行的时候提示“IndexError: not enough values found during array assignment, expected 16, got 6”,其实就是6字节长的“mmmale”赋值给了person_info结构体的“char gender[16]”成员。我们用strcpy来实现字符串之间的拷贝就ok了。
Anki 中的“有效”卡片最终都是要内化到大脑记忆的,那么卡片也就不需要分类了。用易于记忆的方式组织好卡片的内容,记忆到大脑中后,大脑这台高端分类机器会自动分类的。 过度分类最大的弊端是破坏了“间隔重复算法”的有效性。 因为不同类别的卡片记忆难度是不同的,人为分类之后,你会常常在不经意间选择记忆轻松简单的牌组,而不是靠“间隔重复算法”自动为你选择当前最需要复习的卡片。 所以,要记忆的“有效”卡片请全都放到“00-全部”牌组。如果控制不住自己要进行分类,那么问自己“分类通常是为了区分重要程度,既然有不太重要的卡片,直接归档/删除即可,何必要分类?”
“01-迭代”牌组
Anki 卡片内容组织方式是使用 Anki 的难点,卡片内容无法一步到位,通常需要多次的迭代修改。如果多次复习某张卡片时都难以回想起来,那么主要有两种可能的原因:
没有理解卡片对应的知识,靠死记硬背;
卡片的内容组织方式不当,大脑难以记忆。
解决第 1 点问题的方式因人而异,毕竟 Anki 只是记忆工具。如何系统的学习和理解新知识超出了 Anki 的范畴,这方面大家可以求助于讲解学习方法的相关书籍。
第 2 点问题。目前我还没找到“间隔重复”学习理论的专著,只有知乎上的 Anki 爱好者们和 SuperMemo 的博客有一些零星的文章。卡片内容组织方面,推荐阅读 SuperMemo 的一篇博文《有效学习:组织知识的20条原则》[英文][中文]。文章表达的核心观点就是卡片不能把一大堆内容堆砌在卡片中,期望通过间隔重复的方式来记忆,这样是行不通的。卡片的内容要遵循“最小信息原则”,一张卡片只记忆一个极其简单的知识点。
But Duolingo only has a little speak pratice, so i always try to find an better english speaking app.
At last year, ChatGPT became more and more popular. I thought may be some english learning applications could used the chatgpt’s AI feature to make a AI tutor. I searched by google, then i found the application “Speak”.It’s amazing app! I can speak to AI tutor, just like a real person.
I think it may be helping me to speak english fluently in six months.
Purchase 30 products, comment “Tailand mobile phone card, AIS green card, message card(泰国电话卡AIS绿卡短信卡)” at order form, the shopkeeper will deliver the card to you by expressage.
When you receive the card, plugin it into your 4G mobile phone, then visit the WeChat public account “Franwell弗兰威尔” to charge the card balance. At least 10 THB each charge to delay validity a month.
Notice! Delay validity a month because of a charge operate, the AIS not deduct each month. You can charge 12 times to delay a year.
About the card number:
Area code: +66
Country Name:Tailand
If number is 0998877666 (total 10 digit)
When you register any service account, select the country code +66, input the phone number 998877666 (ignore the first digit 0)
Register an overseas email account
Visit Proton(https://proton.me/), register an email account. Becase of Proton forbit the AIS phone number to verify account, you have to use your other email to verify it.
Register a chatgpt account
Some tips to increase the odds of success:
Open web browser’s privacy model, avoid to be recognized that you are in chinese mainland.
Proxy over the GFW to northern european countries, avoid to be restrict registion by Southeast Asia,HongKong,Macow’s IP address.
Don’t use chinese email, recommend to use Proton email.