Java方法传参/值传递/引用传递
引言本文主要讲解Java方法传参、值传递、引用传递,其中涉及到JVM的相关知识,最近弥补了这一块,发现理解很多问题都变得豁然开朗了,知其所以然!(JVM在我其他博客中有详细辨析)在刷力扣题目时,遇到这样一个问题,当我把一个变量传进dfs方法后,无论递归中如何对该变量赋值,最终都没有生效,今来探究其原因,说到底还是Java值传递、引用传递的问题:
方法传参Java的方法传值,有基本数据类型以及引用类型两种:
12int num = 10; //基本类型String str = "hello"; //引用类型
这里num是基本类型,str是引用类型,str是引用类型,对于引用类型来说,它本质上保存的是一个地址,指向了 “hello”这个字符串。
再还要来理解一下赋值操作(=)的具体含义:
基本类型的赋值,是直接对其保存的值进行修改的,而引用类型的赋值,本质上是改变了它指向的对象而已,原来指向的对象并没有改变:
继续看方法的调用:
在方法中传参数时,实际上是进行了赋值操作
123456789101112131415161718192021222324252627282930作者: ...
深入理解JVM【垃圾回收机制】
三、JVM垃圾回收机制3.1 堆为什么要分成年轻代和老年代?因为年轻代和老年代不同的特点,需要采用不同的垃圾回收算法;
年轻代的对象,它的特点是创建之后很快就会被回收,所以需要用一种垃圾回收算法;
老年代的对象,它的特点是需要长期存活,所以需要另外一种垃圾回收算法 ;
所以需要分成两个区域来放不同的对象;
1、绝大多数对象都是朝生夕灭的;
如果一个区域中大多数对象都是朝生夕灭,那么把它们集中放在一起,每次回收时只关注如何保留少量存活对象,而不是去标记那些大量将要被回收的对象,就能以较低的代价回收到大量的空间;
2、熬过越多次垃圾收集的对象就越难以回收;
如果是需要长期存活的对象,那把它们集中放在一块,虚拟机便可以使用较低的频率来回收这个区域,这就同时兼顾了垃圾收集的时间开销和内存的空间有效利用;
3、JVM划分出新生代、老年代之后,垃圾收集器可以每次只回收其中某一个或者某些部分的区域 ,同时也有了“Minor GC”“Major GC”“Full GC”这样的回收类型的划分;
Minor GC/Young GC :新生代收集
Major GC/Old GC:老年代收集
Full GC ...
深入理解JVM【内存管理】
二、深入剖析JVM内存管理2.1 Java代码到底是如何运行起来的?1、Mall.java –>javac –> Mall.class –> java Mall (jvm进程,也就是一个jvm虚拟机)
2、Mall.java –>javac–>Mall.class –>Mall.jar –> java -jar Mall.jar
3、Mall.java –> javac –> Mall.class –>Mall.war –> Tomcat –> startup.sh –> org.apache.catalina.startup.Bootstrap (jvm进程,也就是一个jvm虚拟机)
其实运行起来一个Java程序,都是通过D:\dev\Java\jdk1.8.0_251\bin\java 启动一个JVM虚拟机,在虚拟机里面运行Mall.class字节码文件;
总结:
java源文件通过javac命令转成java字节码文件,再通过java命令运行起来,JVM是用于屏蔽掉底层操作系统之间的差异,这里不同操作 ...
深入理解JVM【JVM类加载机制】
概述:
JVM类加载机制
深入剖析JVM内存管理
JVM垃圾回收机制
JVM故障诊断性能调优
一、JVM类加载机制1.1 Java运行时一个类是什么时候被加载的?一个类在什么时候开始被加载,《Java虚拟机规范》中并没有进行强制约束,交给了虚拟机自己去自由实现,HotSpot虚拟机是按需加载,在需要用到该类的时候加载这个类;
1、Sun公司最早的 Classic虚拟机;
2、Sun/Oracle公司的HotSpot虚拟机;
3、BEA公司的JRockit虚拟机;
4、IBM公司的IBM J9虚拟机;
官方:https://docs.oracle.com/javase/8/
https://docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html
-XX:+TraceClassLoading
测试类的详细载入:
1.2 JVM一个类的加载过程?一个类从加载到jvm内存,到从jvm内存卸载,它的整个生命周期会经历7个阶段:
1、加载(Loading)
2、验证(Verification)
3、准备(Preparat ...
一文搞懂云计算精髓MapReduce
MapReduce 简介核心思想:“分而治之” MapReduce思想在生活中处处可见。或多或少都曾接触过这种思想。MapReduce的思想核心 是“分而治之”,适用于大量复杂的任务处理场景(大规模数据处理场景)。
Map负责——分,把复杂的任务分解为若干个“简单的任务”来并行处理。可以进行拆分的 前提是这些小任务可以并行计算,彼此间几乎没有依赖关系。
Reduce负责——合,对map阶段的结果进行全局汇总。 MapReduce运行在yarn集群
有两个阶段:
ResourceManager
NodeManager
这两个阶段合起来正是MapReduce思想的体现。后面再细说这两个阶段。 MapReduce的执行流程用下面这张图一目了然: 简而言 ...
弄懂服务端、客户端【手写一个socket聊天室】
常见架构:C/S架构:Client/Server(客户端/服务器)结构B/S架构:Browser/Server(浏览器/服务器)结构
服务端和客户端 简单地说:一般客户端负责和用户的交互,也就是屏幕显示(UI/UE),服务端负责数据存储,也就是你的用户数据,而计算能力,客户端和服务端一般各负责一部分。 微信、qq这种聊天功能一般在用户之间通信时,用户的数据先是发送到服务器上的,然后通过服务器进行转发给指定用户,从而完成一次用户间的通信,那么如何证明这一点呢?比如一下几种场景:
当A用户不在线时,B用户给A发送,A是接收不到的,当A一上线,信息会立马发送给他,可推理出B用户发送的数据会保存在服务器中。
当A用户给B传输文件时,上传完后,B需要下载才可传输到本地,说明下载之前已经上传到服务器了,如果清空本地的该文件,在一定时间范围内仍然可以重新下载回来,说明服务器上文件还在。 ...
深入线程池【手写线程池!阿里弃用之辨析】
什么是线程池 线程池和数据库连接池非常类似,可以统一管理和维护线程,减少没有必要的开销。
为什么要使用线程池 因为频繁的开启线程或者停止线程,线程需要从新被 cpu 从就绪到运行状态调度,需要发生cpu 的上下文切换,效率非常低。
当线程从run中sleep后,会到达阻塞状态,这时候要想再回到run状态,得先就绪再到run状态,成本极高;
分析:如果这里有100个线程,则会新建100个newThread,100次start,100次的就绪,100次的CPU调度,才能被运行,必然也有100次的销毁,整个的成本非常高!所以我们提前创建好100个线程,都在运行状态,只要有请求过来了,直接再run方法中进行执行就行了!而不是又经过创建->就绪->运行 这个耗时的过程! ...
别再问我字符串了!彻底理解Java中的字符串(==、equals、堆内存、常量池)
预备知识equals、== 首先明确一点,==比较的是引用,equals比较的是内容,在类库没有定义equals方法重写的情况下,自然继承的是Object类的equals方法,上源码:
123public boolean equals(Object obj) { return (this == obj); }
那么对于String类来说,官方已封装了复写之后的equals方法,比较的是具体内容,判断:如果是引用相同,也就是堆内的地址相同,那么就是同一个对象,直接返回true,否则就遍历字符串中的每一个字符进行比较:
123456789101112131415161718192021public boolean equals(Object anObject) { if (this == anObject) { return tr ...
Mac Alfred 工作流 Python开发,可自定义任何接口,全自动化办公
Alfred 用Mac的人应该大多都知道这个,但是workflow工作流,应该是很多人没自己写过,得知支持Python脚本后,自己花了几个小时研究了一下如何把接口融合到Alfred快捷方式中,这里给大家提供一个模板,以这样的形式,无论是免费api还是自己封装的工具接口,均可集成到Alfred中!
效果图
申请接口 市面上有很多免费接口,这里以聚合数据的头条新闻api为例,链接:https://www.juhe.cn/docs/api/id/235,在官网注册申请api即可,得到一个key,发送请求参数时带上key和其他参数即可。
Workflow建立空白workflow填上基本信息即可,也可以设置一个图标再在里面空白处右键选择script filter
在script filter里面,我们去运行Python脚本,接受的参数就是”{query}”可以进行传参,这里采用了一个免费的头条新闻api,只要接口能测成功即可,不赘 ...
多线程中的wait与sleep ,synchronize与lock有啥子区别?死锁辨析
wait与sleep
来自不同的类首先,wait和sleep都不是一个类下的方法:wait来自:Objectsleep来自:Thread
因为java中所有的类都是继承自object的,所以所有类都可以调用wait方法,这是一个final的方法,同时不是一个静态方法,所以调用该方法需要先实例化一个Object对象才可以
释放锁的不同wait 会释放锁,sleep 睡觉了,抱着锁睡觉,不会释放! 也就是说,如果有两个线程,其中一个锁住了某个对象时,中间sleep了,这时候另一个线程时拿不到该对象的锁的,得等第一个线程sleep完并释放锁才可。wait会释放这个锁,并把这个wait的线程加入到这个锁的等待队列中去
使用的范围不同wait必须在同步代码块中使用
使用sleep不需要被唤醒,但是wait是需要notify()或者notifyAll()去唤醒的,除了wait(1000)这种形式.
举例说明问题:
synchronized与locksynchronized synchronized如果 ...














