<?xml version="1.0" encoding="utf-8" ?><rss version="2.0"><channel><title><![CDATA[sylnb的博客]]></title><description><![CDATA[]]></description><link>https://blog.youkuaiyun.com/sylnb</link><language>zh-cn</language><generator>https://blog.youkuaiyun.com/</generator><copyright><![CDATA[Copyright &copy; sylnb]]></copyright><item><title><![CDATA[mysql系列—超详细索引讲解（下）]]></title><link>https://blog.youkuaiyun.com/sylnb/article/details/129760201</link><guid>https://blog.youkuaiyun.com/sylnb/article/details/129760201</guid><author>sylnb</author><pubDate>Fri, 24 Mar 2023 22:54:58 +0800</pubDate><description><![CDATA[那如果我们分别在 last_name 和 first_name 上创建两个列索引，mysql的处理方式就不一样了，它会选择一个最严格的索引来进行检索，可以理解为检索能力最强的那个索引来检索，另外一个利用不上了，这样效果就不如多列索引了。对于复合索引:Mysql 从左到右的使用索引中的字段，一个查询可以只使用索引中的一部份，但只能是最左侧部分。​		覆盖索引的好处：二级索引如果是覆盖索引，避免了一次聚簇索引的查找，且覆盖索引的大小只包含需要的数据，而聚簇索引包含全部数据，覆盖索引可以更好的放入到内存当中。]]></description><category></category></item><item><title><![CDATA[mysq—超详细索引讲解（上）]]></title><link>https://blog.youkuaiyun.com/sylnb/article/details/129760188</link><guid>https://blog.youkuaiyun.com/sylnb/article/details/129760188</guid><author>sylnb</author><pubDate>Fri, 24 Mar 2023 22:51:34 +0800</pubDate><description><![CDATA[不是单独的索引类型，而是一种数据存储方式，指的是**数据行跟相邻的键值紧凑的存储**在一起。]]></description><category></category></item><item><title><![CDATA[mysql系列—事务详解]]></title><link>https://blog.youkuaiyun.com/sylnb/article/details/129760137</link><guid>https://blog.youkuaiyun.com/sylnb/article/details/129760137</guid><author>sylnb</author><pubDate>Fri, 24 Mar 2023 22:48:40 +0800</pubDate><description><![CDATA[例如：用户 A 向用户 B 转账 100 元当只执行第一条 SQL 时，A 通知 B 查看账户，B 发现确实钱已到账（此时即发生了脏读），而之后无论第二条 SQL 是否执行，只要该事务不提交，则所有操作都将回滚，那么当 B 以后再次查看账户时就会发现钱其实并没有转。​		例如事务 T1 在读取某一数据，而事务 T2 立马修改了这个数据并且提交事务给数据库，事务 T1 再次读取该数据就得到了不同的结果，发送了不可重复读。（这点就脏读不同），所不同的是不可重复读查询的都是同一个数据项，而。]]></description><category></category></item><item><title><![CDATA[mysql系列—超详细调优策略]]></title><link>https://blog.youkuaiyun.com/sylnb/article/details/129760054</link><guid>https://blog.youkuaiyun.com/sylnb/article/details/129760054</guid><author>sylnb</author><pubDate>Fri, 24 Mar 2023 22:43:05 +0800</pubDate><description><![CDATA[不是同一个表也可以union,，条件是只要列数相同，UNION 结果集中的列名总是等于 UNION 中第一个 SELECT 语句中的列名。，每个查询功能一样，只完成一小部分，如果用一个大的语句一次性完成的话，则可能需要一次锁住很多数据、耗尽系统资源、阻塞很多小的但重要的查询。查询不需要的记录：使用 select 语句查询大量结果，然后再获取前 N 行（如新闻网站，取 100 条记录，只显示前面的 10 条），如果内存大小已经超过了总数据量的大小，那么即使再增加内存，系能提升也不会特别明显。]]></description><category></category></item><item><title><![CDATA[java并发系列—超详细线程池讲解]]></title><link>https://blog.youkuaiyun.com/sylnb/article/details/129759997</link><guid>https://blog.youkuaiyun.com/sylnb/article/details/129759997</guid><author>sylnb</author><pubDate>Fri, 24 Mar 2023 22:40:47 +0800</pubDate><description><![CDATA[在创建了线程池后，默认情况下，线程池中并没有任何线程，而是等待有任务到来才创建线程去执行任务，除非调用了prestartAllCoreThreads()或者 prestartCoreThread()方法，从这 2 个方法的名字就可以看出，是预创建线程的意思，即在没有任务到来之前就创建corePoolSize 个线程或者一个线程。= null || (task =maximumPoolSize：最大线程数，当队列中存放的任务达到队列容量时，当前可以同时运行的数量变为最大线程数，创建线程并立即执行最新的任务，]]></description><category></category></item><item><title><![CDATA[java并发系列—进程与线程详解]]></title><link>https://blog.youkuaiyun.com/sylnb/article/details/129759960</link><guid>https://blog.youkuaiyun.com/sylnb/article/details/129759960</guid><author>sylnb</author><pubDate>Fri, 24 Mar 2023 22:38:01 +0800</pubDate><description><![CDATA[在 JVM 中体现为让可运行池中优先级高的线程拥有 CPU 使用权，如果可运行池中线程优先级一样则随机选择线程，但要注意的是实际上一个绝对时间点只有一个线程在运行（这里是相对于一个CPU 来说，如果你的机器是多核的还是可能多个线程同时运行的），直到此线程进入非可运行状态或另一个具有更高优先级的线程进入可运行线程池，才会使之让出 CPU 的使用权，更高优先级的线程抢占了优先级低的线程的 CPU。其中进程包括地址空间，打开的文件，账户信息，预告的报警，子进程。线程是轻量化的进程，是程序执行流的最小单位；]]></description><category></category></item><item><title><![CDATA[java并发系列—超详细ThreadLocal详解]]></title><link>https://blog.youkuaiyun.com/sylnb/article/details/129759937</link><guid>https://blog.youkuaiyun.com/sylnb/article/details/129759937</guid><author>sylnb</author><pubDate>Fri, 24 Mar 2023 22:36:29 +0800</pubDate><description><![CDATA[这样的话ThreadLocal的生命周期就更长，由于一直存在ThreadLocal的强引用，所以ThreadLocal也就不会被回收，也就能保证任何时候都能根据ThreadLocal的弱引用访问到Entry的value值，然后remove它，防止内存泄露。​		例如：]]></description><category></category></item><item><title><![CDATA[java并发系列—CAS机制概括]]></title><link>https://blog.youkuaiyun.com/sylnb/article/details/129759891</link><guid>https://blog.youkuaiyun.com/sylnb/article/details/129759891</guid><author>sylnb</author><pubDate>Fri, 24 Mar 2023 22:32:25 +0800</pubDate><description><![CDATA[当多个线程尝试使用 CAS 同时更新同一个变量时，只有其中一个线程能更新变量的值，而其它线程都失败，失败的线程并不会被挂起，而是被告知这次竞争中失败，并可以再次尝试。CAS 有 3 个操作数，内存值 V，旧的预期值 A，要修改的新值 B。当且仅当预期值 A 和内存值 V 相同时，将内存值 V 修改为 B，否则什么都不做。compareAndSet 利用 JNI （本地方法）来完成 CPU 指令的操作。其它原子操作都是利用类似的特性完成的。利用 CPU 的 CAS 指令，CAS 是靠硬件实现的。]]></description><category></category></item><item><title><![CDATA[java并发系列—指令重排序与volatile详解]]></title><link>https://blog.youkuaiyun.com/sylnb/article/details/129759850</link><guid>https://blog.youkuaiyun.com/sylnb/article/details/129759850</guid><author>sylnb</author><pubDate>Fri, 24 Mar 2023 22:30:40 +0800</pubDate><description><![CDATA[而且重排序操作 A 和操作 B 后的执行结果，与操作 A 和操作 B 按 happens- before 顺序执行的结果一致。线程2 先执行了 ready = true（线程二内部发生了指令重排，前后没有数据依赖关系），切换到线程1，进入 if 分支，相加为 0，再切回线程2 执行 num = 2。​		上面三种情况，只要重排序两个操作的执行顺序，程序的执行结果将会被改变。​		在本线程内观察，所有操作都是有序的；，线程持有的是共享变量的副本，无法感知其他线程对于共享变量的更改，导致读取的值不是最新的。]]></description><category></category></item><item><title><![CDATA[java并发系列—JMM与先行先发原则详解]]></title><link>https://blog.youkuaiyun.com/sylnb/article/details/129759821</link><guid>https://blog.youkuaiyun.com/sylnb/article/details/129759821</guid><author>sylnb</author><pubDate>Fri, 24 Mar 2023 22:28:23 +0800</pubDate><description><![CDATA[也就是 read 和 load之间，store 和 write 之间是可以插入其他指令的，如对主内存中的变量 a、b 进行访问时，可能的顺序是 read a，read b，load b， load a。锁定规则 ：一个 unlock 操作先行发生于后面（时间的先后）对同一个锁的 lock 操作，所以线程解锁 m 之前对变量的写（解锁前会刷新到主内存中），对于接下来对 m 加锁的其它线程对该变量的读可见。​		时间上的先后顺序对先行发生没有太大的关系，所以衡量并发安全问题的时候不要受到时间顺序的影响，]]></description><category></category></item><item><title><![CDATA[jvm虚拟机系列—栈帧详解]]></title><link>https://blog.youkuaiyun.com/sylnb/article/details/129731462</link><guid>https://blog.youkuaiyun.com/sylnb/article/details/129731462</guid><author>sylnb</author><pubDate>Thu, 23 Mar 2023 15:12:24 +0800</pubDate><description><![CDATA[当调用方法是非 static 方法时，**局部变量表中第 0 位索引的 Slot 默认是用于传递方法所属对象实例的引用，即“this”关键字指向的对象。令下面的部分操作数栈与上面的局部变量表重叠在一块，这样在方法调用的时候可以共用一部分数据，无需进行额外的参数复制传递。（不受程度运行期变量数据的影响），并且写入到了方法表的 Code 属性中，因此一个栈帧需要分配多少内存，不会受到程序运行期变量数据的影响，而仅仅取决于具体虚拟机的实现。栈帧存储了方法的局部变量表，操作数栈，动态连接和方法返回地址等信息。]]></description><category></category></item><item><title><![CDATA[jvm系列—详细讲解内存区域]]></title><link>https://blog.youkuaiyun.com/sylnb/article/details/129731338</link><guid>https://blog.youkuaiyun.com/sylnb/article/details/129731338</guid><author>sylnb</author><pubDate>Thu, 23 Mar 2023 15:06:41 +0800</pubDate><description><![CDATA[局部变量表所需的空间在编译期间完成分配，当进入一个方法时，其需要在帧中分配多大的局部变量空间是确定的，方法运行期间不会改变局部变量表的大小。当方法传递参数时实际上是一个方法将自己栈帧中局部变量表的副本传递给另一个方法栈帧中的局部变量表（注意是副本，而不是其本身），不管数据类型是什么（基本类型，引用类型），如同磁盘空间一样，既可以实现成固定大小，也可以是扩展的，当前主流虚拟机都是按照扩展来实现的（通过-Xmx 和-Xms 控制）。​		元空间的本质和永久代类似，都是对 JVM 规范中方法区的实现。]]></description><category></category></item><item><title><![CDATA[（java）netty框架—reactor线程模型详解]]></title><link>https://blog.youkuaiyun.com/sylnb/article/details/129731055</link><guid>https://blog.youkuaiyun.com/sylnb/article/details/129731055</guid><author>sylnb</author><pubDate>Thu, 23 Mar 2023 15:00:11 +0800</pubDate><description><![CDATA[负责，线程池可以采用标准的JDK线程池实现，它包含一个任务队列和N个可用的线程，由这些NIO线程负责消息的读取、解码、编码和发送。缺点：多线程数据共享和访问比较复杂， reactor 处理所有的事件的监听和响应，在单线程运行， 在高并发场景容易出现性能瓶颈.使用场景：客户端的数量有限，业务处理非常快速，比如 Redis 在业务处理的时间复杂度 O(1) 的情况。​		一个NIO线程可以同时处理N条链路，但是一个链路只对应一个NIO线程，防止发生并发操作问题。优点：可以充分的利用多核 cpu 的处理能力。]]></description><category></category></item><item><title><![CDATA[java.io—Nio详解]]></title><link>https://blog.youkuaiyun.com/sylnb/article/details/129730873</link><guid>https://blog.youkuaiyun.com/sylnb/article/details/129730873</guid><author>sylnb</author><pubDate>Thu, 23 Mar 2023 14:53:27 +0800</pubDate><description><![CDATA[​		一个多路复用器Selector可以同时轮询多个Channel,**由于JDK使用了epoll（)代替传统的select实现（unix网络编程卷1中有讲到），**所以它并没有最大连接句柄1024/2048的限制。而 NIO 是基于通道（Channel）和缓冲区（Buffer）进行操作，数据总是从通道读取到缓冲区中，或者从缓冲区写入到通道中。，该对象提供了一组方法，可以更轻松地使用内存块，缓冲区对象内置了一些机制，能够跟踪和记录缓冲区的状态变化情况。​		标准的 IO 基于字节流和字符流进行操作的，]]></description><category></category></item><item><title><![CDATA[java.io—socket网络编程详解]]></title><link>https://blog.youkuaiyun.com/sylnb/article/details/129730949</link><guid>https://blog.youkuaiyun.com/sylnb/article/details/129730949</guid><author>sylnb</author><pubDate>Thu, 23 Mar 2023 14:52:22 +0800</pubDate><description><![CDATA[如果这次没有把数据一次性全部读写完(如读写缓冲区太小)，那么下次调用 epoll_wait()时，它还会通知你在上没读写完的文件描述符上继续读写，当然如果你一直不去读写，它会一直通知你！如果系统中有大量你不需要读写的就绪文件描述符，而它们每次都会返回，这样会大大降低处理程序检索自己关心的就绪文件描述符的效率！**但 select，poll，epoll 本质上都是同步 I/O，**因为他们都需要在读写事件就绪后自己负责进行读写，**也就是说这个读写过程是阻塞的，**而异步 I/O则无需自己负责进行读写，]]></description><category></category></item><item><title><![CDATA[java并发系列—concurrenthashmap（jad 1.7）]]></title><link>https://blog.youkuaiyun.com/sylnb/article/details/129730809</link><guid>https://blog.youkuaiyun.com/sylnb/article/details/129730809</guid><author>sylnb</author><pubDate>Thu, 23 Mar 2023 14:47:17 +0800</pubDate><description><![CDATA[我们知道Java中关键词final修饰的域成为最终域。]]></description><category></category></item><item><title><![CDATA[java并发系列—concurrenthashmap详解（下）]]></title><link>https://blog.youkuaiyun.com/sylnb/article/details/129730741</link><guid>https://blog.youkuaiyun.com/sylnb/article/details/129730741</guid><author>sylnb</author><pubDate>Thu, 23 Mar 2023 14:47:11 +0800</pubDate><description><![CDATA[扩容，扩容时以 bin 为单位进行，需要对 bin 进行 synchronized，但这时其它竞争线程也不是无事可做，它们会帮助把其它 bin 进行扩容。如果已经有了，锁住链表头进行后续 put 操作，元素添加至 bin 的尾部。size，元素个数保存在 baseCount 中，并发时的个数变动保存在 CounterCell[] 当中，最后统计数量时累加。树化，当 table.length < 64 时，先尝试扩容，超过 64 时，并且 bin.length > 8 时，会将。]]></description><category></category></item><item><title><![CDATA[java并发系列—concurrenthashmap详解（上）]]></title><link>https://blog.youkuaiyun.com/sylnb/article/details/129730652</link><guid>https://blog.youkuaiyun.com/sylnb/article/details/129730652</guid><author>sylnb</author><pubDate>Thu, 23 Mar 2023 14:43:01 +0800</pubDate><description><![CDATA[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5S5Vxaoa-1679553733560)(https://typora963.oss-cn-hangzhou.aliyuncs.com/ConcurrentHashMap%E6%95%B0%E6%8D%AE%E7%BB%93%E6%9E%84-1673425907078545.png)]简单的说：不同线程调用map时，由于头插法的因素产生了死链结构，ForwardingNode 节点：转移节点。：线程安全类的集合指的是，]]></description><category></category></item><item><title><![CDATA[java集合系列—超详细hashmap讲解（下）]]></title><link>https://blog.youkuaiyun.com/sylnb/article/details/129730362</link><guid>https://blog.youkuaiyun.com/sylnb/article/details/129730362</guid><author>sylnb</author><pubDate>Thu, 23 Mar 2023 14:37:08 +0800</pubDate><description><![CDATA[通过hash的方法，通过put和get存储和获取对象。存储对象时，我们将K/V传给put方法时，它调用hashCode计算hash从而得到bucket位置，进一步存储，HashMap会根据当前bucket的占用情况自动调整容量(超过Load Facotr则resize为原来的2倍)。获取对象时，我们将K传给get，它调用hashCode计算hash从而得到bucket位置，并进一步调用equals()方法确定键值对。如果发生碰撞的时候，Hashmap通过链表将产生碰撞冲突的元素组织起来，在Java。]]></description><category></category></item><item><title><![CDATA[java集合系列—超详细hashmap讲解（上）]]></title><link>https://blog.youkuaiyun.com/sylnb/article/details/129728624</link><guid>https://blog.youkuaiyun.com/sylnb/article/details/129728624</guid><author>sylnb</author><pubDate>Thu, 23 Mar 2023 13:15:35 +0800</pubDate><description><![CDATA[​数组：采用一段连续的存储单元来存储数据。对于指定下标的查找，时间复杂度为O(1)；通过给定值进行查找，需要遍历数组，逐一比对给定关键字和数组元素，时间复杂度为O(n)，当然，对于有序数组，则可采用二分查找，插值查找，斐波那契查找等方式，可将查找复杂度提高为O(logn)；对于一般的插入删除操作，涉及到数组元素的移动，其平均复杂度也为O(n)线性链表：对于链表的新增，删除等操作（在找到指定操作位置后），仅需处理结点间的引用即可，时间复杂度为O(1)，而查找操作需要遍历链表逐一进行比对，复杂度为O(n)]]></description><category></category></item></channel></rss>