ThreadLocal这点牛角尖总算是给我钻明白了

SpringBoot+Vue+MySQL 高校学科竞赛平台 完整可运行版(源码+文档) 本项目基于SpringBoot+Vue+MySQL构建高校学科竞赛管理平台,覆盖学生、教师、领队教师、管理员四大角色,实现竞赛发布、报名、刷题、评分、公示等全流程闭环管理。系统架构清晰,技术主流,配套完整源码、数据库脚本、万字论文、开题报告、答辩PPT及部署文档,支持一键运行,适用于毕业设计、课程设计及院系二次开发,真正实现“开箱即用”。 阅读详情

前言

这个问题算是我的一个羞耻点,起源于一次面试中,面试官问ThreadLocal的底层实现是啥,我那时候一直以为ThreadLocal是一个类似于Redis一样的独立于线程外的第三方存储容器,如何底层维护了一个Map结构,以线程ID为Key,存储的数据为Value,通过线程id去找到这个存储值,那时候还很坚定这个想法,最后面试官说:em~你再回去了解下吧。我:⊙ˍ⊙

ThreadLocal 底层原理

ThreadLocal是多线程中对于解决线程安全的一个操作类,它会为每个线程都分配一个独立的线程副本从而解决了变量并发访问冲突的问题。ThreadLocal 同时实现了线程内的资源共享,可以把ThreadLocal理解为商场的寄存柜,一个人只能有一个柜口,但是可以有多个寄存柜 (为啥这样子比喻?看下去~)

set()源码

scss

复制代码

public void set(T value) { Thread t = Thread.currentThread(); ThreadLocalMap map = getMap(t); if (map != null) map.set(this, value); else createMap(t, value); } ThreadLocalMap getMap(Thread t) { // 当前线程自身所绑定的ThreadLocal对象 return t.threadLocals; }

可以看到它调用了Thread的 threadLocals 对象:

java

复制代码

public class Thread implements Runnable { /* ThreadLocal values pertaining to this thread. This map is maintained * by the ThreadLocal class. */
ThreadLocal.ThreadLocalMap threadLocals = null; 。。。 }

到这里我们基本可以知道ThreadLocal数据隔离的真相了,每个线程Thread都维护了自己的 ThreadLocalMap 成员变量,所以每次使用ThreadLocal.get()时都是从自己线程里面拿到自己的ThreadLocalMap 变量,拿不到别人的变量,从而实现了数据隔离。由于每一条线程均含有各自私有的ThreadLocalMap容器,这些容器相互独立互不影响,因此不会存在线程安全性问题,从而也无需使用同步机制来保证多条线程访问容器的互斥性。

javascript

复制代码

// 第一次执行set操作需要调用createMap函数初始化线程内部的ThreadLocal void createMap(Thread t, T firstValue) { t.threadLocals = new ThreadLocalMap(this, firstValue); }

在ThreadLocalMap的构造方法里,蕴含着初始化创建table数组 (封装类Entry的数组集合,Entry封装了当前的ThreadLocal对象和要存放的值) 的逻辑,源码和注释如下所示:

是不是迷惑为什么ThreadLocalMap中需要存放的是个数组,不是说好了同一个ThreadLocal中只能找到一个位置存一个值吗?

答:一个线程只能在一个ThreadLocal中存放一个值没错。但是现在的问题是我ThreadLocal又不是只有一个,不要把ThreadLocal当作一个第三方缓存啊。可以把ThreadLocal理解为商场的寄存柜,一个人只能有一个柜口;商场那么多,你可以在多个商场的寄存柜中各自存放一件商品,对于你自身来说,你只需要做好记录,说我在哪个商场存放过东西就行。

ThreadLocal——商场的寄存柜 当前线程Thread——你 Thread.ThreadLocalMap——存放记录清单,里面维护了个数组,支持记录多个商场的寄存柜地址,你用一个ThreadLocal来调用set / get 方法,本质上就是校验清单中寄存柜地址并执行相关操作

【解释】从上面源码中我们可以看到,数组默认大小是 16 ,设定的阈值为 0.75 倍的数组长度,并且根据传入的参数,创建了table数组中的第一个Entry元素对象 (ThreadLocal对象为Key, 数据值为Value) 。其中,size用来记录数组中存在的Entry元素的个数。

set插入操作其实很简单,大概流程看看:

get方法

这个其实没啥好说的,就是通过你调用的这个ThreadLocal对象去找当前线程中内置的ThreadLocalMap清单,找到该ThreadLocal对象通过Hash后得到的对应的那个数组下标提取数据就行,如果有

ThreadLocal-哈希冲突

ThreadLocalMap 使用开放定址法解决冲突,具体来说是线性探测法(linear probing) 。线性探测法会在发生哈希冲突时,依次检查下一个位置,直到找到可用的槽位存储数据。

问:线性探测法通过后移寻找空闲位置来插入发生哈希冲突的值,那这样子的话该空闲位置不就被占用了吗?如果下一次有个元素hash后刚好到这个位置咋办?

答:在这种情况下,线性探测法会继续往后查找下一个空闲位置,并依次检查是否有其他元素占用。这个过程被称为"探测"。如果找到了下一个空闲位置,则将元素插入到该位置。如果整个哈希表都被占满了(即没有空闲位置),则说明哈希表已满,无法再插入新的元素。如果哈希表发生冲突较多,可以考虑使用其他的解决冲突的方法,如链式寻址法或开放定址法的二次探测、双重散列等。

为什么要采用线性探测法不用链式寻址法

  • 线性探测法比较适用于哈希表大小相对较小的情况,而 ThreadLocal 的规模通常比较小。因为每个线程都需要独立的空间,所以使用链式寻址法的方式,在开销和效率方面不如线性探测法。
  • 线性探测法具有较好的局部性和缓存友好性,可以使 CPU 缓存的效率得到优化,提高程序的执行效率。

ThreadLocal-内存泄露

  • 强引用: 最为普通的引用方式,表示一个对象处于有用且必须的状态,如果一个对象具有强引用,则GC并不会回收它。即便堆中内存不足了,宁可出现OOM,也不会对其进行回收
  • 弱引用: 表示一个对象处于可能有用且非必须的状态。在GC线程扫描内存区域时,一旦发现弱引用,就会回收到弱引用相关联的对象。对于弱引用的回收,无关内存区域是否足够,也就是说**被弱引用关联的对象只能存活到下一次垃圾回收发生之前。**

每一个Thread维护一个ThreadLocalMap,在ThreadLocalMap中的Entry对象继承了WeakReference。其中key为使用弱引用的ThreadLocal实例,value为强引用的线程变量副本

一旦Key被回收了,key 的引用就变成了 null,就会导致这个内存永远无法被访问,造成内存泄漏。

问题:如果这个线程被回收了,那线程里面的成员变量不是都会被回收吗?就不会存在内存泄漏问题啊?

答:在实际应用中,我们一般都是使用线程池,而线程池本身是重复利用的,所以还是会存在内存泄漏的问题。

解决方法

ThreadLocal自救:

  • ThreadLocal每次调用 get、set、remove 等方法时,会顺便检查并清理掉 Entry 中 Key 为 null 的数据。

伟大的shi山创造者干涉:

  • 每次使用完 ThreadLocal 以后,主动调用 remove()方法移除数据
  • 把 ThreadLocal 声明称全局变量,使得它无法被回收

ThreadLocal 使用场景

  • 在进行对象跨层传递的时候,使用ThreadLocal可以避免多次传递,打破层次间的约束
  • 线程间数据隔离
  • 进行事务操作,用于存储线程事务信息。
  • 数据库连接,Session会话管理。

Spring框架在事务开始时会给当前线程绑定一个Jdbc connection,在整个事务过程都是使用该线程绑定的connection来执行数据库操作,实现了事务的隔离性。Spring框架里面就是用的ThreadLocal来实现这种隔离

单相PWM整流器的数学模型、工作原理 阅读详情

相关推荐

tmux + Claude Code 远程开发指南:从 WSL 配置到断线无忧

远程开发中,SSH 连接中断常导致后台任务丢失,这是困扰开发者的经典难题。tmux 作为终端复用器,通过将进程挂在常驻会话中,使其脱离 SSH 连接独立运行,从根本上解决了断线导致的任务终止问题。Claude Code 等 AI 编程代理需要长时间运行并保持交互上下文,恰好依赖这种会话持久化能力。结合 Windows Subsystem for Linux 提供类 Unix 环境,开发者可在 Windows 上实现稳定的远程开发工作流。本文将完整介绍从 WSL 环境配置、tmux 会话管理,到与 Claud

weixin_30423065的博客 348

ThreadLocal源码读后感总结

1.关联类 ThreadLocal: 线程局部变量 Thread:线程对象 2. Thread与ThreadLocal如何关联?  ThreadLocal类:   /** * Variant of set() to establish initialValue. Used instead * of s...

chtx87_98的博客 157

实践指南——【SPSS操作解析】线性混合效应模型在重复测量数据中的应用

本文详细解析了线性混合效应模型在重复测量数据分析中的应用,并提供了SPSS操作指南。文章阐述了该模型如何通过区分固定效应与随机效应,有效处理数据非独立性和缺失值问题,从而获得更可靠的统计推断。

oo7890的博客 554

2023阿里Java中高级面试1000题精解:八股文背后的原理与刷题方法论

Java面试中的'八股文'并非死记硬背的题海,而是对工程师底层原理掌握程度的系统性考察。从集合框架到JVM调优,从并发编程到分布式中间件,每一类考点都对应着真实业务场景中的关键决策。理解HashMap的扩容机制、MySQL的B+树索引、Redis的缓存策略,不仅能帮助候选人在大厂面试中从容应对追问,更能提升线上系统排查与性能优化的实战能力。基于2023年阿里中高级Java面试1000题梳理的备考指南,覆盖七大知识模块的备考路径与三阶段刷题方法,助力开发者将零散知识点织成完整能力地图。

weixin_33842304的博客 323

PADS VX 蛇形走线的设置方法与绕制

在PCB设计过程中,在等长的设置中是必须用到蛇形走线的,并且DDR模块也会经常使用到。因此掌握蛇形走线的设置方法对我们PCB高速板设计中有很大的帮助。下面介绍蛇形走线的设置方法与绕制。1.单根网络线的蛇形走线的设置:打开PADS router界面,点击“工具”→“选项”(快捷方式“Ctrl+Enter”),弹出“选项”窗口,选择“布线”界面下的“调整”,在“调整”界面,设置蛇形走线,倒角比例可以灵活设置。操作如下图所示:完成蛇形走线的配置后,快捷方式“F3”进行交互式布线时,单击右键选择“添加蛇形走线”,便

tianpu2320959696的博客 3395

iperf3网络性能测试全攻略:从带宽到丢包率的实战技巧

本文提供了iperf3网络性能测试的完整实战指南,涵盖从基础部署到高级诊断的全流程。详细解析了TCP带宽测试的进阶技巧与UDP丢包率分析的深度方法,帮助网络工程师精准量化带宽、丢包率等关键指标,有效定位网络瓶颈并优化性能。

efc123456的博客 1020

腾讯后台开发练习卷:网络、系统、算法与数据库核心解析

后台开发的核心在于理解操作系统、网络、数据库与算法等计算机基础原理,并将这些知识应用于高并发、高性能的工程场景。从进程与线程的调度机制,到TCP连接的状态管理,再到B+树索引的查询优势,每一个底层概念都直接影响着服务端的稳定性与响应速度。在实际生产中,开发者需要借助这些原理解决连接池耗尽、缓存穿透、分布式锁失效等棘手问题。本文围绕腾讯春招后台开发练习卷展开,梳理四大考察维度,并结合Linux排查命令与系统设计框架,帮助读者建立从原理到实践的完整知识体系,为应对笔试与真实业务挑战打下坚实基础。

weixin_31002075的博客 343

RK3568-Linux-麒麟系统---更新制作麒麟rootfs

RK3568 Linux系统 麒麟国产麒麟镜像

qiuzw2003的博客 5361

两周冲刺字节2-2:Java后端考点地图与实战复盘

Java后端面试的本质,是考察候选人对技术原理的深度理解与工程化实践能力。从JVM内存模型到OOM异常的真实排查,从MySQL索引优化到Redis缓存击穿应对,每一个高频知识点的背后都隐藏着可迁移的解决问题思路。与此同时,前后端分离项目实战、RuoYi框架之上的二次开发、Jenkins驱动的自动化构建,这些工程细节越来越成为面试官判断候选人真实水平的关键。掌握这些概念与原理,有助于在项目深挖与场景题中展现出体系化的思考方式。一套被验证过的两周末期冲刺方法论,能够帮助开发者将已有经验结构化,并针对大厂考察风格

weixin_34112181的博客 298

Abaqus 单元与全局刚度矩阵导出实战指南:从INP修改到结果解析

本文提供了Abaqus中导出单元刚度矩阵和全局刚度矩阵的完整实战指南。通过详细步骤讲解INP文件修改、关键指令插入及结果文件解析,帮助工程师、研究人员和二次开发者深入理解有限元软件内核,实现理论验证、二次开发与深度问题调试。

k8s6orchestrator的博客 901

手把手教你用Boot-Repair快速修复Ubuntu启动分区缺失(附详细命令行步骤)

本文详细介绍了如何使用Boot-Repair工具快速修复Ubuntu启动分区缺失问题,包括诊断、应急准备、自动修复和手动命令操作。通过grub rescue模式下的关键命令和Boot-Repair的图形界面操作,帮助用户高效解决启动分区故障,确保系统恢复正常运行。

weixin_29229989的博客 565

InnoDB 内存结构总览:Change Buffer、AHI 与 Log Buffer

本文系统梳理InnoDB内存结构中的ChangeBuffer、Adaptive Hash Index(AHI)与LogBuffer。ChangeBuffer缓存二级索引页不在内存时的变更,减少随机IO,仅在页加载时合并;聚簇索引修改立即执行,因数据本身不可延后。AHI基于高频等值查询自动构建哈希索引,加速定位,仅支持等值操作。LogBuffer为redo log内存缓冲,配合磁盘日志实现崩溃恢复。三者均服务于性能优化,其中ChangeBuffer与AHI共享BufferPool空间,而LogBuffer独立

bksczm的博客 304

用 CDS 作为 Referenced Data Source 开发 SAP Gateway OData 服务,一条更轻的 SEGW 路线

本文介绍了SAP Gateway项目中从传统手工建模到基于CDS View的现代化开发方式转变。主要内容包括: 传统方式需要在SEGW中手动创建Entity Type、Entity Set等元素,并在DPC_EXT中编写大量查询逻辑,存在模型层和业务逻辑重复表达的问题。 7.50版本后,SAP Gateway与ABAP CDS深度集成,可通过SEGW直接引用CDS View作为数据源,自动生成数据模型和SADL读取逻辑,支持完整的OData查询功能。 最佳实践建议通过Consumption View而非直接

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 707

信创环境下PageOffice文档控件适配与实践

信创适配做到文档控件这一层,拼的已经不是"有没有国产版本",而是同一个功能在两类终端上是否真的等价。等价的标准很具体:同一次点击能得到同样的结果,同一份公文能得到同样的版式,同一个项目不需要维护两套代码。这背后是三件并不轻松的工作:服务端用一套接口同时支撑两类终端,客户端把两种系统与四种芯片的安装包分发清楚,文档内核层由产品侧跟着 WPS 的版本走。浏览器这一层的压力,则被收进了产品自己的窗口里——升级节奏由产品掌握,不再交给运气。

zi_wu_xian的专栏 333

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

第三篇 第 6 课

前置:第三篇第 1 课(stdx 引入),第二篇第 1 课(std.regex)。环境:仓颉 SDK 1.2.0。本文所有代码与输出均逐行实测。

weixin_41618057的博客 546

贝叶斯统计 [韦来生编]

贝叶斯(Bayes)统计是近几十年来迅速发展起来的数理统计的一个重要分支。贝叶斯方法与经典统计方法的主要不同之处是进行统计推断时除了利用样本信息外,还要利用参数的先验信息,因此可以提高统计推断或统计决策的效果。它在经济、金融、生物、医学、自然科学和社会科学等许多领域具有广泛的应用。贝叶斯方法的研究已渗透到了统计学的几乎所有领域。作者在给中国科学技术大学概率论与数理统计专业本科生开设的“数理统计”课程中有一章专门讲授“贝叶斯方法和统计决策理论”,近十年来也给中国科学技术大学概率统计专业研究生开设过几次“贝叶斯分析”课。本书是在对过去讲稿的内容作了适当的增减和调整的基础上完成的。  本书共分六章。第1章是绪论,介绍了贝叶斯统计的若干基本概念,同时对必要的数理统计的基础知识有重点地作了回顾。第二章介绍了确定先验分布的若干可供选择的方法。第三章介绍了几类常见统计模型参数的后验分布的主要结果和计算方法。第四章和第五章分别介绍了“贝叶斯统计推断”和“贝叶斯统计决策”的内容。第六章介绍了贝叶斯统计计算的若干方法,包括蒙特卡洛方法和马尔可夫链蒙特卡洛(MCMC)方法以及相关统计软件的简介。本书的每一章附右大量的例题和习题,书末附有常用的几个表格和部分习题解答供读者查用。  大约可在54学时内讲授本书的第1章至第六章的主要内容,教师可根据学时需要选讲本书第1章至第六章的部分内容。书中标“*”号的章节可略去不讲,留给读者作为阅读材料。第六章例题中的R代码和部分例题的数据文件等可从作者个人主页下载。  作者在编写本书的过程中参考了J.O.Berger教授的《统计决策论及贝叶斯分析》和茆诗松教授编写的《贝叶斯统计》等书中的一些内容,以及《贝叶斯分析》一书中由张伟平博士编写的有关贝叶斯统计计算的一些内容。在此表示衷心感谢。  本书编写准备过程中,中国科学技术大学统计与金融系的几个研究生帮助完成了本书部分中文的录入和排版,作者对他们的辛勤工作表示真诚的感谢。高等教育出版社为本书的出版给予了大力支持。在此一并致谢。

【从零理解 Spring AI · 12】MCP 的两种角色:做客户端还是做服务端

上一篇讲了 MCP 的概念:标准协议、三大角色、M+N 替代 M×N。

nice_lcj520的博客 581

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

Java 集合容器高频面试题全解:HashMap 树化阈值、1.7 死循环与 ConcurrentHashMap 演进(2026 招聘 JD 真题复盘)

HashMap 树化阈值 8 的泊松分布依据、退化阈值 6 的防抖设计、JDK 1.7 头插成环死循环的排查与修复、1.8 尾插后为何仍线程不安全、ConcurrentHashMap 放弃分段锁的原因与 ForwardingNode 协作扩容、computeIfAbsent 死锁陷阱、大集合找重复的场景题选型,附三层追问链自测。题目来源为 38 期公开招聘 JD 样本与字节、拼多多、建行、美团、快手公开面经。

蒙眼过河 423

spdlog 同步日志库使用详解

spdlog是一个轻量级 C++ 日志库,支持同步日志、异步日志、多线程日志、日志文件轮转和自定义日志格式。对于嵌入式 Linux 应用开发,我建议先使用。它可以帮我们完成:日志级别过滤。时间戳和线程 ID 输出。日志格式化。终端和文件输出。多线程安全写入。日志文件按大小或时间轮转。我们不需要自己实现互斥锁、文件写入、日志格式化和轮转等底层功能。

zengjiajun2006的博客 1121

JavaSE通关手册:数据类型与变量

代码无需额外处理,编译时编译器自动完成转换。

xys_678的博客 232

Java 多态 学习笔记

多态是面向对象编程的重要特性,指同一操作作用于不同对象时产生不同行为。其核心在于“父类引用指向子类对象”,结合方法重写实现运行时动态绑定。多态使代码更灵活、可扩展,如用Person p = new Student();统一处理各类人员注册,无需修改调用逻辑。但多态无法直接调用子类特有方法,需通过instanceof判断并强制转换。编译时看左边(类型),运行时看右边(实际对象),实现解耦与维护便利。

AA_AA114514的博客 369

IDEA 简介:从零认识 IntelliJ IDEA

IDEA 全称,是由 JetBrains 公司开发的一款主流 Java 集成开发环境(IDE)。它集代码编辑、编译、调试、测试、版本控制、构建管理等功能于一体,被大量 Java 开发者视为日常开发的首选工具。所谓 IDE(Integrated Development Environment,集成开发环境),就是把写代码所需的各类工具整合到同一个界面中。相比只用文本编辑器加命令行编译,IDE 能显著减少重复操作,让开发者把精力集中在业务逻辑上。

ztI10的博客 180

Docker部署linkding:HTTPS与数据备份

部署私人书签库,除了让页面能够打开,还需要考虑几个实际问题:重建容器后数据是否保留、登录和保存是否正常、升级前怎样备份,以及出现 502 或 CSRF 错误时从哪里检查。本文使用 Docker Compose 部署 linkding,采用默认 SQLite 数据库,通过 Caddy 提供 HTTPS,并完成账户创建、数据持久化验证和备份。如果重建后账户或书签消失,应先检查是否换了项目目录、改了挂载路径,或者启动了另一套实例,不要急着重新初始化。遇到权限问题,应根据日志确认具体目录和运行用户,再调整权限。

tedcloud123的博客 177

C++20协程怎么运行?原理与三大核心组件深度剖析

C++20协程是轻量级的无栈状态机,通过co_await、co_yield、co_return实现挂起与恢复,由Promise、协程句柄和Awaitable三大组件协同工作。协程与线程互补,适用于高效管理大量并发I/O任务,显著降低上下文切换开销。其核心在于编译器生成的状态机机制,需配合库(如cppcoro)使用。掌握Promise控制逻辑、句柄生命周期管理及Awaitable语义,是构建高性能异步程序的基础。

Lucis__的博客 160

动态代理两大流派:JDK 代理与子类代理

业务类想加日志,最直白的写法是侵入式修改: 问题很明显:每个方法都要改一遍,改一个业务要动十处。代理模式的解法是:调用方不直接依赖 ,而是依赖一个代理对象。代理对象长得跟目标一模一样,调用它 → 代理先执行增强逻辑 → 再转调真实对象。 关键在于:代理对象的类型是哪来的?这就是"动态"二字的含义:代理类在运行时才诞生。两个角色: 承载增强逻辑, 负责生成代理类。 组装代理并调用: 输出: 业务代码 一行没动,增强逻辑全在 里。这就是 AOP 的味道。 内部四步: 第 2 步 内部:先查 (同一个接口

Android的专栏 654

c++ explicit关键字详解

explicit。

拒绝AI文,努力在AI时代写出感动人心的好文章 169

TRingBuffer两端都能增删(快递站版)

TRingBuffer 是一个支持两端增删、下标访问且容量动态增长的环形双端队列。它通过无符号索引的永不归零设计,利用减法自动模运算实现空满判断与元素计数,避免了传统环形缓冲浪费格子的问题。内部以票号(索引)标记首尾,扩容时重排元素为连续存储,保证 O(1) 操作与高缓存效率。虽不线程安全,但其高效性使其成为游戏开发中事件队列、命令缓冲等场景的理想选择。

u013768914的博客 312
上一篇: 某计科985研究生三面字节成功拿下实习岗面经+Java面试题分享!
下一篇: 阿里P8面试官不小心泄露了25年春招进大厂必备的Java面试场景题!
程序员职业指南
博客等级 码龄4年 2139粉丝 960原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值