1.EasyLogger源码学习笔记(4)
2.Vue Router 源码学习笔记4 - pushState和replaceState的记笔记的记源实现
3.EasyLogger源码学习笔记(3)
4.easylogging源码学习笔记(6)
5.2023小红书web端搜索采集笔记视频点赞关注评论去水印接口源码nodejs
6.EasyLogger源码学习笔记(5)
EasyLogger源码学习笔记(4)
setbuf函数用于开启或关闭缓冲机制,关闭时使用setbuf(stdout,网站 NULL);。
在编程中,源码unlikely(x) 和 likely(x) 函数通过宏定义 __builtin_expect(!!(x),线笔 1) 和 __builtin_expect(!!(x), 0) 实现,用以帮助优化编译器,记笔记的记源实现等价于if(a)但更高效的网站贵州离深圳源码条件判断。
semget()函数用于创建或获取信号量,源码其原型为 int semget(key_t key,线笔 int num_sems, int sem_flags)。它接受一个键值、记笔记的记源指定信号量数量及标志位,网站成功时返回信号标识符,源码失败时返回-1。线笔
semctl()函数用于设置或获取信号量的记笔记的记源值,而semop()函数则用于执行信号量的网站P操作或V操作。
信号量在共享内存管理中扮演关键角色,源码内核维护一个名为shmid_ds的数据结构,用于管理共享内存段。
利用fseek()函数,可以设置文件流的zxing 源码位置,通过参数offset和whence来确定查找位置的偏移量。
a+方式打开文本文件,允许读写,若文件不存在则创建,读取从头开始,写入只能追加。
sem_post函数(int sem_post(sem_t *sem);)将信号量值增加1,当线程阻塞在该信号量上时,调用此函数会使一个线程解除阻塞,选择机制由线程调度策略决定。
sem_wait函数(int sem_wait(sem_t * sem);)则将信号量值减去1,但需等待信号量值非零时才开始减法操作。
一种应用方法是利用信号量实现类似于信号传递的功能,某线程在特定条件下执行任务,其他线程通过调用sem_post()使信号量加一,该线程在调用sem_wait()后解除阻塞,继续执行。
Vue Router 源码学习笔记4 - pushState和replaceState的runnable 源码实现
在Vue Router中,HTML5History的push和replace操作主要通过util/push-state.js中的相应函数来执行,它们依赖window.history.pushState和window.history.replaceState API。对于HTML5History,如果浏览器支持,就按照标准流程进行,即利用pushState或replaceState改变浏览器的历史记录,而不会导致页面刷新。
对于HashHistory,浏览器支持与否对操作方式有影响。若支持,同样采用类似方法,通过pushState设置hash部分,replaceState则调用window.location.replace替换当前URL。然而,如果浏览器不支持pushState,会直接操作window.location更改URL,以#符号为标志。
MDN文档中提到,xmex源码pushState需要三个参数:状态对象、标题(通常忽略)和可选的URL。而replaceState与pushState类似,只是替换当前历史项,而非新增,尽管它会在浏览器历史中生成新的记录。
当路由更改后,紧接着是视图的同步更新。详细了解这两个方法的使用,可以参考MDN文档:developer.mozilla.org/zh-CN/docs/Web/API/History/pushState。
继续深入学习,确保在实际项目中正确运用这些原理,实现无缝的路由切换。
EasyLogger源码学习笔记(3)
在EasyLogger源码学习中,枚举变量的使用十分直观。定义枚举类型后,可以直接在代码中操作,提升可读性和代码清晰度。removeall源码
va_list是一个字符指针,用于在可变参数表中导航和取值。首先,你需要定义一个va_list类型的变量ap,然后通过va_start函数初始化,ap指向变参表的第一个参数,后续的参数获取通过va_arg完成,它会根据指定类型从ap中提取并返回值,同时更新ap的位置。使用完毕后,记得调用va_end来释放ap,以确保程序的健壮性。
对于字符串处理,vsnprintf提供了格式化输出功能,它能在指定长度内限制输出,避免溢出。例如,snprintf函数可以格式化字符串并存储在给定的缓冲区中,确保字符数不超过预设的大小。
在查找字符串时,strstr函数用于在haystack中查找needle首次出现的位置,但不包括结束符。在函数定义中,诸如va_start(args, format)这样的语句用于处理可变参数。
在elog_output函数中,tag_sapce的初始化出现疑问,原因在于需要保证标签对齐,通过memset函数在前面填充空格。这里,用'ELOG_FILTER_TAG_MAX_LEN / 2 - tag_len'的长度来确保足够的空间,而不是'ELOG_FILTER_TAG_MAX_LEN + 1',因为这样可以避免不必要的填充。
在elog_find_tag函数中,返回值的问题在于它实际返回了日志的tag及其后续信息,而不是仅限于tag本身。因此,需要检查并修正这个逻辑,以确保返回正确的内容。
easylogging源码学习笔记(6)
`LOG` 是默认日志、CLOG自定义日志、LOG_IF条件日志
特殊日志
LOG_EVERY_N、LOG_AFTER_N、LOG_N_TIMES
for (int i = 1; i <= ; ++i) {
LOG_EVERY_N(2, INFO) << "Logged every second iter";
}// 5 logs written; 2, 4, 6, 7,
for (int i = 1; i <= ; ++i) {
LOG_AFTER_N(2, INFO) << "Log after 2 hits; " << i;
}// 8 logs written; 3, 4, 5, 6, 7, 8, 9,
for (int i = 1; i <= ; ++i) {
LOG_N_TIMES(3, INFO) << "Log only 3 times; " << i;
}// 3 logs writter; 1, 2, 3
条件日志和特殊日志可以搭配使用
* `VLOG_IF(condition, verbose-level)`
* `CVLOG_IF(condition, verbose-level, loggerID)`
* `VLOG_EVERY_N(n, verbose-level)`
* `CVLOG_EVERY_N(n, verbose-level, loggerID)`
* `VLOG_AFTER_N(n, verbose-level)`
* `CVLOG_AFTER_N(n, verbose-level, loggerID)`
* `VLOG_N_TIMES(n, verbose-level)`
* `CVLOG_N_TIMES(n, verbose-level, loggerID)`
日志详细等级判定
if (VLOG_IS_ON(2)) {
// Verbosity level 2 is on for this file
}
性能追踪
* `TIMED_FUNC(obj-name)`
* `TIMED_SCOPE(obj-name, block-name)`
* `TIMED_BLOCK(obj-name, block-name)`
这些宏实际上都是关于el::base::type::PerformanceTrackerPtr,一个指向el::base::PerformanceTracker的指针
#if defined(ELPP_FEATURE_ALL) || defined(ELPP_FEATURE_PERFORMANCE_TRACKING)
PerformanceTracker::PerformanceTracker(const std::string& blockName,
base::TimestampUnit timestampUnit,
const std::string& loggerId,
bool scopedLog, Level level) :
m_blockName(blockName), m_timestampUnit(timestampUnit), m_loggerId(loggerId), m_scopedLog(scopedLog),
m_level(level), m_hasChecked(false), m_lastCheckpointId(std::string()), m_enabled(false) {
#if !defined(ELPP_DISABLE_PERFORMANCE_TRACKING) && ELPP_LOGGING_ENABLED
// We store it locally so that if user happen to change configuration by the end of scope
// or before calling checkpoint, we still depend on state of configuration at time of construction
el::Logger* loggerPtr = ELPP->registeredLoggers()->get(loggerId, false);
m_enabled = loggerPtr != nullptr && loggerPtr->m_typedConfigurations->performanceTracking(m_level);
if (m_enabled) {
base::utils::DateTime::gettimeofday(&m_startTime);
}
#endif // !defined(ELPP_DISABLE_PERFORMANCE_TRACKING) && ELPP_LOGGING_ENABLED
}
在构造函数中获取一个时间,
PerformanceTracker::~PerformanceTracker(void) {
#if !defined(ELPP_DISABLE_PERFORMANCE_TRACKING) && ELPP_LOGGING_ENABLED
if (m_enabled) {
base::threading::ScopedLock scopedLock(lock());
if (m_scopedLog) {
base::utils::DateTime::gettimeofday(&m_endTime);
base::type::string_t formattedTime = getFormattedTimeTaken();
PerformanceTrackingData data(PerformanceTrackingData::DataType::Complete);
data.init(this);
data.m_formattedTimeTaken = formattedTime;
PerformanceTrackingCallback* callback = nullptr;
for (const std::pair& h
: ELPP->m_performanceTrackingCallbacks) {
callback = h.second.get();
if (callback != nullptr && callback->enabled()) {
callback->handle(&data);
}
}
}
}
#endif // !defined(ELPP_DISABLE_PERFORMANCE_TRACKING)
}
在析构函数中获取一个时间,处理时间data,使用PerformanceTrackingCallback类型指针callback,并在callback->handle(&data)中处理输出。
由于定义了ELPP_FEATURE_PERFORMANCE_TRACKING,因此在初始化(INITIALIZE_EASYLOGGINGPP)中实际上是安装了一个base::DefaultPerformanceTrackingCallback。
在PerformanceTracker类的handle函数中,callback是一个PerformanceTrackingCallback类型指针,由于安装的是DefaultPerformanceTrackingCallback对象,因此是一个基类指针指向了派生类对象。处理输出的逻辑在DefaultPerformanceTrackingCallback类的handle函数中。
DefaultPerformanceTrackingCallback类的handle函数首先会将数据成员m_data的指针赋值给函数参数,并创建一个base::type::stringstream_t类型的对象ss用于构建输出内容。根据m_data的dataType,输出不同的信息。在输出时,会使用el::base::Writer类构造并输出内容。
小红书web端搜索采集笔记视频点赞关注评论去水印接口源码nodejs
本文旨在提供对小红书web端接口的概览,仅供学习与研究,严禁用于非法用途。请遵守法律法规,尊重版权。如有侵权,请及时告知,感谢配合。一、notejs接口调用方法(源码级别):
获取笔记信息:helpnow_get_note_by_id("笔记ID") 获取当前用户信息:helpnow_self_info() 获取用户信息:helpnow_user_info("用户ID") 获取主页推荐:helpnow_home_feed(RECOMMEND) 搜索笔记:helpnow_note_by_keyword("搜索关键字") 获取用户笔记:helpnow_user_notes("用户ID") 获取笔记评论:helpnow_note_comments("笔记ID") 获取笔记子评论:helpnow_note_sub_comments("笔记ID", "父评论ID") 评论笔记:helpnow.comment_note("笔记ID", "评论内容") 删除笔记评论:helpnow.delete_note_comment("笔记ID", "评论ID") 评论用户:helpnow.delete_note_comment("笔记ID", "评论ID", "评论内容") 关注用户:helpnow.follow_user("用户ID") 取关用户:helpnow.unfollow_user("用户ID") 收藏笔记:helpnow.collect_note("笔记ID") 取消收藏笔记:helpnow.uncollect_note("笔记ID") 点赞笔记:helpnow.like_note("笔记ID") 取消点赞笔记:helpnow.dislike_note("笔记ID") 点赞评论:helpnow.like_comment("笔记ID", "评论ID") 取消点赞评论:helpnow.dislike_comment("评论ID") 获取二维码:helpnow.get_qrcode() 检查二维码状态:helpnow.check_qrcode("二维码ID", "二维码编码")二、推荐部分小红书使用接口更新:
以下是小红书推荐接口的代码示例,用于更新推荐内容。 RECOMMEND = "homefeed_recommend" FASION = "homefeed.fashion_v3" FOOD = "homefeed.food_v3" COSMETICS = "homefeed.cosmetics_v3" MOVIE = "homefeed.movie_and_tv_v3" CAREER = "homefeed.career_v3" EMOTION = "homefeed.love_v3" HOURSE = "homefeed.household_product_v3" GAME = "homefeed.gaming_v3" TRAVEL = "homefeed.travel_v3" FITNESS = "homefeed.fitness_v3"三、已支持接口列表如下:
包含以下接口用于访问与小红书相关的数据: 小红书关键字搜索 小红书用户信息详情 小红书用户笔记列表 小红书单个笔记详细数据 小红书用户关注列表 小红书用户粉丝列表 小红书用户点赞的笔记列表 小红书用户收藏的笔记列表 小红书笔记的评论列表 小红书单条评论下的回复列表 小红书单个笔记关联的商品列表 小红书商城店铺下的商品列表 小红书话题页/poi页相关接口EasyLogger源码学习笔记(5)
在EasyLogger源码的学习中,我们了解到日志对象使用了互斥锁以确保同一时刻只有一个线程能进行操作,保证了日志管理的安全性与高效性。
对于异步输出,EasyLogger通过信号量实现了优化。当需要等待执行时,某个线程会被阻塞,以减少CPU的占用。这一特性允许用户单独设置异步输出的日志等级,提高系统的灵活性与可控性。
在文件输出时,使用了信号量集合,其中仅包含一个信号量。这一设计确保了同时只有一个线程能向文件中写入日志,避免了多线程并发写入导致的文件混乱。
日志输出的多样选择体现了EasyLogger的灵活性,无论是输出到文件还是串口,都可以根据需要配置是否采用异步输出,以适应不同的应用场景与性能需求。
此外,sem_post函数用于解锁由semby指定的信号量,执行对特定信号量的解锁操作。而semop函数则用于执行一组预先定义的信号量操作,适用于对多个信号量进行原子性操作。
在信号量集合仅包含一个信号量的情况下,使用sem_post函数进行操作可能直接替代使用semop函数。这一设计简化了信号量管理,提高了代码的可读性和效率。