Python3动态创建module

最近要支持一个功能,让用户自定义一些动态的逻辑,索性让用户自己写代码执行,所以需要做到让用户的代码动态执行起来。下面列举一下核心逻辑。 代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 #!/usr/bin/env python3 import importlib def new_module(mod_name): spec = importlib.machinery.ModuleSpec(mod_name,None) return importlib.util.module_from_spec(spec) def create_module(mod_name, object_list): mod = new_module(mod_name) for obj in object_list: setattr(mod,obj.__name__, obj) return mod 这个脚本主要是用来动态创建module,并且把对象放到module中,这样就可以在其他地方调用了。 参考文章 Creating Dynamic Modules in Python 3 ……

阅读全文

对HTTP制作统一缓存的思考

背景 最近收到反馈,用户觉得小程序比较慢,统一分析后认为,我们系统在用户刷新的一些动作时,耗时比较长。 排查 由于业务的需求,用户在打开微信小程序的时候会调用一次服务端的接口 服务端在执行时会去调用高德地图/IPIP的接口,由于是外部服务的调用,所以耗时比较长(有些极端的会达到好几秒,但是普遍都是500ms+) 由于业务的原因,这些外部调用必须调用 解决思路 一开始是针对部分接口有了缓存的(Redis),但对每一个小的业务场景都使用了一个对象来处理缓存的使用,目前已经积累了五个了,按照堆屎山的逻辑,我应该再去配置一堆缓存对象来处理这个问题,然后在各个调用接口的地方使用缓存对象,但,我认为这不是一个好的设计了,原有的设计不太实用了,并且会造成代码逻辑的混乱,不好维护,以后即便缓存出现了问题,也难以排查。所以怎么解决呢? 启发 无意中看到代码中有http trace的逻辑(可以对http调用过程中的状态进行感知),我想到,是不是可以使用类似的逻辑来实现对HTTP调用统一的缓存呢?我只需要配置一下域名,路由,HTTP Method,是不是就可以快速完成HTTP调用呢? 实现 方案一:在HTTP Trace中制作缓存,但我发现HTTP Trace没有办法去拦截HTTP的Response数据,所以这条路行不通。 方案二:对HTTP的调用进行封装,这样确实是可以统一的进行HTTP缓存的逻辑,但是我想了一下,工作量有点接受不了,太多了。 方案三:我找到了一个aiohttp的client缓存三方库,它相当于对http的调用进行了封装,当然是当一个api gay来得快乐,但是,这个库对于缓存的过期机制的处理有点傻,没有使用Redis的过期机制,所以对其进行改动了一部分。 总结 当初在设计HTTP缓存的时候并没有考虑到这是一个通用的东西,也没有做得太通用,每一种业务调用都和缓存类进行强绑定,所谓“吃一堑,长一智”,下一次遇到类似的逻辑我一定不会写出强侵入式的逻辑。 在调研HTTP Trace的逻辑时,一开始是认为能走通的,但确实是没考虑到HTTP Trace没有办法拦截HTTP的Response数据的问题,导致自己做了一半了,不得不放弃,这也算是自己没有把事情的全流程考虑好,算是拿了半截就跑的典型错误,下一次还是要将全流程的思路写出来才算是调研成功。 目前看来,增加了缓存还是提升了很大的效率,算是告一段落。 现在看来,突然有点理解为什么以前遇到的项目会直接对Redis,Http的调用进行了包装,第一就是老生常谈的可能会换底层包的情况,另外一种可能就是我当前的情况。 ……

阅读全文

记一次线上服务内存优化历程

背景 近期看到企业微信告警,发现线上服务进程隔一段时间就会重启一次,遂开始进行排查。 线上服务描述 Python服务(使用aiohttp) K8S部署 容器中使用gunicorn,每个容器启动4个worker进程 排查过程 观察报警信息,只有一部分线上环境收到了影响。 观察报警时间,观察到只在整点时有一次服务重启告警(告警是进程自己发送的,也就是说只有一个进程重启了),并且不是必现。 观察资源信息,在服务重启前,重启信息的容器的内存有一次跳跃式增长。 最终,总结出几个信息: 某一个环境(该环境数据量大),整点时分,单进程重启,内存暴涨造成的。 而服务在整点时只有一个定时任务,这个定时任务是做多数据库的数据同步。 并且,任务的调起,是由外部的一个服务向本服务发送的一个HTTP请求(只会有一个进程来处理这个HTTP请求),所以,能够说通为什么只有一个进程会重启。 观察该HTTP请求的信息,查看该请求日志中的进程ID和重启的进程ID,最后发现是一致的,并且重启时间的定时任务日志中,没有定时任务完成得日志数据,所以最终推断出进程得重启是由该定时任务导致内存暴涨,从而导致进程重启。 但,还有一个问题没有被印证,进程重启的问题不是必现的,进而,我们需要拉长时间观察,最终发现,进程会因为定时任务导致内存有一次跳跃式的增长,但不一定会导致OOM,但有一个问题,内存虽然增加了,但是并没有看到内存回收,这个需要了解一下Python的内存管理机制,是因为进程执行过程中没有一个Arena中的内存被释放完,所以就不会被回收。 解决问题 通过多进程的方式 从上文的排查过程来看,我们可以从内存回收的角度来,在每次定时任务后保证申请的内存能够还给操作系统,避免造成Python一直持有内存不归还。但直接优化GC和内存管理对我一个普通的小开发来说不太现实,所以换个角度看,进程死亡,他的内存一定会归还,那这样就可以绕开Python内存管理造成的内存不归还的问题了。所以,我尝试了以下办法: 直接在http服务进程中做fork操作,但在aiohttp中执行fork视乎会出现各种各样的小问题,例如,fork出去的进程会copy一份父进程的内存,相当于和父进程使用了同一份async loop对象,在子进程中,会报错loop是异常的报错。所以我猜测,Python异步和同步fork操作应该不同。 在GitHub中查到了一个叫aiomultiprocess的三方库解决了办法1的问题,不会报出loop异常的问题。但,我开发时是未使用gunicorn的,所以在测试环境测试时,发现fork操作其实会卡死,很是困惑,遂Google到一篇文章Gunicorn+GeventWorker环境下fork进程意外结束的问题,这篇文章的解决办法有些trick,不太想用,放弃。 既然fork两条路都走不通,再想出了一个新的方式,脚本执行。我将定时任务中的逻辑,不再放到HTTP请求里面了,而是重新修改为脚本,在HTTP调用中,调起这个脚本。最终发现,行得通,上线。 上线后,发现内存确实是能够正常回收了,内存跳跃式增长不回收,变成了一个又一个的内存尖刺。但过了几周后,又发现了服务重启,查看原因是脚本占用内存太大,导致某个服务进程在申请内存时OOM,虽然告警的频率极低,但也算是一个隐患,需要优化它。 优化代码逻辑,降低内存消耗 从上文中看到,虽然解决了内存回收的问题,但随着业务的日益增长,数据量也会增长,数据同步逻辑会随着数据量的增长导致内存增长,而影响了服务进程。但是由于某些原因,不能新开一个服务来做这个事情,所以,查看了数据同步逻辑的代码,大概逻辑是:对比一个时间段内源数据库与目标数据的数据数量,如果相等,不迁移数据,如果不相等,同步数据。但同步数据并不是按照差异同步,而是使用了源数据库单时间段内的数据全量覆盖。有些暴力了,并且单看数据数量就判断是否需要同步数据也有失偏颇。 所以,最终修改为,根据最后更新时间来对比数据,同步有差异数据。 总结 解决本次的问题,从技术上来说,学习到了: Python的内存管理 了解了Gunicorn fork进程的一些机制 Python异步直接fork子进程的一些坑 从经验上看: 排查该类问题的一些思路以及逻辑。 对解决问题的思考,或者说对无法解决的问题,我如何的避开它,也就是如果规避一个问题的发生。 对数据同步,或者数据对比一些业务逻辑的思考。 ……

阅读全文

Gengine源码阅读 DataContext

数据结构概览 1 2 3 4 5 type DataContext struct { lockVars sync.Mutex // 对外部送进来的vars进行加锁 lockBase sync.Mutex // 对下面一行的`base`字段加锁 base map[string]reflect.Value // 存储各种类型的值, key是变量名, value是变量值, 变量值可以是任意类型, 例如:函数 } 上下文数据的增删查改 1 2 3 4 5 6 7 8 9 10 11 12 13 // 在base中添加一条数据,并将obj转换为reflect.Value类型 // 会使用localBase func (dc *DataContext) Add(key string, obj interface{}) // 批量删除base中的数据 // 会使用localBase func (dc *DataContext) Del(key string) // load一个动态库,并将动态库中提供给外部的接口全部写入base中 // 会使用localBase func (dc *DataContext) PluginLoader(absolutePathOfSO string) (string, plugin.……

阅读全文

决策引擎

决策引擎是一种计算机程序,用于计算一个系统的决策。 目标 提供规则集、决策表、交叉决策表(决策矩阵)、决策树、评分卡、复杂评分卡、规则流等八种类型的业务规则设计工具 并发执行规则 数据库设计 规则 表名称: rules 字段名称 字段类型 描述 id string primary key created int 创建时间 updated int 更新时间 merchant string 商户 code string 规则编码 type string(enum) 规则类型 information json(dict) 规则信息 name string 规则名称 description string 规则描述 type enum列表 raw - 原始脚本 ruleset - 规则集 normal_score_card - 普通评分卡 complex_score_card - 复杂评分卡 decision_tree - 决策树 decision_table - 决策表 decision_matrix - 决策矩阵 information json字段介绍 type == raw 时的information 1 2 3 { "script": "string, 脚本字符串" } type == ruleset 时的information 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 { "rules": [ { "name": "string, 子规则名称", "description": "string, 子规则描述", "rule_group": { // 树形结构 // type: string(enum), 规则条件类型, enum: expression, logic_expression "type": "logic_expression", "op": "string(enum), 规则操作符, or, and", "conditions": [ { "type": "expression", "operator": "string(enum), 表达式操作符, eq, neq, gt, gte, lt, lte, in, nin", "left_value": { "type": "string(enum), 左值类型, variable, constant, function", "value": "string, 左值值" }, "right_value": { "type": "string(enum), 左值类型, variable, constant, function", "value": "string, 左值值" } }, { "type": "logic_expression", "op": "string(enum), 规则操作符, or, and", "conditions": [] } ] } } ] } type == decision_table 时的information 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 { "table_conditions": [ { // 树形结构 // type: string(enum), 规则条件类型, enum: expression, logic_expression "type": "logic_expression", "op": "string(enum), 规则操作符, or, and", "conditions": [ { "type": "expression", "operator": "string(enum), 表达式操作符, eq, neq, gt, gte, lt, lte, in, nin", "left_value": { "type": "string(enum), 左值类型, variable, constant, function", "value": "string, 左值值" }, "right_value": { "type": "string(enum), 左值类型, variable, constant, function", "value": "string, 左值值" } }, { "type": "logic_expression", "op": "string(enum), 规则操作符, or, and", "conditions": [] } ] } ], "table_actions": [ // type: string(enum), 动作类型, assignment, function { "type": "assignment", "field": "string, 字段路径", "value": "string, 写入值" }, { "type": "function", "function_name": "string, 函数名", "arguments": [ { "type": "string(enum), 参数类型, variable, constant", "value": "string, 参数值" } ] } ] } type == decision_matrix 时的information 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 { // 赋值动作 "action": { "field": "string, 字段路径" }, // 表信息 "matrix": [ [ { "crosswise_conditions": [ { "type": "expression", "operator": "string(enum), 表达式操作符, eq, neq, gt, gte, lt, lte, in, nin", "left_value": { "type": "string(enum), 左值类型, variable, constant, function", "value": "string, 左值值" }, "right_value": { "type": "string(enum), 左值类型, variable, constant, function", "value": "string, 左值值" } }, { "type": "logic_expression", "op": "string(enum), 规则操作符, or, and", "conditions": [] } ], "lengthwise_conditions": [ { "type": "expression", "operator": "string(enum), 表达式操作符, eq, neq, gt, gte, lt, lte, in, nin", "left_value": { "type": "string(enum), 左值类型, variable, constant, function", "value": "string, 左值值" }, "right_value": { "type": "string(enum), 左值类型, variable, constant, function", "value": "string, 左值值" } }, { "type": "logic_expression", "op": "string(enum), 规则操作符, or, and", "conditions": [] } ], "value": "string, 值" } ] ] } type == normal_score_card 时的information 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 { "is_weight": "boolean, 权重", "action": { // 求和方式 "type": "function", "function_name": "string, 函数名称" }, "score_card_table": { "string, 字段路径": { "weight": "int, 权重", "conditions_and_score": [ { "conditions": [ { "type": "expression", "operator": "string(enum), 表达式操作符, eq, neq, gt, gte, lt, lte, in, nin", "left_value": { "type": "string(enum), 左值类型, variable, constant, function", "value": "string, 左值值" }, "right_value": { "type": "string(enum), 左值类型, variable, constant, function", "value": "string, 左值值" } }, { "type": "logic_expression", "op": "string(enum), 规则操作符, or, and", "conditions": [] } ], "score": "int, 分数" } ] } } } type == complex_score_card 时的information 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 { "action": { // 求和方式 "type": "function", "function_name": "string, 函数名称" }, "score_card_table": [ [ { "string, 字段路径": { "weight": "int, 权重", "conditions_and_score": [ { "conditions": [ { "type": "expression", "operator": "string(enum), 表达式操作符, eq, neq, gt, gte, lt, lte, in, nin", "left_value": { "type": "string(enum), 左值类型, variable, constant, function", "value": "string, 左值值" }, "right_value": { "type": "string(enum), 左值类型, variable, constant, function", "value": "string, 左值值" } }, { "type": "logic_expression", "op": "string(enum), 规则操作符, or, and", "conditions": [] } ], "score": "int, 分数" } ] } } ] ] } type == decision_tree 时的information 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 { "field": "string, 字段路径", "nodes": [ { "conditions": [ // 需要执行的条件 { "type": "expression", "operator": "string(enum), 表达式操作符, eq, neq, gt, gte, lt, lte, in, nin", "left_value": { "type": "string(enum), 左值类型, variable, constant, function", "value": "string, 左值值" }, "right_value": { "type": "string(enum), 左值类型, variable, constant, function", "value": "string, 左值值" } }, { "type": "logic_expression", "op": "string(enum), 规则操作符, or, and", "conditions": [] } ], "alise": { // type: string(enum), enum: leaf_node(叶子节点), non_leaf_node(非叶子节点) "type": "string(enum), enum: leaf_node", "action": [ // type: string(enum), 动作类型, assignment, function { "type": "assignment", "field": "string, 字段路径", "value": "string, 写入值" }, { "type": "function", "function_name": "string, 函数名", "arguments": [ { "type": "string(enum), 参数类型, variable, constant", "value": "string, 参数值" } ] } ] } }, { "conditions": [ // 需要执行的条件 { "type": "expression", "operator": "string(enum), 表达式操作符, eq, neq, gt, gte, lt, lte, in, nin", "left_value": { "type": "string(enum), 左值类型, variable, constant, function", "value": "string, 左值值" }, "right_value": { "type": "string(enum), 左值类型, variable, constant, function", "value": "string, 左值值" } }, { "type": "logic_expression", "op": "string(enum), 规则操作符, or, and", "conditions": [] } ], "alise": { // type: string(enum), enum: leaf_node(叶子节点), non_leaf_node(非叶子节点) "type": "string(enum), enum: non_leaf_node", "field": "string, 字段路径", "nodes": [] } } ] } 决策流 表名称: decision_flow 字段名称 字段类型 描述 id string primary key created int 创建时间 updated int 更新时间 merchant string 商户 code string 决策流编码 name string 决策流名称 description string 决策流描述 决策流-规则节点 表名称: decision_flow_node 字段名称 字段类型 描述 id string primary key created int 创建时间 updated int 更新时间 merchant string 商户 decision_flow_code string 决策流编码 rule_code string 规则编码 next_node list[string] 下一步规则节点编码列表 name string 规则节点名称 description string 规则节点描述 数据库图 接口文档 规则 创建 Request Method: POST URL: /v1/rule Headers: Content-Type: application/json Body 1 2 3 4 5 6 7 8 9 10 11 12 { "data_list": [ { "merchant": "string, 商户号", "code": "string, 规则编码", "type": "string(enum), 规则类型", "information": "json(dict), 规则信息, 根据type进行变化", "name": "string, 规则名称", "description": "string, 规则描述" } ] } Response 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 { "data": [ { "data": { "id": "string, 主键", "created": "int, 创建时间", "updated": "int, 更新时间" // 其余全量数据 }, "msg": "success", "code": 0 } ], "msg": "success", "code": 0 } 描述 无……

阅读全文

CPython的原子操作

GIL 保证的 Thread-safe 是在 Bytecode 层而不是 Python Code。所以能确保的是每行 Bytecode 都会被运行完成,而多行 Bytecode 是则有被中断切换执行的可能性。 原子操作 读取/覆盖一个单变量 读取/覆盖一个全局变量 从list拿到一个元素 更新list的一个元素(例如: list.append()) 从dictionary中获取一个元素 更新dictionary的一个元素 参考文章 Atomic operations ……

阅读全文

`caarlos0/env`源码阅读

Tips: 建议先看下官方文档,如何使用env再看源码 项目信息 地址:https://github.com/caarlos0/env 描述:一个可以parse环境变量到go struct的简单的三方库 版本:tag: v6.8.0 源码阅读 入口函数(Parse) 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 // Parse parses a struct containing `env` tags and loads its values from // environment variables. func Parse(v interface{}, opts ...Options) error { return ParseWithFuncs(v, map[reflect.Type]ParserFunc{}, opts...) } // ParseWithFuncs is the same as `Parse` except it also allows the user to pass // in custom parsers.……

阅读全文

上下文切换

上下文切换指的是内核(操作系统的核心)在CPU上对进程或者线程进行切换。上下文切换过程中的信息被保存在进程控制块(PCB-Process Control Block)中。PCB又被称作切换帧(SwitchFrame)。上下文切换的信息会一直被保存在CPU的内存中,直到被再次使用。 上下文切换定义 CPU 上下文切换 虽然系统的 CPU 个数有限,但能支持同时运行多个任务。当然这种同时只是宏观上的假象,如果从微观角度观察,会发现系统在不停轮流切换任务,使得每个任务都能获得运行的机会。 CPU 寄存器和程序计数器就是 CPU 上下文,因为它们都是 CPU 在运行任何任务前,必须的依赖环境。 CPU 是状态 + 存储的模型,其符合图灵机这种理想设备 内存 PC 指针指向下一条待运行的指令(状态) 计算规则 其他辅助计算的寄存器(状态) 多任务的每个任务都有自己的状态。当任务 1 切出,任务 2 切入时,CPU 的状态也要切换成任务 2 上一次切出时的状态,这样任务 2 才能继续运行。这些状态即是 CPU 上下文,CPU 上下文切换即保存和恢复 PC 和辅助计算的寄存器(也就是 CPU 寄存器和程序计数器)。 CPU 上下文切换的类型 根据任务的不同,可以分为以下三种类型: 进程上下文切换 线程上下文切换 中断上下文切换 进程上下文切换 发生进程上下文切换的场景 为了保证所有进程可以得到公平调度,CPU 时间被划分为一段段的时间片,这些时间片再被轮流分配给各个进程。这样,当某个进程的时间片耗尽了,就会被系统挂起,切换到其它正在等待 CPU 的进程运行。 进程在系统资源不足(比如内存不足)时,要等到资源满足后才可以运行,这个时候进程也会被挂起,并由系统调度其他进程运行。 当进程通过睡眠函数 sleep 这样的方法将自己主动挂起时,自然也会重新调度。 当有优先级更高的进程运行时,为了保证高优先级进程的运行,当前进程会被挂起,由高优先级进程来运行 发生硬件中断时,CPU 上的进程会被中断挂起,转而执行内核中的中断服务程序。 进程/线程的CPU上下文切换成本来源 CPU 中的寄存器似乎一只手就数的过来,切换的成本非常小,为什么会造成系统负载显著升高呢?Linux 操作系统中的任务有进程和线程,切换的主要成本来自于进程/线程的上下文切换。……

阅读全文

Python的全局锁(GIL)

GIL是什么 首先需要明确的一点是GIL并不是Python的特性,它是在实现Python解析器(CPython)时所引入的一个概念。就好比C++是一套语言(语法)标准,但是可以用不同的编译器来编译成可执行代码。有名的编译器例如GCC,INTEL C++,Visual C++等。Python也一样,同样一段代码可以通过CPython,PyPy,Psyco等不同的Python执行环境来执行。像其中的JPython就没有GIL。然而因为CPython是大部分环境下默认的Python执行环境。所以在很多人的概念里CPython就是Python,也就想当然的把GIL归结为Python语言的缺陷。所以这里要先明确一点:GIL并不是Python的特性,Python完全可以不依赖于GIL。 那么CPython实现中的GIL又是什么呢?GIL全称Global Interpreter Lock为了避免误导,我们还是来看一下官方给出的解释: In CPython, the global interpreter lock, or GIL, is a mutex that prevents multiple native threads from executing Python bytecodes at once. This lock is necessary mainly because CPython’s memory management is not thread-safe. (However, since the GIL exists, other features have grown to depend on the guarantees that it enforces.) 好吧,是不是看上去很糟糕?一个防止多线程并发执行机器码的一个Mutex,乍一看就是个BUG般存在的全局锁嘛!别急,我们下面慢慢的分析。 为什么会有GIL 由于物理上的限制,各CPU厂商在核心频率上的比赛已经被多核所取代。为了更有效的利用多核处理器的性能,就出现了多线程的编程方式,而随之带来的就是线程间数据一致性和状态同步的困难。即使在CPU内部的Cache也不例外,为了有效解决多份缓存之间的数据同步时各厂商花费了不少心思,也不可避免的带来了一定的性能损失。 Python当然也逃不开,为了利用多核,Python开始支持多线程。而解决多线程之间数据完整性和状态同步的最简单方法自然就是加锁。 于是有了GIL这把超级大锁,而当越来越多的代码库开发者接受了这种设定后,他们开始大量依赖这种特性(即默认python内部对象是thread-safe的,无需在实现时考虑额外的内存锁和同步操作)。 慢慢的这种实现方式被发现是蛋疼且低效的。但当大家试图去拆分和去除GIL的时候,发现大量库代码开发者已经重度依赖GIL而非常难以去除了。有多难?做个类比,像MySQL这样的“小项目”为了把Buffer Pool Mutex这把大锁拆分成各个小锁也花了从5.5到5.6再到5.7多个大版为期近5年的时间,并且仍在继续。MySQL这个背后有公司支持且有固定开发团队的产品走的如此艰难,那又更何况Python这样核心开发和代码贡献者高度社区化的团队呢? 所以简单的说GIL的存在更多的是历史原因。如果推到重来,多线程的问题依然还是要面对,但是至少会比目前GIL这种方式会更优雅。 GIL 到底锁的是什么? 大家都说 Python 有 GIL 锁,那么这个锁到底锁的是什么东西??……

阅读全文

四象限工作法

所谓四象限工作法是由著名管理学家史蒂芬柯维提出的一个时间管理理论。该理论把事情按照重要和紧急分成了四个象限:重要而且紧急、重要但不紧急、不重要但紧急、不重要不紧急。 各个象限的解释 第一象限 重要而且紧急。例如为孩子填写高考志愿,处理某某负面消息等等。这些事情必须马上去做,不然后果很严重。 第二象限 重要但不紧急。例如制定公司的战略计划,准备某某合同的资料等。这些事情虽然看起来不紧急,但是却不能置之不理。如果现在不重视它,它随时都会发展成重要而且紧急的事情。 第三象限 不重要但紧急。例如客户突然打来电话,召开临时会议等。这个象限的精力花费是相当无奈的,但包括你在内的很多人都会被假象迷惑,认为紧急就是重要的。其实,紧急和重要一点关系也没有。对于突如其来的紧急事情,你先得评估下这件事情对于手里的其他事情的重要性再决定要不要做这件事情。在这个象限,我们应该思考这个问题,如何减少第三象限的事情? 第四象限 不重要不紧急。看无聊的电视剧,一个人瞎逛,发呆。这个象限的事情都是用来打发时间的,仅仅当做前三个象限的调剂还说得过去,若过多的沉溺于这个象限,那我们的产出则会大打折扣。在这个象限,我们应该思考这个问题,有必要进入这个象限吗? 处理四象限事务的原则 第一象限 没什么好说的,立即去做。在工作中主要压力来自于第一象限,在生活中主要危机也来自于第一象限。 第二象限 有计划去做。 第三象限 交给别人去做。 第四象限 尽量别去做。 应用猴子法则走出第三象限 猴子法则是William Oncken 提出的一个理论,叫背上是我猴子。Oncken教授把那些工作比喻为活蹦乱跳,随时可能跳到你身上的猴子。 你将一些并非自己职责的事情做得很有效率,可这值得沾沾自喜吗?你自己的事情完成得怎么样了呢?这个就是猴子法则。把不是自己背上的猴子巧妙的转移到别人身上,或者是换给给你猴子的人身上。 第二象限工作法 如何走入第二项象限,第二现象工作法是四象限的核心和最终目的。 四象限法小结 根据自己的价值观评判出某件事务的重要程度 根据事务的截止日期判断其紧迫程度 将自己所有的日常事务放到四象限中分析 对于四象限事务有不同处理的方法和原则 我们的主要精力是解决第二象限的事务 平常制定工作计划和目标都是相对于第二象限来说的 ……

阅读全文