当前位置:   article > 正文

java面试笔试题逻辑题怎么做,开发成长之路,这些知识你必须拿下_java开发笔试常见逻辑推理

java开发笔试常见逻辑推理

else{ //空间不够用了

insert_aux(end(),x); //更底层了,看上面那张图

}

}

注意:一旦引起空间重新配置,指向原Vector的所有迭代器都将失效!!!


pop_back() 删除末端元素:

void pop_back(){

–finish;

destroy(finish); //这个destory后面讲空间配置器的时候会讲到

//就是这么简单

}

erase() 清除(first,last)中所有元素:

先看图:

在这里插入图片描述

iterator erase(iterase first,iterase last){

iterator i = copy(last,finish,first) //copy后面的篇章会有,先克服一下困难

destroy(i,finish);

finish = finish - (last - first);

return first;

}

erase() 清除某个位置上的元素:

iterator erase(iterator position){

if(position +1 != end())

copy(position +1,finish,position)

–finish;

destroy(finish);

return position;

}

clear() 方法:

void clear(){

erase(begin(),end());

}


insert() 插入操作:

这个操作的代码实在是太多的底层细节了,还是看图吧:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述


List

Vector可以用数组的知识来覆盖,那么List,就用链表的知识来覆盖吧。

这里要注意:

list对于任何元素的插入和删除,永远都是常数时间,我也得去一探究竟啦,我当初回答错了。

先看看数据结构:

template

struct __list_node{

typedef void* void_pointer;

void_pointer prev;

void_pointer next;

T data;

}

双向链表!!!

list的迭代器和vector的不同,它的要求更高一些。因为链表使用的存储空间往往是零零散散的,所以list的迭代器必须有能力在杂乱的存储空间中快速的跳转。

相对于Vector,List还有一个优势,就是不论如何的插入和接合操作,都不会造成原有的List迭代器失效。List的删除操作也只有指向那个被删除的元素的迭代器失效,其它迭代器不会受影响。

在这里插入图片描述

SGI list不仅仅是一个双向链表,还是个环状双向链表,所以它只需要一个指针,便可以完整的表现链表。

template <class T,class Alloc = alloc> //缺省使用alloc作为配置器

class list{

protected:

typedef __list_node list_node;

public:

typedef list_node* link_type;

protected:

link_type node; //只要一个指针,便可以表示整个循环链表

如果让指针node指向刻意置于尾端的一个空白节点,node便能符合STL对于“前闭后开”的区间要求,成为list迭代器。

iterator begin(){return (link_type)((*node).next);}

iterator end(){return node;}

bool empty() const{return node->next == node;}

size_type size() const{

size_type result = 0;

disance(begin(),end(),result); //一个全局函数

return result;

}

reference front(){return *begin();}

reference back(){return *–end();}

在这里插入图片描述


关于list的增删改查,其实跟链表也就差不多了。


deque


vector是单向开口的连续线性空间,deque则是一种双向开口的连续线性空间。

所谓双向开口,也就是说可以在头尾两端进行插入和删除操作。

vector当然也可以做头部操作,但是其头部操作效率奇差!!!

无法被接受。

(这点以前居然都没有发现!!!)

在这里插入图片描述

deque没有所谓容量的观念,因为它是动态的以分段连续空间组合而成,随时可以增加一段新的空间并链接起来。因此,deque没有必要提供所谓的空间保留功能。

但是呢,为什么我们更多的选用vector而非deque呢?因为它的指针实在是太麻烦了。我们后面就知道了。

除非必要,我们应尽可能的选择使用vector而非deque。对deque进行的排序操作,为了最高效率,可以将deque完整的复制到一个vector身上,将vector排序后,再复制回deque。

不要被事务的表面现象锁迷惑,你看它是分段连续线性空间,就以为它是vector和list的结合体,取长补短?其实不然。

为了维持整体连续的假象,数据结构的设计及迭代器前进后退等操作都颇为繁琐。


deque的中控器

deque采用一块所谓的map映射,来看吧:

template <class T,class Alloc = alloc,size_t BufSiz = 0>

class deque{

public:

typedef T value_type;

typedef value_type* pointer;

···

protected:

//元素的指针的指针

typedef pointer* map_pointer;

protected:

map_pointer map;

//指向map,map是块连续空间,其内的每个元素都是一个指针,指向一块缓冲区

size_type map_size;

//map内可容纳多少指针

}

在这里插入图片描述

在这里插入图片描述

看得我尴尬症都犯了。

此外,deque还维护start、finish两个迭代器,分别指向第一缓冲区的第一个元素和最后缓冲区的最后一个元素(的下一个位置)。

此外,它当然也必须记住目前map的大小,一旦map的空间不足,必须要重新配置一个更大的map。


stack – 栈


什么是栈?怎么说呢,我觉得我真应该先写数据结构专栏。失策失策!!!

栈是一种先进后出的数据结构,它只有一个接口。

只能从一端加入元素,从那一端移除元素,所以并不被允许有其他方法来存取元素。

换言之,stack不允许有遍历行为。

将元素推入stack的方式称为push,将元素退出stack的操作称为pop。

在这里插入图片描述

以某种既有容器作为底部结构,将其接口改变,使之符合“先进后出”的特性,形成一个stack,是很容易做到的。

deque是双向开口数据结构,若以deque为底部结构并封闭其头端开口。

便轻而易举形成了一个stack、

(不知道为什么,我觉得好糟糕哦,vector是不能做吗?)

还是等我过两篇写数据结构的时候再说吧。


除deque之外,list也是双向开口的数据结构。以list为底的stack被称作链栈。

嘿我就挺纳闷儿,为什么就非要双向开口的数据结构???


queue – 队列


队列,是一种先进先出结构,只能从一端加入元素,从另一端移除元素,所以并不被允许有其他方法来存取元素。

换言之,queue不允许有遍历行为。

那这个跟上面的stack其实没多大区别,只不过一个是后进先出,一个是先进先出的罢了。那为什么也要双向开口的数据结构呢?


heap是什么


heap并不属于STL容器组件,它是个“幕后白手”,扮演priority queue的助手。

顾名思义,那个queue允许用户以任何次序插入数据,但是在插入的时候会根据优先级进行排序,以保证取出的时候是按照优先级排序的。

如果以List作为这个优先级队列的底层机制,那么排序将会很麻烦,如果以二叉搜索树的话,未免大材小用了。

而难度夹在中间的binary heap便是不二人选了。

所谓binary heap,就是一种完全二叉树,整棵树除了底层节点外,都是填满的,从左至右又不得又间隙。

苍白无力的文字啊,来看张图实在:

在这里插入图片描述

简单明了吧,可以用想象下面有一个数组来存储所有节点,以树根节点作为数组的[0]位置,可以发现,任何一个节点 [i] 的左子节点必位于 [2i] 处,其右子节点必位于 [2i+1] 处。

而任何一个节点 [k],其父节点必位于 [k/2] 处。

通过这简单的规则,咱就种了一棵树,完全二叉树。

而这颗二叉树需要能动态的增加节点,所以采用vector作为这棵树的底层土壤是个理想的选择。

根据元素排列方式,heap可以分为max-heap和min-heap。STL供应的是max-heap,最大值在头结点。

heap算法

push_heap算法(尾端插入元素)

本来是自己画了图,但是理解了书中的图之后,发现他的图更有一番风味。

在这里插入图片描述

原先我也疑惑于为何同一级中左边的节点会比右边节点大,后来我想明白了。

在插入过程中,这个顺序被打乱是难以避免的,况且这个排序于取出数据并无影响,所以没必要在做额外工作对树的底层做那么精细的排序。

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加V获取:vip1024b (备注Java)
img

Java面试核心知识点笔记

其中囊括了JVM、锁、并发、Java反射、Spring原理、微服务、Zookeeper、数据库、数据结构等大量知识点。

蚂蚁金服(Java研发岗),26岁小伙斩获三面,收获Offer定级P6

Java中高级面试高频考点整理

蚂蚁金服(Java研发岗),26岁小伙斩获三面,收获Offer定级P6

蚂蚁金服(Java研发岗),26岁小伙斩获三面,收获Offer定级P6

最后分享Java进阶学习及面试必备的视频教学

蚂蚁金服(Java研发岗),26岁小伙斩获三面,收获Offer定级P6

一个人可以走的很快,但一群人才能走的更远。如果你从事以下工作或对以下感兴趣,欢迎戳这里加入程序员的圈子,让我们一起学习成长!

AI人工智能、Android移动开发、AIGC大模型、C C#、Go语言、Java、Linux运维、云计算、MySQL、PMP、网络安全、Python爬虫、UE5、UI设计、Unity3D、Web前端开发、产品经理、车载开发、大数据、鸿蒙、计算机网络、嵌入式物联网、软件测试、数据结构与算法、音视频开发、Flutter、IOS开发、PHP开发、.NET、安卓逆向、云计算

据库、数据结构等大量知识点。

[外链图片转存中…(img-3JAEcjO4-1712437937712)]

Java中高级面试高频考点整理

[外链图片转存中…(img-GF1GVVIr-1712437937712)]

[外链图片转存中…(img-FVHUTOv9-1712437937712)]

最后分享Java进阶学习及面试必备的视频教学

[外链图片转存中…(img-Ql6d6XWD-1712437937713)]

一个人可以走的很快,但一群人才能走的更远。如果你从事以下工作或对以下感兴趣,欢迎戳这里加入程序员的圈子,让我们一起学习成长!

AI人工智能、Android移动开发、AIGC大模型、C C#、Go语言、Java、Linux运维、云计算、MySQL、PMP、网络安全、Python爬虫、UE5、UI设计、Unity3D、Web前端开发、产品经理、车载开发、大数据、鸿蒙、计算机网络、嵌入式物联网、软件测试、数据结构与算法、音视频开发、Flutter、IOS开发、PHP开发、.NET、安卓逆向、云计算

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/酷酷是懒虫/article/detail/814624
推荐阅读
相关标签
  

闽ICP备14008679号