java面试小记

第一部分

  1. Linux 查看端口占用情况
    lsof -i:端口号

netstat -tunlp | grep 端口号

https://www.runoob.com/w3cnote/linux-check-port-usage.html

  1. hibernate和mybatis的区别

针对简单逻辑,Hibernate与MyBatis都有相应的代码生成工具,可以生成简单基本的DAO层方法。

针对高级查询,MyBatis需要手动编写SQL语句,以及ResultMap,而Hibernate有良好的映射机制,开发者无需关心SQL的生成与结果映射,可以更专注于流程。

https://www.cnblogs.com/xu-cceed3w/p/9238182.html
https://blog.csdn.net/firejuly/article/details/8190229

  1. http报文组成

一个HTTP请求报文由请求行(request line)、请求头部(header)、空行和请求数据4个部分组成。

https://www.jianshu.com/p/0015277c6575

  1. rest协议
    REST:Representational State transfer 表征状态转变 (基于HTTP协议)面向资源的;
    分布式能力:REST更适合在分布式环境中使用、因为REST是基于原生Http协议的,而http协议是无状态的。

https://www.cnblogs.com/aspirant/p/9172336.html

  1. get和post的区别

1、Get是不安全的,因为在传输过程,数据被放在请求的URL中;Post的所有操作对用户来说都是不可见的。
2. Get传送的数据量较小,这主要是因为受URL长度限制;Post传送的数据量较大,一般被默认为不受限制。
3. Get限制Form表单的数据集的值必须为ASCII字符;而Post支持整个ISO10646字符集。
4. Get执行效率却比Post方法好。Get是form提交的默认方法。

https://www.cnblogs.com/logsharing/p/8448446.html
https://zhuanlan.zhihu.com/p/73475134

  1. Mybatis是怎么避免sql注入的

https://zhuanlan.zhihu.com/p/39408398

  1. request和response的区别

#{}:相当于JDBC中的PreparedStatement

${}:是输出变量的值

简单说,#{}是经过预编译的,是安全的;${}是未经过预编译的,仅仅是取变量的值,是非安全的,存在SQL注入。

https://zhuanlan.zhihu.com/p/39408398

第二部分

  1. 协程

在有大量IO操作业务的情况下,我们采用协程替换线程,可以到达很好的效果,一是降低了系统内存,二是减少了系统切换开销,因此系统的性能也会提升。

在协程中尽量不要调用阻塞IO的方法,比如打印,读取文件,Socket接口等,除非改为异步调用的方式,并且协程只有在IO密集型的任务中才会发挥作用。

协程只有和异步IO结合起来才能发挥出最大的威力。

https://zhuanlan.zhihu.com/p/172471249

  1. TCP三次握手标志位的变化
    在这里插入图片描述

https://www.cnblogs.com/onesea/p/13053697.html

  1. 和vim类似的编辑器
    sed是一种流编辑器,它一次处理一行内容。

处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”,接着用sed命令处理缓冲区的内容,处理完成后,把缓冲区的内容送往屏幕。接着处理下一行,这样不断重复,只到文件末尾。文件内容并没有改变,除非你使用重定向的存储输出。

https://blog.csdn.net/tanrui519521/article/details/79866261

  1. jwt如何实现
    头部(header)
    有效载荷(Payload)
    签名(signature)

https://www.cnblogs.com/kaiqinzhang/p/12132702.html

  1. myisam和Innodb的区别
    Innodb支持事务、外键、聚集索引、表锁行锁;四大特性:插入缓冲(insert buffer),二次写(double write),自适应哈希索引(ahi),预读(read ahead)
    myisam用一个变量保存了整个表的行数,Innodb要全表扫描;myisam支持全文索引;

https://blog.csdn.net/qq_35642036/article/details/82820178

  1. 快速排序手写
package QuickSort;

import java.util.*;

/**
 * @ClassName Main
 * @Description TODO
 * @Author shenxinyuan
 * @Date 2021/10/12 $ {TIME}
 * @Version 1. 0
 **/
public class ShowMeBug {
    public static void main(String[] args) {
        int[] arr = {4, 5, 1, 2, 3};
        quickSort(arr);
        System.out.println(Arrays.toString(arr));   //验证结果
    }

    public static void quick(int[] arr, int left, int right) {
        if (left >= right) {
            return;
        }

        //标准节点
        int tmp = arr[left];
        int i = left;
        int j = right;
        while (i < j) {
            while (i < j && arr[j] > tmp) {
                j--;
            }
            if (i < j) {
                arr[i] = arr[j];
            }
            while (i < j && arr[i] <= tmp) {
                i++;
            }
            arr[j] = arr[i];
        }
        arr[i] = tmp;       //最后找到tmp的真正位置

        int pos = i;
        quick(arr, left, pos - 1);
        quick(arr, pos + 1, right);
    }

    public static void quickSort(int[] arr) {
        if (arr.length == 0) {
            return;
        }

        quick(arr, 0, arr.length - 1);
    }
}


  1. redis的qps为什么这么高呢?
    单线程、内存速度块、数据结构高效、多路复用的IO模型、事件机制

https://blog.csdn.net/huxiaodong1994/article/details/109169556

  1. 虚拟内存

虚拟内存是计算机系统内存管理的一种技术。它使得应用程序认为它拥有连续的可用的内存(一个连续完整的地址空间),而实际上,它通常是被分隔成多个物理内存碎片,还有部分暂时存储在外部磁盘存储器上,在需要时进行数据交换。目前,大多数操作系统都使用了虚拟内存,如Windows家族的“虚拟内存”;Linux的“交换空间”等。

  1. 文件创建读写

使用FileInputStream实现读取txt文件内容:
使用FileOutputStream实现写入txt文件内容:

https://www.cnblogs.com/xiaozhaoboke/p/11177168.html

  1. Myisam实现

MyISAM索引实现:MyISAM索引文件和数据文件是分离的,索引文件仅保存数据记录的地址。
而在InnoDB中,表数据文件本身就是按B+Tree组织的一个索引结构,这棵树的叶节点data域保存了完整的数据记录。这个索引的key是数据表的主键,因此InnoDB表数据文件本身就是主索引。

https://www.cnblogs.com/zlcxbb/p/5757245.html

  1. ReadWriteLock的实现原理

在AQS中,通过int类型的全局变量state来表示同步状态,即用state来表示锁。ReentrantReadWriteLock也是通过AQS来实现锁的,但是ReentrantReadWriteLock有两把锁:读锁和写锁,它们保护的都是同一个资源,那么如何用一个共享变量来区分锁是写锁还是读锁呢?答案就是按位拆分。
由于state是int类型的变量,在内存中占用4个字节,也就是32位。将其拆分为两部分:高16位和低16位,其中高16位用来表示读锁状态,低16位用来表示写锁状态。当设置读锁成功时,就将高16位加1,释放读锁时,将高16位减1;当设置写锁成功时,就将低16位加1,释放写锁时,将第16位减1。

https://blog.csdn.net/qq_34436819/article/details/102929881

  1. SQL嵌套查
    子查询:
    select name from person
    where countryid in
    (
    select countryid from country
    where countryname = ‘韩国’
    );
    in嵌套查询:
    select name from person
    where countryid in
    (
    select countryid from country
    where countryname = ‘魏国’
    );
    some嵌套查询:
    select name from person
    where countryid = some       --用等号和以下查询到的值比较,如果与其中一个相等,就返回
    (
    select countryid from country
    where countryname = ‘魏国’
    );
    all嵌套查询:
    select name from person
    where countryid > all   --当countryid大于以下返回的所有id,此结果才为True,此结果才返回
    (
    select countryid from country
    where countryname = ‘魏国’
    )
    exists嵌套查询
    SELECT * FROM Person
    WHERE exists
    (
    SELECT * FROM Person
    WHERE Person_Id = 100 --如果不存在Person_Id的记录,则子查询没有结果集返回,主语句不执行
    );

https://www.cnblogs.com/glassysky/p/11559082.html

  1. 回表查询

所谓的回表查询,先定位主键值,再定位行记录,它的性能较扫一遍索引树更低。

https://blog.csdn.net/qq_42000661/article/details/108536954

  1. mybatis缓存

mybatis提供了一级缓存和二级缓存

一级缓存是SQLSession级别的缓存,不同的SQLSession的缓存是相互独立的,互不影响的,一级缓存的作用域是同一个SQLSession,在同一个SQLSession中执行两次相同的SQL查询操作,第一次执行查询操作查询数据库将数据写入缓存,第二次会从缓存当中来获取数据,从而提高访问效率,mybatis默认开启一级缓存的

二级缓存是mapper级别的缓存,多个SQLSession去操作同一个mapper的SQL语句,多个SQLSession可以共享二级缓存,二级缓存 是跨SQLSession的

二级缓存作用于是mapper的同一个namespace,不同的SQLSession两次执行相同的namespace下的相同的SQL语句,第一次执行的完毕就会将数据写入缓存,第二次会从缓存中获取数据,mybatis默认没有开启二级缓存,二级缓存的开启需要在setting全局参数中开启二级缓存

1、mybatis中二级缓存是mapper级别的缓存,默认是关闭的,
2、对同一个mapper器不同的SQLSession可以共享二级缓存
3、不同的mapper缓存是相互隔离的二级缓存的使用需要打开缓存配置
4、映射的Java类需要实现序列化

  1. springMVC工作流程

1:用户发起请求(URL),请求request到前端控制器:DispatchServlet

2:前端控制器请求处理器映射器:HardlerMapping查找Handler,可以通过注解,xml配置来进行查找

三:处理器映射器向前端控制器来响应结果,返回的是处理器执行链HandlerExecutionChain,包含一个Handler处理器对象和多个HandlerInterceptor对象

四:由前端控制器请求处理器适配器:请求执行Handler

五:处理器适配器找到真正执行的处理器:Handler

六:处理器返回给处理器适配器:返回一个ModelAndView的对象,该对象的底层是包含View和Model:Model就是响应该请求的数据,View是的逻辑视图名

七:处理器适配器响应前端控制器,返回ModelAndView的对象

八:由前端控制器来请求视图解析器:ViewResolver,视图解析器负责将逻辑视图名解析为具体的视图View(jsp,pdf,freeemark…)

九:视图解析器向前端控制器返回View

十:将前端控制器将数据渲染到页面View上

十一:将填充好的页面响应该用户

第三部分

  1. 行内元素和块级元素

块级元素?
总是在新行上开始;
高度,行高以及外边距和内边距都可控制;
宽度缺省是它的容器的100%,除非设定一个宽度。
它可以容纳内联元素和其他块元素

行内元素?
和其他元素都在一行上;
高,行高及外边距和内边距不可改变;
宽度就是它的文字或图片的宽度,不可改变
内联元素只能容纳文本或者其他内联元素

https://www.cnblogs.com/yanqiu/p/8987126.html

  1. get和post

最直观的区别就是GET把参数包含在URL中,POST通过request body传递参数。
GET在浏览器回退时是无害的,而POST会再次提交请求。
GET产生的URL地址可以被Bookmark,而POST不可以。
GET请求会被浏览器主动cache,而POST不会,除非手动设置。
GET请求只能进行url编码,而POST支持多种编码方式。
GET请求参数会被完整保留在浏览器历史记录里,而POST中的参数不会被保留。
GET请求在URL中传送的参数是有长度限制的,而POST么有。
对参数的数据类型,GET只接受ASCII字符,而POST没有限制。
GET比POST更不安全,因为参数直接暴露在URL上,所以不能用来传递敏感信息。
GET参数通过URL传递,POST放在Request body中。

post用于修改和写入数据,get一般用于搜索排序和筛选之类的操作(淘宝,支付宝的搜索查询都是get提交),目的是资源的获取,读取数据
https://blog.csdn.net/zzk220106/article/details/78595108/
https://www.jianshu.com/p/b69674f51796

  1. 请求方式
    ajax、jquery发送请求,有get、post方式

https://www.cnblogs.com/nanyang520/p/11206290.html
https://blog.csdn.net/m0_46498310/article/details/104711466

  1. 内网外网ip地址转换

NAT可以将内网IP转换成公网IP发送和接收数据
NAT有一个特性,只有先从内网发送请求才能接收对应公网中的响应, 比如只有先从内网询问公网中CSDN我可以访问你吗,CSDN才可以将网页文件发送你,如果你没有先发起请求CSDN就将网页发送来过,NAT会直接拦截。

https://blog.csdn.net/low5252/article/details/101572394

  1. substr

substr 方法用于返回一个从指定位置开始的指定长度的子字符串。
substring 方法返回的子串包括 start 处的字符,但不包括 end 处的字符。

  1. 抽象类内可以有实现的函数吗

有抽象方法的类一定是抽象类。但是抽象类中不一定都是抽象方法,也可以全是具体方法。

  1. String 、Integer是哪个类加载器加载的

Java 中的类加载器大致可以分成两类,一类是系统提供的,另外一类则是由 Java 应用开发人员编写的。系统提供的类加载器主要有下面三个:

引导类加载器(bootstrap class loader):它用来加载 Java 的核心库,是用原生代码来实现的,并不继承自 java.lang.ClassLoader。
扩展类加载器(extensions class loader):它用来加载 Java 的扩展库。Java 虚拟机的实现会提供一个扩展库目录。该类加载器在此目录里面查找并加载 Java 类。
系统类加载器(system class loader):它根据 Java 应用的类路径(CLASSPATH)来加载 Java 类。一般来说,Java 应用的类都是由它来完成加载的。可以通过 ClassLoader.getSystemClassLoader()来获取它。

  1. 抽象工厂

对比工厂方法,其针对的是产品等级结构,而抽象工厂是针对产品族。在二者的使用选择上,需要结合实际业务,对于产品等级数量相对固定的产品族,可以优先考虑抽象工厂模式,但是如果频繁变动,则不大适用,因为在现有的产品族中新增产品等级时,就需要修改产品族工厂,也就违背了开闭原则

https://blog.csdn.net/u014727260/article/details/82560912

  1. 线程池的参数,状态

corePoolSize:核心线程数
queueCapacity:任务队列容量(阻塞队列)
maxPoolSize:最大线程数
keepAliveTime:线程空闲时间
allowCoreThreadTimeout:允许核心线程超时
rejectedExecutionHandler:任务拒绝处理器

线程有5种状态:新建状态,就绪状态,运行状态,阻塞状态,死亡状态。
线程池也有5种状态;然而,线程池不同于线程,线程池的5种状态是:Running, SHUTDOWN, STOP, TIDYING, TERMINATED。

四种拒绝策略:
AbortPolicy – 当任务添加到线程池中被拒绝时,它将抛出 RejectedExecutionException 异常。
CallerRunsPolicy – 当任务添加到线程池中被拒绝时,会在线程池当前正在运行的Thread线程池中处理被拒绝的任务。
DiscardOldestPolicy – 当任务添加到线程池中被拒绝时,线程池会放弃等待队列中最旧的未处理任务,然后将被拒绝的任务添加到等待队列中。
DiscardPolicy – 当任务添加到线程池中被拒绝时,线程池将丢弃被拒绝的任务。

https://www.cnblogs.com/sunny-miss/p/12393194.html
http://blog.sina.com.cn/s/blog_7be8a4cf0102ygu6.html

  1. TCP和UDP的区别

TCP面向连接、UDP无连接
TCP安全可靠、UDP不可靠
UDP速度较快适合实时信息传输,TCP适合数据量少的传输,UDP适合数据量大的传输

https://www.cnblogs.com/williamjie/p/9390164.html

  1. springboot注解

springboot中的常用注解有:
1、SpringBootApplication;这个注解是Spring Boot最核心的注解,用在 Spring Boot的主类上,用于开启服务
2、Repository;3、Service;4、RestController;5、ResponseBody;6、Component等。

7、@EnableAutoConfiguration
允许 Spring Boot 自动配置注解,开启这个注解之后,Spring Boot 就能根据当前类路径下的包或者类来配置 Spring Bean。
8、@ComponentScan
组件扫描。让spring Boot扫描到Configuration类并把它加入到程序上下文。
@ComponentScan注解默认就会装配标识了@Controller,@Service,@Repository,@Component注解的类到spring容器中。

https://m.php.cn/faq/417047.html

  1. 慢查询优化

MySQL慢查询就是在日志中记录运行比较慢的SQL语句,这个功能需要开启才能用。

https://www.jianshu.com/p/7529a0fbf088
https://blog.csdn.net/qq_35571554/article/details/82800463

  1. 重定向和转发

区别:
1、转发使用的是getRequestDispatcher()方法;重定向使用的是sendRedirect();
2、转发:浏览器URL的地址栏不变。重定向:浏览器URL的地址栏改变;
3、转发是服务器行为,重定向是客户端行为;
4、转发是浏览器只做了一次访问请求。重定向是浏览器做了至少两次的访问请求;
5、转发2次跳转之间传输的信息不会丢失,重定向2次跳转之间传输的信息会丢失(request范围)。

1、重定向的速度比转发慢,因为浏览器还得发出一个新的请求,如果在使用转发和重定向都无所谓的时候建议使用转发。
2、因为转发只能访问当前WEB的应用程序,所以不同WEB应用程序之间的访问,特别是要访问到另外一个WEB站点上的资源的情况,这个时候就只能使用重定向了。

https://blog.csdn.net/liubin5620/article/details/79922692

  1. 跨域是什么?怎么解决?

跨域,指的是从一个域名去请求另外一个域名的资源。即跨域名请求!跨域的严格一点来说就是只要协议,域名,端口有任何一个的不同,就被当作是跨域。
 
跨域解决方案
1、 通过jsonp跨域
2、 document.domain + iframe跨域
3、 location.hash + iframe
4、 window.name + iframe跨域
5、 postMessage跨域
6、 跨域资源共享(CORS)
7、 nginx代理跨域
8、 nodejs中间件代理跨域
9、 WebSocket协议跨域

https://www.cnblogs.com/jxxblogs/p/12108036.html
https://blog.csdn.net/lambert310/article/details/51683775

  1. 使用Jendins实现Gitlab的自动化部署jar包

偏向于自动化测试

  1. 前后端分离项目架构

  2. 视图 回滚

  3. jvm 溢出

  4. 内存溢出与内存占满

内存溢出指访问的数据超出了内存总量或界限
内存占满指的是运行所需空间不足,但并未溢出

  1. bean的注入

构造方法、setter方法、注解方式

@Autowired注解和@Resource注解的作用相同,只不过@Autowired按照byType注入,如果@Autowired想使用名称可以结合@Qualifier注解进行使用

http://dditblog.com/itshare_851.html

  1. 初始化

GetBean 的大概过程:

  1.   先试着从单例缓存对象里获取。
    
  2.   从父容器里取定义,有则由父容器创建。
    
  3.   如果是单例,则走单例对象的创建过程:在 spring 容器里单例对象和非单例对象的创建过程是一样的。都会调用父 类 AbstractAutowireCapableBeanFactory 的 createBean 方法。 不同的是单例对象只创建一次并且需要缓 存起来。 DefaultListableBeanFactory 的父类 DefaultSingletonBeanRegistry 提供了对单例对 象缓存等支持工作。所以是单例对象的话会调用 DefaultSingletonBeanRegistry 的 getSingleton 方法,它会间 接调用AbstractAutowireCapableBeanFactory 的 createBean 方法。
    

如果是 Prototype 多例则直接调用父类 AbstractAutowireCapableBeanFactory 的 createBean 方法。

https://www.cnblogs.com/fyx158497308/p/3977391.html

  1. bean的生命周期

实例化、bean的属性注入、判断是否实现了一些接口,调用对应的方法;此时,Bean已经准备就绪,可以被应用程序使用了。他们将一直驻留在应用上下文中,直到应用上下文被销毁。

如果bean实现了DisposableBean接口,Spring将调用它的destory()接口方法,同样,如果bean使用了destory-method 声明销毁方法,该方法也会被调用。

https://www.cnblogs.com/javazhiyin/p/10905294.html

  1. 秒杀系统的设计思路

  2. Set集合中最多允许出现一个null元素

https://blog.csdn.net/weixin_36255718/article/details/114838070

第四部分

  1. 布隆过滤器解决hash冲突

  2. 索引下推 索引覆盖 回表查询

索引下推一次过滤采用了组合索引的两个或多个字段

索引覆盖指的是一次索引查询直接返回数据,不用再回表查询

回表查询指的是现根据索引树找到对应的主键索引,然后根据主键索
引再次查询返回数据,这个过程进行了两次表查询,称为回表

  1. 自定义注解

第五部分

  1. SpringMVC 的servlet处理前端请求的方式

https://www.cnblogs.com/nalanshawn/p/9351782.html

Servlet是一个单实例多线程的。只能被实例化一次,而每次service服务会开启新线程进行处理新请求。

Servlet工作过程

1)browser发出一个http请求;

2)Tomcat的Connector组件监听到该请求,其主线程会创建HttpServletRequest对象和HTTPServletResponse对象;

3)从请求URL中找到正确Servlet后,Tomcat为其创建或分配一个线程,同时将2中对象传递给该线程;

4)Tomcat调用Servlet的service()方法,会根据请求参数的不同来调用doGet()或doPost()等方法,并将结果返回到HTTPServletResponse对象中;

5)Tomcat将响应结果返回到browser。

  1. bootstrap发起请求的方式
    表单提交、超链接、ajax请求
    forward
    location

  2. springMVC requestBody he responseBody 以及默认返回给前端请求一个什么类型的数据

https://blog.csdn.net/weixin_44588495/article/details/94286966

  1. redis和springboot结合,默认的驱动

https://blog.csdn.net/qq_36781505/article/details/86612988

spring-boot-starter-data-redis

  1. 线程池中线程工厂的作用

https://www.cnblogs.com/WangJinYang/p/10226866.html

第1个参数 :corePoolSize 表示常驻核心线程数。如果等于0,则任务执行完成后,没有任何请求进入时销毁线程池的线程;如果大于0,即使本地任务执行完毕,核心线程也不会被销毁。这个值的设置非常关键,设置过大会浪费资源,设置的过小会导致线程频繁地创建或销毁。
第2个参数:maximumPoolSize 表示线程池能够容纳同时执行的最大线程数。从上方的示例代码中第一处来看,必须大于或等于1。如果待执行的线程数大于此值,需要借助第5个参数的帮助。缓存在队列中。如果maximumPoolSize 与corePoolSize 相等,即是固定大小线程池。
第3个参数:keepAliveTime 表示线程池中的线程空闲时间,当空闲时间达到KeepAliveTime 值时,线程被销毁,直到剩下corePoolSize 个线程为止,避免浪费内存和句柄资源。在默认情况下,当线程池的线程大于corePoolSize 时,keepAliveTime 才会起作用。但是ThreadPoolExecutor的allowCoreThreadTimeOut 变量设置为ture时,核心线程超时后也会被回收。
第4个参数:TimeUnit 表示时间单位。keepAliveTime 的时间单位通常是TimeUnit.SECONDS。
第5个参数: workQueue 表示缓存队列。当请求的线程数大于maximumPoolSize时,线程进入BlockingQueue 阻塞队列。后续示例代码中使用的LinkedBlockingQueue 是单向链表,使用锁来控制入队和出对的原子性,两个锁分别控制元素的添加和获取,是一个生产消费模型队列。
第6个参数:threadFactory 表示线程工厂。它用来生产一组相同任务的线程。线程池的命名是通过给这个factory增加组名前缀来实现的。在虚拟机栈分析时,就可以知道线程任务是由哪个线程工厂产生的。
第7个参数:handler 表示执行拒绝策略的对象。当超过第5个参数workQueue的任务缓存区上限的时候,就可以通过该策略处理请求,这是一种简单的限流保护。友好的拒绝策略可以使如下三种:
保存到数据库进行削峰填谷。在空闲的时候再拿出来执行。
转向某个提示页面。
打印日志。

  1. spring中使用事务的方式

https://blog.csdn.net/u013837825/article/details/100101422

  1. springboot结合redis的template

https://blog.csdn.net/ruby_one/article/details/79141940

  1. 微服务组件

https://www.cnblogs.com/findbetterme/p/11195011.html
最后再来总结一下,上述几个Spring Cloud核心组件,在微服务架构中,分别扮演的角色:

Eureka:各个服务启动时,Eureka Client都会将服务注册到Eureka Server,并且Eureka Client还可以反过来从Eureka Server拉取注册表,从而知道其他服务在哪里
Ribbon:服务间发起请求的时候,基于Ribbon做负载均衡,从一个服务的多台机器中选择一台
Feign:基于Feign的动态代理机制,根据注解和选择的机器,拼接请求URL地址,发起请求
Hystrix:发起请求是通过Hystrix的线程池来走的,不同的服务走不同的线程池,实现了不同服务调用的隔离,避免了服务雪崩的问题
Zuul:如果前端、移动端要调用后端系统,统一从Zuul网关进入,由Zuul网关转发请求给对应的服务
以上就是我们通过一个电商业务场景,阐述了Spring Cloud微服务架构几个核心组件的底层原理。

  1. git常用命令

https://blog.csdn.net/web_csdn_share/article/details/79243308

 
# 列出所有本地分支
$ git branch
 
# 列出所有远程分支
$ git branch -r
 
# 列出所有本地分支和远程分支
$ git branch -a
 
# 新建一个分支,但依然停留在当前分支
$ git branch [branch-name]
 
# 以远程分支为基础新建一个分支,并切换到该分支
$ git checkout -b [branch] origin/[remote-branch]
 
# 新建一个分支,指向指定commit
$ git branch [branch] [commit]
 
# 新建一个分支,与指定的远程分支建立追踪关系
$ git branch --track [branch] [remote-branch]
 
# 切换到指定分支,并更新工作区
$ git checkout [branch-name]
 
# 切换到上一个分支
$ git checkout -
 
# 建立追踪关系,在现有分支与指定的远程分支之间
$ git branch --set-upstream [branch] [remote-branch]
 
# 合并指定分支到当前分支
$ git merge [branch]
 
# 选择一个commit,合并进当前分支
$ git cherry-pick [commit]
 
# 删除分支
$ git branch -d [branch-name]
 
# 删除远程分支
$ git push origin --delete [branch-name]
$ git branch -dr [remote/branch]
  1. 如何验证hashmap线程不安全

在高并发情况下,对hashmap做put操作的话最终的结果一般低于预期值,证明hashmap线程不安全

求股票最大收益

1 5 2 3 9 2 1 4 7 5
收益:卖出价格一定大于买入价格,多出的部分为收益

动态规划:时间复杂度O(N) 空间复杂度O(1)

代码略。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Protobuf是一种高效的序列化协议,可以用于数据交换和数据存储。它的主要优势是大小小,速度快,可扩展性强。下面是使用Protobuf的一些小记: 1. 定义消息格式 首先,需要定义消息格式,以便Protobuf可以将数据序列化和反序列化。消息格式定义在.proto文件中,使用protobuf语言编写。例如,下面是一个简单的消息格式定义: ``` syntax = "proto3"; message Person { string name = 1; int32 age = 2; } ``` 这个消息格式定义了一个名为Person的消息,包含两个字段:name和age。 2. 生成代码 一旦消息格式定义好,就可以使用Protobuf编译器生成代码。编译器将根据消息格式定义生成相应的代码,包括消息类、序列化和反序列化方法等。可以使用以下命令生成代码: ``` protoc --java_out=. message.proto ``` 这将生成一个名为message.pb.javaJava类,该类包含Person消息的定义以及相关方法。 3. 序列化和反序列化 一旦生成了代码,就可以使用Protobuf序列化和反序列化数据。例如,下面是一个示例代码,将一个Person对象序列化为字节数组,并将其反序列化为另一个Person对象: ``` Person person = Person.newBuilder() .setName("Alice") .setAge(25) .build(); byte[] bytes = person.toByteArray(); Person deserializedPerson = Person.parseFrom(bytes); ``` 这个示例代码创建了一个Person对象,将其序列化为字节数组,然后将其反序列化为另一个Person对象。在这个过程中,Protobuf使用生成的代码执行序列化和反序列化操作。 以上是使用Protobuf的一些基本步骤和注意事项,希望对你有所帮助!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值