<?xml version="1.0" encoding="utf-8" ?><rss version="2.0"><channel><title><![CDATA[吹雪的专栏]]></title><description><![CDATA[下雨初晴，水风清；烟敛云收，数峰青。]]></description><link>https://blog.youkuaiyun.com/John8169</link><language>zh-cn</language><generator>https://blog.youkuaiyun.com/</generator><copyright><![CDATA[Copyright &copy; John8169]]></copyright><item><title><![CDATA[2021-05-16]]></title><link>https://blog.youkuaiyun.com/John8169/article/details/116903363</link><guid>https://blog.youkuaiyun.com/John8169/article/details/116903363</guid><author>John8169</author><pubDate>Sun, 16 May 2021 21:39:28 +0800</pubDate><description><![CDATA[最近在学习Go语言的特性，看到一个并发的例子特别有意思，在此记录下
func makeThumbnails(filenames &lt;-chan string) int64 {
	sizes := make(chan int64)
	var wg sync.WaitGroup // number of working goroutines
	for f := range filenames {
		wg.Add(1) //Add, which increments the counter, must be]]></description><category></category></item><item><title><![CDATA[缓存与数据库一致性]]></title><link>https://blog.youkuaiyun.com/John8169/article/details/83061801</link><guid>https://blog.youkuaiyun.com/John8169/article/details/83061801</guid><author>John8169</author><pubDate>Mon, 15 Oct 2018 17:20:35 +0800</pubDate><description><![CDATA[1.使用缓存的场景
缓存是提高系统读性能的常用技术，尤其对于读多写少的应用场景，使用缓存可以极大的提高系统的性能.
例子：查询用户的存款： select money from user where uid = YYY;为了优化该查询功能，我们可以在缓存中建立uid-&amp;gt;money的键值对。减少数据库的查询压力。
2.读操作流程
目前数据库和缓存中都有存储数据，当读取数据的时候，流程如下。


...]]></description><category></category></item><item><title><![CDATA[Java内存模型]]></title><link>https://blog.youkuaiyun.com/John8169/article/details/83060491</link><guid>https://blog.youkuaiyun.com/John8169/article/details/83060491</guid><author>John8169</author><pubDate>Mon, 15 Oct 2018 16:17:40 +0800</pubDate><description><![CDATA[前言
我们先来看一个反常识的例子。
int a=0, b=0;

public void method1() {
  int r2 = a;
  b = 1;
}

public void method2() {
  int r1 = b;
  a = 2;
}

这里我定义了两个共享变量 a 和 b，以及两个方法。第一个方法将局部变量 r2 赋值为 a，然后将共享变量 b 赋值为 1。第二个方法...]]></description><category></category></item><item><title><![CDATA[垃圾回收_下]]></title><link>https://blog.youkuaiyun.com/John8169/article/details/83056738</link><guid>https://blog.youkuaiyun.com/John8169/article/details/83056738</guid><author>John8169</author><pubDate>Mon, 15 Oct 2018 11:41:44 +0800</pubDate><description><![CDATA[前言
在读博士的时候，我曾经写过一个统计 Java 对象生命周期的动态分析，并且用它来跑了一些基准测试。
其中一些程序的结果，恰好验证了许多研究人员的假设，即大部分的 Java 对象只存活一小段时间，而存活下来的小部分 Java 对象则会存活很长一段时间。
之所以要提到这个假设，是因为它造就了Java虚拟机的分代回收思想。简单来说，就是将堆空间划分为两代，分别叫做新生代和老年代。新生代用来存储新建...]]></description><category></category></item><item><title><![CDATA[垃圾回收_上]]></title><link>https://blog.youkuaiyun.com/John8169/article/details/83055118</link><guid>https://blog.youkuaiyun.com/John8169/article/details/83055118</guid><author>John8169</author><pubDate>Mon, 15 Oct 2018 10:21:06 +0800</pubDate><description><![CDATA[前言
你应该听说过这么一句话：免费的其实是最贵的。
Java 虚拟机的自动内存管理，将原本需要由开发人员手动回收的内存，交给垃圾回收器来自动回收。不过既然是自动机制，肯定没法做到像手动回收那般精准高效 [1] ，而且还会带来不少与垃圾回收实现相关的问题。
接下来的两篇，我们会深入探索 Java 虚拟机中的垃圾回收器。今天这一篇，我们来回顾一下垃圾回收的基础知识。
引用计数法与可达性分析
垃圾回收，...]]></description><category></category></item><item><title><![CDATA[Java对象的内存布局]]></title><link>https://blog.youkuaiyun.com/John8169/article/details/83054325</link><guid>https://blog.youkuaiyun.com/John8169/article/details/83054325</guid><author>John8169</author><pubDate>Mon, 15 Oct 2018 09:37:14 +0800</pubDate><description><![CDATA[前言
在 Java 程序中，我们拥有多种新建对象的方式。除了最为常见的 new 语句之外，我们还可以通过反射机制、Object.clone 方法、反序列化以及 Unsafe.allocateInstance 方法来新建对象。
其中，Object.clone方法和反序列化通过直接复制已有的数据，来初始化新建对象的实例字段。Unsafe.allocateInstance方法则没有初始化实例字段，而ne...]]></description><category></category></item><item><title><![CDATA[JVM是如何实现反射的]]></title><link>https://blog.youkuaiyun.com/John8169/article/details/83041975</link><guid>https://blog.youkuaiyun.com/John8169/article/details/83041975</guid><author>John8169</author><pubDate>Sat, 13 Oct 2018 20:38:09 +0800</pubDate><description><![CDATA[前言
反射是 Java 语言中一个相当重要的特性，它允许正在运行的 Java 程序观测，甚至是修改程序的动态行为。
举例来说，我们可以通过 Class 对象枚举该类中的所有方法，我们还可以通过 Method.setAccessible（位于 java.lang.reflect 包，该方法继承自 AccessibleObject）绕过 Java 语言的访问权限，在私有方法所在类之外的地方调用该方法。...]]></description><category></category></item><item><title><![CDATA[Java虚拟机是怎么实现synchronized的]]></title><link>https://blog.youkuaiyun.com/John8169/article/details/83036957</link><guid>https://blog.youkuaiyun.com/John8169/article/details/83036957</guid><author>John8169</author><pubDate>Sat, 13 Oct 2018 11:32:45 +0800</pubDate><description><![CDATA[synchronized字节码
在 Java 程序中，我们可以利用 synchronized 关键字来对程序进行加锁。它既可以用来声明一个 synchronized 代码块，也可以直接标记静态方法或者实例方法。
当声明 synchronized 代码块时，编译而成的字节码将包含 monitorenter 和 monitorexit 指令。这两种指令均会消耗操作数栈上的一个引用类型的元素（也就是 s...]]></description><category></category></item><item><title><![CDATA[HSF学习总结]]></title><link>https://blog.youkuaiyun.com/John8169/article/details/83031999</link><guid>https://blog.youkuaiyun.com/John8169/article/details/83031999</guid><author>John8169</author><pubDate>Fri, 12 Oct 2018 19:56:59 +0800</pubDate><description><![CDATA[HSF其实是一个RPC框架，RPC是Remote Procedure Call,就是远程服务调用.
这个功能为什么要写个框架而不是十几行代码呢，因为在分布式场景下并不是这种点对点通讯的模式。
rpc要素：where how
地址：注册中心ConfigServer, 这个中心用来管理整个分布式集群里所有的服务对应服务提供者ip的对应关系，
这玩意是不能写在配置文件里的，在分布式场景下扩容、缩容机器i...]]></description><category></category></item><item><title><![CDATA[TDDL思考总结]]></title><link>https://blog.youkuaiyun.com/John8169/article/details/83031987</link><guid>https://blog.youkuaiyun.com/John8169/article/details/83031987</guid><author>John8169</author><pubDate>Fri, 12 Oct 2018 19:55:55 +0800</pubDate><description><![CDATA[单机数据库
分布式数据库
TDDL原理与最佳实践
1. 数据库的结构
1.1. KV存储(id是K)
1.2. B+树与红黑树
B+树的特点是叶子节点是块状，一个叶子里面有多个数据，相邻数据是存在一起的，123，456起等，
而磁盘也是按块的，B+树的数据是按块存储的正好和磁盘的块的概念是相符的，
所以在数据库里面大多采用了B+树或者类似的一种结构来存储数据。
在java中实现treemap时选择...]]></description><category></category></item><item><title><![CDATA[Java之Integer#highestOneBit代码品读]]></title><link>https://blog.youkuaiyun.com/John8169/article/details/83031950</link><guid>https://blog.youkuaiyun.com/John8169/article/details/83031950</guid><author>John8169</author><pubDate>Fri, 12 Oct 2018 19:52:35 +0800</pubDate><description><![CDATA[/**
 * Returns an {@code int} value with at most a single one-bit, in the
 * position of the highest-order (&quot;leftmost&quot;) one-bit in the specified
 * {@code int} value.  Returns zero if the specified va...]]></description><category></category></item><item><title><![CDATA[MySQL实现分组排序]]></title><link>https://blog.youkuaiyun.com/John8169/article/details/83031887</link><guid>https://blog.youkuaiyun.com/John8169/article/details/83031887</guid><author>John8169</author><pubDate>Fri, 12 Oct 2018 19:45:36 +0800</pubDate><description><![CDATA[想要根据用户分组，以该用户的下单时间为降序，提取所有用户的第二个订单信息。
这属于分组排序，在Oracle有内置函数可以实现，而在mysql就有点麻烦：
CREATE TABLE user_orders (orders_id INT UNSIGNED NOT NULL,
user_id INT UNSIGNED NOT NULL,
add_time INT UNSIGNED NOT NULL,
P...]]></description><category></category></item><item><title><![CDATA[metaq最佳实践]]></title><link>https://blog.youkuaiyun.com/John8169/article/details/81879198</link><guid>https://blog.youkuaiyun.com/John8169/article/details/81879198</guid><author>John8169</author><pubDate>Tue, 09 Oct 2018 22:17:49 +0800</pubDate><description><![CDATA[1. 前言

本文档旨在描述RocketMQ使用过程中的一些最佳实践，建议用户这样做，但是非必须。



2. Producer最佳实践



2.1 发送消息注意事项


一个应用尽可能用一个Topic，消息子类型用tags来标识，tags可以由应用自由设置。只有发送消息设置了tags，消费方在订阅消息时，才可以利用tags在broker做消息过滤。message.setTags(“TagA”)...]]></description><category></category></item><item><title><![CDATA[metaq原理简介]]></title><link>https://blog.youkuaiyun.com/John8169/article/details/81879219</link><guid>https://blog.youkuaiyun.com/John8169/article/details/81879219</guid><author>John8169</author><pubDate>Tue, 09 Oct 2018 22:17:41 +0800</pubDate><description><![CDATA[1. 前言

本文档旨在描述RocketMQ的多个关键特性的实现原理，并对消息中间件遇到的各种问题进行总结，阐述RocketMQ如何解决这些问题。文中主要引用了JMS规范与CORBA Notification规范，规范为我们设计系统指明了方向，但是仍有不少问题规范没有提及，对于消息中间件又至关重要。RocketMQ并不遵循任何规范，但是参考了各种规范与同类产品的设计思想。



产品发展历史

大...]]></description><category></category></item><item><title><![CDATA[metaq杂记]]></title><link>https://blog.youkuaiyun.com/John8169/article/details/81879211</link><guid>https://blog.youkuaiyun.com/John8169/article/details/81879211</guid><author>John8169</author><pubDate>Tue, 09 Oct 2018 22:14:34 +0800</pubDate><description><![CDATA[Name Server：维护broker的地址列表，以及topic和topic对应的队列的地址列表。每个broker与每个Name Server之间使用长连接来保持心跳，并向其定时注册topic信息。可以从两个维度来理解Name Server的能力： 1）Name Server可以提供一个特定的topic对应的broker地址列表；2）Name Server可以提供一台broker上包含的所有to...]]></description><category></category></item><item><title><![CDATA[NIO与IO区别]]></title><link>https://blog.youkuaiyun.com/John8169/article/details/82989822</link><guid>https://blog.youkuaiyun.com/John8169/article/details/82989822</guid><author>John8169</author><pubDate>Tue, 09 Oct 2018 22:09:11 +0800</pubDate><description><![CDATA[流与块的比较
原来的 I/O 库(在 java.io.*中) 与 NIO 最重要的区别是数据打包和传输的方式。正如前面提到的，原来的 I/O 以流的方式处理数据，而 NIO 以块的方式处理数据。
面向流的I/O系统一次一个字节地处理数据。一个输入流产生一个字节的数据，一个输出流消费一个字节的数据。为流式数据创建过滤器非常容易。链接几个过滤器，以便每个过滤器只负责单个复杂处理机制的一部分，这样也是相...]]></description><category></category></item><item><title><![CDATA[ClassNotFoundException和NoClassDefFoundError区别]]></title><link>https://blog.youkuaiyun.com/John8169/article/details/82989817</link><guid>https://blog.youkuaiyun.com/John8169/article/details/82989817</guid><author>John8169</author><pubDate>Tue, 09 Oct 2018 22:08:30 +0800</pubDate><description><![CDATA[ClassNotFoundException:

它是Exception，不是Error在Throwable体系中只是一个Exception，说明它是可恢复的
发生的时机
当应用试图通过给定的name加载对应的class时可能抛出此异常，找不到对应的class文件时抛出。常见的场景就是：

调用class的forName方法时，找不到指定的类
ClassLoader 中的 findSystemCl...]]></description><category></category></item><item><title><![CDATA[Future模式]]></title><link>https://blog.youkuaiyun.com/John8169/article/details/82903027</link><guid>https://blog.youkuaiyun.com/John8169/article/details/82903027</guid><author>John8169</author><pubDate>Sat, 29 Sep 2018 21:28:52 +0800</pubDate><description><![CDATA[1. Future模式简介
Future模式就是，当某一程序提交请求，期望得到一个答复。但是可能服务器程序对这个请求的处理比较慢，因此不可能马上收到答复。但是，在传统的单线程环境下，调用函数是同步的，它必须等到服务程序返回结果，才能继续进行其他处理。而Future模式下，调用方法是异步的，原本等待返回的时间段，在主调函数中，则可以处理其他的任务。传统的串行程序如下图所示：
https://imag...]]></description><category></category></item><item><title><![CDATA[HSF原理简介]]></title><link>https://blog.youkuaiyun.com/John8169/article/details/81433300</link><guid>https://blog.youkuaiyun.com/John8169/article/details/81433300</guid><author>John8169</author><pubDate>Sun, 05 Aug 2018 17:35:18 +0800</pubDate><description><![CDATA[0. 前言

HSF是一个分布式的远程服务调用框架，其实我更喜欢把分布式几个字去掉，因为HSF本身并不是一个单独的服务（指一个进程），他是附属在你的应用里的一个组件，一个RPC组件(远程过程调用——Remote Procedure Call，是一种通过网络从远程计算机程序上请求服务，而不需要了解底层网络技术的协议。在OSI网络通信模型中，RPC跨越了传输层和应用层。RPC使得开发分布式应用更加容易...]]></description><category></category></item><item><title><![CDATA[HSF原理分析]]></title><link>https://blog.youkuaiyun.com/John8169/article/details/81433287</link><guid>https://blog.youkuaiyun.com/John8169/article/details/81433287</guid><author>John8169</author><pubDate>Sun, 05 Aug 2018 17:34:19 +0800</pubDate><description><![CDATA[1. HSF的基本概念

HSF全称为High-Speed Service Framework，旨在为淘系的应用提供一个分布式的服务框架，HSF从分布式应用层面以及统一的发布/调用方式层面为大家提供支持，从而可以很容易的开发分布式的应用以及提供或使用公用功能模块，而不用考虑分布式领域中的各种细节技术，例如远程通讯、性能损耗、调用的透明化、同步/异步调用方式的实现等等问题。



2. 知识准备

...]]></description><category></category></item></channel></rss>