Java

A collection of 8 posts
Java

唯一ID生成算法

前言 唯一ID在互联网大厂的业务线中广泛使用,比如订单号、数据库主键、IM消息序号、交易流水号等等,这些ID的共同特点是唯一标记某一个业务记录或者消息、部分ID自增、全局有序或者局部有序。 UUID作为是一种全局唯一的方案是可供使用的选择之一,但在实际操作中大家一般使用的很少,几个原因: 1. 16个字节128位占用太多的存储空间不适合用来作为主键; 2. UUID的版本1基于MAC地址和时间戳,可保证全局唯一,但容易被硬件追踪; 3. 后续版本使用伪随机数、SHA1又没有前向兼容,用在特定业务的一定范围内使用没有问题,但作为分布式系统的唯一ID不适合。 所以就有了各个互联网大厂分享的各自业务中实现唯一ID的不同算法和系统部署方案,唯一ID算法主要核心聚焦在以下几点: * ID位数 * ID算法原理 * 全局唯一 * 全局(局部)趋势有序 * 时钟回拨问题 * 外部系统依赖 技术实现汇总 从大厂分享的技术实现汇总如下: 厂牌技术方案ID位数全局唯一有序时钟回拨外部系统依赖TwitterSnowFlake64全局唯一局部有序block waitMongoDB
3 min read
Android

Retrofit、Volley、HttpClient比较

Retrofit作为现在大家用的最多HTTP请求框架,非常流行,Github上star 3w+。它为什么能超越Volley、HTTPClient能够一枝独秀呢?那先看看其他两个HTTP栈的实现。 HTTPClient Java界老牌HTTP栈实现,由Apache维护,它支持HTTP1.0/1.1、极其丰富的API来支持各种子协议,代码庞大臃肿也变成了它的缺点,虽然它的创建一开始是为了弥补Java SDK中java.net包HTTP请求的简单实现,Android在6.0以后彻底弃用了它,转而推荐使用HTTPURLConnection。 Volley 作为Google官方开源的一款HTTP栈,它支持切换HTTPURLConnection、HTTPClient底层协议栈的切换,同时提供了请求线程池、缓存的支持,刚一推出也是收获许多赞赏,但是它就像G家好多产品一样,几年一次的维护和有些bug都需要使用方去维护解决,都是开发者逐渐抛弃的原因。虽然从Volley开始,这些HTTP栈的实现都在逐渐向上层实现,因为不管是Android、iOS大部分App的网络交互都是Restful-API的实现,
3 min read
Tech

Java动态代理类的生成和调用

Java的动态代理在开发中都有大量的使用,如Spring框架,Android的HTTP开发框架Retrofit,本文主要关注动态代理编写使用背后的代理类是如何的生成以及与代理对象的调用是如何实现的,以Retrofit这个框架中动态代理的使用为例子进行分析。 在Retrofit中,某类的API接口大多定义在一个Service接口类中,某一个API接口则被声明为Service接口类的一个方法,通过方法的注解、参数来描述具体API参数等信息。在调用某个API接口时,Retrofit实例调用create()创建Service接口类的实例对象来完成调用,具体源代码如下: public T create(final Class service) { // 必须是接口,并且不允许是继承来的接口 Utils.validateServiceInterface(service); //是否预加载 if (validateEagerly) { eagerlyValidateMethods(service); } //动态代理的核心代码 return (T) Proxy.newProxyIn
10 min read
Java

Java WEB系统微服务化迁移

支撑互联网公司运行的庞大后端服务系统经历了原始的BS架构设计、前后端分离、模块化组件、系统分层设计的进化,从计算资源的虚拟化到今天容器技术的应用,互联网一直在朝着资源高效配置、分布式集群服务的方向进发。 Docker [https://www.docker.com/] 作为当下最流行的容器化技术,相比于运行在实体物理机上的虚拟机技术,它具有轻量级资源隔离、快速部署、持续交付、版本控制、 可移植、开放技术等特点。 如果采用虚拟机技术去部署一套系统,需要几个步骤: 1. 分配物理资源(CPU\内存\网络) 2. 开机启动运行 3. 安装系统运行时支撑环境(模版) 4. 发布生产系统 5. 上线。 采用Docker需要如下几个步骤: 1. 拉取Docker Image 2. 发布生产系统 3. 上线 相比来看可能就会发现,Docker相当于把最繁琐最耗时的工作帮助我们解决了。Docker运行在(特定)操作系统之上,只需要一条命令即刻启动;
4 min read
OAuth2

OAuth2协议和Spring Security OAuth2实现

OAuth2协议在API访问授权中广为使用,Google、Facebook、微博、腾讯的公开API也都使用它。虽然在使用上有些复杂,尤其是服务器端的使用更为繁琐,但它在权限授予、资源访问限制上的优势让其使用广泛。 OAuth2的协议流程如下: 以国内的微博为例, Resource Owner=微博用户; Client=第三方应用,如Fuubo、Weico; Authorization Server=微博平台授权服务器; Resource Server=访问微博、用户信息等资源的服务器 当开发者决定要开发一款基于微博的应用时,需要到 http://open.weibo.com 去填写一些资料,比如应用名称、类型、访问哪些资源,提交相关信息之后,微博后台会创建应用,分配一个client_id和client_secret,这两个字段对你的应用至关重要,以后会派上用场。 下面就开始正式的OAuth2协议流程: A、开发者构造Authorization Request (请求微博用户授权),如果此时微博用户A没有登录会直接跳转到微博登录页面,如果已经登录会跳转到授权页面,如图
10 min read
Java

Java的位运算、移位运算

上个月在做蓝牙通讯协议实现时数据操作基本处于Byte级别,所以用到了大量的位运算,恰巧看到这篇简单而又容易遗忘的基础点,所以翻译一下,顺便熟悉熟悉。 -------------------------------------------------------------------------------- Java的位运算和移位运算非常强大,它可以在bit级别上使用int、long、short、byte以及boolean类型的数据,而且相比其他运算方式,位运算和移位运算的速度要快很多。但是很多Java程序员却对此了解不多,尤其时那些没有接触过C、C++语言的程序员。当然对于在学习Java之前已经了解了C、C++的程序员来说就没有那么陌生了,因为这些运算基本与C类似。 在许多面试题中也会经常出现这种运算题目。这个实例代码主要时为了快速的了解Java的位运算符之间的不同,以及如何使用他们,其次我们也会介绍一下无符号移位和有符号的移位运算。 基础 在介绍位运算和移位运算之前,你必须区分二进制、位、字节和位运算。良好的二进制运算基础对理解位运算将大有裨益。 1)二进制数据只会
2 min read
Java

优化String StringBuffer

这篇文章主要介绍了一下String、StringBuffer对象在初始化和字符串连接时的优化,很不错。 -------------------------------------------------------------------------------- This topic illustrates the performance improvement techniques in String and StringBuffer with the following sections: * Overview of String and StringBuffer [https://www.nitrohsu.com/optimize-string-string-buffer.html#Strings101] * Better way of creating Strings [https://www.nitrohsu.com/optimize-string-string-buffer.html#Strings102] * Optimization by i
8 min read
Android

观察者模式 监听器

位置:platform/packages/apps/Contacts 位置:platform/packages/apps/ContactsCommon 1、观察者模式 com.android.contacts.ContactSaveService 事件源类集中处理联系人、用户组的增删改,处理这些数据Activity注册ContactSaveService.RegisterListener监听,当调用数据处理方法完毕后通知各自的监听器。 //定义接口 public interface Listener { //触发事件后通知方法 public void onServiceCompleted(Intent callbackIntent); } //监听器列表 private static final CopyOnWriteArrayList sListeners = new CopyOnWriteArrayList(); ​ //注册监听 public static void registerListener(Listener listene
2 min read