版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
面试基本知识点总结1、关于Singleton模式合理的实现Singleton模式要求考虑到多线程情况以及时间效率。多线程但工作效率差publicclassSingletonThreadPool(privatestaticThreadPoolExecutorthreadPooL;privateSingletonThreadPool()(super();}publicstaticThreadPoolExecutorgetThreadPool()(synchronized(SingletonThreadPool.class)(if(threadPooL==null)(BlockingQueue<Runnable>bqueue=newArrayBlockingQueue<Runnable>(20);threadPooL=newThreadPoolExecutor(2,3,2,TimeUnit.MILLISECONDS,bqueue);}}returnthreadPooL;}}多线程工作效率高(同步锁加前后两次判断),这里主要考虑到加锁操作也是一个非常耗时的。publicclassSingletonThreadPool(privatestaticThreadPoolExecutorthreadPooL;privateSingletonThreadPool()(super();}publicstaticThreadPoolExecutorgetThreadPool()(if(threadPooL==null)(synchronized(SingletonThreadPool.class)(if(threadPooL==null)(BlockingQueue<Runnable>bqueue=newArrayBlockingQueue<Runnable>(20);threadPooL=newThreadPoolExecutor(2,3,2,TimeUnit.MILLISECONDS,bqueue);}}}returnthreadPooL;}}2、Java自带的类中那些应用到了快速排序和平衡二叉排序Java自带排序操作函数:Arrays.sort(数组)、Collections.sort(集合)1)Arrays.sort()是java自带的排序函数,排序Object的时候都是用合并排序,排序primitive(int,float等原型数据)的时候用的是快速排序。对于对象的排序,稳定性很重要,而且优化之后的归并排序其时间复杂度也在O(nlog(n))。对象数组中保存的只是对象的引用,这样多次移位并不会造成额外的开销,但是,对象数组对比较次数一般比较敏感,有可能对象的比较比单纯数的比较开销大很多。归并排序在比较次数方面比快速排序做得更好,这也是选择它作为对象排序的一个重要原因之一。排序优化:实现中快排和归并都采用递归方式,而在递归的底层,也就是待排序的数组长度小于7时,直接使用冒泡排序,而不再递归下去。Arrays.sort(滁可以传入原型类型数组之外,还可以传入Object[]数组;或者传入实现了Comparator的object[].Comparator其实就是一个比较器,规定了对象的比较策略。如下:方法sort(HouseInfo[]a,Comparator<?superHouseinfo>c)publicclassPriceComparator2implementsComparator<Houseinfo>{//约定按照价格的升序排序publicintcompare(HouseinfoIhs,Houseinforhs){//TODOAuto-generatedmethodstubintIPrice=integer,parseInt(lhs.getPrice());intrPrice=integer,parseInt(rhs.getPrice());if(IPrice>rPrice){return1;)elseif(IPrice==rPrice){return0;)else{return-1;}}}快速排序的优化:1、当待排序的数组中的元素个数较少时,源码中的阀值为7,采用的是插入排序。尽管插入排序的时间复杂度为0"2),但是当数组元素较少时,插入排序优于快速排序,因为这时快速排序的递归操作影响性能。2、较好的选择了划分元(基准元素)。能够将数组分成大致两个相等的部分,避免出现最坏的情况。例如当数组有序的的情况下,选择第一个元素作为划分元,将使得算法的时间复杂度达到。(”2).选择划分元策略:当数组大小为size=7时,取数组中间元素作为划分元。intn=m>>1;(此方法值得借鉴)当数组大小7<size<=40时,取首、中、末三个元素中间大小的元素作为划分元。iii.当数组大小size>40时,从待排数组中较均匀的选择9个元素,选出一个伪中数做为划分元。3、普通的快速排序算法,经过一次划分后,将划分元排到素组较中间的位置,左边的元素小于划分元,右边的元素大于划分元,而没有将与划分元相等的元素放在其附近2)Collections.sort先查看一段源码:publicstatic<TextendsComparable<?superT>>voidsort(List<T>list){:Object[]a=list.toArray();:Arrays.sort(a);:ListIterator<T>i=list.listIterator();for(intj=0;j<a.length;j++){i.next();i.set((T)a[j]);}}可以看到,Collections.sort方法的本质实现还是Arrays.sort(),当T类型为对象时,则需要实现Comparable接口,采用MergeSort().3、排序算法对比和优化冒泡排序算法时间复杂度是O(n人2),稳定排序;选择排序算法时间复杂度是O(n人2),不稳定排序;插入排序算法时间复杂度是O(n人2),稳定排序;快速排序是不稳定的。最理想情况算法时间复杂度O(nlog2n),最坏O(n人2)。堆排序算法时间复杂度是O(nlogn),不稳定排序;归并排序算法时间复杂度是O(nlogn),稳定排序。快速排序的优化在于划分元的选择策略上,这一点在第二部分有讲述。归并排序和快速排序都涉及递归操作,当数组元素比较少时,插入排序的效率是更高的,所以可以考虑在递归的最后一步采用插入排序实现。4、跳跃链表SkipListSkipList是一种随机化的数据结构,基于并联的链表,其效率可比拟于二叉查找树(对于大多数操作需要O(logn)平均时间)。基本上,跳跃列表是对有序的链表增加上附加的前进链接,增加是以随机化的方式进行的,所以在列表中的查找可以快速的跳过部分列表(因此得名)。所有操作都以对数随机化的时间进行。SkipList可以很好解决有序链表查找特定值的困难。一个跳表,应该具有以下特征:1)一个跳表应该有几个层(level)组成;2)跳表的第一层包含所有的元素;3)每一层都是一个有序的链表;4)如果元素x出现在第i层,则所有比i小的层都包含x;5)第i层的元素通过一个down指针指向下一层拥有相同值的元素;6)在每一层中,-1和1两个元素都出现(分别表示INT_MIN和INT_MAX);7)Top指针指向最高层的第一个元素。构建有序链表的一个跳跃表如下:ILevel3Level2Level1skipList构造步骤的一个跳跃表如下:ILevel3Level2Level12)选择连表中最大和最小的元素,然后从其他元素中按照一定算法(随机)随即选出一些元素,将这些元素组成有序链表。这个新的链表称为一层,原链表称为其下一层3)为刚选出的每个元素添加一个指针域,这个指针指向下一层中值同自己相等的元素。Top指针指向该层首元素4)重复2、3步,直到不再能选择出除最大最小元素以外的元素。在选定更高一层元素时候,可以采用随机的方法,也可以采用固定的概率P。每个更高层都充当下面列表的"快速跑道”,这里在层i中的元素按某个固定的概率p出现在层i+1中。要查找一个目标元素,起步于头元素和顶层列表,并沿着每个链表搜索,直到到达小于或的等于目标的最后一个元素。通过跟踪起自目标直到到达在更高列表中出现的元素的反向查找路径,在每个链表中预期的步数显而易见是1/P。所以查找的总体代价是O(log1/Pn/p),当p是常数时是O(logn)。通过选择不同p值,就可以在查找代价和存储代价之间作出权衡。5、Java一些内部机制Java的内部机制主要包括:内存管理和内存释放等处理,java类加载和初始化等。内存管理和内存释放等处理分配:内存的分配是由程序完成的,程序员需要通过关键字new为每个对象申请内存空间(基本类型除外),所有的对象都在堆(Heap)中分配空间。释放:对象的释放是由垃圾回收机制决定和执行的,这样做确实简化了程序员的工作。但同时,它也加重了JVM的工作。因为,GC(GarbageCollection)为了能够正确释放对象,GC必须监控每一个对象的运行状态,包括对象的申请、引用、被引用、赋值等,GC都需要进行监控。下面我们再来讨论一下内存泄露的问题,内存泄漏有两种情况。一种情况如在C/C++语言中的,在堆中的分配的内存,在没有将其释放掉的时候,就将所有能访问这块内存的方式都删掉(如指针重新赋值),这是在C编程中经常容易犯的错误即忘记内存的释放;另一种情况则是在内存对象明明已经不需要的时候,还仍然保留着这块内存和它的访问方式(引用)。第一种情况,在Java中已经由于垃圾回收机制的引入,得到了很好的解决。所以,Java中的内存泄漏,主要指的是第二种情况。为了避免第二种方式造成的内存泄露,在使用中,应该注意的问题有:在不涉及复杂数据结构的一般情况下,Java的内存泄露表现为一个内存对象的生命周期超出了程序需要它的时间长度。我们有时也将其称为“对象游离”。要避免这种情况下的内存泄露,要求我们以C/C++的内存管理思维来管理自己分配的内存。第一,是在声明对象引用之前,明确内存对象的有效作用域。在一个函数内有效的内存对象,应该声明为local变量,与类实例生命周期相同的要声明为实例变量……以此类推。第二,在内存对象不再需要时,记得手动将其引用置空。Java中有几种不同的引用方式,它们分别是:强引用、软引用、弱引用和虚引用。这几种引用方式对于GC回收机制具有不同的效果,具体如下:强引用在此之前我们介绍的内容中所使用的引用都是强引用,如Objectobject=newObject();这是使用最普遍的引用。如果一个对象具有强引用,那就类似于必不可少的生活用品,垃圾回收器绝不会回收它。当内存空间不足,Java虚拟机宁愿抛出OutOfMemoryError错误,使程序异常终止,也不会靠随意回收具有强引用的对象来解决内存不足问题。软引用(SoftReference)SoftReference类的一个典型用途就是用于内存敏感的高速缓存cache。SoftReference的原理是:在保持对对象的引用时保证在JVM报告内存不足情况之前将清除所有的软引用。关键之处在于,垃圾收集器在运行时可能会(也可能不会)释放软可及对象。对象是否被释放取决于垃圾收集器的算法以及垃圾收集器运行时可用的内存数量。弱引用(WeakReference)WeakReference类的一个典型用途就是规范化映射(canonicalizedmapping)。另外,对于那些生存期相对较长而且重新创建的开销也不高的对象来说,弱引用也比较有用。关键之处在于,垃圾收集器运行时如果碰到了弱可及对象,将释放WeakReference引用的对象。然而,请注意,垃圾收集器可能要运行多次才能找到并释放弱可及对象。虚引用(PhantomReference)PhantomReference类只能用于跟踪对被引用对象即将进行的收集。同样,它还能用于执彳亍pre-mortem清除操作。PhantomReference必须与ReferenceQueue类一起使用。需要ReferenceQueue是因为它能够充当通知机制。当垃圾收集器确定了某个对象是虚可及对象时,PhantomReference对象就被放在它的ReferenceQueue上。将PhantomReference对象放在ReferenceQueue上也就是一个通知,表明PhantomReference对象引用的对象已经结束,可供收集了。这使您能够刚好在对象占用的内存被回收之前采取行动。Reference与ReferenceQueue的配合使用。2)java类加载和初始化java类的加载主要有以下几点原则:对实体的创建或者对static成员的访问都会触发类的加载,类的加载是按照“子类->基类->根基类”的顺序进行的,类的加载只进行一次,加载之后新实体类的创建不会触发类的重新加载,因为这时类已经处于内存之中。初始化的进行则是按照“根基类->基类->子类”的顺序进行,因为子类的访问可能依赖基类成员变量,这个顺序非常重要。3)java内存管理在java中,有java程序、虚拟机、操作系统三个层次,其中java程序与虚拟机交互,而虚拟机与操作系统间交互!这就保证了java程序的平台无关性!a)程序运行前:JVM向操作系统请求一定的内存空间,称为初始内存空间!程序执行过程中所需的内存都是由java虚拟机从这片内存空间中划分的。b)程序运行中:java程序一直向java虚拟机申请内存,当程序所需要的内存空间超出初始内存空间时,java虚拟机会再次向操作系统申请更多的内存供程序使用!c)内存溢出:程序接着运行,当java虚拟机已申请的内存达到了规定的最大内存空间,但程序还需要更多的内存,这时会出现内存溢出的错误!JVM会把申请的内存从逻辑上划分为三个区域,即:方法区、堆与栈。a)方法区:方法区默认最大容量为64M,Java虚拟机会将加载的java类存入方法区,保存类的结构(属性与方法),类静态成员等内容。b)堆:默认最大容量为64M,堆存放对象持有的数据,同时保持对原类的引用。可以简单的理解为对象属性的值保存在堆中,对象调用的方法保存在方法区。
栈:栈默认最大容量为1M,在程序运行时,每当遇到方法调用时,Java虚拟机就会在栈中划分一块内存称为栈帧(Stackframe),栈帧中的内存供局部变量(包括基本类型与引用类型)使用,当方法调用结束后,Java虚拟机会收回此栈帧占用的内存。里._灿F56溯10里._灿F56溯10内存地址堆湖K3627周星岩2536DF旺旺如图所示,java对象的数据是存放在堆中的,栈则是存放引用和基本数据6、递归算法时间复杂度的计算递归算法的时间复杂度我们可以采用递归树来计算。在引入递归树之前可以考虑一个例子:T(n)=2T(n/2)+n2迭代2次可以得:T(n)=n2+2(2T(n/4)+(n/2)2)还可以继续迭代,将其完全展开可得:T(n)=n2+2((n/2)2+2((n/22)2+2((n/2s)2+2((n/24)2+„+2((n/2i)2+2T(n/2i+1)))„))))……(1)而当n/2i+i==1时,迭代结束。将(1)式小括号展开,可得:T(n)=n2+2(n/2)2+22(n/22)2+…+2i(n/2i)2+2i+1T(n/2i+1)这恰好是一个树形结构,由此可引出递归树法。U)图中的(a)(b)(c)(d)分别是递归树生成的第1,2,3,n步。每一节点中都将当前的自由项n2留在其中,而将两个递归项T(n/2)+T(n/2)分别摊给了他的两个子节点,如此循环。图中所有节点之和为:[1+1/2+(1/2)2+(1/2)3+…+(1/2)i]n2=2n2可知其时间复杂度为O(n2)可以得到递归树的规则为:每层的节点为T(n)=kT(n/m)+f(n)中的f(n)在当前的n/m下的值;每个节点的分支数为k;每层的右侧标出当前层中所有节点的和。再举个例子:T(n)=T(n/3)+T(2n/3)+n其递归树如下图所示:◎罪0(nloan)可见每层的值都为n,从根到叶节点的最长路径是:*—W#fW己——,+1因为最后递归的停止是在(2/3)kn==1.则于是T®W二应=(先+加=«(1^3/2招+1)]=0即T(n)=O(nlogn)卜面我们可以来考察一下归并排序的时间复杂度:O(nlogn)。7、单链表相关算法单链表倒置
IjRrepCur□NextpPrepCurpNcxtpPirepCi_iTIjRrepCur□NextpPrepCurpNcxt如图所示,借助辅助指针,采用倒插法实现:tNode*pCypedefintDataType;〃类型定义typedefstructnode(//单链表定义DataTypedata;structnode*next;}LinkedNode,*LinkList;voidReverseList(LinkList&ListHead)(cout<<"BegintoReversetheList"<<endl;if((NULL==ListHead)||(NULL==ListHead->next))return;/边界检测LinkedNode*pPre=ListHead;/冼前指针Linkedur=pPre->next;//当前指针LinkedNode*pNext=NULL;/后继指针while(pCur!=NULL){pNext=pCur->next;pCur->next=pPre;2)求链表的倒数第K个节点,如果K大于链表长度则返回NULL采用一种比较经典的思想:两个游标指针,两个指针相差K个节点,同时移动,直到后面那个指针遍历完整个链表。3)不知道单链表节点前驱的情况下,删除该节点方法就是将该节点的后继结点中的值数据拷到本节点中,然后删掉后继节点。删除节点的本质其实还是删除节点中的数值,这个要注意。4)求单链表的中间节点,偶数个节点时返回中间两个节点的前一个同样采用两个游标的方式,游标p按照步长1移动,游标q按照步长2移动,直到游标q遍历完整个链表。5)判断单链表是否有环,并求出环开始的节点;如果没有环,就返回NULL同样采用两个游标的方式,游标p按照步长1移动,游标q按照步长2移动,如果q能够追上p则说明他们存在环,若q到达了终点,那就说明没有环的存在。环的长度计算,当p,q相遇之后,记下相遇的点,然后继续让p移动,再次回到该点时计算移动的步数,这就是环的长度。6)判断两个单链表是否相交,如果相交则返回交点的指针,否则返回NULL如果两个链表相交,那么,在这个相交的节点之后所有的节点都是两个链表共有的,抓住这一点。求交点思路有些巧妙:在判断是否存在交点遍历两链表的时候,我们可以顺便分别计算两链表的长度,然后计算其长度差d,再分别从短链表和长链表的第d个节点开始遍历并判断两者是否相等,第一个相等的节点指针就是交点指针。从尾到头打印链表8)8、C语言类型和类型转换的问题符号属性长度属性基本型所占位数取值范围输入符举例输出符举例——char8-2^7A7-1%c%c%d、%usigned—char8-2^2八7-1%c%%d、%uunsigned—char8~砂8-1%c%(%d、%u[signed]short[int]16-2八15~2八15-1%hdun
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 二零二五版门面铺面租赁合同-附商铺营销推广服务4篇
- 二零二五年度城市河道绿化带养护与生态修复合同3篇
- 二零二五版高端婚嫁婚前协议书标准范本3篇
- 2025年度棉纱跨境电商销售与市场拓展合同4篇
- Unit 4 History and Traditions reading for writing 说课稿-2024-2025学年人教版(2019)高中英语必修第二册
- Unit 2 Sports and Fitness Lesson 2 Rules of the Game 第一课时说课稿-2024-2025学年高中英语北师大版(2019)必修第一册001
- 二零二五年度农产品销售合同中的质量标准与检验方法4篇
- 2023六年级英语下册 Unit 5 General Revision 2(Part 3)说课稿 人教精通版(三起)
- 2025年度模具维修服务及设备租赁合同4篇
- 二零二五年度地震监测临时驾驶员用工合同4篇
- 中国的世界遗产智慧树知到期末考试答案2024年
- 2023年贵州省铜仁市中考数学真题试题含解析
- 世界卫生组织生存质量测量表(WHOQOL-BREF)
- 《叶圣陶先生二三事》第1第2课时示范公开课教学PPT课件【统编人教版七年级语文下册】
- 某送电线路安全健康环境与文明施工监理细则
- GB/T 28885-2012燃气服务导则
- PEP-3心理教育量表-评估报告
- 控制性详细规划编制项目竞争性磋商招标文件评标办法、采购需求和技术参数
- 《增值税及附加税费申报表(小规模纳税人适用)》 及其附列资料-江苏税务
- 中南民族大学中文成绩单
- 危大工程安全管理措施方案
评论
0/150
提交评论