java面试题,有synchronized锁,threadlocal、数据可以设置默认值、把redis中的json转为对象

有面试题,有synchronized锁,threadlocal

  • 一、面试题小记
  • 二、加锁synchronized
    • 1. 先看代码
    • 2. synchronized 讲解
      • 2.1. 同步代码块
      • 2.2. 同步方法
      • 2.3. 锁的选择和影响
      • 2.4. 注意事项
      • 2.5 锁的操作,手动释放锁,显式地获取锁(属性名第一个lock代表的是)
  • 三、ThreadLocal
    • 1. 基本用法
    • 2. ThreadLocal 的关键方法
    • 3. 使用场景
    • 4. 注意事项
    • 5. 示例:使用 ThreadLocal 进行数据库连接管理
  • 四、数据库用来设置某个字段的默认值。
  • 五、 把redis的json转为对象
    • 1. 从 Redis 获取 JSON 数据
    • 2 使用 Gson

(一切都是自己的笔记!!!请勿上纲上线)

一、面试题小记

在这里插入图片描述
在这里插入图片描述
java10 本地类型推断
在这里插入图片描述
switch表达式
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

二、加锁synchronized

1. 先看代码

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.HashSet;public class Example {private static final SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");private static final Set<String> dates = new HashSet<>();private static final CountDownLatch countDownLatch = new CountDownLatch(10);private static final ExecutorService pool = Executors.newFixedThreadPool(10);public void addDate(int i) {Calendar calendar = Calendar.getInstance(); // 创建Calendar实例int finalI = i; // final变量用于在lambda表达式中使用pool.execute(() -> {synchronized (simpleDateFormat) { // 对simpleDateFormat加锁// 时间增加calendar.add(Calendar.DATE, finalI);// 通过simpleDateFormat把时间转换成字符串String dateString = simpleDateFormat.format(calendar.getTime());// 把字符串放入Set中dates.add(dateString);}// CountDowncountDownLatch.countDown();});}public void awaitCompletion() throws InterruptedException {countDownLatch.await(); // 等待所有线程完成pool.shutdown(); // 关闭线程池}public static void main(String[] args) throws InterruptedException {Example example = new Example();for (int i = 0; i < 10; i++) {example.addDate(i); // 添加日期}example.awaitCompletion(); // 等待所有线程完成System.out.println(dates); // 输出结果}
}

2. synchronized 讲解

synchronized 是 Java 中用于实现线程同步的关键字,确保多个线程在执行某段代码时不会发生冲突,从而保证线程安全。它有两种主要的使用方式:同步代码块和同步方法。

2.1. 同步代码块

通过 synchronized 关键字修饰的代码块可以确保在同一时间只有一个线程可以执行该代码块中的代码。以下是如何使用同步代码块的示例:

public class SynchronizedBlockExample {private final Object lock = new Object(); // 用于锁定的对象public void doWork() {synchronized (lock) { // 对 lock 对象加锁// 临界区代码System.out.println("Thread " + Thread.currentThread().getName() + " is working.");} // 离开synchronized块时自动释放锁}
}

锁定对象:synchronized (lock) 表示对 lock 对象加锁。只有获取了 lock 锁的线程可以执行 synchronized 块中的代码。
自动释放:当线程退出 synchronized 块(包括发生异常的情况),JVM 会自动释放锁。

2.2. 同步方法

synchronized 也可以用于修饰方法,这样整个方法在同一时间只会被一个线程执行。同步方法可以分为实例方法和静态方法:

实例同步方法:锁定的是方法所在对象的实例。

public class SynchronizedMethodExample {public synchronized void instanceMethod() {// 临界区代码System.out.println("Thread " + Thread.currentThread().getName() + " is working.");}
}

静态同步方法:锁定的是类的 Class 对象。静态同步方法同一时间只允许一个线程访问类的所有实例的静态方法。

public class SynchronizedStaticMethodExample {public static synchronized void staticMethod() {// 临界区代码System.out.println("Thread " + Thread.currentThread().getName() + " is working.");}
}

2.3. 锁的选择和影响

对象锁:在同步代码块中指定的对象(例如 lock 对象)会作为锁对象。这种锁是对象级别的,不同对象的同步代码块不会互相影响。

类锁:对于静态同步方法,锁的是类的 Class 对象。这意味着类的所有静态同步方法是互斥的。

锁的粒度:选择锁的粒度时需要考虑性能和安全。粒度过大(例如锁住整个方法或类)可能导致性能下降,而粒度过小则可能无法有效防止数据竞争。

2.4. 注意事项

死锁:多个线程可能互相等待对方释放锁,导致系统僵死。应避免复杂的锁定顺序和嵌套锁。

性能开销:同步会引入性能开销,因为它涉及到线程上下文的切换和锁管理。只在必要时使用同步,尽量减少锁的持有时间。

不可重入:虽然 synchronized 是可重入的(即同一个线程可以多次获取同一个锁),但在设计时仍需注意避免复杂的锁定结构。

总结
同步代码块:通过 synchronized (lock) 对特定的对象进行加锁,确保只有一个线程能执行代码块中的代码。
同步方法:通过 synchronized 关键字修饰实例方法或静态方法,确保方法在同一时间内只有一个线程能执行。

2.5 锁的操作,手动释放锁,显式地获取锁(属性名第一个lock代表的是)

lock.lock():显式地获取锁。
lock.unlock():在 finally 块中释放锁,以确保即使发生异常也能释放锁。

三、ThreadLocal

ThreadLocal 是 Java 中用于实现线程局部存储的类,允许每个线程在访问某个变量时拥有自己的独立副本。这样,每个线程都可以操作自己的副本而不会与其他线程的副本发生冲突。ThreadLocal 主要用于需要线程隔离的场景,例如每个线程需要独立的配置、数据库连接、会话等。

1. 基本用法

ThreadLocal 的基本用法非常简单。可以通过 ThreadLocal 提供的 get 和 set 方法来获取和设置当前线程的值。

public class ThreadLocalExample {private static final ThreadLocal<Integer> threadLocalValue = ThreadLocal.withInitial(() -> 1);public static void main(String[] args) {Runnable task = () -> {// 获取当前线程的线程局部变量值Integer value = threadLocalValue.get();System.out.println("Initial Value: " + value);// 设置当前线程的线程局部变量值threadLocalValue.set(value + 1);// 再次获取当前线程的线程局部变量值System.out.println("Updated Value: " + threadLocalValue.get());};// 创建多个线程,测试每个线程的线程局部变量是否独立Thread thread1 = new Thread(task);Thread thread2 = new Thread(task);thread1.start();thread2.start();}
}

2. ThreadLocal 的关键方法

ThreadLocal.withInitial(Supplier<? extends T> supplier):创建一个 ThreadLocal 实例,并设置初始值。这个方法可以指定一个 Supplier 来提供初始值。

T get():获取当前线程的 ThreadLocal 变量的值。如果当前线程没有设置过这个值,则会调用 initialValue() 方法来设置初始值。

void set(T value):设置当前线程的 ThreadLocal 变量的值。

void remove():移除当前线程的 ThreadLocal 变量的值,防止内存泄漏。

3. 使用场景

ThreadLocal 主要适用于以下场景:

数据库连接:每个线程需要一个独立的数据库连接。

用户会话:每个线程需要维护独立的用户会话信息。

配置和上下文:每个线程需要独立的配置或上下文信息。

4. 注意事项

内存泄漏:如果 ThreadLocal 的 ThreadLocalMap 中的 ThreadLocal 引用被持有而没有被正确清理(通过调用 remove() 方法),可能会导致内存泄漏,特别是在长期运行的应用中。由于 ThreadLocal 是线程本地的,它的值只会在当前线程中有效,所以如果线程池中线程长时间存在而没有被回收,就可能导致内存泄漏。

适用性:ThreadLocal 适用于线程独立的场景。如果不同线程之间需要共享数据,考虑使用其他同步机制(如 synchronized 或 Concurrent 数据结构)。

性能:虽然 ThreadLocal 提供了线程隔离,但它也有一定的性能开销。避免在高并发场景中频繁使用 ThreadLocal,特别是当线程局部变量对象较大或线程较多时。

5. 示例:使用 ThreadLocal 进行数据库连接管理

public class DatabaseConnectionManager {private static final ThreadLocal<Connection> connectionHolder = ThreadLocal.withInitial(() -> {try {return DriverManager.getConnection("jdbc:yourdb", "username", "password");} catch (SQLException e) {throw new RuntimeException(e);}});public static Connection getConnection() {return connectionHolder.get();}public static void closeConnection() {Connection connection = connectionHolder.get();if (connection != null) {try {connection.close();} catch (SQLException e) {e.printStackTrace();} finally {connectionHolder.remove(); // 清理线程局部变量}}}
}

在这个示例中,每个线程会有自己独立的数据库连接,使用完后记得调用 remove() 方法以避免潜在的内存泄漏。

四、数据库用来设置某个字段的默认值。

ALTER TABLE in_inspect_info
ALTER result SET DEFAULT 1;

五、 把redis的json转为对象

从 Redis 中获取 JSON 数据并将其转换为 Java 对象,通常涉及以下几个步骤:

从 Redis 获取 JSON 数据: 你可以使用 Redis 客户端库(例如 Jedis 或 Lettuce)从 Redis 中获取存储的 JSON 数据。
将 JSON 转换为 Java 对象: 使用 JSON 解析库(如 Jackson 或 Gson)将 JSON 字符串转换为 Java 对象。
以下是详细的步骤和代码示例:

1. 从 Redis 获取 JSON 数据

假设你使用 Jedis 作为 Redis 客户端库,首先从 Redis 中获取 JSON 数据:

import redis.clients.jedis.Jedis;public class RedisExample {public static void main(String[] args) {// 创建 Jedis 实例Jedis jedis = new Jedis("localhost", 6379);// 从 Redis 中获取 JSON 数据String jsonData = jedis.get("yourRedisKey");// 关闭 Jedis 连接jedis.close();// 打印获取到的 JSON 数据System.out.println(jsonData);}
}
  1. 将 JSON 转换为 Java 对象
    使用 Jackson 或 Gson 库将 JSON 字符串转换为 Java 对象。以下是使用 Jackson 和 Gson 的示例。

使用 Jackson
添加依赖(如果你使用 Maven,可以在 pom.xml 中添加以下依赖):

<dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.14.2</version>
</dependency>

转换 JSON:

import com.fasterxml.jackson.databind.ObjectMapper;public class JsonExample {public static void main(String[] args) {String jsonData = "{\"term_sn\":\"12345\",\"devid_qi_cname\":\"设备名称\",\"devid_qi_time\":\"2024-07-22T10:00:00Z\",\"inspect_list\":[{\"code\":\"INS001\",\"name\":\"检查1\",\"term_sn\":\"TERM001\",\"inspect_ask\":\"检查要求1\",\"result\":\"结果1\"},{\"code\":\"INS002\",\"name\":\"检查2\",\"term_sn\":\"TERM002\",\"inspect_ask\":\"检查要求2\",\"result\":\"结果2\"}],\"dq_info_file_ids\":98765,\"devidqi_state\":1}";ObjectMapper objectMapper = new ObjectMapper();try {// 将 JSON 转换为 Java 对象MyClass myObject = objectMapper.readValue(jsonData, MyClass.class);// 打印转换后的对象System.out.println(myObject);} catch (Exception e) {e.printStackTrace();}}
}class MyClass {private String term_sn;private String devid_qi_cname;private String devid_qi_time;private List<Inspect> inspect_list;private int dq_info_file_ids;private int devidqi_state;// Getter 和 Setter 方法@Overridepublic String toString() {return "MyClass{" +"term_sn='" + term_sn + '\'' +", devid_qi_cname='" + devid_qi_cname + '\'' +", devid_qi_time='" + devid_qi_time + '\'' +", inspect_list=" + inspect_list +", dq_info_file_ids=" + dq_info_file_ids +", devidqi_state=" + devidqi_state +'}';}
}class Inspect {private String code;private String name;private String term_sn;private String inspect_ask;private String result;// Getter 和 Setter 方法@Overridepublic String toString() {return "Inspect{" +"code='" + code + '\'' +", name='" + name + '\'' +", term_sn='" + term_sn + '\'' +", inspect_ask='" + inspect_ask + '\'' +", result='" + result + '\'' +'}';}
}

2 使用 Gson

添加赖(如果你使用 Maven,可以在 pom.xml 中添加以下依赖):

<dependency><groupId>com.google.code.gson</groupId><artifactId>gson</artifactId><version>2.10.1</version>
</dependency>

转换 JSON:

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import java.lang.reflect.Type;
import java.util.List;public class JsonExample {public static void main(String[] args) {String jsonData = "{\"term_sn\":\"12345\",\"devid_qi_cname\":\"设备名称\",\"devid_qi_time\":\"2024-07-22T10:00:00Z\",\"inspect_list\":[{\"code\":\"INS001\",\"name\":\"检查1\",\"term_sn\":\"TERM001\",\"inspect_ask\":\"检查要求1\",\"result\":\"结果1\"},{\"code\":\"INS002\",\"name\":\"检查2\",\"term_sn\":\"TERM002\",\"inspect_ask\":\"检查要求2\",\"result\":\"结果2\"}],\"dq_info_file_ids\":98765,\"devidqi_state\":1}";Gson gson = new Gson();// 将 JSON 转换为 Java 对象MyClass myObject = gson.fromJson(jsonData, MyClass.class);// 打印转换后的对象System.out.println(myObject);}
}class MyClass {private String term_sn;private String devid_qi_cname;private String devid_qi_time;private List<Inspect> inspect_list;private int dq_info_file_ids;private int devidqi_state;// Getter 和 Setter 方法@Overridepublic String toString() {return "MyClass{" +"term_sn='" + term_sn + '\'' +", devid_qi_cname='" + devid_qi_cname + '\'' +", devid_qi_time='" + devid_qi_time + '\'' +", inspect_list=" + inspect_list +", dq_info_file_ids=" + dq_info_file_ids +", devidqi_state=" + devidqi_state +'}';}
}class Inspect {private String code;private String name;private String term_sn;private String inspect_ask;private String result;// Getter 和 Setter 方法@Overridepublic String toString() {return "Inspect{" +"code='" + code + '\'' +", name='" + name + '\'' +", term_sn='" + term_sn + '\'' +", inspect_ask='" + inspect_ask + '\'' +", result='" + result + '\'' +'}';}
}

关键点总结
选择合适的库: Jackson 和 Gson 都是流行的 JSON 解析库,可以根据你的需求选择其中一个。
确保字段匹配: JSON 字段名称应与 Java 类中的字段名称匹配,注意大小写和命名风格。
处理日期: 如果 JSON 中包含日期,确保正确解析和格式化日期字段。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/48893.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

开源XDR-SIEM一体化平台 Wazuh (1)基础架构

简介 Wazuh平台提供了XDR和SIEM功能&#xff0c;保护云、容器和服务器工作负载。这些功能包括日志数据分析、入侵和恶意软件检测、文件完整性监控、配置评估、漏洞检测以及对法规遵从性的支持。详细信息可以参考Wazuh - Open Source XDR. Open Source SIEM.官方网站 Wazuh解决…

AV1技术学习:Transform Coding

对预测残差进行变换编码&#xff0c;去除潜在的空间相关性。VP9 采用统一的变换块大小设计&#xff0c;编码块中的所有的块共享相同的变换大小。VP9 支持 4 4、8 8、16 16、32 32 四种正方形变换大小。根据预测模式选择由一维离散余弦变换 (DCT) 和非对称离散正弦变换 (ADS…

免费分享一套微信小程序图书馆座位预约管理系统(SpringBoot后端+Vue管理端)【论文+源码+SQL脚本】,帅呆了~~

大家好&#xff0c;我是java1234_小锋老师&#xff0c;看到一个不错的微信小程序图书馆座位预约管理系统(SpringBoot后端Vue管理端)&#xff0c;分享下哈。 项目介绍 随着移动互联网技术的飞速发展和智能设备的普及&#xff0c;图书馆服务模式正在经历深刻的变革。本论文旨在…

从PyTorch官方的一篇教程说开去(3.3 - 贪心法)

您的进步和反馈是我最大的动力&#xff0c;小伙伴来个三连呗&#xff01;共勉。 贪心法&#xff0c;可能是大家在处理陌生问题时候&#xff0c;最容易想到的办法了吧&#xff1f; 还记得小时候&#xff0c;国足请了位洋教练发表了一句到现在还被当成段子的话&#xff1a;“如…

第2章-数学建模

目录 一、数据类型 【函数】&#xff1a; &#xff08;1&#xff09;find()、rfind()、index()、rindex()、count() &#xff08;2&#xff09;split()、rsplit() &#xff08;3&#xff09;join() &#xff08;4&#xff09;strip()、rstrip()、lstrip() &#xff08;5&…

【Python】sqlite加密库pysqlcipher3编译安装步骤

目录 说明准备工作openssl编译sqlite tclsetup.py修改quote_argumentopenssl路径 安装加密示例代码测试附录参考 说明 pysqlcipher3是针对Python 3使用的pysqlcipher的一个分支&#xff0c; 尽管仍然维护对Python 2的支持。它仍然处于测试阶段&#xff0c; 尽管这个库包含的最…

请你谈谈:spring bean的生命周期 - 阶段5:BeanPostProcessor前置处理-自定义初始化逻辑-BeanPostProcess后置处理

BeanPostProcessor的postProcessBeforeInitialization方法是在bean的依赖注入&#xff08;即属性填充&#xff09;完成后&#xff0c;但在bean的初始化回调&#xff08;如PostConstruct注解的方法或InitializingBean接口的afterPropertiesSet方法&#xff09;之前被调用的。 具…

sql_exporter通过sql收集业务数据并通过prometheus+grafana展示

下载并解压安装sql_exporter wget https://github.com/free/sql_exporter/releases/download/0.5/sql_exporter-0.5.linux-amd64.tar.gz #解压 tar xvf sql_exporter-0.5.linux-amd64.tar.gz -C /usr/local/修改主配置文件 cd /usr/local/ mv sql_exporter-0.5.linux-amd64 s…

google 浏览器插件开发简单学习案例:TodoList

参考&#xff1a; google插件支持&#xff1a; https://blog.csdn.net/weixin_42357472/article/details/140412993 这里是把前面做的TodoList做成google插件&#xff0c;具体网页可以参考下面链接 TodoList网页&#xff1a; https://blog.csdn.net/weixin_42357472/article/de…

SwiftSage:参考人脑双系统,结合快思和慢想的智能体,解决复杂任务同时降低成本

SwiftSage&#xff1a;参考人脑双系统&#xff0c;结合快思和慢想的智能体&#xff0c;解决复杂任务同时降低成本 提出背景解法拆解子解法1&#xff1a;SWIFT模块子解法2&#xff1a;SAGE模块模块整合和决策树 SwiftSage 工作流程效果 论文&#xff1a;SWIFTSAGE: A Generative…

5G赋能新能源,工业5G路由器实现充电桩远程高效管理

随着5G技术的广泛应用&#xff0c;新能源充电桩的5G应用正逐步构建起全新的生态系统。在数字化转型的浪潮中&#xff0c;新能源充电桩行业正迎来数字化改革。工业5G路由器的引入&#xff0c;为充电桩的远程管理提供了强有力的技术支持&#xff0c;新能源充电桩5G路由器网络部署…

共享充电桩语音ic方案,展现它的“说话”的能力

随着电动汽车的普及&#xff0c;充电设施的便捷性、智能化需求日益凸显&#xff0c;共享充电桩语音IC应运而生&#xff0c;成为连接人与机器、实现智能交互的桥梁。本文将为大家介绍共享充电桩语音ic的概述、应用词条以及优势&#xff0c;希望能够帮助您。 一、NV170D语音ic概述…

选购指南:如何挑选最适合的快手矩阵系统

在短视频风潮席卷的今天&#xff0c;快手作为其中的佼佼者&#xff0c;吸引了无数创作者和商家的目光。然而&#xff0c;想要在快手上脱颖而出&#xff0c;仅凭内容和创意是远远不够的。一个强大且适合的快手矩阵系统&#xff0c;将是你通往成功的重要钥匙。那么&#xff0c;如…

SEO域名外链生成工具PHP源码

两款不同版本的SEO超级外链工具PHP源码&#xff0c;网址外链-seo外链推广工具源码&#xff0c;SEO网站推广外链工具源码SEO域名外链生成工具PHP源码 _ 博客趣两款不同版本的SEO超级外链工具PHP源码&#xff0c;网址外链-seo外链推广工具源码&#xff0c;SEO网站推广外链工具源码…

Web前端:HTML篇(一)

HTML简介&#xff1a; 超文本标记语言&#xff08;英语&#xff1a;HyperText Markup Language&#xff0c;简称&#xff1a;HTML&#xff09;是一种用于创建网页的标准标记语言。 您可以使用 HTML 来建立自己的 WEB 站点&#xff0c;HTML 运行在浏览器上&#xff0c;由浏览器…

批量打断相交线——ArcGISpro 解决方法

在数据处理&#xff0c;特别是地理空间数据处理或是任何涉及图形和线条分析的场景中&#xff0c;有时候需要把相交的线全部从交点打断一个常见的需求。这个过程对于后续的分析、编辑、或是可视化展现都至关重要&#xff0c;因为它可以确保每条线都是独立的&#xff0c;避免了因…

.NET下支持多框架的托盘功能NotifyIconEx(WPF / WinForms / Avalonia / WinUI / MAUI / Wice)

支持 WPF / WinForms / Avalonia / WinUI / MAUI / Wice 应用。 先看效果&#xff1a; using NotifyIconEx;var notifyIcon new NotifyIcon() {Text "NotifyIcon",Icon Icon.ExtractAssociatedIcon(Process.GetCurrentProcess().MainModule?.FileName!)! }; not…

【论文速读】| LLMCloudHunter:利用大语言模型(LLMs)从基于云的网络威胁情报(CTI)中自动提取检测规则

本次分享论文&#xff1a;LLMCloudHunter: Harnessing LLMs for Automated Extraction of Detection Rules from Cloud-Based CTI 基本信息 原文作者&#xff1a;Yuval Schwartz, Lavi Benshimol, Dudu Mimran, Yuval Elovici, Asaf Shabtai 作者单位&#xff1a;Ben-Gurion…

第一弹:基于ABAP OLE技术实现对服务器文件进行读写操作

前言 最近遇到这样一个需求&#xff0c;需要对BW服务器上的文件进行下载的同时写入每个用户相对应的数据。之前的服务器模版是一个死模版&#xff0c;对于这样的要求&#xff0c;我就想到了OLE技术&#xff0c;那么什么是OLE技术呢&#xff1f; 一、什么是OLE技术&#xff1f…

Python 全栈体系【三阶】(三)

第一章 Django 七、静态文件 1. 概述 静态文件是指在WEB应用中的图像文件、CSS文件、Javascript文件。 2. 静态文件的配置 settings.py中关于静态文件的配置如下&#xff1a; STATICFILES_DIRS [BASE_DIR , static, ]STATIC_URL /static/其中&#xff1a; STATICFILES…