前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >招银网络科技,心痛拒了!

招银网络科技,心痛拒了!

作者头像
沉默王二
发布2024-05-14 18:50:17
800
发布2024-05-14 18:50:17
举报
文章被收录于专栏:沉默王二沉默王二

Lambda表达式的作用?

Lambda 表达式主要用于提供一种简洁的方式来表示匿名方法,使 Java 具备了函数式编程的特性。

比如说我们可以使用 Lambda 表达式来简化线程的创建:

代码语言:javascript
复制
new Thread(() -> System.out.println("Hello World")).start();

这比以前的匿名内部类要简洁很多。

所谓的函数式编程,就是把函数作为参数传递给方法,或者作为方法的结果返回。比如说我们可以配合 Stream 流进行数据过滤:

代码语言:javascript
复制
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6);
List<Integer> evenNumbers = numbers.stream()
    .filter(n -> n % 2 == 0)
    .collect(Collectors.toList());

其中 n -> n % 2 == 0 就是一个 Lambda 表达式。表示传入一个参数 n,返回 n % 2 == 0 的结果。

Java集合有哪些?

Java 集合框架可以分为两条大的支线:

①、Collection,主要由 List、Set、Queue 组成:

  • List 代表有序、可重复的集合,典型代表就是封装了动态数组的 ArrayList 和封装了链表的 LinkedList;
  • Set 代表无序、不可重复的集合,典型代表就是 HashSet 和 TreeSet;
  • Queue 代表队列,典型代表就是双端队列 ArrayDeque,以及优先级队列 PriorityQueue。

②、Map,代表键值对的集合,典型代表就是 HashMap。

二哥的 Java 进阶之路:Java集合主要关系

线程不安全的集合变成线程安全的方法?

可以使用 Collections.synchronizedList() 方法,它将返回一个线程安全的 List。

代码语言:javascript
复制
SynchronizedList list = Collections.synchronizedList(new ArrayList());

内部是通过 synchronized 关键字加锁来实现的。

也可以直接使用 CopyOnWriteArrayList,它是线程安全的,遵循写时复制的原则,每当对列表进行修改(例如添加、删除或更改元素)时,都会创建列表的一个新副本,这个新副本会替换旧的列表,而对旧列表的所有读取操作仍然可以继续。

代码语言:javascript
复制
CopyOnWriteArrayList list = new CopyOnWriteArrayList();

通俗的讲,CopyOnWrite 就是当我们往一个容器添加元素的时候,不直接往容器中添加,而是先复制出一个新的容器,然后在新的容器里添加元素,添加完之后,再将原容器的引用指向新的容器。多个线程在读的时候,不需要加锁,因为当前容器不会添加任何元素。这样就实现了线程安全。

有什么办法能解决 HashMap 线程不安全的问题呢?

在 Java 中,有 3 种线程安全的 Map 实现,最常用的是ConcurrentHashMap和Collections.synchronizedMap(Map)包装器。

Hashtable 也是线程安全的,但它的使用已经不再推荐使用,因为 ConcurrentHashMap 提供了更高的并发性和性能。

①、HashTable 是直接在方法上加 synchronized 关键字,比较粗暴。

二哥的 Java 进阶之路:HashTable

②、Collections.synchronizedMap 返回的是 Collections 工具类的内部类。

二哥的 Java 进阶之路:Collections.synchronizedMap

内部是通过 synchronized 对象锁来保证线程安全的。

③、ConcurrentHashMap 在 JDK 7 中使用分段锁,在 JKD 8 中使用了 CAS(Compare-And-Swap)+ synchronized 关键字,性能得到进一步提升。

初念初恋:ConcurrentHashMap 8 中的实现

JDK1.8的特性?

JDK 1.8 新增了不少新的特性,如 Lambda 表达式、接口默认方法、Stream API、日期时间 API、Optional 类等。

三分恶面渣逆袭:JDK1.8主要新特性

①、Java 8 允许在接口中添加默认方法和静态方法。

代码语言:javascript
复制
public interface MyInterface {
    default void myDefaultMethod() {
        System.out.println("My default method");
    }

    static void myStaticMethod() {
        System.out.println("My static method");
    }
}

②、Lambda 表达式描述了一个代码块(或者叫匿名方法),可以将其作为参数传递给构造方法或者普通方法以便后续执行。

代码语言:javascript
复制
public class LamadaTest {
    public static void main(String[] args) {
        new Thread(() -> System.out.println("沉默王二")).start();
    }
}

《Effective Java》的作者 Josh Bloch 建议使用 Lambda 表达式时,最好不要超过 3 行。否则代码可读性会变得很差。

③、Stream 是对 Java 集合框架的增强,它提供了一种高效且易于使用的数据处理方式。

代码语言:javascript
复制
List<String> list = new ArrayList<>();
list.add("中国加油");
list.add("世界加油");
list.add("世界加油");

long count = list.stream().distinct().count();
System.out.println(count);

④、Java 8 引入了一个全新的日期和时间 API,位于java.time包中。这个新的 API 纠正了旧版java.util.Date类中的许多缺陷。

代码语言:javascript
复制
LocalDate today = LocalDate.now();
System.out.println("Today's Local date : " + today);

LocalTime time = LocalTime.now();
System.out.println("Local time : " + time);

LocalDateTime now = LocalDateTime.now();
System.out.println("Current DateTime : " + now);

⑤、引入 Optional 是为了减少空指针异常。

代码语言:javascript
复制
Optional<String> optional = Optional.of("沉默王二");
optional.isPresent();           // true
optional.get();                 // "沉默王二"
optional.orElse("沉默王三");    // "bam"
optional.ifPresent((s) -> System.out.println(s.charAt(0)));     // "沉"

HTTP传送请求的一次流程

HTTP 全称是超文本传输协议(HyperText Transfer Protocol),是一个基于请求与响应模式的应用层协议,基于 TCP/IP 协议传输数据。

HTTP 遵循标准的客户端-服务器模型,客户端打开连接以发出请求,然后等待它收到服务器端响应。

三分恶面渣逆袭:HTTP 请求的过程和原理

  • 在浏览器输入 URL 后,浏览器首先会通过 DNS 解析获取到服务器的 IP 地址,然后与服务器建立 TCP 连接。
  • TCP 连接建立后,浏览器会向服务器发送 HTTP 请求。
  • 服务器收到请求后,会根据请求的信息处理请求。
  • 处理完请求后,服务器会返回一个 HTTP 响应给浏览器。
  • 浏览器收到响应后,会根据响应的信息渲染页面。然后,浏览器和服务器断开 TCP 连接。

客户端发送一个请求到服务器,服务器处理请求并返回一个响应。这个过程是同步的,也就是说,客户端在发送请求后必须等待服务器的响应。在等待响应的过程中,客户端不会发送其他请求。

进程和线程的区别?

进程说简单点就是我们在电脑上启动的一个个应用,比如我们启动一个浏览器,就会启动了一个浏览器进程。进程是操作系统资源分配的最小单位,它包括了程序、数据和进程控制块等。

线程说简单点就是我们在 Java 程序中启动的一个 main 线程,一个进程至少会有一个线程。当然了,我们也可以启动多个线程,比如说一个线程进行 IO 读写,一个线程进行加减乘除计算,这样就可以充分发挥多核 CPU 的优势,因为 IO 读写相对 CPU 计算来说慢得多。线程是 CPU 分配资源的基本单位。

三分恶面渣逆袭:进程与线程关系

一个进程中可以有多个线程,多个线程共用进程的堆和方法区(Java 虚拟机规范中的一个定义,JDK 8 以后的实现为元空间)资源,但是每个线程都会有自己的程序计数器和栈。

如何创建线程?

Java 中创建线程主要有三种方式,分别为继承 Thread 类、实现 Runnable 接口、实现 Callable 接口。

二哥的 Java 进阶之路

线程的生命周期和状态?

在 Java 中,线程共有 6 种状态:

状态

说明

NEW

当线程被创建后,如通过new Thread(),它处于新建状态。此时,线程已经被分配了必要的资源,但还没有开始执行。

RUNNABLE

当调用线程的start()方法后,线程进入可运行状态。在这个状态下,线程可能正在运行也可能正在等待获取 CPU 时间片,具体取决于线程调度器的调度策略。

BLOCKED

线程在试图获取一个锁以进入同步块/方法时,如果锁被其他线程持有,线程将进入阻塞状态,直到它获取到锁。

WAITING

线程进入等待状态是因为调用了如下方法之一:Object.wait()或LockSupport.park()。在等待状态下,线程需要其他线程显式地唤醒,否则不会自动执行。

TIME_WAITING

当线程调用带有超时参数的方法时,如Thread.sleep(long millis)、Object.wait(long timeout) 或LockSupport.parkNanos(),它将进入超时等待状态。线程在指定的等待时间过后会自动返回可运行状态。

TERMINATED

当线程的run()方法执行完毕后,或者因为一个未捕获的异常终止了执行,线程进入终止状态。一旦线程终止,它的生命周期结束,不能再被重新启动。

线程在自身的生命周期中,并不是固定地处于某个状态,而是在不同的状态之间进行切换:

三分恶面渣逆袭:Java线程状态变化

JUC并发编程中的ThreadPoolExecutor的拒绝策略什么时候发生?

如果等待队列满了,而且正在运行的线程数量大于或等于 maximumPoolSize,那么线程池会执行拒绝策略。

SpringBoot框架的AOP、IOC/DI?

AOP,也就是 Aspect-oriented Programming,译为面向切面编程。

简单点说,就是把一些业务逻辑中的相同代码抽取到一个独立的模块中,让业务逻辑更加清爽。

三分恶面渣逆袭:横向抽取

举个例子,假如我们现在需要在业务代码开始前进行参数校验,在结束后打印日志,该怎么办呢?

我们可以把日志记录数据校验这两个功能抽取出来,形成一个切面,然后在业务代码中引入这个切面,这样就可以实现业务逻辑和通用逻辑的分离。

三分恶面渣逆袭:AOP应用示例

业务代码不再关心这些通用逻辑,只需要关心自己的业务实现,这样就实现了业务逻辑和通用逻辑的分离。

所谓的IoC(控制反转,Inversion of Control),就是由容器来控制对象的生命周期和对象之间的关系。以前是我们想要什么就自己创建什么,现在是我们需要什么容器就帮我们送来什么。

引入IoC之前和引入IoC之后

也就是说,控制对象生命周期的不再是引用它的对象,而是容器,这就叫控制反转

三分恶面渣逆袭:控制反转示意图

没有 IoC 之前:

代码语言:javascript
复制
我需要一个女朋友,刚好大街上突然看到了一个小姐姐,人很好看,于是我就自己主动上去搭讪,要她的微信号,找机会聊天关心她,然后约她出来吃饭,打听她的爱好,三观。。。

有了 IoC 之后:

代码语言:javascript
复制
我需要一个女朋友,于是我就去找婚介所,告诉婚介所,我需要一个长的像赵露思的,会打 Dota2 的,于是婚介所在它的人才库里开始找,找不到它就直接说没有,找到它就直接介绍给我。

婚介所就相当于一个 IoC 容器,我就是一个对象,我需要的女朋友就是另一个对象,我不用关心女朋友是怎么来的,我只需要告诉婚介所我需要什么样的女朋友,婚介所就帮我去找。

Spring 倡导的开发方式就是这样,所有的类创建都通过 Spring 容器来,不再是开发者去 new,去 = null 销毁,这些创建和销毁的工作都交给 Spring 容器来。

于是,对于某个对象来说,以前是它控制它依赖的对象,现在是所有对象都被 Spring 控制,这就是控制反转

图片来源于网络

说说什么是 DI?

DI(依赖注入,Dependency Injection):有人说 IoC 和 DI 是一回事,有人说 IoC 是思想,DI 是 IoC 的实现。2004 年,Martin Fowler 在他的文章《控制反转容器&依赖注入模式》首次提出了依赖注入这个名词。

控制反转这个词太宽泛,并不能很好地解释这个框架的具体实现,于是就想到了一个新名词:依赖注入。

打个比方,你现在想吃韭菜馅的饺子,这时候就有人用针管往你吃的饺子里注入韭菜鸡蛋馅。就好像 A 类需要 B 类,以前是 A 类自己 new 一个 B 类,现在是有人把 B 类注入到 A 类里。

UDP和TCP的区别?

TCP 是面向连接的,而 UDP 是无连接的。

三分恶面渣逆袭:TCP 和 UDP 区别

可以这么形容:TCP 是打电话,UDP 是大喇叭(😂)。

三分恶面渣逆袭:TCP 和 UDP 比喻

在数据传输开始之前,TCP 需要先建立连接,数据传输完成后,再断开连接。这个过程通常被称为“三次握手”。

UDP 是无连接的,发送数据之前不需要建立连接,发送完毕也无需断开连接,数据以数据报形式发送。

在此基础上,我们可以得出:TCP 是可靠的,它通过确认机制、重发机制等来保证数据的可靠传输。而 UDP 是不可靠的,数据包可能会丢失、重复、乱序。

了解MySQL、Redis吗?

MySQL 是一个开源的关系型数据库管理系统,现在隶属于 Oracle 旗下。MySQL 也是我们国内使用频率最高的一种数据库,我在本地安装的是最新的 8.0社区版。

MySQL 官网

Redis 是 Remote Dictionary Service 三个单词中加粗字母的组合,是一种基于键值对(key-value)的 NoSQL 数据库。

三分恶面渣逆袭:Redis图标

但比一般的键值对,比如 HashMap 强大的多,Redis 中的 value 支持 string(字符串)、hash(哈希)、 list(列表)、set(集合)、zset(有序集合)、Bitmaps(位图)、 HyperLogLog(基数估算)、GEO(地理信息定位)等多种数据结构。

而且因为 Redis 的所有数据都存放在内存当中,所以它的读写性能非常出色。

参考链接

  • 三分恶的面渣逆袭:https://javabetter.cn/sidebar/sanfene/nixi.html
  • 二哥的 Java 进阶之路:https://javabetter.cn
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-05-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 沉默王二 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Lambda表达式的作用?
  • Java集合有哪些?
  • 线程不安全的集合变成线程安全的方法?
    • 有什么办法能解决 HashMap 线程不安全的问题呢?
    • JDK1.8的特性?
    • HTTP传送请求的一次流程
    • 进程和线程的区别?
    • 如何创建线程?
    • 线程的生命周期和状态?
    • JUC并发编程中的ThreadPoolExecutor的拒绝策略什么时候发生?
    • SpringBoot框架的AOP、IOC/DI?
      • 说说什么是 DI?
      • UDP和TCP的区别?
      • 了解MySQL、Redis吗?
      • 参考链接
      相关产品与服务
      容器服务
      腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档