自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+

吃透Java

关注移动互联网

  • 博客(212)
  • 资源 (2)
  • 收藏
  • 关注

原创 吃透Redis(十一):Redis原子性的保证

Redis server 一旦和一个客户端建立连接后,就会在事件驱动框架中注册可读事件,这就对应了客户端的命令请求。而对于整个命令处理的过程来说,我认为主要可以分成四个阶段

2023-02-07 20:05:57 2392 1

原创 吃透Redis(十):Redis网络框架

很多人认为 Redis 是单线程,这个描述是不准确的。准确来说 Redis 只有在处理「客户端请求」时,是单线程的。但整个 Redis Server 并不是单线程的,还有后台线程在辅助处理一些工作。Redis 还启动了 3 个线程来执行文件关闭、AOF 同步写和惰性删除等操作。

2023-02-03 09:42:49 410

原创 吃透Redis(九):缓存淘汰篇-LFU算法

Redis 在 4.0 版本后,还引入了 LFU 算法,也就是最不频繁使用(Least Frequently Used,LFU)算法。LFU 算法在进行数据淘汰时,会把最不频繁访问的数据淘汰掉。而 LRU 算法是把最近最少使用的数据淘汰掉,看起来也是淘汰不频繁访问的数据。那么,LFU 算法和 LRU 算法的区别到底有哪些呢?我们在实际场景中,需要使用 LFU 算法吗?

2022-09-07 22:24:32 3006

原创 吃透Redis(八):缓存淘汰篇-LRU算法

近似 LRU 算法并没有使用耗时耗空间的链表,而是使用了固定大小的待淘汰数据集合,每次随机选择一些 key 加入待淘汰数据集合中。最后,再按照待淘汰集合中 key 的空闲时间长度,删除空闲时间最长的 key。这样一来,Redis 就近似实现了 LRU 算法的效果了...

2022-08-16 17:43:22 2358 1

原创 吃透Redis(七):网络框架篇-redis 6.0 IO多线程原子性保证

Redis的主线程处理客户端连接操作Redis的IO线程处理客户端的读、写操作Redis IO线程处理时,Redis主线程处理部分连接完毕后需要等待IO线程处理读写完成。

2022-08-10 21:31:03 745

原创 吃透Redis(六):网络框架篇-redis框架源码

很多人认为 Redis 是单线程,这个描述是不准确的。准确来说 Redis 只有在处理「客户端请求」时,是单线程的。但整个 Redis Server 并不是单线程的,还有后台线程在辅助处理一些工作。Redis 还启动了 3 个线程来执行文件关闭、AOF 同步写和惰性删除等操作。...

2022-08-07 21:34:25 424

原创 吃透Redis(五):网络框架篇-reactor模型

Redis 是由 C 语言实现的,它采用的正是「单 Reactor 单进程」的方案,因为 Redis 业务处理主要是在内存中完成,操作的速度是很快的,性能瓶颈不在 CPU 上,所以 Redis 对于命令的处理是单进程的方案。......

2022-08-06 20:08:50 1018

原创 吃透Redis(四):网络框架篇-多路复用器

主要介绍了Redis网络通信依赖的操作系统底层机制,也就是IO多路复用机制。由于Redis是单线程程序,如果使用基本的Socket编程模型的话,只能对一个监听套接字或一个已连接套接字进行监听。而当Redis实例面临很多并发的客户端时,这种处理方式的效率就会很低。所以,和基本的Socket通信相比,使用IO多路复用机制,就可以一次性获得就绪的多个套接字,从而避免了逐个检测套接字的开销。单线程服务器模型,面临的最大的问题就是,一个线程如何处理多个客户端请求?https。...

2022-08-01 17:48:02 486

原创 吃透Redis(三):数据结构篇-skiplist、quicklist、listpack

跳表是一个多层的有序链表,在跳表中进行查询操作时,查询代码可以从最高层开始查询。层数越高,结点数越少,同时高层结点的跨度会比较大。因此,在高层查询结点时,查询一个结点可能就已经查到了链表的中间位置了。这样一来,跳表就会先查高层,如果高层直接查到了等于待查元素的结点,那么就可以直接返回。如果查到第一个大于待查元素的结点后,就转向下一层查询。下层上的结点数多于上层,所以这样可以在更多的结点中进一步查找待查元素是否存在。Redis的ZSet为什么用skiplist而不用平衡二叉树实现?https。......

2022-07-27 11:01:48 1067

原创 吃透Redis(二):数据结构篇-内存优化的数据结构设计

降低内存开销,对于Redis这样的内存数据库来说非常重要,Redis用于优化内存使用效率的两种方法内存优化的数据结构设计和节省内存的共享数据访问。

2022-07-24 22:35:43 873 1

原创 吃透Redis(一):数据结构篇-全局Hash表

通过源码分析Redis的全局Hash表,dictEntry源码,RedisObject源码,SDS、Hash表扩容、渐进式reHash等原理

2022-07-15 15:47:28 2162 2

原创 吃透MySQL(十四):主从延时问题

mysql的主从复制都是单线程的操作,主库对所有DDL和DML产生的日志写进binlog,由于binlog是顺序写,所以效率很高,slave的sql thread线程将主库的DDL和DML操作事件在slave中重放。DML和DDL的IO操作是随机的,不是顺序,所以成本要高很多,另一方面,由于sql thread也是单线程的,当主库的并发较高时,产生的DML数量超过slave的SQL thread所能处理的速度,或者当slave中有大型query语句产生了锁等待,那么延时就产生了。所谓的主备延迟就是同一个事务

2022-07-04 09:48:23 205

原创 吃透Kafka七:Producer NIO 网络模型

主要讲述以下两个问题:Producer 的大概网络模型,与 Java NIO 模型之间关系;Producer 整体流程及其整体流程详解。Producer 的网络模型KafkaProducer 通过 Sender 进行相应的 IO 操作,而 Sender 又调用 NetworkClient 来进行 IO 操作,NetworkClient 底层是对 Java NIO 进行相应的封装,其网络模型如下图所示从图中可以看出,Sender 为最上层的接口,即调用层,Sender 调用 NetworkCl

2022-03-19 19:49:49 336

原创 吃透Kafka六:topic 创建过程

本文主要讲述一个 topic 的创建过程,从 topic 是如何创建到 topic 真正创建成功的中间详细过程,文章主要内容可以分为以下几个部分:1,topic 是如何创建的?命令行创建;Producer 发送数据时,自动创建;2,topic创建时,replicas 是如何分配的?指定 replicas 的分配;自动 replicas 分配;3,replicas 更新到 zk 后,底层如何创建一个 topic?创建 Partition 对象及状态更新;创建 Partition 的

2022-03-15 21:51:04 6948 1

原创 吃透Kafka五:Producer Metadata 更新机制

在上一篇文章中,已经介绍了 Producer 的发送模型,Producer dosend() 方法中的第一步,就是获取相关的 topic 的 metadata,但在上篇中并没有深入展开,因为这部分的内容比较多,所以本文单独一篇文章进行介绍,本文主要来讲述以下三个问题:metadata 内容是什么。Producer 更新 metadata 的流程。Producer 在什么情况下会去更新 metadata。Metadata 内容Metadata 信息的内容可以通过源码看明白:// 这个类被 cl

2022-03-10 21:31:05 3098

原创 吃透Netty一:普通IO

这里以文件输入输出流:FileInputStream、FileOutputStream来进行解释。由继承关系得知,这两个输入输出类继承自InputStream和OutputStream这两个基础的输入、输出的抽象类,这时我们可以看到当我们需要读写文件的时候,就需要创建两个流对象。原理图如下:由图中可以知道,OS提供了API的接口给用户程序调用,这时我们可以将API接口和OS,比喻成C/S,也即应用程序就是浏览器端或者桌面端程序,OS和API等价于服务器,也即Controller接口。public cl

2021-12-19 21:30:03 902

原创 吃透Kafka四:kafka producer源码详细分析

一,kafka producer基本使用kafka生产则代码如下: public static void main(String[] args) throws ExecutionException, InterruptedException { Properties conf = new Properties(); conf.setProperty(ProducerConfig.ACKS_CONFIG, "0"); conf.setProperty(Pr

2021-12-08 22:43:52 1968

原创 吃透Kafka三:详细分析生产和消费对消息的保障

一,kafka消息传递的三种语义At most once:最多一次,消息可能会丢失,但不会重复。At least once:最少一次,消息不会丢失,可能会重复。Exactly once:只且一次,消息不丢失不重复,只且消费一次。我们使用kafka肯定是希望Exactly once,要保证Exactly once效率上面需要做出一定的牺牲,那么是要Exactly once还是效率就要结合具体业务来分析了。但是整体的消息投递语义需要 Producer 端和 Consumer 端两者来保证。二,Pr

2021-12-03 16:58:21 1835

原创 吃透HTTP一:Http请求HttpUrlConnection,HttpClient、OKHttp详细介绍

一,HTTP概述HTTP协议是无状态的协议,即每一次请求都是互相独立的。因此它的最初实现是,每一个http请求都会打开一个tcp socket连接,当交互完毕后会关闭这个连接。HTTP协议是全双工的协议,所以建立连接与断开连接是要经过三次握手与四次挥手的。显然在这种设计中,每次发送Http请求都会消耗很多的额外资源,即连接的建立与销毁。于是,HTTP协议的也进行了发展,通过持久连接的方法来进行socket连接复用。HTTP/1.0+的Keep-Alive使用HTTP/1.0的客户端在首部中加上"C

2021-12-02 17:52:42 2342

原创 吃透Kafka二:kafka高性能之顺序IO、页缓存、零拷贝

大家都知道Kafka是将数据存储于磁盘的,而磁盘读写性能往往很差,但Kafka官方测试其数据读写速率能达到600M/s,那么为什么Kafka性能会这么高/为什么这么快呢?首先producer往broker发送消息时,采用batch的方式即批量而非一条一条的发送,这种方式可以有效降低网络IO的请求次数,提升性能。此外这些批次消息会"暂存"在缓冲池中,避免频繁的GC问题。批量发送的消息可以进行压缩并且传输的时候可以进行高效的序列化,从而减少数据大小。Kafka除了在producer发送消息方面做了很多优化,

2021-11-16 12:38:27 3821

原创 吃透Kafka一:Kafka架构剖析

一,kafka简介Kafka 是一种分布式的,基于发布 / 订阅的消息系统。主要设计目标如下:以时间复杂度为 O(1) 的方式提供消息持久化能力,即使对 TB 级以上数据也能保证常数时间复杂度的访问性能。高吞吐率。即使在非常廉价的商用机器上也能做到单机支持每秒 100K 条以上消息的传输。支持 Kafka Server 间的消息分区,及分布式消费,同时保证每个 Partition 内的消息顺序传输。同时支持离线数据处理和实时数据处理。Scale out:支持在线水平扩展。kafka的使用

2021-11-13 21:10:52 2494

原创 吃透单元测试:Spock单元测试框架的应用与实践

一,单元测试单元测试是对软件基本组成单元进行的测试,如函数或一个类的方法。程序是由函数组成的,每个函数都要健壮,这样才能保证程序的整体质量。单元测试是对软件未来的一项必不可少的投资。”具体来说,单元测试有哪些收益呢?它是最容易保证代码覆盖率达到100%的测试。可以⼤幅降低上线时的紧张指数。单元测试能更快地发现问题。单元测试的性价比最高,因为错误发现的越晚,修复它的成本就越高,而且难度呈指数式增长,所以我们要尽早地进行测试编码人员,一般也是单元测试的主要执行者,是唯一能够做到生产出无缺陷程序的人

2021-10-24 21:46:24 14300 7

原创 分布式系统架构系列讲解十(分布式一致性 10):ZAB协议

ZAB协议,全称 Zookeeper Atomic Broadcast(Zookeeper 原子广播协议)。它是专门为分布式协调服务——Zookeeper,设计的一种支持崩溃恢复和原子广播的协议。从设计上看,ZAB协议和 Raft 很类似。ZooKeeper集群中,只有一个Leader节点,其余均为Follower节点。整个ZAB协议一共定义了三个阶段:发现(Discovery)、同步(Synchronization)、广播(Broadcast)。三个阶段执行完为一个周期,在Zookeeper集群的整个

2021-06-17 10:24:50 245

原创 分布式系统架构系列讲解九(分布式一致性 9):PoW算法

谈起比特币,大家至少都应该有所耳闻吧?比特币是基于区块链实现的,而区块链运行在Internet上,这就存在有人试图作恶的情况。前面几章,我提到的口信消息解决方案和PBFT算法,虽然能防止坏人作恶,但只能防止少数,也就是 (n-1)/3 个坏人 (其中 n 为节点数)。可由于很多区块链是在公网环境,可能有坏人不断增加节点数,轻松突破 (n - 1) / 3 的限制。解决上述问题的方法就是PoW算法。PoW算法通过工作量证明(Proof of Work)增加了坏人作恶的成本,以此防止坏人作恶。本章,我就来讲

2021-06-16 09:43:36 1766 1

原创 分布式系统架构系列讲解八(分布式一致性 8):PBFT算法

Leslie Lamport在论文中提出的口信消息解决方案就属于BFT,需要考虑恶意节点的篡改、攻击等问题。但是,口信消息解决方案在现实场景中很难落地。比如,它并不关心这个共识的结果是什么,这会出现一种情况:现在适合进攻,但将军们达成的共识却是撤退。另外,实际场景中,我们往往需要就提议的一系列值(而不是单值)在拜占庭错误发生的时候,也能被达成共识。那应该怎么做呢?一种方案就是本文要讲解的PBFT算法。PBFT算法,是一种能在实际场景中落地的BFT算法,它在区块链中应用广泛。一、oral message的

2021-06-15 10:51:47 24553 14

原创 分布式系统架构系列讲解七(分布式一致性 7):Quorum NWR算法

CAP理论中的一致性一般指的是强一致性,也就是说写操作完成后,任何后续访问都能读到更新后的值。而BASE理论中的一致性指的是最终一致性,也就是说写操作完成后, 任何后续访问可能会读到旧数据,但是整个分布式系统的数据最终会达到一致。那么,如果我们的系统现在是最终一致性模型,也就是AP模型,突然有一天因为业务需要,要临时保证节点间的数据强一致性,有没有办法临时做这样的改造呢?一种办法是重新开发一套系统,但显然成本太高了。另一种办法就是本章要介绍的Quorum NWR算法。通过 Quorum NWR,我们可以

2021-06-11 09:46:26 593 3

原创 分布式系统架构系列讲解六(分布式一致性 6):Gossip协议

Gossip 协议,顾名思义,就像流言蜚语一样,利用一种随机、带有传染性的方式,将信息传播到整个网络中,并在一定时间内,使得系统内的所有节点数据一致。根据 Base 理论,如果你需要实现最终一致性,那么就可以通过 Gossip 协议实现这个目标。Gossip协议的核心一共是三块内容:直接邮寄(Direct Mail)、反熵(Anti-entropy)和谣言传播(Rumor mongering)。一、直接邮寄(Direct Mail)所谓直接邮寄,就是直接发送更新数据,当数据发送失败时,将数据缓存下来

2021-06-10 12:02:58 541 9

原创 分布式系统架构系列讲解五(分布式一致性 5):Raft算法

Raft算法在理解和实现上都要比Paxos容易得多,也是现在分布式系统开发首选的共识算法,掌握Raft算法,可以得心应手地处理绝大部分场景的容错和一致性需求,比如分布式配置系统、分布式 NoSQL 存储等等。一、角色Raft 算法是通过”一切以领导者为准“的方式,实现一系列值的共识和各节点日志的一致。Raft算法的核心就是通过 选举 来达成一致性,该算法一共涉及三种角色(状态)、两大过程(Leader Election、Log Replication)。我们先来看下Raft算法涉及的角色,在Raft算

2021-05-28 15:34:21 285 4

原创 分布式系统架构系列讲解四(分布式一致性 4):Paxos算法

Paxos算法是一种基于消息传递的,解决分布式系统共识问题的经典算法, 当前最常用的一批共识算法都是基于它改进的。比如,Fast Paxos 算法、Cheap Paxos 算法、Raft 算法等等。Paxos算法最初由Leslie Lamport提出,但是他在论文《Paxos Made Simple》(https://www.microsoft.com/en-us/research/uploads/prod/2016/12/paxos-simple-Copy.pdf)中并没有用任何数学语言对Paxos算法

2021-04-23 14:26:58 275

原创 分布式系统架构系列讲解三(分布式一致性 3):共识问题

共识问题是分布式领域最复杂的一个容错模型,只有搞懂它,你才能掌握常用的各种共识算法,才能在设计分布式系统时,根据业务场景的特点选择适合的算法。那么,什么是共识问题呢?简单的讲,共识问题就是分布式系统需要解决的一个核心问题:在一个可能发生机器宕机、网络异常、数据篡改的环境下,如何让分布式系统中的所有节点快速准确的对某个数据值达成一致,且不会破坏整个系统的一致性。Leslie Lamport曾在论文《 The Byzantine Generals Problem》(https://www.microsof

2021-04-22 12:26:58 660 2

原创 分布式系统架构系列讲解二十八(分布式ID)分布式ID详细介绍

一,为什么要使用分布式ID1,什么是分布式ID在我们业务数据量不大的时候,单库单表完全可以支撑现有业务,数据再大一点搞个MySQL主从同步读写分离也能对付。但随着数据日渐增长,主从同步也扛不住了,就需要对数据库进行分库分表,但分库分表后需要有一个唯一ID来标识一条数据,数据库的自增ID显然不能满足需求;特别一点的如订单、优惠券也都需要有唯一ID做标识。此时一个能够生成全局唯一ID的系统是非常必要的。那么这个全局唯一ID就叫分布式ID。2,分布式ID需要满足的条件全局唯一:必须保证ID是全局性唯一

2021-04-21 11:03:47 329

原创 分布式系统架构系列讲解二十七(分布式锁 7)Zookeeper实现分布式锁

一,Zookeeper实现分布式锁原理利用Zookeeper的临时有序节点可以实现分布锁,简要复习一下Zookeeper的临时有序节点:Ephemeral节点,在创建它的客户端与服务器间的 Session 结束时自动被删除。服务器重启会导致 Session 结束,因此 Ephemeral 类型的 znode 此时也会自动删除。Sequence节点,创建出的节点名在指定的名称之后带有10位10进制数的序号。多个客户端创建同一名称的节点时,都能创建成功,只是序号不同。实现原理加锁首先,在Zoo

2021-04-20 09:33:40 133 1

原创 分布式系统架构系列讲解二十六(分布式锁 6)Redisson红锁(red lock)原理源码分析

一,redlock算法Redis 官网对 redLock 算法的介绍大致如下:在分布式版本的算法里我们假设我们有N个Redis master节点,这些节点都是完全独立的,我们不用任何复制或者其他隐含的分布式协调机制。之前我们已经描述了在Redis单实例下怎么安全地获取和释放锁。我们确保将在每(N)个实例上使用此方法获取和释放锁。在我们的例子里面我们把N设成5,这是一个比较合理的设置,所以我们需要在5台机器上面或者5台虚拟机上面运行这些实例,这样保证他们不会同时都宕掉。为了取到锁,客户端应该执行以下操作:

2021-04-19 20:59:15 517

原创 分布式系统架构系列讲解二十五(分布式锁 5)Redisson加锁原理源码分析

一,Lua脚本Redisson这个框架重度依赖了Lua脚本和Netty,用Lua脚本来保证加锁和解锁的原子操作,用Netty来保证高性能。1,加锁Lua脚本脚本入参参数示例值含义KEY个数1KEY个数KEYS[1]my_first_lock_name锁名ARGV[1]60000持有锁的有效时间:毫秒ARGV[2]58c62432-bb74-4d14-8a00-9908cc8b828f:1唯一标识:获取锁时set的唯一值,实现上为redisson

2021-04-19 18:03:11 146

原创 分布式系统架构系列讲解二十四(分布式锁 4)Redisson单点,哨兵,红锁实战

Redisson是java的redis客户端之一,提供了一些api方便操作redis。Redisson为我们提供了单台Redis加锁,Redis哨兵加锁,红锁等方案。本节我们只介绍使用,至于原理和源码我们后面会详细分析,下面我们通过示例来展示一下用Redisson加锁的几种方式:一,单台Redis单点模式,也就是使用一台Redis服务来实现分布式锁。缺点也是显而易见的,无法实现高可用,万一这台设备挂了,那么将无法加锁。pom依赖 <dependency>

2021-04-16 17:47:39 416

原创 分布式系统架构系列讲解二十三(分布式锁 3)Redis单机实现

一,可靠性首先,为了确保分布式锁可用,我们至少要确保锁的实现同时满足以下四个条件:互斥性:在任意时刻,只有一个客户端能持有锁。不会发生死锁:即使有一个客户端在持有锁的期间崩溃而没有主动解锁,也能保证后续其他客户端能加锁。具有容错性:只要大部分的Redis节点正常运行,客户端就可以加锁和解锁。解铃还须系铃人:加锁和解锁必须是同一个客户端,客户端自己不能把别人加的锁给解了。二,代码实现1,组件依赖 <dependency> <groupId>

2021-04-15 18:30:58 160

原创 分布式系统架构系列讲解二十二(分布式锁 2)数据库方式实现

基于数据库的实现由两种实现方式:基于数据库表和基于数据库排他锁的方式。一,基于数据库表要实现分布式锁,最简单的方式就是直接创建一张锁表,然后通过操作该表中的数据来实现了。当我们要锁住某个方法或资源时,我们就在该表中增加一条记录,想要释放锁的时候就删除这条记录。场景模式:在网约车系统中,乘客下一条订单,然后需要司机去抢单,一个订单唯一一个ID,且唯一对应一个司机,所以我们可以这样设计数据库表。create table tbl_order_lock( order_id int unique,

2021-04-14 14:07:37 207 1

原创 分布式系统架构系列讲解二十一(分布式锁 1)分布式锁概述

一,什么是分布式锁在分布式系统中,为了防止分布式系统中的多个进程之间相互干扰,保证一个方法或属性在高并发情况下的同一时刻只能被同一个线程执行和使用,就需要一种分布式协调技术来对这些进程进行控制和调度。而分布式锁就是能够实现分布式协调调度的技术。二,为什么使用分布式锁在单机环境中Java提供了很多并发处理相关的API。比如在传统单体应用单机部署的情况下,可以使用Java并发处理相关的API(如ReentrantLock或Synchronized)进行互斥控制。但是,随着业务发展的需要,原单体单机部署的系

2021-04-13 20:43:18 186

原创 分布式系统架构系列讲解三十三(高可用 1):Master-Slave

一、引言分布式系统通常由大量异构的节点和网络组成,节点随时可能crash,网络也随时可能出现延迟、丢包、分区。相比集中式应用,分布式系统放大了出故障的概率,因此分布式系统的其中一个实现目标就是高可用,高可用意味着系统必须具有较强的容错性,即在部分节点故障的情况下仍然能正常对外提供服务。分布式系统实现高可用的方式有很多,常见的主要有以下几种:Master-Slave(包括主备、主从、主主)集群熔断降级限流Master-Slave、集群的本质都是冗余。熔断、降级、限流则从另一个维度——系统内

2021-04-12 21:14:09 857

原创 分布式系统架构系列讲解二十(分布式事物实战 10):事物消息最终一致性方案 实战

一,项目背景事物消息最终一致性方案,其实它也是可靠消息最终一致性方案。在事物消息方案中,RocketMQ(kafka)包含了可靠消息方案中的可靠消息服务+MQ,所以,如果用此方案,那么我们就不用再写一个可靠消息服务了,消息的状态,回查机制等等RocketMQ都已经帮我们做了。事物消息最终一致性方案和可靠消息最终一致性方案只能应用在异步场景中,比如:下单成功之后,增加积分服务,物流服务等。不要求时时性。如果要求时时性的场景中,比如A向B转账,A减少100,B就必须要时时增加100,这种情况就不能用可靠消

2021-04-10 16:21:53 186

Android例子源码GPS自动定位城市首字母导航

这是一款搜索功能和GPS定位功能的项目源码。本项目主要采用是百度定位。项目可以自动定位到但钱所在城市。也可以手动更改定位城市。主要是根据字母检索城市,热门城市等界面和功能都做得非常好,完全可以移植到自己的项目中去使用。而且代码写的也很简洁,没有拖拖拉拉的感觉。代码中也有简单的注释。非常项目对大家有帮助。(项目采用GBK编码)。

2015-08-13

Android例子源码各种二级分类列表

这是一款有好多种二级菜单的项目。有类似美团上的美食购物分类,有类似QQ分组的,有listview里面嵌套gridview的。几乎项目中个能用到的二级菜单这里都有,而且界面还是比较简洁的,很实用,又得直接可以在项目中应用。项目代码量也不是很多,而且都有详细的分层。项目中重要的部分也都有详细的注释。(本项目采用UTF-8编码)。

2015-08-13

空空如也

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

TA关注的人

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