
日课
藿香正气
这个作者很懒,什么都没留下…
展开
-
python日课1-1:一摞有序的纸牌
《流畅的python》 第一章 示例1-1特殊方法python解释器碰到特殊的句法时,会使用特殊方法去激活一些基本的对象操作,这些特殊方法的名字以以两个下划线开头,以两个下划线结尾的方法:__init__,__len__,__getitem__。这些特殊方法名能让自己的对象实现和支持以下的语言架构,并与之交互:迭代集合类属性访问运算符重载函数和方法的调用对象的创建和销毁字符串表示形式和格式化管理上下文(即with块)示例1-1import collectionsfrom .原创 2020-08-19 14:32:27 · 310 阅读 · 0 评论 -
happens-before
理解happens-before是理解JMM的关键。JMM的设计在设计JMM时,需要考虑两个关键因素:程序员对内存模型的使用。程序员希望内存模型易于理解、易于编程,希望基于一个强内存模型来编写代码。编译器和处理器对内存模型的实现。编译器和处理器希望内存模型对它们的束缚越少越好,这样它们就可以尽可能多的优化来提高性能。编译器和处理器希望实现一个弱内存模型。JMM向程序员提供的happens-before规则不但简单易懂,也向程序员提供了足够强的内存可见性保证。JMM对编译器和处理器的束缚已原创 2020-08-06 17:05:43 · 208 阅读 · 0 评论 -
锁的内存语义
锁可以让临界区互斥执行。锁的释放和获取的内存语义当线程释放锁时,JMM(Java内存模型)把该线程对应的本地内存中的共享变量刷新到主内存中。当线程获取锁时,JMM会把该线程对应的本地内存置为无效。从而使得被监视器保护的临界区代码必须从主内存中读取共享变量。对比锁释放-获取的内存语义与volatile写-读的内存语义可以看出:锁释放与volatile写有相同的内存语义;锁获取与volatile读有相同的内存语义。线程A释放一个锁,实质上是线程A向接下来将要获取这个锁的某个线程发出了(线程A对共原创 2020-08-04 14:26:13 · 261 阅读 · 0 评论 -
synchronized和ReentrantLock
共同点都是用来协调多线程对共享对象、变量的访问都是可重入锁,同一线程可以多次获得同一个锁都保证了可见性和互斥性不同点ReentrantLock显示的获得、释放锁,synchronized隐式获得释放锁ReentrantLock可响应中断,可轮回ReentrantLock是API级别的,synchronized是JVM级别的ReentrantLock可以实现公平锁,可以通过Condition绑定多个条件底层实现不一样,synchronized是同步阻塞,使用的是悲观并发策略,lock是原创 2020-08-03 16:53:01 · 150 阅读 · 0 评论 -
java-volatile关键字
volatile的特性可见性。对一个volatile变量的读,总是能看到(任意线程)对这个volatile变量最后的写入原子性。对任意单个volatile变量的读/写具有原子性,但类似于volatile++这种复合操作不具有原子性。volatile写的内存语义当写一个volatile变量时,JMM(Java内存模型)会把该线程对应的本地内存中的共享变量值刷新到主内存。如图,线程A在写flag变量后,本地内存A中被线程A更新过的两个共享变量的值被刷新到主内存中。此时,本地内存A和主内存中的共享原创 2020-08-03 14:35:16 · 189 阅读 · 0 评论 -
Java为什么能够跨平台运行
1、Java代码不是直接运行在CPU上,而是运行在Java虚拟机上的(JVM)。2、java是先把java文件编译成二进制字节码的class文件,jvm就解释执行class文件。3、就是因为java是运行在jvm上的,所以它的代码就能不经修改在不同平台的jvm上运行。...原创 2020-07-31 19:01:41 · 1573 阅读 · 0 评论 -
经典垃圾收集器
Serial收集器单线程工作只会使用一个处理器或一条收集线程去完成垃圾收集工作进行垃圾收集时,必须暂停其他所有工作线程,直到它收集结算 “Stop The World”与其他收集器的单线程相比,Serial收集器简单而高效;对于内存资源受限的环境,它是所有收集器里额外内存消耗最小的;对于单核处理器或者处理器核心数较少的环境来说,Serial收集器由于没有线程交互的开销,专心做垃圾收集自然可以获得最高的单线程收集效率。ParNew收集器Serial收集器的多线程并行版本除了Seria.原创 2020-07-31 18:43:23 · 230 阅读 · 0 评论 -
在并发编程中:线程之间如何通信及线程之间如何同步?
线程之间如何通信通信指线程之间以何种机制来交换信息。在命令式编程中,线程之间的通信机制有两种共享内存消息传递共享内存在共享内存的并发模型里,线程之间共享程序的公共状态,通过 写—读内存中的公共状态进行隐式通信。消息传递在消息传递的并发模型里,线程之间没有公共状态,线程之间必须通过发送消息来显式进行通信。线程之间如何同步同步是指程序中用于控制不同线程间操作发生相对顺序的机制。在共享内存并发模型里,同步是显式进行的。程序员必须显式指定某个方法或者某段代码需要在线程之间互斥执行。在消息传原创 2020-07-30 17:04:50 · 1030 阅读 · 0 评论 -
内存分配与回收策略学习理解
Java技术体系的自动内存管理,最根本的目标是自动化解决两个问题:自动给对象分配内存以及自动回收给对象的内存。基本的内存分配原则:对象优先在Eden分配大对象直接进入老年代长期存活的对象将进入老年代空间分配担保对象优先在Eden分配大多数情况下,对象在新生代Eden区中分配。当Eden区没有足够空间进行分配时,虚拟机将发起一次Minor GC。大对象直接进入老年代大对象指需要大量连续内存空间的Java对象,最典型的大对象便是那种很长的字符串,或者元素数量很庞大的数组。在JVM中要避免原创 2020-07-30 15:40:46 · 293 阅读 · 0 评论 -
JVM-运行时数据区
线程私有:程序计数器、虚拟机栈、本地方法栈共享区域:堆、方法区Java堆所有线程共享的一块内存区域,在虚拟机启动时创建。此内存区域的唯一目的就是存放对象实例。几乎所有的对象实例和数组都应当在堆上分配。Java堆既可以被设计成固定大小的,也可以是可扩展的。(通过-Xmx、-Xms设定)。方法区各个线程共享的内存区域。运行时常量池是方法区的一部分。Class文件中的一项信息——常量池表,用于存放编译期生成的各种字面量与符号引用,这部分内容将在类加载后存放在方法区的常量池中。运行时常量池.原创 2020-07-29 17:04:01 · 145 阅读 · 0 评论 -
Java如何实现原子操作
原子操作(atomic operation):不可被中断的一个或一系列操作。Java通过锁和循环CAS的方式来实现原子操作循环CAS自旋CAS实现的基本思路:循环进行CAS操作直到成功为止。CAS实现原子操作的三大问题1)ABA问题参考: Java中的CAS操作2)循环时间长开销大自旋CAS如果长时间不成功,会给CPU带来非常大的执行开销。3)只能保证一个共享变量的原子操作。锁机制锁机制保证了只有获得锁的线程才能够操作锁定的内存区域。JVM内部实现了很多锁机制:偏向锁、轻量级锁、互斥锁原创 2020-07-28 11:25:03 · 355 阅读 · 0 评论 -
动态代理&&静态代理
代理模式的定义:代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用,通俗的来讲代理模式就是我们生活中常见的中介。动态代理和静态代理的区别在于静态代理我们需要手动的去实现目标对象的代理类,而动态代理可以在运行期间动态的生成代理类。静态代理1、为现有的类(Printer类)编写一个对应的代理类,并且让它实现和目标类相同的接口(public class PrinterProxy implements IPrinter )2、在创建代理对象时,通过构造器塞入一个目标对象private原创 2020-07-23 18:08:48 · 183 阅读 · 0 评论 -
Java中的CAS操作
CAS(Compare and Swap),JDK提供的非阻塞原子性操作,通过硬件保证了比较-更新操作的原子性。JDK里面的Unsafe类提供了一系列compareAndSwap*方法:public final native boolean compareAndSwapObject(Object var1, long var2, Object var4, Object var5); public final native boolean compareAndSwapInt(Object var原创 2020-07-17 16:25:38 · 711 阅读 · 0 评论 -
ReentrantLock公平锁及非公平锁实现
ReentrantLock是可重入的独占锁,同时只能有一个线程可以获取该锁,其他获取该锁的线程会被阻塞而被放入该锁的AQS阻塞队列里面。根据参数来决定其内部是一个公平锁还是非公平锁。默认非公平锁。 public ReentrantLock() { sync = new NonfairSync(); } public ReentrantLock(boolean fair) { sync = fair ? new FairSync() : new NonfairSync(原创 2020-07-15 20:19:10 · 877 阅读 · 0 评论 -
java四种对象引用
强引用软引用弱引用虚引用强引用Strongly Reference指在程序代码之中普遍存在的引用赋值,即:Object obj = new Object()。无论任何情况下,只要强引用关系还存在,垃圾收集器就永远不会回收掉被引用的对象。软引用Soft Reference描述一些还有用,但非必须的对象。只被软引用关联着的对象,在系统将要发生内存溢出一场前,会把这些对象列进回收范围之中进行第二次回收,如果这次回收还没有足够的内存,才会抛出内存溢出异常。/** * Soft refe.原创 2020-07-13 19:48:48 · 233 阅读 · 0 评论 -
ThreadLocal
ThreadLocal是JDK包提供的,它提供了本地线程变量。如果你创建了一个ThreadLocal变量,那么访问这个变量的每个线程都会有这个变量的一个本地副本。当多个线程操作这个变量时,实际操作的是自己本地内存里面的变量,从而避免了线程安全问题。内存溢出每个线程内部都有一个名为threadLocals的成员变量/* ThreadLocal values pertaining to this thread. This map is maintained * by the Threa原创 2020-07-13 19:32:32 · 231 阅读 · 0 评论 -
线程池ThreadPoolExecutor的基本配置
ThreadPoolExecutor通用构造函数:public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQ.原创 2020-07-12 22:39:38 · 442 阅读 · 0 评论 -
Redis是如何处理过期的key的?
两种方式被动:惰性删除主动:随机删除当客户端请求一个key时,redis发现该key以过期,则会触发删除操作(惰性删除)。仅仅通过这种被动的方式处理是不够的,毕竟也可能存在大量过期的key永远不会被客户端访问,所以Redis会定期的测试一些随机的存在过期的key,如果过期则会删除(随机删除)。随机测试20个存在过期时间的key删除所有已过期的key如果超过25%的key过期了,则从步骤1开始再来一遍关于数据一致性,当一个key过期了,DEL操作会合到AOF文件中,并获得所有连接的从节原创 2020-07-09 18:11:15 · 623 阅读 · 0 评论 -
leetcode:数组-桶排序思想理解
数组-1365. 有多少小于当前数字的数字内外循环遍历解法最易懂的方式:1、外循环,遍历数组内每个元素2、内循环,遍历当前元素之前所有元素,累加class Solution { public int[] smallerNumbersThanCurrent(int[] nums) { int[] res = new int[nums.length]; for(int i=0;i<nums.length;i++){ int coun原创 2020-06-16 17:22:20 · 324 阅读 · 0 评论 -
Redis的十个问题
1.Redis支持的数据类型?2.什么是Redis持久化?Redis有哪几种持久化方式?优缺点是什么?3.Redis 有哪些架构模式?讲讲各自的特点4.使用过Redis分布式锁么,它是怎么实现的?5.使用过Redis做异步队列么,你是怎么用的?有什么缺点?6.什么是缓存穿透?如何避免?什么是缓存雪崩?何如避免?7.Redis常用命令8.为什么Redis 单线程却能支撑高并发?9.说说Redis的内存淘汰策略10.Redis的并发竞争问题如何解决?1.Redis支持的数据类型?2..原创 2020-06-03 17:27:34 · 216 阅读 · 0 评论 -
mysql:char && varchar
CHAR 和 VARCHAR类型类似,不同之处在于存储和获取末尾空格char(n): 0<n<=255存储时,右侧会自动填充空格以达到指定长度,获取时填充的空格会移除varchar(n) : <0<=65535varchar会额外使用1~2byte来存储该列value的长度1 byte :长度<=2552 byte : 长度>255存储时,不会自动填充空格示例:char类型末尾的空格都会移除,varchar类型的会保留。参考官方文档:ht原创 2020-06-01 19:29:18 · 252 阅读 · 0 评论 -
Java关键字:final
final关键字可以声明类、成员变量、方法、本地变量。// 声明类// 不允许被继承 Cannot inherit from final 'java.lang.String'public final class String implements java.io.Serializable, Comparable<String>, CharSequence {}// 声明成员变量private static final long serialVersionUID = -6849转载 2020-05-28 15:58:35 · 413 阅读 · 0 评论 -
JVM:垃圾收集GC要完成的三件事
垃圾收集需要完成的三件事:哪些内存需要回收什么时候回收如何回收哪些内存需要回收Java堆、方法区程序计数器、本地方法栈、虚拟机栈随线程而生、随线程而灭。栈中的栈帧随着方法的进入和退出而有条不紊地执行着出栈和入栈操作。每一个栈帧中分配多少内存基本上是在类结构确定下来时就已知的。因此程序计数器、本地方法栈、虚拟机栈不需要过多考虑如何回收的问题,当方法结束或者线程结束时,内存自然就跟着回收了。什么时候回收Java堆:对象已死方法区:废弃的常量、不再使用的类如何判断对象已死?引用计数原创 2020-05-25 14:58:21 · 243 阅读 · 0 评论 -
Java-for循环、for-each、forEach()中的break、continue、return;
语句普通for循环for-eachJava8-forEachreturn跳出循环,直接返回方法跳出循环,直接返回方法跳过当前元素,继续执行循环break跳出循环,继续执行方法跳出循环,继续执行方法不可用continue跳过当前元素,继续执行循环跳过当前元素,继续执行循环不可用Java-for循环return:跳出循环,直接返回方法List<Integer> integers = new ArrayList<>(); ...原创 2020-05-18 16:57:36 · 5915 阅读 · 1 评论 -
mysql-ON DUPLICATE KEY UPDATE
官方文档sql语句:INSERT INTO t1 (a,b,c) VALUES (1,2,3) ON DUPLICATE KEY UPDATE c=c+1;表t1中,存在(a是唯一索引),则上述sql语句等同于if(表中不存a=1的数据) : INSERT INTO t1 (a,b,c) VALUES (1,2,3) else UPDATE t1 SET c=c+1 WHERE a=1;表t1中,存在(a是唯一索引,b是唯一索引),则上述sql语句等同于if(表中不存原创 2020-05-11 16:43:07 · 129 阅读 · 0 评论 -
20191211-编写高质量代码:6-枚举和注解
推荐使用枚举定义常量enum Season{ Spring,Summer,Autumn,Winter;}枚举常量更简单枚举常量属于稳太型枚举具有内置方法values()获取所有的枚举项。枚举可以自定义方法在项目开发中,推荐使用枚举常量代替接口常量或类常量。使用构造函数协助描述枚举项小心switch带来的空值异常在switch的default代码块中增加As...原创 2019-12-11 19:30:20 · 91 阅读 · 0 评论 -
20191202-编写高质量代码:5-数组和集合
性能考虑,数组是首选在Java中数组确实没有List、Set、Map这些集合类用起来方便,但在基本类型处理方面,数组还是占优势的,而且集合类的底层也都是通过数组实现的。若有必要,使用变长数组Java中的数组是定长的,一旦经过初始化声明就不可改变长度。可以通过对数组扩容来解决该问题:public static <T> T[] expandCapacity(T[] data...原创 2019-12-02 19:20:34 · 180 阅读 · 0 评论 -
20191201-编写高质量代码:4-字符串
推荐使用String直接量赋值推荐直接声明方式:String str = "a" String str1 = "china"; String str2 = "china"; String str3 = new String("china"); String str4 = str3.intern(); System.out.println(str1 == str2); Sys...原创 2019-12-01 16:03:38 · 407 阅读 · 0 评论 -
20191128-编写高质量代码:3-类、对象及方法
在接口中不要存在实现代码静态变量一定要先声明后赋值static { i = 100;}public static int i=1;public static void main(String[] args){ System.out.println("i="+i);}这段代码是可以编译的,输出结果为:i=1静态变量是类加载时被分配到数据区(Data Area)的...原创 2019-11-29 06:14:15 · 123 阅读 · 0 评论 -
20191127-编写高质量代码:2-基本类型
Java中的基本数据类型有8个:byte、short、int、long、float、double、boolean、char用偶判断,不用奇判断String str = 1%2==1?"奇数":"偶数";System.out.println("1 是" + str);str = 2%2==1?"奇数":"偶数";System.out.println("-2 是" + str);...原创 2019-11-27 17:03:07 · 128 阅读 · 0 评论 -
20191126-编写高质量代码:1-Java开发中
不要在常量和变量中出现易混淆的字母莫让常量蜕变成变量常量就是常量,在编译期就必须确定其值,不应该在运行期更改务必让常量的值在运行期保持不变三元操作符的类型务必一致三元操作符是if-else的简化写法int i=80;System.out.println(String.valueOf(i<100 ? 90 : 100));System.out.println(String....原创 2019-11-26 18:21:51 · 141 阅读 · 0 评论 -
20191121-Java8 Action 第四章:引入流
什么是流流是Java API的新成员,它允许你以声明性方式处理数据集合(通过查询语句来表达,而不是临时编写一个实现)。可以把它看成遍历数据集的高级迭代器。流可以透明的并行处理。流简介流的简短定义:从支持数据处理操作的源生成的元素序列。元素序列——流提供了一个接口,可以访问特定元素类型的一组有序值源——流会使用一个提供数据的源,如集合、数组或者输入|输出资源。(从有序集合生成流时会保留...原创 2019-11-21 19:33:21 · 275 阅读 · 0 评论