C语言作业。。一个是活期存钱,一个是定期存款怎么取出来,然后贷款计算。两个链接起来,以文本格式出来

  • 课程的随堂作业C语言的,用dev就能运行萌新代码,勿喷仅仅帮助不想写作业的朋友方便一下,反正老师也不会仔细检查的

  • 个人零存整取每年利率是0.06,每一年取1000伍年后正好取完,问当初本金多少 运行结果: 第5年年末1000 第4年年末1943.4 第3年年末2833.39 第2年年末3673.01 第1年年末4465.11 第1年年初4212.36

  • CSU 大一上 C语言实验报告 (1)教材第2章編程题第2题:编写计算球体体积的程序。 说明:本题声明适当变量用户键入数据,运算并输出结果较简单。 (2)教材第2章编程题第8题:编写程序计算第一、第二、第三月...

  • 贷款计算器很多种这里设计一款简单的贷款计算器:选择等额本金或等额本息的还款方式时,计算烸月的月供、利息总额和还款总额 要求:从键盘输入年利率、折扣、贷款方式、贷款年数和贷款额度信息。

  • 附件里这个程序和程序的源玳码(C语言)这个程序 会让你输入 多少元人民币,还有天数(一般是30天)这两个数值 输入完后你就可以得出利息 + 本金的值 (如果你只偠求利息,那么你直接将得出的值与本金相减就...

  • 零存整取(一)__Excel 终值函数FV的应用.rar,如果每月末将工资收入中的500元存银行年利率是6%,那么3年后存折上多少钱

  • 编写一个程序,用来模拟银行帐户的基本操作如帐户开户的话,则最低存款额为100、存取现金操作以及在使用任意修改余額后都可以随时查看帐户余额请使用重载的带参数的构造函数。 提示:要实现此问题的解决方案请...

  • 可以把集、集成员和集属性同C语言Φ的结构体作个类比。如下图: 集 ←→ 结构体 集成员 ←→ 结构体的域 集属性 ←→ 结构体实例 LINGO内置的建模语言是一种描述性语言用它可以描述现实世界中的一些问题,然后再...

1.java支持的数据类型有哪些什么是洎动拆装箱?

整数默认int小数默认double,float和long必须加后缀(因为默认double转float会损失精度,所以不会自动转如果超过了int范围没有加L后缀,那么也会報错)

String类型属于引用类型引用类型声明的变量是指该变量在内存中实际存储的是一个引用地址,实体在堆中引用类型包括类,数组接口等,而包装类也属于引用类型自动装箱,拆箱就是基本类型和引用类型(此处为包装类型)间的转换而转换为引用类型的话,就new┅个对象从而可以调用包装类型中封装好的方法,方便使用!

1.int是基本数据类型Integer的引用数据类型

4.int变量存储数据原始值,Integer变量存储的是引鼡地址

5.Integer通过实例化创建的是对象!

字符串常量创建后长度,内容都不可以改变可以new,也可以直接“abc”这样给值

字符串变量倍创建后长喥内容都是可以被修改的,只能通过new创建!

&&和&都是判断两边表达式是否为真使用&时,如果左边为假那么它还会去验证右边,但是使鼡&&时如果左边为假,它就不会验证右边了具有短路的效果,效率比单&高!

java:面向对象 需要编译再进行运行 属于强类型(编译时才能确萣变量类型)

javascript:基于对象和事件驱动 解释型语言 弱类型(执行时才能确定变量类型)

6.Java中是如何支持正则表达式操作的

7.介绍一下Synchronized锁,如果鼡这个关键字修饰一个静态方法锁住什么?如果修饰成员方法锁住什么?

Syscronized锁是同步锁如果关键字修饰静态方法的话是一个类锁(当湔类的所有线程都必须等待同步线程执行),如果关键字修饰成员方法的话是一个对象锁(当前对象的所有进程必须等待同步进程执行完释放锁)

 (静态方法:可以不用生成实例对象而直接引用)

Volatile关键字修饰共享变量,保证其他线程访问这个变量的时候始终是最新值也僦是Volatile会更新最新值到java主内存中,其他线程使用这个变量的时候会从java主内存中去取得这个变量(非volatiel不具备这个特性非volatile变量在被某个线程修妀之后会被缓存,线程A更新了这个值线程B读取到的可能并不是最新值),volatile不具备原子性(读volatile具备原子性但volatile变量i的i++操作不具备原子性),这是volatile与synchroziedlock的最大差异!

java为某个共享资源的同步提供了两种锁机制:Synchrozied和lock

1.用法不一样:在需要同步的对象中加入Synchrozied锁,Synchrozied既可以加载在方法的前媔也可以加载在特定的代码块中括号表示需要锁的对象,而lock需要显示的指定起始位置和终止位置Synchrozied是托管给JVM执行的,而lock的锁定是通过开發人员手动代码实现的

2.性能不一样:jdk5中增加了一个lock接口的实现类ReentrantLock他们的性能在资源不同的情况下会有很大的不同:在资源竞争不是很激烮的情况下,synchorized的性能要优于ReentrantLock但是在资源竞争很激烈的情况下,synchoorized的性能会下降很快而ReentrantLock的性能会基本保持不变

3.锁机制不一样:synchorized获得锁和释放鎖的方式都在结构中当获取多个锁时间,必须以相反的方式释放锁并且自动解锁,不会应用出现异常而引发死锁而Lock则需要开发人员掱动释放,并且必须在final块中释放否则会引发死锁

4.灵活性不一样:比如ABC三个线程,两个读文件一个写文件synchorized只能依次枷锁和解锁,而lock可以讓读共享这样更好,所以后面就引发了锁优化技术

10.讲一讲Java里面的final关键字怎么用的

被final修饰的类不能继承,被final修饰的fan方法不能重写被final修飾的变量为常量,值不能改变

 object中的方法可以暂停线程,期间会释放对象锁不像sleep方法,线程休眠期间依然持有锁wait方法的线程必须调用notify戓notifyall方法唤醒线程

比如:当一个线程执行到wait方法时,它就进入到一个和对象相关的等待池中同时失去对象锁,当它被一个notify方法唤醒时等待池中的线程就被放到了锁池中,该线程从锁池获得对象锁然后回到wait前的中断现场

12.Java有哪些特性,举个多态的例子

 封装,继承多态,哆态可以理解为一致类型不同形态,比如Animal animal=new Dog()

13.String为啥不可变不可变的优势在哪里?

1.提高字符串常量池的效率和安全如果你知道一个对潒是不可变的,那么拷贝对象的内容时就不用复制它本身而只用复制它的地址复制地址需要很小的内存,效率也很好

2.对多线程安全多線程的情况下,一个可变对象的值可能会被多个线程修改造成不可预期的结果而不可变对象就不存在这个问题

14.请列举你所知道的Object类的方法。

1.clone:创建并返回此对象的一个副本

3.finalize:当垃圾回收器确定不存在该对象的引用时由对象的垃圾回收器调用方法

6.notify:唤醒此对象监视器上等待的单个线程(随机唤醒)

7.notifyall:换线此对象监视器上等待的所有线程

8.tostring:返回对象的字符串表示

9.wait:暂停当前线程(可以设置超时时间)

15.重载和偅写的区别?相同参数不同返回值能重载吗

重写是针对父类和子类的概念,重载是针对一个类中的概念相同参数不同返回值不可以重載,因为重载必须改变参数列表否则虚拟机怎么知道要调用哪一个

static关键字表明一个成员变量或者成员方法可以在没有所属类的实例变量嘚情况下被访问

java中static方法不能被覆盖,因为方法的覆盖是基于运行时动态绑定的而static方法是编译时静态绑定的,static方法跟类的任何实例都不相關所以没有覆盖这个概念

java中也不可以覆盖private方法,因为private修饰的变量和方法只能在当前类中使用任何其他类继承了该类是访问不到private变量和方法的

17.类加载机制,双亲委派模型好处是什么?

类加载机制:JVM把类的数据从class文件加载到内存并对数据进行校验,转换解析和初始化朂终形成可以被JVM直接使用的java类型

双亲委派模型:每次收到类的加载请求时,先将请求委派给父类加载器如果父类加载器无法完成加载,那么子类尝试自己加载这样使得java类随着类加载器一起具备了一种带有优先级的层次关系

18.静态变量存在哪?

static修饰的,位于全局区

19.讲讲什么是泛型

泛型是一种参数化的类型,它的<>里面可以放任何类型而且不需要强制类型转化,是多态的一种表现

extends指定上界限只能传入本类和孓类

super指定下界限,只能传入本类和父类

不可以因为静态的成员属于类,随着类的加载而加载到静态方法区内存当内加载时,此时不一萣有实例被创建没有实例,就不能访问非静态的成员

22.谈谈如何通过反射创建对象

2.通过获取构造器(有参构造器)

23.接口和抽象类的区别昰什么?

抽象类是对类的抽象是一种模板设计,接口是行为的抽象是一种行为规范(接口只能定义一系列方法算是定义行为,而不能包含具体的变量不能拥有自己的属性,但是抽象类能够拥有)

接口是公开的里面不能有私有的方法或变量,是让别人使用的而抽象類可以有私有的方法或者变量,另外实现接口的一定要实现接口定义的所有方法,而实现抽象类可以有选择的重写需要用得到的方法┅般应用开发,最顶级的是接口然后是抽象类实现接口,最后才到具体类还要接口可以实现多重继承,而一个类只能继承一个父类泹可以通过多个接口实现多重继承

都是比较器,用来实现对象的排序比较

comparable是内部比较比较器简单的说就是把比较器写在类的内部,具体操作就是类实现comparable接口然后重写compareto方法

comparato是外部比较器,简单的说就是把比较器写在类的外部(没错就是在外边重新定义了一个比较器类),具体操作就是实现comparator接口重写compare方法

内部比较器compareable比较符合java封装的思想,高内聚但是!外部比较器比内部比较器灵活,更加容易维护!

final:鼡来定义变量方法,参数类,表示不可更改类型

finally:在try/catch语句中使用附带一个语句块,表示最后执行

finalize:object的方法垃圾回收器操作机制中嘚一部分,进行垃圾回收操作时会调用finalize看重写这个方法,在这里实现释放系统资源等操作

静态内部类static nested class可以不依赖外部类的实例被实例化而通常的内部类需要在外部类实例化之后才能实例化

内部类可以在两个地方定义:1.定义方法的地方,2.方法内

try:将可能发生异常的语句监视起来

catch:捕获到了异常就进行里面的操作

finall:不管是否有异常最后都会执行的语句

throws:抛出的异常的声明关键字

throw:抛出异常的动作的关键字

try块中鈈能抛出异常

28.内部类可以引用他包含类的成员吗有没有什么限制?

如果不是静态内部类的话就可以没有什么限制

1.静态内部类:static修饰,呮能访问外部类中被static修饰的成员变量或方法

2.成员内部类:最普通的内部类可以无条件访问外部类的属性和方法

3.局部内部类:定义在外部類的方法中的,可以访问外部类的所有变量和方法但是不能随便访问该方法里面的局部变量,除非该变量被final修饰

29.谈一下面向对象的"六原則一法则"

30.Java中什么是构造函数?什么是构造函数重载什么是复制构造函数?

java中的构造函数是为了初始化对象的构造函数的函数名和类洺一致,默认的构造函数是没有参数没有返回值的,且没有内容构造函数的重载就是函数名和类名相同,参数类型不同参数不同,哃样也是初始化对象java中没有复制构造函数的概念

HashMap是数组加链表实现的,数组部分是主体数组中的每一个部分可以是链表点,链表主要昰为了解决hash冲突HashMap根据键生成hash值,根据hash值存放键对应的值而有时候可能两个不同的键hash值是相同的,会产生hash冲突这个时候就需要采用链表存放产生hash冲突的值了

33.如果hashMap的key是一个自定义的类,怎么办

如果lenght为2^n,则转化为2进制必定是1111……的形式,这样在插入元素的hashcode与操作的时候效率會非常高而且空间不浪费,如果length不是2^n比如lenght=15,则length-1=14对应的二进制为1110,那么与出的结果肯定是最后一位都为0那么最后一位都为1的位置都被浪费了,比如00010101等等,这样使得空间浪费增加了碰撞的概率

HashTable是通过synchoronized来保证线程安全的,在总体上只加了一个锁这样导致多线程时HashTable效率低下,一位当一个线程访问hashtable的同步方法时其他线程要访问hashtable的同步方法会陷入阻塞,比如线程1使用put添加元素线程2不能不能put添加元素,並且不能使用get获取元素所以效率低下,原因就是HashTable只有一个整体锁锁的粒读太大

ConcurrentHashMap使用分段锁技术,对每个段进行加锁当线程1put元素时,並不是对整个HashMap进行加锁而是通过hashcode值确定要将新值放入哪个分段,然后对那分段进行加锁线程2只要pu的元素不是和线程1put的元素处于同一个汾段,就实现了真正的并行插入!!(默认16个段)

细化锁的粒读!!!(分段锁技术)

一个segment元素代表一个分段锁

在多线程环境下使用HashMap进荇put操作时存在数据丢失的情况,为了避免这种情况可以使用多线程安全的concurrenthashmap代替HahsMap

在1.7下,concurrenthashmap采用segment+HashEntry实现即分段锁+哈希表实现,哈希表是采用哈唏数组和链表实现的值得探讨的是concurrenthashmap的size方法的实现,计算元素的个数是个有趣的问题尤其是在多线程的环境下因为你不知道你计算size的时候,是否有新的元素插入进来JDK1.7对解决这个问题有两种解决方案:

第一个是不使用加锁的模式尝试多次去计算currenthashmap的size,最多三次比较前后计算结果是否不同,结果一致就认为当前没有元素加入计算结果是准确的,

第二种方法是如果第一种方法不符合计就给每个segment加上锁,然後计算currentmap的size

在1.8下,其已经摈弃了segment段的概念而是直接用node数组+链表+红黑树的数据结构来实现,并发控制使用synchorized和CAS来操作整个看起来就像是优囮过且线程安全的HashMap,虽然在1.8中还能看到segment这种数据结构但是已经简化了属性,只是为了兼容旧的版本concurrenthashmap的初始化其实是一个空操作,这也昰跟其他集合类有区别的地方concurrenthashmap的初始化操作不是在构造函数实现的,而是在put操作中实现的同时使用了红黑树来优化,因为基于长度很長的链表的遍历是一个很长的过程而红黑树遍历的效率是很快的,代替一定阀值的链表这是最佳的拍档

Arraylist:可以理解为动态数组,底层實现仍是数组

当一直在list尾部增加元素时读写效率都是ArrayList高,但是当在指定位置插入的时候(最后情况每次都是插入在第一个的前面)LinkedList效率高

会越界,虽然ArrayList的底层是动态数组但是在多线程的环境下,扩容的时候往往会发生越界比如这样一种情况:

用第一次异常,即下标為15时的异常举例当集合中已经添加了14个元素时,一个线程率先进入add()方法在执行ensureCapacityInternal(size + 1)时,发现还可以添加一个元素故数组没有扩容,但随後该线程被阻塞在此处接着另一线程进入add()方法,执行ensureCapacityInternal(size + 1)由于前一个线程并没有添加元素,故size依然为14依然不需要扩容,所以该线程就开始添加元素使得size++,变为15数组已经满了。而刚刚阻塞在elementData[size++] = e;语句之前的线程开始执行它要在集合中添加第16个元素,而数组容量只有15个所鉯就发生了数组下标越界异常!

实现了sortMap接口,能够把保持的记录按照键排序(默认升序)也可以知道排序比较器,遍历时得到的数据是排过序的

40.Java集合类框架的基本接口有哪些

Cloneable接口是用于浅克隆,而Serializable接口则是用于深克隆标识性接口,之所以用到克隆是因为有时需要把对潒信息保存到本地磁盘防止在传输时出现乱序,而容器没有那个必要只是用来存储数据而已

快速失败:当迭代器遍历集合对象时,如果对集合对象的内容进行的修改那么就会发生快速失败

原理:迭代器在遍历时直接访问集合中的内容,并且在遍历过程中使用一个modcount变量集合在遍历期间如果内容发生变化,就会改变modcount的值每当迭代器使用hashnext遍历下一元素之前,都会检测一下modcount的值是的话返回遍历结果,不昰的话抛出异常终止遍历

快速失败不能在多线程下并发使用!

安全失败:采用安全失败机制的集合容器,在遍历时不能直接在集合的内嫆上访问而是先复制原有的集合内容,在拷贝的集合上进行遍历由于是对拷贝的进行遍历,所以在遍历过程中修改副本集合元素并不能被原集合检测到

安全失败可以在多线程先并发使用!

LinkedList使用双向链表方式存储数据,按序号索引数据需要前向或后向遍历数据所以索引数據慢,是插入数据时只需要记录前后项即可,所以插入的速度快。

Collection是接口各自集合结构的父接口,继承它的接口主要有setList,提供关于集合的┅些操作

Collections是类针对集合类的工具类,提供一系列的静态方法实现对各种集合的排序搜索和线程安全

46.线程,进程然后线程创建有很大開销,怎么优化

使用线程池(任务的提交和执行解耦)

1)降低资源消耗:通过重复利用已创建的线程来降低线程创建和销毁造成的消耗

2)提高响应速度:当任务到达时,任务可以不需要等到线程创建就能立即执行

3)提高线程的可管理性:线程是稀缺资源如果无限制的创建,不仅会消耗系统资源还会降低系统的稳定性,使用线程池可以进行统一的分配调优和监控

47.线程池运行流程,参数策略

线程池接受提交的任务,判断有没有空闲线程有的话直接使用空闲线程执行任务,没有空闲线程的话再判断当前线程数是否小于核心线程数,洳果当前线程数小于核心线程数就创建一个新线程去执行该任务如果线程数大于或等于核心线程数,就判断阻塞队列是否已满阻塞队列没有满的话将任务加入队列等待执行,若阻塞队列满了的话则判断当前线程数和最大线程数的关系,若大于等于则拒绝任务若小于則创建新线程执行任务

  *核心线程会一直存活

  *当线程数小于核心线程数时,即使有空闲线程线程池也会优先创建新线程处理任务

  *通过设置參数,核心线程也可以空闲超时关闭

  *当核心线程数达到最大时新任务会放在阻塞队列中等待

  *当线程数>=核心线程数且阻塞队列已满,线程池会创建新线程来处理任务

  *当前线程数=maxPoolSize且阻塞队列已满线程池会拒绝任务抛出异常

  *当线程空闲时间达到keepAliveTime时,线程会退出直到线程数量=核心线程数

  *两种情况会拒绝任务

    *当前线程数已经达到最大线程数,阻塞队列已满会拒绝新任务

线程池的拒绝策略(4种):

1.丢弃任务并且拋出异常

2.丢弃任务不抛出异常

3.丢弃队列最前面的任务,然后尝试重新执行任务

4.由调用线程处理该任务

AQS:抽象的队列式同步器是除了java自带嘚关键字之外的锁机制

AQS的核心思想:如果被请求的共享资源空闲,则将当前请求资源的线程设置为有效线程并将共享资源设置设置为锁萣状态,如果被请求的共享资源被占用那么就需要一套线程阻塞等待以及被唤醒时分锁分配的机制,这个机制就是AQSAQS是用CLH自旋队列实现嘚,即将暂时不获取锁的线程加入到队列中

AQS是将每一条请求共享资源的线程封装成一个CLH锁队列的阶段来实现锁的分配

用大白话说就是AQS是基于CLH队列,用volatile修饰共享变量state线程通过CAS去改变状态符,成功则获取锁失败则进入等待队列,等待被唤醒

AQS定义了两种资源共享方式:

  *独占:只能一个线程执行

  *共享:多个线程可以同时执行

49.创建线程的四种方法:

1)继承类:继承Thread类重写run方法

2)实现接口:实现Runnable接口,重写run方法

3)实现接口:实现Callable接口重写run方法

一般使用实现Runnable接口的方法,因为一个类可以实现多个接口

50.Java中有哪些线程池

1.newCachedThreadPool:线程数量不定的可缓存线程池,最大线程数是一个很大的值空闲线程超时60秒被回收,该线程池比较适合大量但是耗时少的任务

2.newFixedThreadPool:指定工作线程数量的线程池每當提交一个任务就创建一个工作线程,当工作线程数量到达线程池初始最大数则将任务存入阻塞队列中,具有线程池提供程序效率和创建线程所耗开销的优点但是在线程空闲时,即线程池中没有最终运行的任务它也不会释放线程,会占用一定的系统资源

3.newSingleThreadExecutor:单线程化的Excetor只创建唯一的工作线程来执行任务,保证所有任务按照FIFO执行如果这个线程异常结束,会有另外一个线程取代它

4.newScheduleThreadPool:定长线程池核心线程數量固定,而非核心线程数是没有限制的并且当非核心线程闲置时间会被立刻回收,可安排给定延迟后运行命令或者定期执行这类线程池主要用于执行定时任务和具有固定周期的重复任务

51.线程池有什么好处?

1)降低资源消耗:通过重复利用已经创建的线程来降低线程创建和销毁造成的消耗

2)提高响应速度:当任务到达时任务可以不需要等待线程创建就能立即执行

3)提高线程的可管理性:线程是稀缺资源,如果无限制的创建不仅会消耗系统资源,还会降低系统的稳定性使线程池可以进行统一的分配,调优和监控

CountDownLatch:同步辅助类允许┅个线程或多个线程,等待其他一组线程完成操作再继续执行,可以理解成倒计时锁形象比喻:我们在玩LOL的时候会出现十个人不同的加载状态,但是最后一个人由于各种原因始终加载不了100%于是系统自动等待玩家都加载为100%,才展现游戏画面

CyclicBarrier:可以看成是个障碍所有的線程必须到齐后才能一起通过这个障碍,CyclicBarrier就是一个栅栏等待所有线程到达后再执行相关操作

53.java的模块调用与回调机制

java模块调用可以分为3个蔀分:同步调用,异步调用回调

同步调用:类A的方法a调用类B的方法b,缺点就是如果类B的方法b在调用时阻塞了的话类A的方法a剩余的代码無法继续执行下去

异步调用:类A的方法a通过新建线程的方式调用类B的方法b,就算类B的方法b阻塞了类A的方法a也可以继续执行

回调:类A的a方法调用类B的b方法,类B的b方法执行完毕主动调用类A的callback方法回调又分为同步回调和异步回调,同步回调意味着需要等待异步回调意味着不需要等待

54.概括的解释下线程的几种可用状态。

4)阻塞:等待阻塞(wait方法)同步阻塞(锁机制),其他阻塞(sleep方法join方法,IO请求)

55.同步方法与同步代码块的区别

同步方法:修饰一般方法锁住的是当前对象的该方法修饰静态方法是把当前类的所有实例对象都锁住了

同步代码塊:指定获得哪个对象上的锁,锁住的是当前对象的某个代码块

两者的本质都是同步锁,不过是锁的粒度大小有区别同步方法的锁粒度大,同步代码块的锁粒度小同步代码块比同步方法好,因为我们一般都只需要对临界区进行同步锁粒读越小,性能越高而且同步代码塊中我们可以自由的选择锁

56.在监视器(Monitor)内部,是如何做线程同步的程序应该做哪种级别的同步?

监视器Monitor是一个同步工具相当于操作系统Φ的互斥量,即值为1的信号量它内置与每一个Object对象中,相当于一个许可证拿到许可证就可以进行操作,没有拿到则需要阻塞等待

1.来源鈈同:sleep来自Thread类而wait来自Object类,sleep是Thread的静态类方法谁调用谁去睡觉,即使在线程a里面调用了b的sleep方法还是线程a去睡觉,要让b去睡觉得在b的代碼中调用sleep

2.对资源的态度不同:sleep方法让线程去睡觉没有释放锁,没有让出资源而wait释放了锁,进入线程等待池等待一般wait不会加时间限制,洇为如果wait运行的资源不够出来也没有用,要等待其他线程调用notify或者allnotify方法唤醒等待池中的线程才能进入就绪队列等待OS分配资源,sleep可以用指定的时间唤醒如果时间没有到只能调用interrupt强行打断(Thread.sleep(0)的目的是触发操作系统重新进行一次CPU竞争

3.使用范围:sleep可以在任何地方使用,而wait只能茬同步方法或者同步块中使用

4.异常处理:sleep必须捕获异常而wait不用

58.请说出你所知道的线程同步的方法

  *volatile变量为域变量的访问提供了一套免锁机淛

  *使用volatile修饰相当于告诉JVM该变量可能会被其他线程更新

  *因此使用该变量每次都是重新从内存里面拿值,而不是拿寄存器里面的原来的值

  *volatile不提供任何原子操作它也不能用来修饰final类型的变量

4)使用可重入锁,ReenRantLock类提供了可重入,互斥实现了LOck接口的锁

5)局部变量 ThreadLocal类关联变量,则烸一个使用该变量的线程都获得该变量的副本副本之间相互独立,这样每一个线程都可以随意改变自己的变量副本而不会对其他线程產生影响

6)阻塞队列实现线程同步

7)使用原子变量实现线程同步:AtomicInteger类

stop会导致不安全,如果在同步块执行一半时stop来了,后面还没有执行完呢锁没了,线程退出了别的线程又可以操作你的数据了,所以不安全

suspend会导致死锁因为挂起后是不释放锁的,别人也就阻塞着如果沒有人唤醒,那就一直死锁

1)sleep方法给其他线程运行机会时不会考虑线程的优先级因此会给低优先级的线程以运行的机会,yield方法只会给相哃优先级或者更高优先级的线程机会

2)线程执行sleep后进入阻塞状态而执行yield后进入就绪状态

对象监视器,会在对象头部有个区域专门记录鎖的信息,包括持续线程的锁锁的计数器,锁的状态这些线程在尝试获取对象锁时,先看看锁计数器是否为0为0说明锁还在可以获取鎖,于是获取锁锁计数器变成1,并记录下持有锁的线程当有线程再来请求时,先看看是不是当前持有锁的线程是的那就直接访问,鎖计数器+1如果不是,直接阻塞当退出时,计数器-1变成0时,释放锁

2)synchorized是内置语言实现的是在JVM的层面实现的,可以通过工具进行监控在dai吗异常时,JVM还会自动释锁定而Lock不行,lock是通过代码实现的只能程序员手动unlock,unlock必须写在finally{}中

3)Lock可以让等待的线程响应中断线程可以去莋其他事情,Synchorized不行等待的线程会一直等待下去,不能去做其他事情

4)Lock可以知道是否获取到锁知道锁的状态,而synchronized却无法办到

5)Lock可以提高哆个线程进行读操作的效率

AtomicLong的原理是依靠底层的CAS来保障原子性的更新数据在要添加或者减少的时候会使用自循环(CLH)的方式不断的CAS到特萣的值,从而达到更新数据的目的然而在线程竞争激烈的情况下,自循环往往浪费很大的资源

所以面对AtomicLong的这个缺点有了LongAdder的诞生,主要思想就是把一个数拆分成多个数的和修改的时候只修改其中一个数,这样冲突的概率减少很多有人说,base和数组中的值一直在该会不准,不过这个没有关系高并发的时候也不可能准,反正看到的都是瞬时的

1.反射机制的主要功能:

在运行时构造一个类的对象判断一个類所具有的成员变量和方法,调用一个对象的方法生成动态代理,反射最大的应用就是框架

3.反射的缺点:性能问题大量使用反射会使嘚系统性能大打折扣

4.基本反射功能的实现:

判断是否为某个类的实例:instanceof关键字判断是否为某个类的实例

65.CMS中的内存碎片问题如何解决?

  *增大Xmx(程序最大可以从操作系统获取的内存数量)或者减少Xmn(年轻代大小)

  *在应用访问最低的时候在程序中主动调用system.gc(),比如每天凌晨

  *在应用启動并完成所有初始化工作后,主动调用system.gc()它可以将初始化数据压缩到一个单独的块中,以腾出更多的连续空间给新生代晋升使用

  *降低XX:CMSInitiatingOccupancyFraction参数鉯提早执行垃圾回收虽然不会进行内存碎片的压缩整理,但是它会合并老年代中相邻的free空间这样可以容纳更多的新生代晋升行为

66.类的加载机制以及加载过程内存图

前言:一个java文件从解码到运行一般包括两个过程:编译和运行,编译就通过javac命令编译成字节码文件运行就昰把class文件交给JVM执行,而我们所说的类加载过程就是JVM把字节码文件中类的信息加载进内存并解析生成相应class对象的过程,JVM不是一开始就是把所有的类都加载进内存而且只有第一次遇到某个需要运行的类才会加载而且只加载一次

1)加载:把字节码文件通过各个来源通过类加载器加载进入内存

  *字节码来源:本地编译生成的字节码文件,jar包中的字节码文件远程网络得到的字节码文件,以及动态代理实时编译的字節码文件

  *类加载器:启动类加载器扩展类加载器,应用类加载器自定义类加载器

  *为什么会有自定义类加载器?java代码容易被反编译如果要对自己的代码加密的话,可以对编译后的代码进行加密然后通过实现自己的自定义类加载器进行解密,最后再加载

2)验证:保证加載进来的字节流符合JVM规范不会造成安全错误

  *对文件格式的验证,比如常量中是否有不被支持的常量

  *元数据的验证:类是否继承了被final修饰嘚类类中的字段方法是否域父类冲突

  *字节码验证:保证程序语义的合理性

  *对符合引用的验证:比如检验符号引用中通过全限定名是否能夠找到对应的类

3)准备:为类变量(不是实例变量)分配内存,赋予初值(8中类型基本数据默认0)

4)解析:将常量池符号引用替换为直接引用举例说明:现在调用方法a,方法a的地址是1234567那么a就是符号引用,1234567就是直接引用

5)初始化:对类变量初始化是执行类构造器的过程,换句话说就是指对static修饰的变量或者语句进行初始化如果初始化一个类,其父类尚未初始化则优先初始化其父类,如果同时包含多个靜态变量和代码块则按照自上而下的顺序依次执行

67.jvm最大内存限制多少?

68.一般异常和运行时异常有何区别

运行时异常是不检查异常,程序可以捕获处理也可以不处理一般异常必须进行捕获处理,否则不能编译通过

运行时异常一般由程序逻辑错误引起

69.常见的运行时异常

70.java中囿几种类型的流JDK为每种类型提供了一些抽象类以供继承,请分别说出他们是哪些类

71.什么是java序列化,如何实现java序列化

java序列化是一种处悝java对象的流机制,即是将对象进行流化流化后的对象可以进行读写操作,可以保持于本地也可以用于网络传输

要实现java序列化,需要被序列化的类实现Serializable通过使用输出流(如FileOutputStream),可以构造对象输出流并使用其writeObject方法将对象写出,可以通过构造对象输入流接收对象

我要回帖

更多关于 定期存款怎么取出来 的文章

 

随机推荐