前言
收集腾讯的面经,不包含自己面的,记录自己不会/认为高频的
不知道什么G
键入一个网站,会发生什么
- 域名解析;
- 发起TCP的3次握手;
- 建立TCP连接后发起http请求;
- 服务器响应http请求,浏览器得到html代码;
- 浏览器解析html代码,并请求html代码中的资源(如js、css、图片等);
- 浏览器对页面进行渲染呈现给用户。
该过程使用到的协议?
- DNS协议—-向指定DNS域名服务器发送DNS请求报文,以解析域名www.baidu.com对应的IP地址。
- UDP协议—DNS基于UDP协议的。
- TCP协议—-TCP连接报文:根据IP地址,与www.baidu.com服务器建立TCP连接。
- ARP协议—-ARP请求报文:根据默认网关的IP地址查询其MAC地址。
- HTTP协议—HTTP请求报文:向www.baidu.com网页服务器发送HTTP请求报文,以获取该网站首页的内容。
- ICMP协议—提供网络传输中的差错检测。
MySQL有什么函数
len、upper、lower
pow
datediff
SpringBoot加载的过程
整个spring框架启动分为两部分,
构造SpringBootApplication对象
和执行run方法
核心注解@SpringBootConfiguration标识启动类为配置类,@EnableAutoConfiguration通过内部@Import注解AutoConfigurationImportSelector.class实现自动装配,@ComponentScan默认扫描当前目录及子目录下的bean。
SpringBootApplication的构造方法主要做了几件事
根据是否加载servlet类判断是否是web环境
获取所有初始化器,扫描所有
META-INF/spring.factories
下的ApplicationContextInitializer子类通过反射拿到实例,在spring实例启动前后做一些回调工作。获取所有监听器,同2,也是扫描配置加载对应的类实例。
定位main方法
run方法主要创建了配置环境、事件监听、启动应用上下文,其中rfresh方法贯穿springbean的生命周期,执行bean的生命周期的前后置钩子方法,并且处理spring的注解标注的类。在onRefresh中通过Java代码构建出tomcat容器并启动。
PCG
各种排序对比
排序算法 | 平均时间复杂度 | 最坏时间复杂度 | 最好时间复杂度 | 空间复杂度 | 稳定性 |
---|---|---|---|---|---|
冒泡排序 | O(n²) | O(n²) | O(n) | O(1) | 稳定 |
直接选择排序 | O(n²) | O(n²) | O(n) | O(1) | 不稳定 |
直接插入排序 | O(n²) | O(n²) | O(n) | O(1) | 稳定 |
快速排序 | O(nlogn) | O(n²) | O(nlogn) | O(nlogn) | 不稳定 |
堆排序 | O(nlogn) | O(nlogn) | O(nlogn) | O(1) | 不稳定 |
希尔排序 | O(nlogn) | O(ns) | O(n) | O(1) | 不稳定 |
归并排序 | O(nlogn) | O(nlogn) | O(nlogn) | O(n) | 稳定 |
计数排序 | O(n+k) | O(n+k) | O(n+k) | O(n+k) | 稳定 |
基数排序 | O(N*M) | O(N*M) | O(N*M) | O(M) | 稳定 |
MySQL 的存储引擎有哪些,常用的是哪个
索引常见面试题 | 小林coding (xiaolincoding.com)
IOC底层是怎么实现的
不知道
Linux指令:如何查看线程、
1、top -H
手册中说:-H : Threads toggle
加上这个选项启动top,top一行显示一个线程。否则,它一行显示一个进程。
2、ps xH
手册中说:H Show threads as if they were processes
这样可以查看所有存在的线程。
数值范围0-40亿的数如何排序
bitmap,对应位置
协程
协程是比线程更小的一种执行单元,你可以认为是轻量级的线程,线程的调度是在操作系统中进行的,而协程调度则是在用户空间进行的,是开发人员通过调用系统底层的执行上下文相关api来完成的,有些语言,比如nodejs、go在语言层面支持了协程,而有些语言,比如C,需要使用第三方库才可以拥有协程的能力。
java gc,类加载
guide
http和HTTPS异同
小林
mysql的缓存机制
bufferpool
HTTP没那么安全的例子
无法验证消息完整、无法验证对对省份等等
创建HTTPS的步骤
我的理解就是tcp三次+SLL四次
Nosql的缺点
- 一致性问题
NoSQL数据库通常采用最终一致性的策略,即在一段时间内达到一致状态,可以容忍一定的数据不一致性。在数据更新和复制过程中,可能会出现数据不一致的情况。对于一些对数据一致性要求较高的场景,如金融系统或事务处理系统,NoSQL数据库可能不适合。
- 查询能力限制
NoSQL数据库的查询能力相对较弱,通常只支持基本的查询操作。与传统关系型数据库相比,NoSQL数据库缺少复杂的查询操作和聚合函数。在需要进行复杂的数据查询和分析的场景中,NoSQL数据库的查询能力可能无法满足需求。
接口和抽象类的区别
guide
介绍自己的优势
没优势
构建一个系统需要关注哪些方面
系统的性能
海量并发读取与写入
系统的安全性
系统的操作,数据的变更都应有日志进行跟踪
基于HTTPS的加密访问
系统的高可用性
微服务的部署方式
当服务出现不可用时需要对服务进行隔离,保障核心的服务不受影响,使得核心应用可以正常运行
系统的可运营性
指标监控
链路跟踪
系统的全球化性
多语言机制,适应海外及特定需求
多租户管理,对用户,子公司实现不同数据隔离和差异化处理
地方合规性
系统的架构设计是一项非常细致缜密的工作,前期需要对系统涉及的业务,关联到的业务以及企业的IT架构有足够的了解和认知,然后结合法律法规,利用当下企业提供的有限的条件进行设计。
系统高可用高容错的方案
就扯系统容灾吧
然后服务熔断服务降级来说
一个网页里一个图片链接,点开用了哪些协议
我觉得就是http等
Linux怎么查看网络状态
guide
Linux怎么查看文件位置,怎么查看程序的运行情况,怎么查看CPU使用情况,怎么查看进程pid
guide
Redis事务
总结说:redis事务就是一次性、顺序性、排他性
的执行一个队列中的一系列命令。
若在事务队列中存在语法性错误
(类似于java的1/0的运行时异常),则执行EXEC命令时,其他正确命令会被执行,错误命令抛出异常。
注意:已经执行完毕的命令对应的数据不会自动回滚
,需要程序员自己在代码中实现回滚
解决哈希冲突的办法?
拉链和线性探测
以及二次哈希
:若当前key与原来key产生相同的哈希地址,则当前key存在该地址后偏移量为(1,2,3…)的二次方地址处
key1:hash(key)+0
key2:hash(key)+1^2
key3:hash(key)+2^2
腾讯安全
如何在300万个字符串中找到ip地址,如果找不到,如何找到前一个地址或者后一个地址
正则表达式吧,ip地址都有固定的格式,0-255,无前导0,三个小数点
如何设计一个高并发网络系统
io模型,缓存,数据库,容灾,负载均衡,协议等等就这几个方面
TEG
算法合集
2. 两数相加 - 力扣(LeetCode)
public class Main {
public static void main(String[] args) {
}
}
class ListNode{
ListNode next;
int val;
ListNode(){}
ListNode(int val){this.val=val;}
}
class Solution{
public ListNode addNumbers(ListNode l1,ListNode l2)
{
ListNode dummy=new ListNode(0);
ListNode p=dummy;
int carry=0;
while(l1!=null||l2!=null)
{
int a=l1==null?0:l1.val;
int b=l2==null?0:l2.val;
int sum=a+b+carry;
carry=sum/10;
sum%=10;
p.next=new ListNode(sum);
p=p.next;
l1=l1==null?null:l1.next;
l2=l2==null?null:l2.next;
}
if(carry==1) p.next=new ListNode(1);
return dummy.next;
}
}
206. 反转链表 - 力扣(LeetCode)
package org.example;
import java.util.*;
// Press Shift twice to open the Search Everywhere dialog and type `show whitespaces`,
// then press Enter. You can now see whitespace characters in your code.
public class Main {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
Solution sl=new Solution();
while(sc.hasNextInt())
{
int count=sc.nextInt();
if(count==0)
{
System.out.println("list is empty");
continue;
}
ListNode head=new ListNode(sc.nextInt());
ListNode p=head;
for(int i=1;i<count;i++)
{
p.next=new ListNode(sc.nextInt());
p=p.next;
}
sl.print(head);
head=sl.reverseList(head);
sl.print(head);
}
}
}
class ListNode{
ListNode next;
int val;
ListNode(){}
ListNode(int val){this.val=val;}
}
class Solution{
public ListNode reverseList(ListNode head)
{
ListNode cur=head;
ListNode pre=null;
while(cur!=null)
{
ListNode aft=cur.next;
cur.next=pre;
pre=cur;
cur=aft;
}
return pre;
}
public void print(ListNode head)
{
StringBuilder sb=new StringBuilder();
while(head!=null)
{
sb.append(head.val);
sb.append(" ");
head=head.next;
}
System.out.println(sb.toString().trim());
}
}
83. 删除排序链表中的重复元素 - 力扣(LeetCode)
package org.example;
import java.util.*;
// Press Shift twice to open the Search Everywhere dialog and type `show whitespaces`,
// then press Enter. You can now see whitespace characters in your code.
public class Main {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
Solution sl=new Solution();
while(sc.hasNextLine())
{
String a=sc.nextLine();
ListNode head=new ListNode(a.charAt(0)-'0');
ListNode p=head;
for(int i=1;i<a.length();i++)
{
p.next=new ListNode(a.charAt(i)-'0');
p=p.next;
}
sl.deleteSame(head);
//.,...
}
}
}
class ListNode{
ListNode next;
int val;
ListNode(){}
ListNode(int val){this.val=val;}
}
class Solution{
public ListNode deleteSame(ListNode head)
{
ListNode dummy=new ListNode(0);
dummy.next=head;
ListNode p=head;
while(p!=null&&p.next!=null)
{
if(p.val==p.next.val)
{
p.next=p.next.next;
}else
{
p=p.next;
}
}
return dummy.next;
}
}
删除链表中重复的结点
class Solution{
public ListNode deleteSame(ListNode head)
{
ListNode dummy=new ListNode();
ListNode p=dummy;
while(head!=null&&head.next!=null)
{
if(head.val!=head.next.val)
{
p.next=head;
p=p.next;
}
while(head.next!=null&&head.val==head.next.val)
{
head=head.next;
}
head=head.next;
}
p.next=null;
return p;
}
}
这个就不能原地改了
21. 合并两个有序链表
package org.example;
import java.util.*;
// Press Shift twice to open the Search Everywhere dialog and type `show whitespaces`,
// then press Enter. You can now see whitespace characters in your code.
public class Main {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
Solution sl=new Solution();
while(sc.hasNextLine())
{
String[]lists=sc.nextLine().split(" ");
ListNode l1=sl.strToList(lists[0]);
ListNode l2=sl.strToList(lists[1]);
ListNode res=sl.mergeTwoLists(l1,l2);
//......
}
}
}
class ListNode{
ListNode next;
int val;
ListNode(){}
ListNode(int val){this.val=val;}
}
class Solution{
public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
ListNode dummy=new ListNode(0);
ListNode p=dummy;
while(list1!=null&&list2!=null)
{
if(list1.val<list2.val)
{
p.next=list1;
list1=list1.next;
}else
{
p.next=list2;
list2=list2.next;
}
p=p.next;
}
p.next=list1==null?list2:list1;
return dummy.next;
}
public ListNode strToList(String a)
{
ListNode head=new ListNode(a.charAt(0)-'0');
ListNode p=head;
for(int i=1;i<a.length();i++)
{
p.next=new ListNode(a.charAt(i)-'0');
p=p.next;
}
return head;
}
}
912. 手撕归并排序(数组)****
class Solution {
int []tmp;
public int[] sortArray(int[] nums) {
tmp=new int[nums.length];
mergeSort(nums, 0, nums.length-1);
return nums;
}
public void mergeSort(int[]nums,int l,int r)
{
if(l>=r)
{
return ;
}
int mid=(l+r)>>1;
mergeSort(nums, l, mid);
mergeSort(nums, mid+1,r);
int i=l;
int j=mid+1;
int cnt=0;
while(i<=mid&&j<=r)
{
if(nums[i]<=nums[j])
{
tmp[cnt++]=nums[i++];
}else
{
tmp[cnt++]=nums[j++];
}
}
while(i<=mid)
{
tmp[cnt++]=nums[i++];
}
while(j<=r)
{
tmp[cnt++]=nums[j++];
}
//排序好的部分再放到nums里面
for(int k=0;k<r-l+1;k++)
{
nums[k+l]=tmp[k];
}
}
}
链表版的就是先找到中间然后再断开,然后归并,一样的
选取重复频率最高前k个数_求频率最高的前k个数-CSDN博客
有一说一手写堆不会,这里用桶排序的方法吧
19. 删除链表的倒数第 N 个结点
public ListNode removeNthFromEnd(ListNode head, int n) {
ListNode dummy=new ListNode(0);
dummy.next=head;
ListNode slow=dummy;
ListNode fast=head;
while(n>0)
{
fast=fast.next;
n--;
}
while(fast!=null)
{
fast=fast.next;
slow=slow.next;
}
slow.next=slow.next.next;
return dummy.next;
}
5. 最长回文子串
public String longestPalindrome(String s) {
boolean[][]dp=new boolean[s.length()][s.length()];
for(int i=0;i<s.length();i++)
{
dp[i][i]=true;
}
int maxleft=0;
int maxlen=1;
for(int j=1;j<dp.length;j++)
{
for(int i=0;i<j;i++)
{
if(s.charAt(j)!=s.charAt(i))
{
dp[i][j]=false;
}else
{
if(j-i<3)
{
dp[i][j]=true;
}else
{
dp[i][j]=dp[i+1][j-1];
}
}
if(dp[i][j]&&j-i+1>maxlen)
{
maxlen=j-i+1;
maxleft=i;
}
}
}
return s.substring(maxleft,maxleft+maxlen);
}
442. 数组中重复的数据 - 力扣(LeetCode)
原地哈希
public List<Integer> findDuplicates(int[] nums) {
List<Integer>res=new ArrayList<>();
int n=nums.length;
for(int i=0;i<n;i++)
{
int num=nums[i];
int index=Math.abs(num)-1;//对应的位置
if(nums[index]>0)
{
nums[index]=-nums[index];//表示第一次出现
}else
{
res.add(index+1);//这个位置对应的数出现了两次
}
}
return res;
}
36车 6跑道 没有计时器 最少要几次取前三
答:B、8次 解答:
先分6组 比赛6次,每组取前三 ,得
a1 b1 c1 d1 e1 f1
a2 b2 c2 d2 e2 f2
a3 b3 c3 d3 e3 f3
再每组第一名比一次 ,得
真·第一名 a1 以及 第二名 b1 第三名 c1
d e f 组第一名都上不了前三,所以去掉 d e f
b3<b2<b1<a1,所以 b3 也不要了
c3 <c2< c1< b1< a1, 所以 c3 c2 也不要了
然后再让 b1 c1 b2 a2 a3 去比赛
得出 真·第二名和真·第三名
155. 最小栈
easy
4. 寻找两个正序数组的中位数
class Solution {
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
int n=nums1.length;
int m=nums2.length;
int left=(n+m+1)/2;
int right=(n+m+2)/2;
return (getKth(nums1, 0, n - 1, nums2, 0, m - 1, left) + getKth(nums1, 0, n - 1, nums2, 0, m - 1, right)) * 0.5;
}
int getKth(int[]nums1,int start1,int end1,int []nums2,int start2,int end2,int k)
{
int len1=end1-start1+1;
int len2=end2-start2+1;
if(len1>len2)return getKth(nums2, start2, end2, nums1, start1, end1, k);//保证如果有数组空了一定是LEN1
if(len1==0)return nums2[start2+k-1];
if(k==1)return Math.min(nums1[start1],nums2[start2]);
int i=start1+Math.min(len1, k/2)-1;
int j=start2+Math.min(len2, k/2)-1;
if(nums1[i]>nums2[j])
{
return getKth(nums1, start1, end1, nums2, j+1,end2,k-(j-start2+1));
}else
{
return getKth(nums1, i+1, end1, nums2, start2, end2, k-(i-start1+1));
}
}
}
单例模式
class Singleton{
private volatile static Singleton instance;
private Singleton(){}
public static Singleton getInstance()
{
if(instance==null)
{
synchronized (Singleton.class)
{
if(instance==null)
{
instance=new Singleton();
}
}
}
return instance;
}
}
1120. 子树的最大平均值 - 力扣(LeetCode)
class Solution {
double res=0;
public double maximumAverageSubtree(TreeNode root) {
get(root);
return res;
}
int[]get(TreeNode root)
{
if(root==null)return new int[]{0,0};
int[]left=get(root.left);
int[]right=get(root.right);
int sum=left[0]+right[0]+root.val;
int count=left[1]+right[1]+1;
double avg=1.0*sum/count;
res=Math.max(avg, res);
return new int[]{sum,count};
}
}
144. 二叉树的前序遍历 - 力扣(LeetCode)
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer>res=new ArrayList<>();
Deque<TreeNode>stk=new LinkedList<>();
if(root==null)
{
return res;
}
TreeNode p=root;
while(!stk.isEmpty()||p!=null)
{
while(p!=null)
{
res.add(p.val);
stk.push(p);
p=p.left;
}
p=stk.pop();
p=p.right;
}
return res;
}
压缩字符串abbccc->a1b2c3
LCR 155. 将二叉搜索树转化为排序的双向链表 - 力扣(LeetCode)
简单
*/
class Solution {
Node pre, head;
public Node treeToDoublyList(Node root) {
if(root==null)return null;
dfs(root);
head.left=pre;
pre.right=head;
return head;
}
void dfs(Node cur) {
if (cur == null)
return;
dfs(cur.left);
if(pre!=null)pre.right=cur;
else head=cur;
cur.left=pre;
pre=cur;
dfs(cur.right);
}
}
1044. 最长重复子串 - 力扣(LeetCode)
1262. 可被三整除的最大和 - 力扣(LeetCode)****
这题目难的要死,我选择直接背诵
public int maxSumDivThree(int[] nums) {
int n=nums.length;
int[][]f=new int[n+1][3];
f[0][1]=f[0][2]=Integer.MIN_VALUE;
for(int i=0;i<n;i++)
{
for(int j=0;j<3;j++)
{
f[i+1][j]=Math.max(f[i][j], f[i][(j+nums[i])%3]+nums[i]);
}
}
return f[n][0];
}
186. 反转字符串中的单词 II - 力扣(LeetCode)
这个你麻痹腾讯问了滴滴也问了
思路就是先字符串整体翻转,再对每个单词翻转
1044. 最长重复子串 - 力扣(LeetCode)
这题直接用hashcode,不用自定义哈希了