java后端笔试刷题总结

数据结构

数组

1、设有100个元素,用二分法查找时,最大比较次数是(7)
[log2n]向下取整再加1
公式:[log2n]+1
2、顺序表查找指的是在顺序存储结构上进行查找。(正确 )
顺序表查找是指从第一个数据元素开始查找,一直找到最后一个为止。
3、二分查找
针对有序数组来查找的。
主要思想是:(设查找的数组期间为array[low, high])
(1)确定该期间的中间位置K
(2)将查找的值T与array[k]比较。若相等,查找成功返回此位置;否则确定新的查找区域,继续二分查找。区域确定如下:
a.array[k]>T 由数组的有序性可知array[k,k+1,……,high]>T;故新的区间为array[low,……,K-1]
b.array[k]<T 类似上面查找区间为array[k+1,……,high]。每一次查找与中间值比较,可以确定是否查找成功,不成功当前查找区间缩小一半。递归找,即可。
**时间复杂度:**O(log2n);
代码实现:


    public int BinarySearch(int[] array, int T)
        {
            int low, high, mid;
            low = 0;
            high = array.Length - 1;
            while (low <= high)
            {
                mid = (low + high) / 2;
                if (array[mid] < T)
                {
                    low = mid + 1;
                }
                else if (array[mid]>T)
                {
                    high = mid - 1;
                }
                else 
                {
                    return mid;
                }
            }
            return -1;
        }   

4、快速排序
(1)选一个基准数,一般以数组中第一个元素为基准数,然后将大于基准数的元素交换放置基准数右边,将小于基准数的元素放置左边;
(2)设定两个变量i,j。可以将这两个变量看作指针,代指所对应的元素。首先让i指向序列d最左边(i0),j指向序列的最右边(jlength-1),然后先让j向左移动找到第一个小于基准数的元素,从左到右找到第一个大于基准数的元素,将找到的两个元素交换。
(3)循环这样的过程直到i=j,i和j碰头。此后将基准数与i位置元素交换位置,相当于确定基准数的最终位置。这样就根据基准数划分为左右两个部分。
(4)再对这两个部分分别进行快排操作,直到正确的顺序。
平均时间复杂度: O(NlogN)

#include<cstdio>
#include<cstring>
int a[1100];
void  quicksort(int left,int right)
{
	int i,j,t,temp;
	if(left>right)
	return ;
	temp=a[left];//temp为基准数
	i=left;
	j=right;
	while(i!=j)//判断i和j是否碰头
	{
		while(a[j]>=temp&&i<j)//从右到左找到第一个小于基准数的元素
		 j--;
		while(a[i]<=temp&&i<j)//从左到右找到第一个大于基准数的元素
		 i++;
		 if(i<j)//将找到的两个元素交换
		 {
		 	t=a[i];
		 	a[i]=a[j];
		 	a[j]=t;
		 }
	}
	a[left]=a[i];//将基准数和i和j碰头的元素交换,相当于确定基准数的最终位置
	a[i]=temp;
quicksort(left,i-1);//递归变换位置后基准数两侧的子序列
	quicksort(i+1,right);
	return ;
}
int main()
{
	int n;
	while(scanf("%d",&n)!=EOF)
	
	{
		int i;
		for(i=1;i<=n;i++)
		 scanf("%d",&a[i]);
		 quicksort(1,n);
		for(i=1;i<=n;i++)
		 printf("%d\n",a[i]);
	}
	return 0;
}

5、插入排序
将一组数据分成两组,我分别将其称为有序组与待插入组。每次从待插入组中取出一个元素,与有序组的元素进行比较,并找到合适的位置,将该元素插到有序组当中。就这样,每次插入一个元素,有序组增加,待插入组减少。直到待插入组元素个数为0。当然,插入过程中涉及到了元素的移动。

  #include<stdio.h>
  void InsertionSort(int *num,int n) 
  {
  	int i = 0;
  	int j = 0;
  	int tmp = 0;
  	for(i = 1;i<n;i++)
  	{
      tmp = num[i];//从待插入组取出第一个元素。 
	  j = i-1; //i-1即为有序组最后一个元素(与待插入元素相邻)的下标 
	  while(j>=0&&tmp<num[j])  //注意判断条件为两个,j>=0对其进行边界限制。第二个为插入判断条件 
	  {
	    num[j+1] = num[j];//若不是合适位置,有序组元素向后移动 
		j--; 
	  }
	  num[j+1] = tmp;//找到合适位置,将元素插入。 
	}
  }
  int main() 
  {
  	int i = 0;
  	int num[8]={9,3,4,2,6,7,5,1};
  	InsertionSort(num,8); 
  	/*这个函数必须知道元素的个数,所以将元素个数传入。
	有心者可以在函数内部用sizeof求出元素个数 */
  	for(i=0;i<8;i++)
  	{
     	printf("%d ",num[i]);
	}
  	return 0;
  }

5、就平均查找速度而言,下列几种查找速度从慢至快的关系是___________。
顺序查找的时间复杂度为o(n)
分块查找的时间复杂度为o(log2n)到o(n)之间
二分查找的时间复杂度为o(log2n)
哈希查找的时间复杂度为o(1)
6、设顺序线性表的长度为30,分成5块,每块6个元素,如果采用分块查找 并且索引表和块内均采用顺序查找 ,则其平均查找长度为 ( ) 。
总的平均查找长度为:分块查找的平均长度+顺序查找的平均长度
7、二分查找要满足顺序存储、链存储、按value有序中的哪些条件?
顺序存储、按value有序
首先二分查找要求序列必须是有序的,其次序列可以随机访问任何有效范围内索引的值,链式存储不能随机访问,必须是顺序存储

8、For the following Java or C# code(3 Points),What will my Array3[2][2] returns?
int [][] myArray3 =
new int[3][]{
new int[3]{5,6,2},
new int[5]{6,9,7,8,3},
new int[2]{3,2}
};
由于无Array3[2][2]这个数据项,所以overflow
每一行数据的声明为new int[]{};注意此种表示方法
9、 数组名就是数组的首地址,
对一个指针加1的结果是对该指针增加一个存储单元,对数组而言,地址会增加到下一个元素的地址。
C中的p[i]等同于p+i,它是指向数组a[i]的指针。
10、①线性表的顺序存储结构是一种 (随机存取 ) 的存储结构。用一组地址连续的存储单元依次存储线性表的数据元素(数组),存入的时候是顺序的,前后位置关系在内存中也是固定的,取出的时候直接依据编号就可以找到,不需要遍历一遍,所以是随机取出的。
②线性表的链式存储结构,顺序存取。数据元素在内存中的位置是动态分配的无序的(链表),所以取出的时候并不知道其具体位置,必须要从头开始遍历,是顺序取出的。
11、广义表
表头可以为表或单元素值
表尾是指除去表头后剩下的元素组成的表(即使只剩一个元素也视为表),可以为空表
12、和顺序栈相比,链栈有一个比较明显的优势是(通常不会出现栈满的情况)
因为顺序栈用数组实现,必须事先确定栈的大小,对内存的使用效率并不高,无法避免因数组空间用光而引起的溢出问题:而链栈因为动态申请内存,一般不会出现栈满情况,空栈还是会出现的
都是栈,栈先进后出,只能在栈顶进行插入和删除操作,所以链栈在这点对于顺序栈并无优势。
13、有一个 100 × 90 的稀疏矩阵,非 0 元素有 10 ,设每个整型数占 2 个字节,则用三元组表示该矩阵时,所需的字节数是66 。

10个非零元素:1032=60字节(i,j,元素值)
剩下的6个字节:分配给行数、列数、总元素数,即3*2=6字节
总字节数目:60+6=66字节
14、下列关于线性表中的链表描述正确的是ABCD
适用于数据项数量不能预知的情况。
逻辑相邻的2元素的存储空间可以是不连续的。
链表节点一般有数据元素和指针域两部分组成。
存储空间需要动态分配。
15、循环队列
队列空的条件:front==rear (front队头 rear队尾)
队列满的条件:(rear+1)%maxsize = front
队列中元素个数:(rear-front+maxsize)%maxsize
入队:rear=(rear+1) % maxsize ;
出队:front=(front+1) % maxsize ;
16、以下属于逻辑结构的是(有序表)
有序表中所有元素以递增或递减方式排列,对数据之间的关系进行了描述,是一种逻辑结构。
顺序表是指用一组地址连续的存储单元依次存储数据元素的线性结构。
哈希表用散列法存储的线性表叫散列表。
单链表用一组地址任意的存储单元存放线性表中的数据元素,均只是一种存取结构,不是逻辑结构。

1、设有一组初始记录关键字序列为(34,76,45,18,26,54,92),则由这组记录关键字生成的二叉排序树的深度为(4)。

BST构造的时候,如果根节点为空,则首先序列的第一个作为根节点,然后第二个与根节点比较:小的放到左边,大的放到右边;根节点不为空的时候,待插入的节点跟根节点比较:小的往左子树去比较,大的往右子树去比较。比较过程中,待插入节点只作为某节点的左或右节点插入,而不会变动之前的节点位置。
2、平衡二叉树
平衡二叉树(AVL树):它是一棵空树或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树都是一棵平衡二叉树。
https://blog.youkuaiyun.com/u010442302/article/details/52713585
左旋、右旋
1、单旋转
在这里插入图片描述
左左、右右情况
2、双旋转
在这里插入图片描述
针对于左右、右左情况
3、设有数组A[i,j],数组的每个元素长度为3字节,i的值为1到8,j的值为1到10,数组从内存首地址BA开始顺序存放,当用以列为主存放时,元素A[5,8]的存储首地址为(BA+180)。

**行优先: Loc(aij) = Loc(a11) +[(i-1)*n + j-1 ]*sizeof(元素)
列优先: Loc(aij) = Loc(a11) + [(j-1)m + i-1]sizeof(元素)
4、一棵有12个节点的完全二叉树,其深度是(4)
具有n个结点的完全二叉树(包括满二叉树)的高度为【log2 n】+1 或者(【log2 (n+1 )】)

5、假设一棵完全二叉树含有456个结点,则度为0、1、2的结点个数分别为( 228,1,227 )
完全二叉树,度数为1的节点数要么1个,要么0个。
n2=n0+1;
n0+n1+n2=456

6、具有3个结点的二叉树有几种形态? 5
C(n)=(1/(n+1))((2n)!/(n!*n!))
7、常见的遍历次序:
(1)先序遍历;A BDFE CGHI(根左右)
(1)访问根节点;
(2)采用先序递归遍历左子树;
(3)采用先序递归遍历右子树;

在这里插入图片描述
(2)中序遍历;(左根右)

在这里插入图片描述
(3)后序遍历。(左右根)DEFBHGICA
在这里插入图片描述
三种方法的遍历都是根左右,只是打印顺序不同

8、不含任何结点的空树(不是特指树和二叉树,即一个集合)可能是一棵二叉树;
树的节点数最少为1,而二叉树最小节点数可以为0.
9、二叉树是一种树形结构,每个节点至多有两颗子树,下列一定是二叉树的是(红黑树、AVL树)
(1)红黑树(Red Black Tree) 是一种自平衡二叉查找树
https://blog.youkuaiyun.com/zl1zl2zl3/article/details/83999542
(2)B树是一种平衡的多叉树。
B+ 树 是一种树数据结构,是一个n叉树
AVL树是自平衡二叉查找树。

<think>嗯,用户之前问过Java后端开发中是否用得到算法,现在又接着问面试笔试中会考哪些算法。看来他可能正在准备面试,想了解需要重点准备哪些算法内容。首先,我需要回顾之前给他的回答,确保内容连贯,不重复但互补。 之前的回答分层次讲了实际开发中的算法应用,现在用户关心的是面试考点。需要明确面试和实际开发的不同,面试更注重基础算法和解能力。接下来要考虑常见的Java后端面试算法类型,比如数据结构、排序、查找、动态规划等。 用户可能没有算法竞赛经验,所以需要强调常考的高频目,而不是过于复杂的算法。同,结合Java的特性,比如集合类的实现原理,如HashMap、TreeMap,这些在面试中经常被问到。 还要注意区分笔试和面试的不同,笔试可能更侧重代码编写,而面试可能涉及思路讨论和复杂度分析。需要涵盖这两个方面,给出具体的例子和解策略。 另外,用户可能希望知道如何准备,比如网站、推荐书籍,以及如何结合项目经验展示算法能力。这部分需要给出实用建议,帮助他有效备考。 需要确保回答结构清晰,分点列出高频考点,每个考点给出例子和Java实现的提示。同,提醒注意算法原理和实际应用的结合,比如在项目中如何优化性能,使用特定算法解决问。 最后,总结部分要强调算法在面试中的重要性,以及如何平衡理论学习和实践应用,避免用户陷入盲目而忽略理解原理的误区。</think>在Java后端岗位的面试和笔试中,算法考核主要聚焦于**基础数据结构、高频算法思想及工程场景结合**。以下是具体分类和典型例: --- ### 一、**必考基础数据结构** 1. **数组与字符串** - 双指针:三数之和、接雨水问 - 滑动窗口:最长无重复子串(LeetCode 3) ```java // 滑动窗口模板示例 int left = 0, maxLen = 0; Map<Character, Integer> map = new HashMap<>(); for (int right = 0; right < s.length(); right++) { char c = s.charAt(right); if (map.containsKey(c)) { left = Math.max(left, map.get(c) + 1); } map.put(c, right); maxLen = Math.max(maxLen, right - left + 1); } ``` 2. **链表** - 反转链表(迭代/递归) - 环形链表检测(快慢指针) - 合并K个有序链表(优先队列) 3. **树与图** - 二叉树层序遍历(BFS) - 最近公共祖先(LCA) - 图的拓扑排序(课程表问) --- ### 二、**高频算法思想** | 算法类型 | 典型问 | 关键点 | |----------------|-----------------------------------|---------------------------------| | **排序算法** | 手写快速排序/归并排序 | 分治思想、间复杂度$O(n \log n)$ | | **动态规划** | 最长递增子序列、背包问 | 状态转移方程、空间优化 | | **回溯算法** | 全排列、N皇后问 | 剪枝策略、路径回溯 | | **贪心算法** | 跳跃游戏、区间调度 | 局部最优证明 | | **二分查找** | 旋转数组搜索、查找边界 | 循环不变量、边界条件处理 | --- ### 三、**工程结合型目** 1. **设计数据结构** - 实现LRU缓存(LinkedHashMap或双向链表+哈希表) - 设计线程安全的生产者-消费者队列(阻塞队列+锁) 2. **系统场景** - 海量数据找Top K(堆算法 vs 快排分区) - 短链生成(哈希算法 vs 自增ID进制转换) 3. **并发与算法结合** ```java // 例:多线程交替打印ABC(使用AtomicInteger或ReentrantLock) class PrintABC { private AtomicInteger count = new AtomicInteger(0); public void printA() { while (count.get() % 3 != 0) { /* wait */ } System.out.print("A"); count.incrementAndGet(); } // 类似实现printB, printC... } ``` --- ### 四、**Java特性相关考点** 1. **集合底层原理** - HashMap的哈希冲突、扩容机制(从链表到红黑树的转换阈值) - ConcurrentHashMap的分段锁/CAS实现 2. **JVM内存模型** - GC算法(标记-清除、复制、分代收集) - 对象可达性分析与垃圾回收触发条件 --- ### 五、**笔试高频型(带答案提示)** 1. **代码补全** ```java // 补全快速排序partition函数 int partition(int[] arr, int low, int high) { int pivot = arr[high]; int i = low - 1; for (int j = low; j < high; j++) { if (arr[j] < pivot) { i++; // 补全交换逻辑 swap(arr, i, j); } } swap(arr, i + 1, high); return i + 1; } ``` 2. **复杂度分析** - 分析双重循环递归的间复杂度(如斐波那契递归:$O(2^n)$ vs 动态规划:$O(n)$) --- ### 六、**应对策略** 1. **优先级建议** - 剑指Offer(75核心版) > LeetCode热HOT 100 > 《程序员代码面试指南》 2. **Java优化技巧** - 用`StringBuilder`代替字符串拼接 - 避免在循环中创建对象(如`new ArrayList<>()`) 3. **面试表达模板** ```text 1. 明确问边界(数据规模、特殊输入) 2. 描述暴力解法 -> 分析瓶颈 -> 提出优化思路 3. 举例验证算法正确性(如walk through测试案例) ``` --- ### 总结 Java后端算法面试的核心规律: 1. **70%基础**:数组/链表/二叉树 + 排序/二分/动态规划 2. **20%工程**:结合并发、缓存或系统设计的算法实现 3. **10%深度**:红黑树调整、分布式一致性算法(如Raft协议) 建议掌握**20~30道核心目的手写能力**,并能够用Java特性(如集合API、并发工具)优化代码实现。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值