「java小案例分析」java案例分析题
今天给各位分享java小案例分析的知识,其中也会对java案例分析题进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!
本文目录一览:
- 1、java基础与案例分析 第二章最后一个题 结合换行 制位表 空格在控制台打印出由“*”所组成的心形效果图
- 2、北大青鸟java培训:软件开发集合类的概念解析?
- 3、JVM对于signal的处理及案例分析
- 4、实例分析Java中public static void main是什么意思
- 5、java代码解析
java基础与案例分析 第二章最后一个题 结合换行 制位表 空格在控制台打印出由“*”所组成的心形效果图
凑合着看吧,刚实现了一个,代码如下:
public class Test {
public static void main(String args[]) {
System.out.println("this is XX!");
System.err.println(" ** ** ");
System.err.println(" ** ** ** ** ");
System.err.println(" ** ** ** ");
System.err.println(" ** ** ");
System.err.println(" ** ** ");
System.err.println(" ** ** ");
System.err.println(" ** ");
}
}
复制到百度里面有点乱,你要是会用MyEclipse的话直接Ctrl+Shift+F;
如果喜欢的话希望采纳@~
北大青鸟java培训:软件开发集合类的概念解析?
我们学习java编程开发语言,除了需要掌握基本语法以外,同时也需要了解什么是集合与数据结构,下面我们就通过具体的案例分析来了解一下吧。
希望通过对本文的阅读,大家对于java编程有更多的了解。
什么是集合类如果你学习说数据结构,那么学习集合就很简单.因为集合就是存储数据的结构.例如有链表结构(list)还有map结构.等等.集合类就是存储数据的集合.Collection接口.由Set类.以及List类就行实现.并且还有子类.Map有HashMap类.还有TreeMap类继承.各个类都是不一样的.比如List.代表链表类.可以存储数据,是连续的.只要有前驱后继即可.子类就是对链表进行了限制而已.二丶Collection接口每次学习一个类的时候.都要从它的顶层开始学习.比如我们学习list类.那么先就要看他的父类.父类是否还有父类.因为公共父类是Object,所以我们就不介绍了.直接介绍Conllection接口这个接口.是层级结构中的根接口.构成Collection的单位称为元素.Collection通常是不能直接使用的.但是这个接口提供了添加元素.删除元素.管理数据的方法.List跟Set接口.都继承了Collection接口.所以她们也都默认有这些方法.三丶List接口从上面的类的继承图可以看到.List接口实现了Collection接口.所以List接口中包含了Collection接口的方法.但是List接口还提供了两个重要的方法.get(intindex):获取指定索引位置的元素set(intindex,Objectobj);将集合中指定索引位置的对象修改为指定的对象.提供了Setget方法.因为添加了两个重要方法.所以List接口有两个类实现了它.分别有不同的作用ArrayList类:这个类就是可变的数组.我们定义的数组都是死的.new多大就是多大.它是可以变得.跟数组一样用.就是可以自动变.我们自己也可以封装.在C++中就是STL的vcteor.作用:可以进行快速的随机访问.缺点就是向指定索引位置插入或者删除对象慢.原因:如果学过C++并且自己封装就知道.其实当你数据超过数组大位置的时候.而是释放这块内存.重新申请一块大内存.并且湖南北大青鸟建议拷贝原有数据.然后插入到指定位置的时候.,还需要遍历数组.移动元素.所以底层做了很多.所以这就是慢的原因.
JVM对于signal的处理及案例分析
Windows的Signal相对少一些, 如下:
Linux的Signal比较多, 如下:
Linux中的Signal可以由 kill 命令发起, 比如 kill -1 [pid] 是对某一个进程发出SIGHUP信息.
JVM 所使用的信号:
信号的类型为 异常、错误、中断和控制 。
表 1
注:
信号名称后提供的数字是该信号的标准数值。
使用 -Xrs(减少信号使用)选项来防止 JVM 处理大多数的信号。有关更多信息,请参阅 Oracle 的 Java™ 应用程序启动程序页面 。
JVM 线程上的信号 1(SIGHUP)、2(SIGINT)、4(SIGILL)、7(SIGBUS)、8(SIGFPE)、11(SIGSEGV)和 15(SIGTERM)导致 JVM 关闭;因此,应用程序信号处理程序不应该尝试从这些信号恢复,除非它不再需要 JVM。
以上表格引用原文链接:
至于JVM是如何处理这些Signal的, 请参考以下链接:
除了JVM默认处理Signal的行为, 我们还可以自定义 SignalHandler 来做一些额外的工作, 比如在关闭JVM之前做一些回收或记录的事情.
例子:
关闭钩子使用的方法也很简单, Runtime.getRuntime().addShutdownHook(Thread hook) 即可。关闭钩子其实可以看成是一个已经初始化了的但还没启动的线程,当 JVM关闭时会并发地执行注册的所有关闭钩子 。
JVM的关闭方式可以分为三种:
注意: Hook线程在JVM 正常关闭 才会执行,在强制关闭时不会执行。(异常关闭没试过, 有空试一下..)
另外在使用关闭钩子还要注意以下几点:
Spring 在初始化容器的时候就会注册一个hook线程用于清理容器.
[图片上传失败...(image-3b9611-1513089974690)]
JVM进程已经不在了, 重启后, 几分钟到半小时之间, 会看到获取不到spring bean的错误日志, 同时系统服务异常.
[图片上传失败...(image-cfc2ef-1513089974690)]
奇怪的是, 2台集群中的其他一台一直都是稳定运行, 只有这台是一直异常状态.
从以上的日志, 可以看出spring容器已经在销毁中了, 感觉是一个正常的关闭系统的流程.
在监控系统(Marvin)中观察了内存的情况, 没有什么波动, 基本排除了oom的情况.
接下来, 我使用jstack输出了当时的线程栈信息, 保留现场痕迹.
[图片上传失败...(image-508b17-1513089974690)]
由上图所示, 从jstack日志中发现了2个关键的点:
自此, 大家可能已经看出来, SIGHUP 正是JVM会处理的Signal之一, 并且在上面的表格中已经清楚的写着 SIGHUP 的操作是 挂起, 让JVM正常退出 , SIGHUP 是 中断 类型的信号, 上面对于 中断 类型的信号是这样描述的: 将从 JVM 进程外部异步发出中断信号以请求关闭。
结论:
可惜的是, 找了很多资料, 始终没有找到确定信号来源的方案. Linux本身也没有相关的日志, JVM也只能获取信号的名称, 对于信号源也是无法确定.(如果有这方面研究的同学望告知..)
找不到根本原因, 那么只能是想办法绕过这个问题.
所幸的是, 在搜索问题的时候, 让我知道了Linux还有一个 nohup 的命令.
nohup命令可以将 程序以忽略挂起信号( SIGHUP)的方式运行起来,被运行的程序的输出信息将不会显示到终端。
于是把JVM的启动脚本改动了一下:
[图片上传失败...(image-7897ca-1513089974690)]
再次启动后, 稳定运行, 问题解决.
实际上通过JVM本身 -Xrs 的参数应该也能控制忽略SIGHUP信号的, 但是时间关系, 我没去实验..
这里案例也让我学到了很多JVM的处理细节.
同时也有了一些思考:
排查线上故障的基本步骤无非就是
实际上, 前面3步基本上已经能解决大部分的问题了, 剩下的一些疑难问题才会用到第4步. 但是第4步的操作对于实时性的要求是最高的, 必须第一时间搞定, 晚一点可能你就捕捉不到有效的证据了.
在出现故障的情况下, 有时候难免手忙脚乱, 如果有一个可以自动化收集现场证据的脚本, 在出现这种疑难问题的时候将会是一个极大的助力.
实例分析Java中public static void main是什么意思
此方法为Java程序的入口方法,jvm在运行程序时,会首先查找main()方法。其中public是权限修饰符,表明任何类或对象都可以访问这个方法,static表明是静态方法,及方法中的代码是存储在静态存储区的,只要类被加载后,就可以使用该方法,不需要通过实例化来访问,可直接通过类名.main()直接访问,jvm在启动时就是按照上诉方法的签名(必须有public和static修饰,返回值为void,且方法参数为字符串数组)来查找方法的入口地址,若找到就执行,找不到就会报错。void表明方法没有返回值,mian是jvm识别的特殊方法,名,是程序的入口方法。字符串数组参数args为开发人员在命令行状态下与程序交互提供了一种手段。
注意
public与static没有先后顺序关系
static public void mian(String[] args)
也可以把main()方法定义为final
public static final void main(String[] args)
也可以用syncchronized来修饰main()方法
static public synchronized void main(String[] args)
不管是哪种定义形式,都必须保证返回值为void,并有static和public关键字修饰,因为是入口函数,所以绝对不能用abstract关键字来修饰
同一个.java文件可以有多个main方法,但只有与文件名相同的用public修饰的类中的main()方法才能作为整个程序的入口方法
java代码解析
一楼的说的够全面了,不过稍有误解.
再来表示抱歉,我对编程语言中的中文名词非常不了解,所以如果以下的回复对你的阅读或者理解造成困难,请见谅.
1.首先,要明白这个问题的答案,需要了解call (pass) by value 和 call (pass) by reference 的区别.简单来说:
call by value通常是复制这个parameter的值去另外一块内存里,然后传给function, 所以在method/function里边对这个变量的所有变更,实际上都是对复制过来的镜像进行操作,不会对原本的variable有任何影响.
call by reference是将parameter的reference传给function,简单点理解就是直接把variable传给function.所以说这个variable的值是可以被function改变的.这个用法在c/c++中非常常见,用法是variable_name.
2.再来,在Java里边,你可以很简单的理解为: Java中只有call by value, 也就是说,所以所有传给function的parameter本身都不会被改变. (这是最简单直白的理解,当然也有另一种常从sun的人那边听到的说法:Java是call by value + call by reference by value)
3.那么现在的问题就是为什么第二个结果是2了. 首先说一下sun官方的解释: 对于reference type在作为parameter/argument的时候,也是call by value, 但是在你拥有足够权限时(比方说那个变量是public的, 不是final的等等各种符合的情况),可以修改这个object中fields的值(也就是属于这个object(严谨点讲是an instance of the object) 内部的变量, 在你的例子中, ko 里边的 a 就是一个field, 所以update(ko)会使ko.a变成2).
4.如果你是一个有过c/c++学习经验的人或者你以上的解释很难理解,以下这种说法或许更适合你 (当然了,这只是大多包括我在内有c经验的人的一种理解方式)
这里可以引入一个新的概念,pointer. 这是一种比较特殊的变量,它内部所储存的东西,其实只是另外一个变量的内存地址. 如果对内存没有概念,你可以把它简单理解为是风筝的线轴,虽然看它本身看不出什么端倪,但是顺着摸过去总会找到风筝,看到它是什么样子. 以pointer方式理解Java的人,通常会说: Type variable = new Type(); 这个过程中,最后生成的这个variable其实就是一个pointer,而不是instance本身.
在Java中, 有c/c++经验的人通常认为Java是call by value.同时,当一个变量用在储存reference type的时候,实际上储存的是它的pointer,这也一样可以解释为什么ko.a会有2这个结果,因为虽然pointer被传到function里边时,本身是call by value,无法被改变.但这并不影响function本身对这个pointer指向的object的内容做任何改变. 当然,再次声明,这只是一种帮助有c/c++经验的人理解的方法. Sun本身严正声明Java里边没有pointer这个东西的存在.
5. 再来解释一下为什么说楼上所说的(或者说楼上引用的)理解略有偏差.
引用"我们上面刚学习了JAVA的数据类型,则有:值类型就是按值传递的,而引用类型是按引用传递的" 这句话很明显的有两点错误. 第一点,如果我上面所说的,Java是没有call by reference的.
第二点,暂且假设Java里边是有call by reference的, 这句话依然不成立.
Java中的变量有两种类型: primitive types 和 reference type.
primitive type包括byte, short, int, long, char, boolean, float和double.
而这8种之外的所有的,都是reference type.
下面是一段对你的贴上来的code的一点延伸,希望可以帮助你更好的理解Java中的argument / parameter到底是如何运作的.
public class Test {
public static void main(String[] args) {
int a = 1;
Koo koo = new Koo();
Object o = new Integer(1);
Koo newKoo = new Koo();
update(a);
update(koo);
update(o);
update(newKoo);
newUpdate(newKoo);
System.out.println(a);
System.out.println(koo.a);
System.out.println(o);
System.out.println(newKoo.a);
}
static void update(int a) {
a++;
}
static void update(Koo koo) {
koo.a++;
}
static void update(Object o) {
o = (int) (Integer.parseInt(o.toString()) + 1);
}
static void newUpdate(Koo koo) {
koo = new Koo();
}
}
class Koo {
int a = 1;
}
/*
o = (int) (Integer.parseInt(o.toString()) + 1); 这一行中的(int)纯粹是多余的,是否有这个casting对code本身没有任何影响. 如果你高兴也可以用
o = new Integer(Integer.parseInt(o.toString()) + 1);
或者干脆
o = Integer.parseInt(o.toString()) + 1;
*/
以上这些code运行之后会得到1 2 1 2的结果. 后面两个结果可以很好的说明, 即使对objects (reference type variables) 来看, Java所应用的也并不是call by reference. 否则的话,以上code运行结果应该是1 2 2 1
希望你可以真正理解这个新的例子中,产生1212这个结果的原因,从而对Java中的arguments有一个系统全面的认识.
图片是相关资料的链接,知道里貌似不能加网址
关于java小案例分析和java案例分析题的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。
发布于:2022-12-25,除非注明,否则均为
原创文章,转载请注明出处。