用户发起请求到前端控制器(DispatcherServlet)
前端控制器收到请求调用处理器映射器(HandlerMapping)
处理器映射器根据请求的URL找到具体的处理器 生成处理器对象及处理器拦截器 一并返回给DispatcherServlet
前端控制器调用处理器适配器(HandlerAdapter)去执行处理器(Handler)
处理器适配器去执行Handler
Handler执行完给处理器适配器返回ModelAndView
处理器适配器向前端控制器返回ModelAndView
前端控制器请求视图解析器(ViewResolver)去执行视图解析
视图解析器向前端控制器返回视图View
前端控制器对视图View进行渲染
前端控制器向用户响应结果
4399笔试一
package com.huhu.sort;
import java.util.Arrays;
//归并排序
public class MergeSort {public static void main(String[] args) {
// int[] arr = {8, 4, 5, 7, 1, 3, 6, 2};int[] arr = {100,5,7,20,97,18,39,50,72};int[] temp = new int[arr.length];//归并排序需要一个额外空间mergeSort(arr, 0, arr.length - 1, temp);System.out.println("归并排序后数组:" + Arrays.toString(arr));}//分+合方法public static void mergeSort(int[] arr, int left, int right, int[] temp) {if (left < right) {int mid = (left + right) / 2;//中间索引//向左递归进行分解mergeSort(arr, left, mid, temp);//向右递归进行分解mergeSort(arr, mid + 1, right, temp);//到合并merge(arr, left, mid, right, temp);}}//合并方法/*** @param arr 排序的原始数组* @param left 左边有序序列的索引* @param mid 中间索引* @param right 右边索引* @param temp 做中转的数组*/public static void merge(int[] arr, int left, int mid, int right, int[] temp) {//System.out.println("xxxx");int i = left;//初始化i,左边有序序列的初始索引int j = mid + 1;//初始化j,右边有序序列的初始索引int t = 0;//指向temp数组的当前索引//(一)//先把左右两边(有序)的数据按照规则填充到temp数组//直到左右两边的有序序列,有一边处理完毕为止while (i <= mid && j <= right) {//如果左边的有序序列的当前元素,小于等于右边有序序列的当前元素//则把左边有序序列的当前元素放到temp数组//然后t++,i++if (arr[i] <= arr[j]) {temp[t] = arr[i];t += 1;i += 1;} else {//反之//如果左边的有序序列的当前元素,大于右边有序序列的当前元素//则把右边有序序列的当前元素放到temp数组//然后t++,i++temp[t] = arr[j];t += 1;j += 1;}}//(二)//把有剩余数据的一边的数据依次全部填充到tempwhile (i <= mid) {//左边的有序序列还有剩余的元素,就全部填充到temptemp[t] = arr[i];t += 1;i += 1;}while (j <= right) {//右边的有序序列还有剩余的元素,就全部填充到temptemp[t] = arr[j];t += 1;j += 1;}//(三)//将temp数组拷贝到arr//注意:并不是每次都拷贝所有t = 0;int tempLeft = left;////System.out.println("tempLeft=" + tempLeft + ",right=" + right);while (tempLeft <= right) {//第一次合并 tempLeft=0 right=1 第二次合并 tempLeft=2 right=3 第三次合并 tempLeft=0 right=3//第四次合并 tempLeft=4 right=5 第五次合并 tempLeft=6 right=7 第六次合并 tempLeft=4 right=7//最后一次合并 tempLeft=0 right=7arr[tempLeft] = temp[t];t += 1;tempLeft += 1;}}
}
4399笔试二
有 n 个气球,编号为0 到 n - 1,每个气球上都标有一个数字,这些数字存在数组 nums 中。
现在要求你戳破所有的气球。戳破第 i 个气球,你可以获得 nums[i - 1] * nums[i] * nums[i + 1] 枚硬币。 这里的 i - 1 和 i + 1 代表和 i 相邻的两个气球的序号。如果 i - 1或 i + 1 超出了数组的边界,那么就当它是一个数字为 1 的气球。
求所能获得硬币的最大数量。
示例 1:
输入:nums = [3,1,5,8]
输出:167
解释:
nums = [3,1,5,8] --> [3,5,8] --> [3,8] --> [8] --> []
coins = 3*1*5 + 3*5*8 + 1*3*8 + 1*8*1 = 167
示例 2:输入:nums = [1,5]
输出:10
n == nums.length
1 <= n <= 300
0 <= nums[i] <= 100
题解:求解戳破所有气球之和最大硬币数量,换思路来说假设第k个气球为最后一个戳破的,那么maxCoin=Math.max(dp[i][j],dp[i,k]+dp[k,j]+nums[0]*nums[nums.length]*nums[k])(nums数组原来气球基础上首尾加上虚拟气球值1,方便计算,注意区间都是左开右开)
重要技巧:我们初始一维数组所有值都为-1
import java.util.Arrays;public class BiShi3 {public static void main(String[] args) {int[] a = {3, 1, 5, 8};ChuoQiQiu c = new ChuoQiQiu();System.out.println(c.maxCoins(a));}
}class ChuoQiQiu {int[][] dp;public int maxCoins(int[] a) {int n = a.length;int[] temp = new int[n + 2];temp[0] = 1;temp[n + 1] = 1;for (int i = 0; i < n; i++) {temp[i + 1] = a[i];}dp = new int[n + 2][n + 2];for (int i = 0; i < n + 2; i++) {Arrays.fill(dp[i], -1);//标记位dp[i]下一维数组都为-1}return solve(temp, 0, n + 1);}// 开区间(l,r)private int solve(int[] temp, int l, int r) {if (l + 2 > r) {// 区间内没有气球return 0;}if (l + 2 == r) {// 区间刚好有1个气球return temp[l] * temp[l + 1] * temp[r];}if (dp[l][r] != -1) {return dp[l][r];}int k = l + 1;//戳第k个气球int res=0;// k的范围是[1,n]while (k <= r - 1) {int left = solve(temp, l, k);//第k个气球左区间最大硬币值int right = solve(temp, k, r);//第k个气球右区间最大硬币值res=Math.max(res,left+right+temp[l]*temp[k]*temp[r]);k++;}dp[l][r]=res;return res;}
}
招聘笔试
输入一个字符串,在其中寻找长度最长的,不含重复字符的字符串,如果有多个长度相同的最长子字符串,则全部输出
注意:子字符串应由输入的字符串中的连续字符组成
输入:abcdabcde
输出:abcde
输入:abcdabcde
输出:abcd,bcda,cdab,dabc,abcd
package 滑动窗口;import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
public class Main {public static void main(String[] args) {String str="abcdabcd";HashMap