Technology

Chart Type 《大数据经典论文解读》 三驾马车学习 Spark 内存管理及调优 Yarn学习 从Spark部署模式开始讲源码分析 容器狂占内存资源怎么办? 多角度理解一致性 golang io使用及优化模式 Flink学习 c++学习 学习ebpf go设计哲学 ceph学习 学习mesh kvm虚拟化 学习MQ go编译器 学习go 为什么要有堆栈 汇编语言 计算机组成原理 运行时和库 Prometheus client mysql 事务 mysql 事务的隔离级别 mysql 索引 坏味道 学习分布式 学习网络 学习Linux go 内存管理 golang 系统调用与阻塞处理 Goroutine 调度过程 重新认识cpu mosn有的没的 负载均衡泛谈 单元测试的新解读 《Redis核心技术与实现》笔记 《Prometheus监控实战》笔记 Prometheus 告警学习 calico源码分析 对容器云平台的理解 Prometheus 源码分析 并发的成本 基础设施优化 hashicorp raft源码学习 docker 架构 mosn细节 与微服务框架整合 Java动态代理 编程范式 并发通信模型 《网络是怎样连接的》笔记 go channel codereview gc分析 jvm 线程实现 go打包机制 go interface及反射 如何学习Kubernetes 《编译原理之美》笔记——后端部分 《编译原理之美》笔记——前端部分 Pilot MCP协议分析 go gc 内存管理玩法汇总 软件机制 istio流量管理 Pilot源码分析 golang io 学习Spring mosn源码浅析 MOSN简介 《datacenter as a computer》笔记 学习JVM Tomcat源码分析 Linux可观测性 学习存储 学计算 Gotty源码分析 kubernetes operator kaggle泰坦尼克问题实践 kubernetes扩缩容 神经网络模型优化 直觉上理解深度学习 如何学习机器学习 TIDB源码分析 什么是云原生 Alibaba Java诊断工具Arthas TIDB存储——TIKV 《Apache Kafka源码分析》——简介 netty中的线程池 guava cache 源码分析 Springboot 启动过程分析 Spring 创建Bean的年代变迁 Linux内存管理 自定义CNI IPAM 共识算法 spring redis 源码分析 kafka实践 spring kafka 源码分析 Linux进程调度 让kafka支持优先级队列 Codis源码分析 Redis源码分析 C语言学习 《趣谈Linux操作系统》笔记 docker和k8s安全访问机制 jvm crash分析 Prometheus 学习 Kubernetes监控 容器日志采集 Kubernetes 控制器模型 容器狂占资源怎么办? Kubernetes资源调度——scheduler 时序性数据库介绍及对比 influxdb入门 maven的基本概念 《Apache Kafka源码分析》——server Kubernetes类型系统 源码分析体会 《数据结构与算法之美》——算法新解 Kubernetes源码分析——controller mananger Kubernetes源码分析——apiserver Kubernetes源码分析——kubelet Kubernetes介绍 ansible学习 Kubernetes源码分析——从kubectl开始 jib源码分析之Step实现 jib源码分析之细节 线程排队 跨主机容器通信 jib源码分析及应用 为容器选择一个合适的entrypoint kubernetes yaml配置 《持续交付36讲》笔记 mybatis学习 程序猿应该知道的 无锁数据结构和算法 CNI——容器网络是如何打通的 为什么很多业务程序猿觉得数据结构和算法没用? 串一串一致性协议 当我在说PaaS时,我在说什么 《数据结构与算法之美》——数据结构笔记 PouchContainer技术分享体会 harbor学习 用groovy 来动态化你的代码 精简代码的利器——lombok 学习 《深入剖析kubernetes》笔记 编程语言那些事儿 rxjava3——背压 rxjava2——线程切换 spring cloud 初识 《深入拆解java 虚拟机》笔记 《how tomcat works》笔记 hystrix 学习 rxjava1——概念 Redis 学习 TIDB 学习 如何分发计算 Storm 学习 AQS1——论文学习 Unsafe Spark Stream 学习 linux vfs轮廓 《自己动手写docker》笔记 java8 实践 中本聪比特币白皮书 细读 区块链泛谈 比特币 大杂烩 总纲——如何学习分布式系统 hbase 泛谈 forkjoin 泛谈 看不见摸不着的cdn是啥 《jdk8 in action》笔记 程序猿视角看网络 bgp初识 calico学习 AQS——粗略的代码分析 我们能用反射做什么 web 跨域问题 《clean code》笔记 《Elasticsearch权威指南》笔记 mockito简介及源码分析 2017软件开发小结—— 从做功能到做系统 《Apache Kafka源码分析》——clients dns隐藏的一个坑 《mysql技术内幕》笔记 log4j学习 为什么netty比较难懂? 回溯法 apollo client源码分析及看待面向对象设计 学习并发 docker运行java项目的常见问题 OpenTSDB 入门 spring事务小结 分布式事务 javascript应用在哪里 《netty in action》读书笔记 netty对http2协议的解析 ssl证书是什么东西 http那些事 苹果APNs推送框架pushy apple 推送那些事儿 编写java框架的几大利器 java内存模型 java exception Linux IO学习 netty内存管理 测试环境docker化实践 netty在框架中的使用套路 Nginx简单使用 《Linux内核设计的艺术》小结 Go并发机制及语言层工具 Linux网络源代码学习——数据包的发送与接收 《docker源码分析》小结 docker namespace和cgroup Linux网络源代码学习——整体介绍 zookeeper三重奏 数据库的一些知识 Spark 泛谈 链式处理的那些套路 netty回顾 Thrift基本原理与实践(二) Thrift基本原理与实践(一) 回调 异步执行抽象——Executor与Future Docker0.1.0源码分析 java gc Jedis源码分析 深度学习泛谈 Linux网络命令操作 JTA与TCC 换个角度看待设计模式 Scala初识 向Hadoop学习NIO的使用 以新的角度看数据结构 并发控制相关的硬件与内核支持 systemd 简介 quartz 源码分析 基于docker搭建测试环境(二) spring aop 实现原理简述 自己动手写spring(八) 支持AOP 自己动手写spring(七) 类结构设计调整 分析log日志 自己动手写spring(六) 支持FactoryBean 自己动手写spring(九) 总结 自己动手写spring(五) bean的生命周期管理 自己动手写spring(四) 整合xml与注解方式 自己动手写spring(三) 支持注解方式 自己动手写spring(二) 创建一个bean工厂 自己动手写spring(一) 使用digester varnish 简单使用 关于docker image的那点事儿 基于docker搭建测试环境 分布式配置系统 JVM执行 git maven/ant/gradle/make使用 再看tcp kv系统 java nio的多线程扩展 《Concurrency Models》笔记 回头看Spring IOC IntelliJ IDEA使用 Java泛型 vagrant 使用 Go常用的一些库 Python初学 Goroutine 调度模型 虚拟网络 《程序员的自我修养》小结 Kubernetes存储 访问Kubernetes上的Service Kubernetes副本管理 Kubernetes pod 组件 Go基础 JVM类加载 硬币和扑克牌问题 LRU实现 virtualbox 使用 ThreadLocal小结 docker快速入门

Architecture

实时训练 分布式链路追踪 helm tensorflow原理——python层分析 如何学习tensorflow 数据并行——allreduce 数据并行——ps 机器学习中的python调用c 机器学习训练框架概述 embedding的原理及实践 tensornet源码分析 大模型训练 X的生成——特征工程 tvm tensorflow原理——core层分析 模型演变 《深度学习推荐系统实战》笔记 keras 和 Estimator tensorflow分布式训练 分布式训练的一些问题 基于Volcano的弹性训练 图神经网络 pytorch弹性分布式训练 在离线业务混部 RNN pytorch分布式训练 CNN 《动手学深度学习》笔记 pytorch与线性回归 多活 volcano特性源码分析 推理服务 kubebuilder 学习 mpi 学习pytorch client-go学习 tensorflow学习 提高gpu 利用率 GPU与容器的结合 GPU入门 AI云平台 tf-operator源码分析 k8s批处理调度 喜马拉雅容器化实践 Kubernetes 实践 学习rpc BFF 生命周期管理 openkruise学习 可观察性和监控系统 基于Kubernetes选主及应用 《许式伟的架构课》笔记 Kubernetes webhook 发布平台系统设计 k8s水平扩缩容 Scheduler如何给Node打分 Scheduler扩展 controller 组件介绍 openkruise cloneset学习 controller-runtime源码分析 pv与pvc实现 csi学习 client-go源码分析 kubelet 组件分析 调度实践 Pod是如何被创建出来的? 《软件设计之美》笔记 mecha 架构学习 Kubernetes events学习及应用 CRI 资源调度泛谈 业务系统设计原则 grpc学习 元编程 以应用为中心 istio学习 下一代微服务Service Mesh 《实现领域驱动设计》笔记 serverless 泛谈 概率论 《架构整洁之道》笔记 处理复杂性 那些年追过的并发 服务器端编程 网络通信协议 架构大杂烩 如何学习架构 《反应式设计模式》笔记 项目的演化特点 反应式架构摸索 函数式编程的设计模式 服务化 ddd反模式——CRUD的败笔 研发效能平台 重新看面向对象设计 业务系统设计的一些体会 函数式编程 《左耳听风》笔记 业务程序猿眼中的微服务管理 DDD实践——CQRS 项目隔离——案例研究 《编程的本质》笔记 系统故障排查汇总及教训 平台支持类系统的几个点 代码腾挪的艺术 abtest 系统设计汇总 《从0开始学架构》笔记 初级权限系统设计 领域驱动理念入门 现有上传协议分析 移动网络下的文件上传要注意的几个问题 推送系统的几个基本问题 用户登陆 做配置中心要想好的几个基本问题 不同层面的异步 分层那些事儿 性能问题分析 当我在说模板引擎的时候,我在说什么 用户认证问题 资源的分配与回收——池 消息/任务队列


一切瓶颈都是思维瓶颈

2018年11月28日

简介

站在思维的高处,才有足够的视野和能力欣赏“美”。

如何正确看待时间?你需要做得就是成为时间的朋友,用最初的努力,赢取到微弱的优势后,不断不断地坚持下去,你的优势就会被时间持续的放大再放大,然后到某一个时间点,你终于突破了平台期,或者度过了增长缓慢的起始阶段。「善弈者通盘无妙手」,是说一个高手,其实下完一整盘棋,你并不觉得他有哪一招惊天动地。以五子棋为例, 就是走的每一步能起到多个作用(比如既防御又进攻),多积累几步就会有全局的优势。

边界思维

《软件架构设计》:不管哪种分析方法、设计方法,最终必须保证每个系统有清晰的边界、分工清晰。无论谁要了解这个系统,他不用看这个系统是怎么实现的,只要看系统的接口,就知道系统支持什么,不支持什么。

把复杂留给自己,把简单留给用户!

边界思维的重点在于“约束”,是一个“负方法”思维方式。什么意思呢?比如要看一个开源软件的功能,要看的不是它能做什么,而是它不能做什么!“不能做什么”决定了系统的边界或极限。

系统化思维

与边界思维相对应的就是系统化思维

几个体现

  1. 哲学中有一句话:事物之间的普遍联系。通俗的说法就是:不能头痛医头,脚痛医脚。
  2. 系统化思维的另一个体现,就是刨根问底。对于问题追索到最后,直至事物的本质。这点在物理学上叫“第一性原理”,在哲学上叫“道”,这个倒追的过程会让你探索到事物与事物之间的普遍联系。
  3. 笔者曾经看过一个产品总监的ppt,有一张图:最顶层是日活,然后分解为拉新和留存,拉新、留存继续分解,直到日常程序猿接到的一个个需求。这就是系统性思维。很多产品,在做具体的事情的时候,脑子里只有那个具体的事情,没有这张图,最后就被琐事牵着走了。

得力干将多是有“体系”的人系统化思维,理顺元素与元素之间的关系,避免“头痛医头”,“脚痛医脚”;看见变化的形态,而不是转瞬即逝的一幕;是要以一种结构“长”在脑子里,并且会随着环境的变化,不断地生长迭代。高瓴资本运营合伙人干嘉伟也曾在混沌大学研习社的课程里分享说,自己辨识优秀人的方法:一个是见过好体系,一个是建过好体系

怎样避免“螺丝钉”或者线性思维的惯性呢?阿里的一个手段就是轮岗,甚至是干的越出色越要轮掉你,以此培养员工的系统思维能力。据称,在马云看来,“没有换过5个老板的人不算在阿里巴巴工作过”。

「系统是一个连续变化的东西,或者是一项技能,或者是一个关系。为了这个系统,你可以做各种项目,你可以要求自己养成什么习惯,你要的不是某个具体事件的成败,而是发展这个系统」。

没有的后果

你觉得一个事情很复杂,一定是你理解的不够透彻。

见招拆招,就意味着你对事情是被动应对,而不是主动把控。

缺乏「系统思维」的人,总是从此时此刻,去衡量一件事情到底有没有价值,不懂得把这件事情,放在人生大系统中去衡量。

有的好处

对于同一件事,你能从中参悟到什么,理解到什么程度,是一个管理者是否可以持续提高的关键所在。所在作为一个管理者,至少留给自己 20% 的时间在思考,而不是具体做事情,你要不断的反思自己的决策、沟通、影响、开放当中的问题, 是否可以有更好的方法来提高。一个人能做到什么样规模的高级管理者,和他对于自己、对于业务、对于管理甚至对于世界的参悟程度有关系,最终管理的瓶颈是对于自己对于世界的认知瓶颈,而不是技能瓶颈。

学习这个东西,没有什么捷径。而且往往是需要先明白更多抽象的相对比较难的东西之后,学习简单的东西就只是一个查文档的过程。所谓的学习,知识只是一部分,理解知识是如何被抽象和提炼的过程,才是更重要的。很不幸没什么人愿意做。 认知 ==> 抽象 ==> 指导实践,循环往复。

分层,大幅度降低认知复杂度 认知的几点规律

笔者最近的学习习惯是

  1. 看一篇文章,先画一个脑图,梳理一个结构
  2. 如果碰到一个新内容,不知道放到这个结构的哪里去,就说明结构梳理的不合理,再换一个结构
  3. 有了一个合理的结构,看文章不是作者说什么我看什么,而是作者说什么,我放到我的结构里去。最终提炼的结构 + 细节,就是一个有层次的知识体系。

结构化思维

一切都有套路

华为离职副总徐家骏给任正非的辞职信,振聋发聩!

很多事情知易行难,关键是要有行动,特别是管理类的一些理论、方法、观念。空谈、空规划一点用处都没有,不如实际把它做出来,做出来后不断反思改进,实实在在最有说服力。没有实践中的反复演练和反思,即使是人人皆知的东西要做好都其实不容易。

举个小例子,比如做管理者要会倾听,我想华为99.9%的管理者都很懂这一点,但实际做的如何呢?华为有多少管理者做到了不打断别人讲话?不急于下结论给定义?不急于提供解决方案?有多少管理者能够做到自然地引导对方表达?问问对方感受?确认自己明白对方?

西方公司职业化的专家,做任何事情都有方法论、有套路,甚至于如何开一个会都有很多套路,后来我对这些套路的研究有了兴趣,自己总结出了不少套路并给部门的骨干培训和讨论。在一个复杂的环境下,很多问题已经不能就事论事来研究和解决,非常需要系统性的方法和战略性的眼光

We can‘t solve problems by using the same kind of thinking we used when we created them.

工程师思维——产品、技术和工程

优秀工程师必备的三大思维,你拥有哪些?

  1. 专人专岗的协作模式在进一步改善团队的协作效能时所面临的最大挑战在于“岗位墙”,即岗位间衔接不可避免会出现一些模糊地带,而这些模糊地带又很容易相互忽视,导致失去关注而很大程度地拉低了团队效能。比如,开发工程师会认为保证质量是测试工程师单方面的职责,一些可做可不做的事儿留给别人做。
  2. 工程师思维分解为产品、技术和工程三大思维。了解工程师思维的价值在于,工程师个体需要在工作中逐步建立起产品、技术和工程三大思维,以便用更为全面的视角去看待日常工作中所面临的困境和困惑
  3. 良好的用户体验一定是站在用户的角度,基于用户心智来塑造概念,由于概念存在理解和解释成本,所以塑造的概念应足够轻、少且易掌握。好的产品体现于“易用”二字,其极致在于迎合用户的本能反应并符合各种生活或专业常识(也就是系统设计可以分层实现,但给用户呈现的一定是最简单的概念,没有自己的加工与提炼)。为了产品更好地演进,需要通过数据闭环的形式去检验创造用户价值的效果,让产品的开发、运营、营销工作做到有的放矢。不仅能让整个产品大团队聚焦于核心价值,还能帮助团队在探索用户价值的道路上理性地做减法。大多情形下,做减法远难于做加法。
  4. 不少工程师这里会有一个误区,忘记了敏捷思想所倡导的“项目计划的目的是为了适应变化”,而是将“按时交付”当作是天职,各种赶工爬到终点时却毫不意外地看到了“一地鸡毛”的景象。
  5. 工程思维的起点是流程。流程的背后是科学,以既定的步骤、阶段性的输入/输出去完成价值创造,通过过程控制确保最终结果让人满意。由于流程涉及每一个工程师的工作质量与效率,其含义不只在于定义、工具化、检查等内容,而是应基于工程师的日常工作习惯,将流程与工程师的工作环境无缝整合。“无缝”体现于流程中的概念与工程师群体已建立的专业常识相一致、没有增加毫无价值的负担,根本仍是确保易用性。
  6. 机制的含义是通过对所需解决问题的分析,以一种模式去解决同类问题。机制应体现一定的系统性,而非“头痛治头,脚痛治脚”。系统性不是一开始就能被洞察到,可能在演进的过程中逐步发现和完善的,因而需要工程师在工作的过程中不时回顾并付诸实践去落实。对于工程师来说,机制是通过系统性的软件设计去达成的。

工程:

  1. 可演进式架构
  2. 可维护的代码
  3. 更好的工程实践

很多事是没有边界的,唯一麻烦的在于角色的转变——你可能没有意识到现在的位置,它需要你去做什么,而不是抗拒他

如若只是每天完成工作上的代码,怕也不算是投入。所谓的才华,大抵便是悟性。而悟性这种东西,往往不是练出来的,更可能是看出来的,或者对话出来的。

事务与工程:什么是工程师文化?什么才是真正的工程师文化?从浅层的意义来说,工程师就是要实现业务的自动化。DON’T REPEAT YOURSELF ! 某件重复发生的事情只干一次就好,以后也不需要再重复做。工程师的自动化思维,所体现的内在逻辑是如何把问题 Close,如何把问题彻底解决掉,而编码只是一种工具。在我们日常生活中,很多问题不需要编码来解决,但是确实需要用 “彻底解决它” 的思维去完成。这种思维不仅限于工程师,同样适用于所有人。

很多人会习惯呆在自己的舒适区,习惯于做任务,每天重复相同的作业,这就不符合我们所说的 “工程师文化”。我们需要达到的状态是,今天干完一件事,明天开启新的事。怎么判断自己在做新的事情?那就要看我们问题是否解决得够彻底。从另一个维度看,工程师这种把问题 Close,彻底解决掉的思维,看重的是自己工作内容的长期价值。如果我们只是在做事务,如果我们并没有在实质性解决一个问题,那么这件事情的长期价值就是零。每个人都应该秉承工程师精神,把一个个问题 Close,让它不要再发生。不需要显得很忙,忙不代表成就,真正的工程师文化应该是推动整个团队往前走,每个团队成员都在成长。

少就是指数级的多!

极端地说,当你指望一个软件 24 小时不间断服务时,在某种程度上来说每一行代码都是负担。所以 SRE 需要推崇的实践是保证所有的代码行都有必须存在的目的。

知乎破8万赞回答:那些厉害的人,思维方式比你强在哪儿?

NLP理解层次:对一件事情的理解,我们可以分成6个不同的层次,而这个层次是有高低之分的。如果你用低维度的视角去看这个问题的时候,感觉它无法解决。但当你站在更高的一个维度去看它,也许就变成了一个很简单的问题,甚至连问题本身也消失了。

  碰到问题时归因 表现 解决方式 备注
环境 环境不好 抱怨 换环境,比如跳槽、换男/女朋友等  
行为 因为我的努力还不够 更努力xx 看看还有什么事情是可以去做,去改变的?  
能力 因为我的能力不足 请教、报班等 把学习到的知识,转化为可操作的方法,进而改善效率,解决问题 「能力」这个理解层次,是我们「意识」能想到的最高层次了。有什么问题「能力」也解决不了的呢?选择错了问题
BVR     系统的分析变化的原因、关键因素,进而找到自己的切入点 B(Believe):信念,你相信什么是对的?
V(Value):价值观,你认为A和B哪个更重要?
R(Rule):规条,做人做事的原则
「能力」层是让你把事情做对,而「BVR」层则是帮你选择做对的事情
身份 “你是谁?你想成为一个怎么样的人?” 我一定要当老板么?是否可以只是辅助性角色?   每个角色或者身份,都对应着一套帮助他「能够更好的成为这个身份」的BVR体系
精神   乔布斯:活着就为改变世界    

店内的生意不好,是团队管理的问题?营销方式的问题?还是商业模式的问题?一旦选择错了问题,你那优秀的「能力」和「行动力」只会让你越走越远。

规条存在的意义,就是帮助你更高效的做出选择,不用每次都思考、讨论、互相权衡比较…

从自己理想的「精神层次 / 身份层次」发展出来的人生规划,可能会与你的现实生活有很大的不同,将更具挑战性,但却能让你身心统一,因而能激发出你更强大的潜能!PS:笔者个人的一些体会是,很多事你可能不愿意干,但当你发现这是实现某一个目标的必经之路时,心态会平和很多,进而比逆来顺受状态做的更好。关键是:你有一个目标,并且认为自己必须要实现那一个目标,并准备做牺牲。

用户体验要素五层次

用户体验与结婚教练

一个没有建立思考框架的普通人,面对一个人,一个产品当然也会有自己的原生感受。但是因为没有经过专业训练,所以感受是混沌纠结的,并且会过于强化和放大自己关注的某个点,不但有强烈认知偏差和情绪偏差,还有大面积的认知盲点和思维遮蔽。而产品经理则是有个框架体系来看一个产品的体验,不管你的第一直觉是喜欢还是不喜欢,都应该用这套框架,相对完整地量度一下对方,强迫自己建立完整观察。

存在感之于人,就像生存之于动物一样,是触发情绪,推动行动的开关。 一个人为什么奔波,焦躁,不安,机关算尽,上蹿下跳?因为还没有被满足。 所以,你看到一个人焦虑、痛苦、不满、烦躁,别给TA讲大道理。而是要看到,TA到底是什么,没得到满足。这种像饥饿的猛虎一样灼烧的内心,不是一句大道理或者鸡汤话可以安慰的。 像动物在奔波厮打中强健了自己的肌肉一样,一个人会为了自己的存在感的左冲右突的挣扎奋进里,扩充自己的能力圈。他的存在感被满足了,能力圈就不会在扩充了。就好像好多女人结婚了就不化妆了一样,男人满足了就不奋斗了一样。

有一种人,他的存在感设定就是为了凸显自己牛逼。他做的所有事都是为了这件事的机会最大化,这个场域我最牛逼。不行我就撤,换个地方再打。我个人而言,可能我会更喜欢对自己为什么而存在的认知比较恒定的人。

其它

读书在当今的时代真的是一项能力,一本书看完,作者想表达的观点到底是什么,如何与你的生活与实际进行结合,书中的知识怎么和你的存量知识进行连接,这是一个需要长期锻炼的能力。

今天,要聊的是学习方法,大家平时是不是都是通过以下途径来学习技术的?

  1. 看英文官网?头疼!
  2. 通过项目学习?不系统!
  3. Google搜索?同一个知识点,各处不一样!
  4. 买书看?啃不下去!

我这些年的建议是:找到目标领域的专家,学习他们系统化的总结。 《Spark性能调优实战》学习的本质是一个不断做熵减、消除不确定性的过程,不同的方法对熵减的贡献有所不同,交流讨论对于熵减的贡献是指数级的,理论学习和动手实践对于熵减的贡献都是线性而平缓的。

两个人互相审视,一定会发现一个盲点,即你身上的问题我知道,而你不自知。

有意识地进入某一个圈子,找到能听懂你说话的人,大家经常一起切磋交流,共同成长。恰当的时机可以采用协作的方式,因为这样可以推动你的成果提升到一个新档次。

无论胜负,只有战斗才会让你变强,退一步想,很多时候,也许,填坑力,真的就是你最了不起的才华,因为,当下的不确定性太多了,所有正确的意见,要经过许多等待、迂回才能取得胜利,为大家所接受。这个过程中,什么是最重要的呢?就是在坎坷的行进过程中,不断地收集正向反馈循环,不断地积累,比如个人信用、心理能量、有意义的人际关系(我深深地关心对方,对方也深深地关心我)等等,最终实现厚积薄发。