如何编写Java递归函数?
这篇关于Java中递归的深入教程通过示例、类型和相关概念解释了什么是递归。它还包括递归与迭代: 从Java的早期教程中,我们已经看到了迭代方法,其中我们声明一个循环,然后通过一次获取一个元素以迭代的方式遍历数据结构。 我们还看到了一个条件流,其中我们保留一个循环变量并重复一段代码,直到循环变量满足条件为止。说到函数调用,我们还研究了函数调用的迭代方法。 Java中的递归是什么? 递归是一个函数或方
这篇关于Java中递归的深入教程通过示例、类型和相关概念解释了什么是递归。它还包括递归与迭代: 从Java的早期教程中,我们已经看到了迭代方法,其中我们声明一个循环,然后通过一次获取一个元素以迭代的方式遍历数据结构。 我们还看到了一个条件流,其中我们保留一个循环变量并重复一段代码,直到循环变量满足条件为止。说到函数调用,我们还研究了函数调用的迭代方法。 Java中的递归是什么? 递归是一个函数或方
在Java中,调用自身的方法称为递归方法。这个过程被称为递归。 一个物理世界的例子是将两个平行的镜子相对放置。它们之间的任何对象都将被递归地反射。 递归是如何工作的? 在上面的示例中,我们从main方法内部调用了recurse()方法。(普通方法调用)。在recurse()方法中,我们再次调用相同的recurse方法。这是一个递归调用。 为了停止递归调用,我们需要在方法内部提供一些条件。否则,方法
Java中的递归 什么是递归? 函数直接或间接调用自身的过程称为递归,相应的函数称为递归函数。使用递归算法,某些问题可以很容易地解决。这类问题的例子有Hanoi的Towers(TOH)、序/前序/后序树遍历、图的DFS等。 递归中的基本条件是什么? 在递归程序中,给出了基本情况的解,大问题的解用小问题表示。 int fact(int n) { if (n < = 1) // base cas
Java8中关于Java7的一个重大变化是用元空间替换永久代。 我们将通过提醒一些关于永久代的信息来开始本文。主要,我们将列出它的缺点,以便更好地理解Java8中用元空间替换它的原因。第二部分将描述更多的新空间在内存中。最后一部分将介绍分析元空间中发生的事情的不同方法。 永久代Permgen缺陷 永久代是一个包含JVM所需数据的池,例如类或方法。当JVM想要创建给定类的新实例时,此数据很有用。通常
对于我的应用程序,Java进程使用的内存远远大于堆大小。 运行容器的系统开始出现内存问题,因为容器占用的内存远远超过堆大小。 堆大小设置为128MB(-Xmx128m -Xms128m),而容器最多占用1GB内存。正常情况下需要500MB。如果docker容器的限制低于(例如mem_limit=mem_limit=400MB),则进程将被操作系统的内存不足杀手杀死。 那么为什么Java进程比堆占用
一. JVM内存模型 根据JVM规范,JVM内存分为五个部分:虚拟机堆栈、堆、方法区、程序计数器和本地方法堆栈。 虚拟机堆栈:每个线程都有一个私有堆栈,该堆栈在创建线程时创建。堆栈内部是一种称为“堆栈帧”的东西。每个方法将创建一个堆栈帧。堆栈帧存储局部变量表(基本数据类型和对象引用)、操作数堆栈、方法退出和其他信息。堆栈的大小可以固定,也可以动态扩展。当堆栈调用深度大于JVM允许的范围时,将抛出s
这个java.lang.OutOfMemoryError:Metaspace表示为Java类元数据分配的本机内存量已被耗尽。让我们来看看如何解决这个问题。 一般来说,可以在命令行上设置MaxMetaSpaceSize: java -XX:MaxMetaspaceSize=3200m 你可以试着增加它的价值,看看它是否能解决问题。还要记住,减小Java堆的大小将为MetaSpace提供更多的可用空间
Java虚拟机(JVM)使用其类的内部表示形式,其中包含每个类的元数据,如类层次结构信息、方法数据和信息(如字节码、堆栈和变量大小)、运行时常量池以及解析的符号引用和Vtables。 在过去(当自定义类装入器不那么常见的时候),类大多是“静态”的,很少被卸载或收集,因此被标记为“永久”。另外,由于类是JVM实现的一部分,而不是由应用程序创建的,因此它们被视为“非堆”内存。 对于JDK8之前的hot
在我们平时开发中或多或少都会遇到需要调用接口来完成一个功能的需求,这个接口可以是内部系统也可以是外部的,然后等到接口返回数据了才能继续其他的业务流程,这就是传统的同步模式。 同步模式虽然简单但缺点也很明显,如果对方服务处理缓慢迟迟未能返回数据,或网络问题导致响应变长,就会阻塞我们调用方的线程,导致我们主流程的耗时latency延长,传统的解决方式是增加接口的超时timeout设置,防止无限期等待。
ForkJoinPool线程池最大的特点就是分叉(fork)合并(join),将一个大任务拆分成多个小任务,并行执行,再结合工作窃取模式(worksteal)提高整体的执行效率,充分利用CPU资源。 一. 应用场景 ForkJoinPool使用分治算法,用相对少的线程处理大量的任务,将一个大任务一拆为二,以此类推,每个子任务再拆分一半,直到达到最细颗粒度为止,即设置的阈值停止拆分,然后从最底层的任
今天继续远程办公,好想出去打篮球,但是怂,外面场地也不开放,只能窝在家憋大招。 互联网公司流行敏捷开发,快速迭代,所以憋出的大招不一定适用(扯远了)。 言归正传这次和大家分享一些虚拟机方面的知识,主要是关于jvm的client和server端区别,支持的工作模式有哪几种以及他们之间的关系。 java -version 命令大家都用过,大部分就是看下jdk版本或检查下环境变量的设置,但最后一行的信息
上海这边的互联网公司大部分是2-7号在家远程办公,有些可能更晚,这期间工作上的事情不多,就把《深入理解java虚拟机》这本书又撸了一遍,顺便写下心得体会,和大家分享,温故知新。 一. codeCache简介 从字面意思理解就是代码缓存区,它缓存的是JIT(Just in Time)编译器编译的代码,简言之codeCache是存放JIT生成的机器码(native code)。当然JNI(Java本地
JAVA开发中,大部分的性能问题原因并不在于JAVA语言本身,而是我们用这些语言写的程序,所以养成良好的编码习惯非常重要。 下面给大家分享一些日常开发中比较常见的典型案例: 一. 类中的内部方法声明为private 很多同学觉得这个无所谓,写代码时喜欢一个类里的所有方法都是public的(原因大家都懂),美其名曰:便于后期扩展。。 对于不需要外部访问的方法改为私有的,不仅仅是因为面向对象的思想,符
线程池大家都很熟悉,无论是平时的业务开发还是框架中间件都会用到,大部分都是基于JDK线程池ThreadPoolExecutor做的封装,比如tomcat的线程池,当然也有单独开发的,但都会牵涉到这几个核心参数的设置:核心线程数,等待队列,最大线程数,拒绝策略等。 先说下我们项目组在使用线程池时踩到的坑: 线程池的参数设置一定要结合具体的业务场景,区分I/O密集和CPU密集,如果是I/O密集型业务,
现在大部分公司都有自己完整的一套监控系统,比如美团的CAT,我们公司的监控系统也是基于CAT做的二次开发。一般测试环境或生产环境有问题可以直接使用这些系统查看线程和内存运行情况,分析排查问题。 但对于我们开发人员来说还是有必要了解最原始的排查流程,也就是不借助这些系统,使用最基本的命令解决,毕竟了解了这些底层实现对自身发展也是有帮助的。 网上搜下这样的文章其实很多,比如排查cpu过高,死锁问题的文
一. 现象 前段时间公司线上环境的一个Java应用因为OOM的异常报警,导致整个服务不可用被拉出集群,本地模拟重现的现象如下: 当时的解决方案是增加metaspace的容量:-XX:MaxMetaspaceSize=500m,从原来默认的256m改为500m,虽然没有再出现oom,但这个只是临时解决方案,通过公司的监控系统观察metaspace的使用情况还是在上升,而且后面随着业务访问量越来越大还
一. 简介 Arthas是阿里在2019年9月份开源的一款java在线诊断工具,能够分析、诊断、定位java应用问题,例如:jvm信息、线程信息、搜索类中的方法、 跟踪代码执行、观测方法的入参和返回参数等等。 Arthas最大的特点是能在不修改代码和不需要重新发布的情况下,对业务问题进行诊断,包括查看方法调用的出参入参、异常、监测方法执行耗时、类加载信息等,大大提升线上问题排查效率。 二. 适用场
在平时开发中经常会遇到需要调用接口和外部服务的场景,但是有些接口服务方不能立即返回数据,而是需要处理一段时间才能返回真实的业务数据,如果没有处理完则直接返回一个中间状态的结果。 业务场景: 代码中存在依赖不稳定的场景,需要使用重试获取预期结果或者尝试重新执行逻辑不立即结束,比如远程接口访问,数据加载访问,数据上传校验等 对于异常需要重试的场景,同时希望把正常逻辑和重试逻辑解耦 对方接口不支持异步回
java.util.Arrays的asList方法可以方便的将数组转化为集合,我们平时开发在初始化ArrayList时使用的比较多,可以简化代码,但这个静态方法asList()有几个坑需要注意: 一. 如果对集合使用增加或删除元素的操作将会报错 如下代码: List list = Arrays.asList("a","b","c"); list.add("d"); 输出结果: Exception
在java.math包中提供了对大数字的操作类,用于进行高精确计算,如BigInteger,BigDecimal类。而平常我们开发中使用最多的float和double只能适用于一般的科学和工程计算,如果要在比较精确的计算方面如货币,那么使用float和double会相应的丢失精度,因此用于精密计算大数字的类BigDecimal就必不可少了。所以BigDecimal适合商业计算场景,用来对超过16位