源码
文章平均质量分 94
瞎猫技术研究员
不积跬步无以至千里:phoenix_tech
展开
-
扫描全能王文档矫正逆向记录
花了两三个月时间将扫描全能王的一个算法扒了个底朝天原创 2023-10-19 20:45:00 · 1338 阅读 · 2 评论 -
TFLite - NDK11 构建问题
Duplicated key “arm64-v8a” when creating dictionarytflite - bazel 1.2.0 - ndk11 构建发生错误Duplicated key “arm64-v8a” when creating dictionarybazel构建会去找 BUILD.bazel里对应的 cc_toolchain_suite 工具链套件,工具链套件是在构建过程中由bazel的androidndk插件自动生成的,位置在/private/var/tmp/_b原创 2020-07-10 17:56:03 · 368 阅读 · 0 评论 -
Binder通信和启动流程源码详解
所有源码均基于android M本篇从情景化角度出发分析Binder的通信逻辑。其中会涉及到几个概念· media server - 系统多媒体服务· media player server - 多媒体服务下的视频服务· Binder驱动先总结一下本篇所会涉及到的概念和他们之间的关系。media server 是安卓系统中用来管理各个多媒体服务的“服务的服务类”。media server管理着多个服务的启动和加载,包括 AudioFlinger,Camera,MediaPlayerServi原创 2020-05-26 16:14:16 · 910 阅读 · 0 评论 -
Kotlin协程-Scheduler的优秀设计
在仔细分析协程源码后,发现kotlin中协程的很多设计都参考了golang中的实现。比如跟线程和任务调度关系最密切的 Scheduler 类,在它的注释中看到这句话,* The original idea with a single-slot LIFO buffer comes from Golang runtime scheduler by D. Vyukov. * It was proven to be "fair enough", performant and generally well ac原创 2020-05-19 20:38:46 · 678 阅读 · 0 评论 -
Kotlin协程-特殊的阻塞协程
阻塞协程是种特殊的协程启动方式,一般是用 runBlocking{} 扩起来一段协程。fun main() = runBlocking { launch { println("launch start") delay(100L) // 非阻塞的等待 1 秒钟(默认时间单位是毫秒) println("World Thread: ${Thread.currentThread().name}") println("World!") // 在原创 2020-05-18 22:45:35 · 4106 阅读 · 0 评论 -
Kotlin协程-协程的内部概念Continuation
一个协程的生命周期是这样的,±---------+ ±---------------------+| START |----------------------->| SUSPENDED |±---------+ ±---------------------+ | ^ V | ±-----------+ completion invoked ±----------------原创 2020-05-18 18:01:07 · 2842 阅读 · 0 评论 -
Kotlin协程-调度器中的精妙实现
kotlin的默认调度器实现其实有两个,而我们常用的是DefaultScheduler。另一个是CommonPool。internal actual fun createDefaultDispatcher(): CoroutineDispatcher = if (useCoroutinesScheduler) DefaultScheduler else CommonPoolCommonPool也是一个线程池实现。它创建线程池的部分很有意思,private fun createPool():原创 2020-05-18 17:50:35 · 890 阅读 · 0 评论 -
Kotlin协程-一个协程的生命周期
《Kotlin协程》均基于Kotlinx-coroutines 1.3.70在安卓或者kotlin平台上使用协程是很简单的一件事情。举一个最简单的例子,不依赖安卓平台的协程代码,fun main() { GlobalScope.launch { delay(1000L) // 非阻塞的等待 1 秒钟(默认时间单位是毫秒) println("World!") // 在延迟后打印输出 } delay(100L) println("Hello,"原创 2020-05-18 14:27:14 · 1863 阅读 · 0 评论 -
Kotlin协程-协程派发和调度框架
一个coroutine创建好之后,就交给协程框架去调度了。这篇主要讲从launch{…}开始,到最终得到执行的时候,所涉及到的协程框架内部概念。一般开发中所接触到的协程类和接口无非是 launch, async, Dispatch.IO…,这些概念是对我们开发者来说的。进入协程源码的世界之后,这些概念就会被一些内部概念所替代。搞清楚内部概念对分析协程源码来说非常关键。协程的最小粒度-Coroutine对没接触过协程的人来说,一个OOP代码的最小调度粒度是函数。在协程中,最小的调度粒度是协程,在kotl原创 2020-05-14 17:23:02 · 583 阅读 · 0 评论 -
Kotlin协程开篇
《Kotlin协程》均基于Kotlinx-coroutines 1.3.70· 协程是什么?· 什么时候用协程?· 协程的核心是什么?· kotlin的协程和其他语言的协程有什么异同?协程没那么难协程的出现是为了解决异步编程中遇到的各种问题。从高级编程语言出现的第一天,异步执行的问题就伴随出现。在Kotlin里使用协程非常方便,import kotlinx.coroutines.*fun main() { GlobalScope.launch { // 在后台启动一个新的协程并继原创 2020-05-13 15:10:02 · 276 阅读 · 0 评论 -
Redis事件驱动(2)- 注册
在创建完文件描述符FD之后,Redis就拥有了一个可以监听客户端事件的句柄了。注意在创建fd之后,实际上并没有开始接受客户端连接。接受客户端连接请求过程分两个部分,· accept· waitaccept做的事情是等待客户端连接。当我们在服务器上运行了 redis-server,Redis会启动并开始初始化,在初始化完成时,Redis持有了一个文件描述符,并且开始等待连接。直到有一个...原创 2020-04-27 18:05:34 · 417 阅读 · 0 评论 -
Redis事件驱动(1)- 创建
Redis作为一个能负载十万级别QPS的数据库,它在高峰并发情况下能够承载1000个客户端的并发请求。除此之外,Redis还是在单线程模式下工作。从这个角度可以说Redis是人类编程精华。而事件驱动则是Redis的心脏。Redis的事件驱动从一个函数开始,aeCreateEventLoop()aeCreateEventLoop()在ae.h中,声明了 aeCreateEventLoop(...原创 2020-04-27 18:05:00 · 223 阅读 · 0 评论 -
Redis的客户端服务端连接-事件驱动前言
事件驱动是Redis的最核心功能,但在看这部分源码之前需要先了解Redis是怎么建立一个 C/S 连接的。事件驱动分为两部分,· 文件事件· 时间事件时间事件很好理解,就是一个定时任务,对当前Redis环境的信息统计,内存整理。文件事件比较晦涩,特别是对于从来没接触过Unix系统,在Unix上写过代码的人来说,这部分代码可能会占到整个源码阅读时间的1/3。所谓文件事件,在Redis中...原创 2020-04-27 14:39:14 · 202 阅读 · 0 评论 -
C语言实现类似Java接口的设计
面向对象设计中的接口在高级语言中常见,在Redis中居然有用C语言实现类似接口功能的代码。在阅读 dict 代码的过程中发现,词典的数据结构有个奇怪的结构体typedef struct dictType { unsigned int (*hashFunction)(const void *key); void *(*keyDup)(void *privdata, const ...原创 2020-04-26 20:38:19 · 556 阅读 · 0 评论 -
Redis数据对象(2)-注册与匹配
稍微猜想的话应该能猜到,Redis是根据不同的命令来找到不同的处理函数的。这些命令的构成基本有以下规则COMMAND KEY VALUE…那么Redis是怎么根据不同的COMMAND找到对应的处理函数的?Redis Comand的原型声明在开始理解这部分之前,有个前提需要说明这部分分析是脱离了Redis对client传输到服务端的数据获取和解析过程的,因为这部分逻辑涉及到事件循...原创 2020-04-26 20:36:47 · 152 阅读 · 0 评论 -
Redis数据对象(1)-架构
在对Redis源码的梳理过程中,下面这几类被分为数据对象。数据对象object.ct_stringt_listt_hasht_set什么是数据对象?实际上在Redis中并没有数据对象这个概念。但如果从Redis架构设计上来进行分析的话,上面这几类数据,和 sds, adlist,在Redis中起到的作用有非常大的差异。首先这几类对象只有 .c 文件,而没有 .h。相关函数声明...原创 2020-04-26 20:36:11 · 92 阅读 · 0 评论 -
人类编程精华 -- Redis核心源码分析开篇
以下内容默认以redis 2.8版本源码作为基础Redis的主要内容可以分为几个部分· 基本数据结构· 数据对象· 核心逻辑-事件循环/事件驱动· 磁盘文件系统围绕核心的架构,Redis还可以区分出几个模块· 服务端/客户端连接· 事务(transation/multi)· master-slave机制· expire机制· 慢查询· pub-sub机制Redis代码结构...原创 2020-04-26 20:35:36 · 264 阅读 · 1 评论 -
Redis基本数据结构(3)-dict
熟悉python的开发者应该对字典结构非常了解,字典通常泛指这类高层数据结构,dict: {“name”:“Jack”}更广泛意义上可以理解为 key-value 结构的都是 dict。在进一步地了解Redis的dict之前,需要清空对dict的刻板思维。不要认为它只是一个存储数据的数据结构。否则会对源码分析造成很大困难。Redis的dict设计非常精妙,不仅实现key-value...原创 2020-04-26 20:34:59 · 525 阅读 · 0 评论 -
Redis基本数据结构(2)-adlist
adlist是Redis中的双向链表。双向链表的数据结构,和遍历算法有很多资料可以查到,这里不对其中的算法细节详细描述。主要关注的是Redis利用双向链表结构,实现了什么样的精妙设计。节点的数据结构adlist首先是个链表,链表中的节点listNode定义在adlist.h中,typedef struct listNode { struct listNode *prev; ...原创 2020-04-26 20:34:28 · 364 阅读 · 0 评论 -
Redis基本数据结构(1)-sds
sds是Redis中最简单的数据结构,用来规范Redis中字符串的。在高级语言里我们有很多函数可以方便的操作字符串,像Java里的String,有append,trim,replace,但在C层面上,Redis为了方便操作字符串,同时为了内存管理,巧妙设计了sds这个结构体。它有两个文件· sds.c· sds.hsds 结构体sds结构体定义在 sds.h 中struct sds...原创 2020-04-26 20:33:52 · 394 阅读 · 0 评论