自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(2406)
  • 资源 (1)
  • 收藏
  • 关注

原创 你不是 leader,怎么推动事情走下去?

你不是指挥官,但你是facilitator —— 促动者,让人听你不是因为你大,而是你有组织力。有时候你不说话,事情就真没人记得了。不是你说了算,但你提的方案有道理,大家就会照你说的做。为了不耽误进度,我先拟了一个初步下一步,欢迎补充修改。不是甩锅,而是聪明地引入该出现的人,顺带洗清责任。提前提醒一下,如果要推进,可能需要领导的决策。你作为这方面的专家,是不是可以牵头一下这块?这边我草拟了一个初步方案,欢迎大家补充建议。我只是想帮大家对齐一下,方便推进下一步。我把这个加进我们的进度表,方便持续关注。

2025-06-26 00:16:36 573

转载 服务端高并发分布式架构演进之路

1. 概述本文以淘宝作为例子,介绍从一百个到千万级并发情况下服务端的架构的演进过程,同时列举出每个演进阶段会遇到的相关技术,让大家对架构的演进有一个整体的认知,文章最后汇总了一些架构设计的原则。特别说明:本文以淘宝为例仅仅是为了便于说明演进过程可能遇到的问题,并非是淘宝真正的技术演进路径2. 基本概念在介绍架构之前,为了避免部分读者对架构设计中的一些概念不了解,下面对几个最基础的概念进行介绍:分布式 系统中的多个模块在不同服务器上部署,即可称为分布式系统,如Tomcat和数据库分别部署

2021-05-25 17:47:54 471

转载 警惕软件复杂度困局

简介:对于大型的软件系统如互联网分布式应用或企业级软件,为何我们常常会陷入复杂度陷阱?如何识别复杂度增长的因素?在代码开发以及演进的过程中需要遵循哪些原则?本文将分享阿里研究员谷朴关于软件复杂度的思考:什么是复杂度、复杂度是如何产生的以及解决的思路。较长,同学们可收藏后再看。写在前面软件设计和实现的本质是工程师相互通过“写作”来交流一些包含丰富细节的抽象概念并且不断迭代过程。另外,如果你的代码生存期一般不超过6个月,本文用处不大。一 软件架构的核心挑战是快速增长的复杂性越是...

2021-05-19 18:17:58 680

转载 常见代码重构技巧,非常实用

关于重构为什么要重构项目在不断演进过程中,代码不停地在堆砌。如果没有人为代码的质量负责,代码总是会往越来越混乱的方向演进。当混乱到一定程度之后,量变引起质变,项目的维护成本已经高过重新开发一套新代码的成本,想要再去重构,已经没有人能做到了。造成这样的原因往往有以下几点:编码之前缺乏有效的设计 成本上的考虑,在原功能堆砌式编程 缺乏有效代码质量监督机制对于此类问题,业界已有有很好的解决思路:通过持续不断的重构将代码中的“坏味道”清除掉。什么是重构重构一书的作者Martin..

2021-05-13 10:01:52 1096

转载 JAVA线上故障排查全套路

线上故障主要会包括cpu、磁盘、内存以及网络问题,而大多数故障可能会包含不止一个层面的问题,所以进行排查时候尽量四个方面依次排查一遍。同时例如jstack、jmap等工具也是不囿于一个方面的问题的,基本上出问题就是df、free、top 三连,然后依次jstack、jmap伺候,具体问题具体分析即可。一、CPU一般来讲我们首先会排查cpu方面的问题。cpu异常往往还是比较好定位的。原因包括业务逻辑问题(死循环)、频繁gc以及上下文切换过多。而最常见的往往是业务逻辑(或者框架逻辑)导致的,可以使用js

2020-09-22 17:45:24 484

转载 图解+代码|常见限流算法以及限流在单机分布式场景下的思考

大家好,我是 yes。今天来说说限流的相关内容,包括常见的限流算法、单机限流场景、分布式限流场景以及一些常见限流组件。当然在介绍限流算法和具体场景之前我们先得明确什么是限流,为什么要限流?。任何技术都要搞清它的来源,技术的产生来自痛点,明确痛点我们才能抓住关键对症下药。限流是什么?首先来解释下什么是限流?在日常生活中限流很常见,例如去有些景区玩,每天售卖的门票数是有限的,例如 2000 张,即每天最多只有 2000 个人能进去游玩。题外话:我之前看到个新闻,最不想卖门票的景区“

2020-09-22 13:06:08 593

转载 springboot实现定时任务,异步操作,统一结果返回,全局异常处理,拦截器及事务处理

本文都是springboot的常用和实用功能,话不多说开始吧定时任务1.启动类开启注解@EnableScheduling //开启基于注解的定时任务@MapperScan("com.pdzx.dao")@SpringBootApplicationpublic class VideoApplication { public static void main(String[] args) { SpringApplication.run(VideoApplicatio

2020-08-26 20:22:41 1998

原创 聊聊微服务架构及分布式事务解决方案

分布式事务场景如何设计系统架构及解决数据一致性问题,个人理解最终方案把握以下原则就可以了,那就是:大事务=小事务(原子事务)+异步(消息通知),解决分布式事务的最好办法其实就是不考虑分布式事务,将一个大的业务进行拆分,整个大的业务流程,转化成若干个小的业务流程,然后通过设计补偿流程从而考虑最终一致性。什么是事务事务(Transaction)及其ACID属性事务是由一组SQL语句组成的逻...

2020-04-21 22:34:45 662

转载 Java线程池实现原理及其在美团业务中的实践

随着计算机行业的飞速发展,摩尔定律逐渐失效,多核CPU成为主流。使用多线程并行计算逐渐成为开发人员提升服务器性能的基本武器。J.U.C提供的线程池ThreadPoolExecutor类,帮助开发人员管理线程并方便地执行并行任务。了解并合理使用线程池,是一个开发人员必修的基本功。本文开篇简述线程池概念和用途,接着结合线程池的源码,帮助读者领略线程池的设计思路,最后回归实践,通过案例讲述使用线程...

2020-04-03 14:58:43 715

转载 Synchronized 和 Lock 锁在JVM中的实现原理以及代码解析

一、深入JVM锁机制:synchronizedsynrhronized关键字简洁、清晰、语义明确,因此即使有了Lock接口,使用的还是非常广泛。其应用层的语义是可以把任何一个非null对象作为"锁",当synchronized作用在方法上时,锁住的便是对象实例(this);当作用在静态方法时锁住的便是对象对应的Class实例,因为Class数据存在于永久带,因此静态方法锁相当于该类的一个全局锁...

2020-04-01 16:00:25 595

转载 一文带你理解Java中Lock的实现原理

当多个线程需要访问某个公共资源的时候,我们知道需要通过加锁来保证资源的访问不会出问题。java提供了两种方式来加锁,一种是关键字:synchronized,一种是concurrent包下的lock锁。synchronized是java底层支持的,而concurrent包则是jdk实现。关于synchronized的原理可以阅读再有人问你synchronized是什么,就把这篇文章发给他。在这里...

2020-04-01 15:04:40 939

转载 业务复杂=if else?刚来的大神竟然用策略 工厂彻底干掉了他们!

对于业务开发来说,业务逻辑的复杂是必然的,随着业务发展,需求只会越来越复杂,为了考虑到各种各样的情况,代码中不可避免的会出现很多if-else。一旦代码中if-else过多,就会大大的影响其可读性和可维护性。首先可读性,不言而喻,过多的if-else代码和嵌套,会使阅读代码的人很难理解到底是什么意思。尤其是那些没有注释的代码。其次是可维护性,因为if-else特别多,想要新加一个分...

2019-10-24 13:41:06 901

原创 MySQL分库分表 VS 分布式数据库

优化需按 “从简单到复杂” 的顺序推进:先通过表结构 + 索引 + 查询优化解决大部分问题;若数据量仍增长,再考虑分表分库 + 读写分离;最后结合配置与硬件提升基础性能。核心是结合业务场景(如查询频率、数据增长速度、读写比例)选择合适方案,避免过度优化。分库分表的核心问题本质是 “分布式环境下的一致性、复杂性与可用性平衡”。是否采用需结合业务场景:若单表数据量未达瓶颈(如千万级以下),优先通过索引、SQL 优化等简单方案解决;

2025-09-07 01:35:49 667

原创 常用分布式数据库介绍与对比(五)

Elasticsearch 是 “全文检索的专家”,而非 “BI 分析的能手”—— 它可以勉强支撑简单的统计场景,但无法满足核心 BI 报表的 “复杂聚合、精确性、多表关联” 需求。若将 ES 作为核心 BI 报表的底层数据库,会面临 “性能差、成本高、数据不准” 的问题,最终导致业务体验下降。ES 存储的半结构化数据,本质是 “有基础结构但不严格固定、以键值对形式组织、需近实时检索与统计” 的数据,典型代表包括日志、用户行为埋点、文档元数据、IoT 设备数据。

2025-09-07 00:31:59 941

原创 常用分布式数据库介绍与对比(四)

适合的情况:更新以 “单文档” 为单位、分片键可均匀分布压力、对一致性要求为 “最终一致”(如用户状态、IoT 设备、非秒杀库存);不适合的情况:需 “多文档原子更新”(如金融转账)、强一致性要求(如秒杀)、存在明显热点分片(如热门商品集中更新);替代方案:若场景不适合 MongoDB,可选择支持 “分布式事务 + 强一致” 的数据库,如 TiDB、OceanBase(OLTP 数据库,适合高并发强一致更新)。

2025-09-07 00:13:49 715

转载 微服务拆错一步,项目直接崩!资深架构师这样避坑

想象一个场景:周五下午5点,你正准备下班,突然收到监控告警——整个系统崩了!排查半天发现,仅仅因为用户服务的一个小改动,连带把订单、支付、库存全部搞崩溃。为啥当初要拆微服务?单体架构它不香吗?2025年,随着人工智能技术的爆发式增长和云原生技术的深化应用,微服务架构作为企业数字化转型的核心技术底座,正经历着前所未有的变革。但是,微服务绝不是拿着锯子就开始乱切的游戏。一步走错,整个项目可能就要“重新做人”。今天咱们就来聊聊,那些年架构师们在微服务拆分路上踩过的坑,以及如何优雅地绕过这些“地雷”。

2025-09-06 23:14:40 26

转载 Spring Batch 批处理让效率飙升 500%

经过实战验证,Spring Batch 绝对是企业级批处理的「神器」。它不仅能大幅提升开发效率和系统性能,还能降低维护成本和故障风险。无论是数据迁移、报表生成,还是日志分析、金融对账,Spring Batch 都能轻松应对。如果你还在为批处理任务头疼,不妨试试 Spring Batch。相信我,学会它之后,你会发现批处理原来可以这么简单、这么高效!

2025-09-06 23:11:14 15

转载 Spring Batch 批处理让效率飙升 100 倍

在批处理的江湖中,并非一枝独秀,还有许多其他优秀的框架。是大数据领域的先驱,它采用 “分而治之” 的思想,将大规模数据处理任务分解为 Map 和 Reduce 两个阶段。在 Map 阶段,数据被分割成多个小块,每个小块由一个 Map 任务独立处理,生成一系列的键值对。例如,在处理海量文本数据统计单词出现次数的场景中,Map 任务会将每一行文本拆分成单词,并为每个单词生成一个键值对,其中键是单词,值是 1。在 Reduce 阶段,具有相同键的键值对会被聚合在一起进行处理,得到最终的结果。

2025-09-06 22:55:55 23

原创 常用分布式数据库介绍与对比(三)

MongoDB 是全球最流行的开源文档型 NoSQL 数据库,由 MongoDB Inc. 开发维护,核心设计理念是 “摆脱结构化表结构束缚,支持灵活扩展的 JSON-like 文档存储”,主打 “高并发读写、分布式弹性扩展”,适配非结构化 / 半结构化数据的存储需求。核心能力灵活文档模型:存储 BSON(二进制 JSON)格式数据,字段可动态新增 / 删除(无需预先定义表结构),例如电商商品可按需添加 “颜色”“尺码”“重量” 等非固定属性;

2025-09-03 01:56:13 801

原创 常用分布式数据库介绍与对比(二)

Apache Doris 是一款轻量级 MPP 架构的开源 OLAP 数据库,由百度主导开源并捐献给 Apache 基金会,核心设计理念是 “简单易用、高性能、低运维”,专为中小团队快速搭建分析平台而生。核心能力兼容性强:100% 兼容 MySQL 协议,支持用 MySQL 客户端 / BI 工具(Tableau、PowerBI)直接连接,无需学习新语法;预聚合优化:支持 “Rollup 表”(预计算高频聚合结果)和 “物化视图”,将亿级数据的聚合查询从 “秒级” 压缩到 “毫秒级”;

2025-09-03 01:20:00 825

原创 常用分布式数据库介绍与对比(一)

OLTP(在线事务处理)的核心需求是高并发、强一致性、高可用、低延迟,需支撑金融转账、电商下单、用户账户操作等 “零误差” 事务场景。TiDB、OceanBase、CockroachDB 均为分布式 OLTP 领域的标杆产品,但技术出身、核心定位和优化方向存在显著差异。优先选 TiDB:若团队熟悉 MySQL、需要开源方案、业务有 “事务 + 简单分析” 混合需求(如互联网订单 + 实时统计),且预算有限;优先选 OceanBase。

2025-09-03 01:09:58 866

原创 有关算法的思考(三)

解决确定性问题:不依赖数据训练,而是通过明确的逻辑规则,保证结果的准确性(如哈希表的键值查询、二分查找的定位);支撑系统性能:是 “高并发、大数据量” 场景的性能瓶颈解决方案(如 B + 树优化数据库查询、KMP 算法加速文本匹配);降低开发成本:大部分编程语言(如 Java、Python)的标准库已内置这些算法(如 Java 的TreeMap基于红黑树,基于二分查找),无需重复开发。

2025-09-01 02:47:45 671

原创 有关算法的思考(二)

先看数据类型结构化数据(表格数据:日期、销量、金额)→ 优先传统 ML;非结构化数据(图片、文本、音频)→ 必须 DL。再看数据量小数据(几百 / 几千条)→ 传统 ML(DL 会过拟合);大数据(几万 / 几十万条)→ 若场景复杂(如语义理解),选 DL;若场景简单(如排序),仍可选传统 ML。最后看业务需求需可解释性(金融、医疗)→ 传统 ML;需处理复杂模式(图像、语音)→ DL;需低成本快落地(中小企业)→ 传统 ML;需攻坚技术难点(如 AGI)→ DL。

2025-09-01 02:10:00 518

原创 有关算法的思考(一)

匹配问题场景:如有序数据用二分查找,无序数据用线性查找;图的最短路径根据是否有负权边选 Dijkstra 或 Bellman-Ford。权衡效率与复杂度:如小规模数据用冒泡排序(实现简单),大规模数据用快速排序(效率高);DP 算法提升效率但需额外存储空间。结合数据特性:如高维数据用 SVM,时序数据用 RNN,图结构数据用 DFS/BFS。掌握这些典型算法,不仅能解决实际工程问题,也是理解人工智能、大数据技术的基础。特定领域场景算法在之前分类的基础上,还有一些重要算法分布在特定领域场景。

2025-08-31 03:51:54 1138

原创 企业架构框架TOGAF中的4A架构

软件开发中的 “4A 架构” 需结合具体场景理解:若聚焦 “架构设计的维度拆解”,多指向业务、应用、数据、技术架构;若侧重 “架构质量的目标衡量”,则常指可用性、可维护性、可扩展性、可集成性。两种解读均围绕 “让系统更贴合业务、更稳定高效” 的核心,只是视角不同。如果有更具体的场景(如企业级系统设计、架构评估等),可以进一步细化说明哦!简单说,业务架构是 “业务的骨架”,定义业务的 “是什么、为什么”;应用架构是 “支撑业务的技术骨架”,定义系统的 “用什么、如何做”。

2025-08-28 19:01:38 675

转载 RETE算法简述 & 实践

Rete 算法是卡内基梅隆大学的 Charles L.Forgy 博士在 1974 年发表的论文中所阐述的算法。该算法提供了专家系统的一个高效实现。Rete 在拉丁语中译为”net”(即网络)。Rete 是一种进行大量模式集合和大量对象集合间比较的高效方法,通过网络筛选的方法找出所有匹配各个模式的对象和规则。其核心思想是用分离的匹配项构造匹配网络,同时缓存中间结果。以空间换时间。规则编译(rule compilation)和运行时执行(runtime execution)。

2025-08-28 18:43:57 67

原创 MySQL PostgreSQL Oracle对比(三)

简言之:Oracle 不是 “对硬件要求高”,而是 “为企业级场景设计的高可用、高性能能力,需要匹配更高规格的硬件来承载”;,但随着负载规模(并发、数据量)增长,两者的硬件需求差异会逐渐缩小,甚至在高并发、复杂查询场景下,MySQL 因架构特性可能需要更高配置才能维持性能 —— 这种差异本质是由两者的架构设计与资源管理逻辑决定的,而非绝对的 “高低” 之分。两者的硬件需求差异,本质是 “轻量架构的短期优势” 与 “高效架构的长期优势” 的对比,而非绝对的 “高低” 之分。Oracle 为保证数据安全性,

2025-08-28 04:38:05 893

原创 MySQL PostgreSQL Oracle对比(二)

它通过简化架构(单进程多线程)、限制功能(优化器、索引类型),换取了 “低配置门槛、快速部署” 的优势,适合中小规模 OLTP 场景(单表千万级、并发千级);但在 “复杂查询、高并发写入、亿级单表、特殊数据类型” 等场景中,这些简化设计成为性能瓶颈。不过,通过 “针对性优化”(如合理设计索引、调大 Buffer Pool、启用线程池、分库分表),MySQL 仍可支撑大部分互联网业务 —— 它的 “有限性” 更多是 “场景适配性” 问题,而非 “技术落后”。在。

2025-08-28 04:25:45 995

原创 MySQL PostgreSQL Oracle对比(一)

MySQL 的性能局限性,本质上是其 “轻量、开源、易用” 定位与 “企业级高性能需求” 之间的矛盾。它在简化架构、降低门槛的同时,牺牲了复杂优化、精细控制和大规模扩展能力。但这并不意味着 MySQL “性能差”—— 在中小规模场景(单表千万级、并发千级),通过合理优化(如索引设计、配置调优、分库分表),MySQL 完全能满足需求。只是在超大规模(单表亿级、并发万级)或复杂查询场景下,其设计上的固有局限会使其难以与 Oracle 等企业级数据库抗衡。

2025-08-28 04:14:08 587

原创 jvm垃圾回收器的选择

JVM GC 组合的核心是 “分代适配” 和 “场景匹配”:早期 JDK 依赖 “年轻代 + 老年代” 的固定组合(如 ParNew+CMS),而高版本 JDK(17+)更倾向于 “单 GC 整堆回收”(如 G1、分代 ZGC),简化配置的同时提升性能。企业选型时需结合 JDK 版本、堆大小、业务延迟需求,优先选择官方推荐的成熟组合(如 JDK 21 的分代 ZGC、G1),避免使用已废弃的 GC(如 CMS)。JDK 1.8 生产环境 JVM 参数设置的核心是 “场景驱动 + 监控优先。

2025-08-24 01:36:17 906

原创 抽象是什么

所以,我们大部分的时间并不是在写代码,而是在梳理需求,理清概念,当然,也包括尝试看懂那些“该死的、别人写的”代码。抽象是从众多的事物中抽取出共同的、本质性的特征,而舍弃其非本质的特征的过程。具体地说,抽象就是人们在实践的基础上,对于丰富的感性材料通过去粗取精、去伪存真、由此及彼、由表及里的加工制作,形成概念、判断、推理等思维形式,以反映事物的本质和规律的方法。实际上,抽象是与具体相对应的概念,具体是事物的多种属性的总和,因而抽象亦可理解为由具体事物的多种属性中舍弃了若干属性而固定了另一些属性的思维活动。

2025-08-19 00:12:31 246

原创 重试机制如何考量

微服务接口重试机制的核心是 “理性重试”—— 既不回避瞬时故障,也不盲目重试引发新问题。先保幂等:无幂等,不重试;精准筛选:只对瞬时故障重试,永久故障直接失败;策略合理:优先 “指数退避 + 抖动”,控制次数和间隔;联动容错:与熔断、限流、监控配合,规避重试风暴;组件落地:用 Resilience4j/Spring Retry 等成熟组件,减少手写逻辑;监控闭环:通过指标监控及时发现故障,持续优化。通过以上设计,重试机制才能真正成为微服务稳定性的 “守护者”,而非 “风险源”。

2025-08-18 21:19:46 689

原创 软件设计中的抽象思维,从封装变化开始

2年时间过去,对于抽象思维在软件设计中的运用,我又有了一些新的体会。。因为内容比较多,我会用两篇文章分别介绍。

2025-08-18 21:06:29 997

转载 跨越DDD从理论到工程落地的鸿沟

本文分享自华为云社区《》,作者:敏捷小智。。然而又因为DDD本身难以掌握,很容易造成DDD从理论到工程落地之间出现巨大的鸿沟。就像电影里面的桥段,只谈DDD理论姿势很优美,一旦工程落地就跪了......所以DDD的项目,工程落地很重要,。

2025-08-18 19:11:16 31

原创 抽象思维在软件开发中的运用

在企业级软件开发中,抽象思想是核心设计原则之一,其应用场景广泛且多层次。

2025-08-16 03:05:38 800

原创 面向对象语言的核心竞争力

面向对象语言的核心价值,不在于 “类、继承、多态” 这些语法特性本身,而在于它们共同构成了一套 **“将复杂系统拆解为可理解、可复用、可扩展的模块” 的方法论 **。这种方法论让开发者能更高效地应对大型软件的 “复杂性、迭代性、协作性” 挑战,最终实现 “代码易理解、易维护、易扩展” 的目标 —— 这也是为什么面向对象成为企业级软件开发的主流范式。

2025-08-16 01:06:15 795

原创 非内存资源和JVM 堆外内存

非内存资源(文件流、连接等)由操作系统或外部系统管理,Java 对象只是它们的 “引用者”。GC 仅负责回收对象的内存,无法知晓或执行资源的释放协议,因此必须手动调用释放方法(或利用 try-with-resources 自动释放)。否则,即使对象被回收,底层资源仍会被占用,最终导致资源泄漏。两者都不受 GC 自动管理,需手动释放,否则会导致资源泄漏。区别在于:非内存资源是操作系统级的非内存资源,堆外内存是操作系统管理的内存资源。

2025-08-16 00:35:31 755

原创 GO(C、C++、Python)语言的认识(三)

下面以一个为例,展示 Go 语言开发企业级项目的核心代码实现。该服务包含用户 CRUD、认证授权、日志、配置管理、数据库交互等企业级项目常见模块,采用分层架构(API 层、服务层、数据层)设计。

2025-08-16 00:19:49 859

原创 GO(C、C++、Python)语言的认识(二)

C++ 的设计初衷就是在 C 的基础上增加面向对象能力,因此面向对象是其主流用法,尤其在中大型项目中;但它并不排斥面向过程,而是允许开发者根据实际需求灵活选择,实现 “混合编程”。Python 不是 “纯面向对象语言”(如 Java 要求所有代码必须在类中),也不是 “纯过程语言”,而是以面向对象为核心、同时兼容面向过程的多范式语言。其设计理念是 “灵活实用”—— 开发者可根据任务复杂度选择合适的编程风格,这也是 Python 能广泛应用于脚本开发、Web 开发、数据分析、AI 等领域的重要原因。

2025-08-15 20:36:37 667

原创 GO(C、C++、Python)语言的认识(一)

结构体用于封装数据(字段),相当于类中的成员变量。// 定义一个 Person 结构体,包含 Name 和 Age 两个字段Name string // 姓名Age int // 年龄结构体(struct)相当于 “类” 的属性定义,用于存储数据。方法(通过接收器绑定到结构体)相当于 “类” 的方法,用于定义行为。指针接收器用于修改结构体实例的数据,值接收器用于只读操作。这种方式虽然没有 “类” 的关键字,但能实现类的核心功能(封装、数据与行为绑定)。Go 没有传统的 “继承”,但通过。

2025-08-15 19:07:02 994

Java8 新特性.rar

Java8新特性,包含代码实例与技术文档。

2020-03-29

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除