你真的会用?type吗?90%开发者忽略的空类型边界问题曝光

第一章:可为空类型(?type)的起源与意义

在现代编程语言设计中,可为空类型(Nullable Types),通常以 ?type 的语法形式出现,是为了解决“空值语义模糊”这一长期困扰开发者的问题而诞生的重要机制。它的核心意义在于显式表达一个变量是否可能包含 null 值,从而将空值处理从运行时错误提前到编译时检查。

空值的历史困境

早期编程语言如 C 和 Java 允许引用类型默认可为空,但未在类型系统中体现这一点,导致“空指针异常”成为最常见的运行时错误之一。托尼·霍尔(Tony Hoare)曾称发明 null 为“十亿美元的错误”。可为空类型的引入,正是为了弥补这一设计缺陷。

类型系统的进化

通过扩展类型系统,语言如 C#、Kotlin 和 TypeScript 引入了可为空类型语法。例如,在 C# 中:
// 普通类型不可为空
string name = null; // 编译警告或错误(启用可空上下文时)

// 显式声明可为空
string? optionalName = null; // 合法
上述代码表明,string? 明确告诉编译器该变量可为空,开发者必须在使用前进行非空判断,否则会收到警告。

安全与表达力的提升

可为空类型带来的不仅是安全性,还有更强的语义表达能力。以下对比展示了其优势:
特性传统类型系统可为空类型系统
空值语义隐式,不明确显式声明
空指针风险高低(编译期提示)
代码可读性依赖注释或约定类型即文档
此外,编译器能基于可为空类型进行控制流分析,自动推断变量在条件分支中的空状态,进一步减少手动检查负担。这种机制不仅提升了程序健壮性,也推动了类型驱动开发的实践普及。

第二章:可为空类型的核心机制解析

2.1 理解 ?type 的语法本质与底层实现

在现代类型系统中,`?type` 是一种用于表示可空类型的语法糖。其本质是在编译期将 `?T` 转换为 `T | null` 的联合类型,赋予变量可为空的语义。
语法解析与等价转换
以 TypeScript 为例,`?string` 在 AST 解析阶段被识别为可选类型标记:

function greet(name?: string) {
  return name ? `Hello, ${name}` : "Hello, Guest";
}
上述代码中,`name?: string` 等价于 `name: string | undefined`。编译器在类型检查时会强制要求对 `null` 或 `undefined` 进行处理。
底层实现机制
在运行时,JavaScript 并不保留类型信息,但静态分析工具依赖此语法进行流控制判断。类型检查器通过数据流分析追踪变量是否已被判空:
  • 遇到 `?` 修饰的参数,自动添加 undefined 到类型联合中
  • 在条件分支中推导出非空类型(如通过 if 判断)
  • 生成对应的类型约束警告,防止空值误用

2.2 ?type 与 nullable=true 的历史对比分析

在早期API设计中,?type常用于标识字段类型查询,而nullable=true则用于声明字段可为空。两者服务于不同语义层,但长期存在概念混淆。
语义职责分离演进
  • ?type最初用于动态语言中运行时类型推断
  • nullable=true源自数据库映射需求,表达数据持久化约束
  • 现代类型系统(如TypeScript)将二者解耦:类型标注与空值安全性独立处理
典型代码演变

// 旧式混合表达
interface User {
  name: string | null; // 隐含 nullable
}

// 新式清晰分离
interface User {
  name?: string; // 明确可选
}
上述重构体现设计哲学转变:类型定义关注结构,修饰符控制存在性。这种分离提升了类型推导准确性和API可维护性。

2.3 类型系统中的 null 合法性边界探讨

在现代类型系统中,null 的合法性常成为程序健壮性的关键因素。类型安全语言通过可空类型(Nullable Types)明确区分可能为空的引用与非空值。
可空类型的语法表达
以 Kotlin 为例,变量声明需显式标注可空性:
var name: String = "Alice"      // 非空,不可赋 null
var nickname: String? = null    // 可空,允许为 null
上述代码中,String? 表示该变量可持有 null 值,编译器将强制调用者在访问前进行空值检查。
安全调用与操作符链
Kotlin 提供安全调用操作符 ?. 避免空指针异常:
val length = nickname?.length ?: 0
此表达式等价于:若 nickname 非 null,返回其长度;否则返回默认值 0,有效划定 null 处理边界。

2.4 函数参数与返回值中的 ?type 实践应用

在现代类型系统中,`?type` 表示参数或返回值可为 `null` 或指定类型,用于增强代码的健壮性与可读性。
可空类型的函数参数
func ProcessUser(name *string) string {
    if name == nil {
        return "Anonymous"
    }
    return "Hello, " + *name
}
该函数接收指向字符串的指针(即 `?string` 的 Go 实现),允许调用者传递“无名称”语义。通过判断指针是否为 `nil`,实现安全的空值处理。
返回值中的可空类型实践
使用 `?type` 风格返回可能缺失的数据:
  • 数据库查询未命中时返回 `null` 而非默认值
  • API 解析中标识可选字段的存在性
场景推荐返回类型
用户查找?User
配置读取?Config

2.5 静态分析工具对 ?type 的支持现状

随着类型推导与泛型编程的广泛应用,?type 作为一种占位符类型,在现代编程语言中逐渐普及。主流静态分析工具对其支持程度不一。
工具支持对比
工具名称语言支持?type 支持
Go VetGo部分(实验性)
Kotlin CompilerKotlin完全支持
ESLint + TypeScriptTypeScript否
代码示例与分析

func Process(data []?type) ?type {
    if len(data) == 0 {
        return nil
    }
    return data[0] // 推导返回类型为切片元素类型
}
上述 Go 扩展语法中,?type 允许函数在不显式声明泛型参数的情况下进行类型推导。然而,当前 Go Vet 仅能识别局部上下文中的占位符,无法跨包传播类型信息,限制了其在复杂项目中的应用。

第三章:常见误用场景与陷阱剖析

3.1 混淆 ?type 与默认值 null 的逻辑错误

在类型系统设计中,可选类型(如 ?string)常被误认为等同于默认值为 null。然而,二者语义不同:前者表示“可能无值”,后者则是明确赋值。
常见错误示例

func processName(name *string) string {
    if name == nil {
        return "Unknown"
    }
    return *name
}
// 错误:调用时传入未初始化的指针可能导致非预期行为
上述代码假设 *string 等价于可选类型,但若调用方未显式传递 nil,可能引发解引用 panic。
正确处理方式
使用显式判断或默认值注入机制:
  • 通过结构体标签定义默认行为
  • 在参数校验阶段统一处理空值场景

3.2 在严格类型模式下 ?type 的行为异常

在启用严格类型检查的环境下,查询参数 ?type 可能因类型推断冲突导致解析异常。此类问题常出现在动态路由与静态类型校验共存的框架中。
典型异常场景
当请求携带 ?type=number 时,TypeScript 或类似系统可能误将字符串字面量 "number" 强制匹配为原生类型,引发校验失败。

// 路由处理逻辑
interface Query { type: 'string' | 'number'; }
const query = parseQuery<Query>(); // 实际传入 "?type=number"
上述代码在严格模式下会因字符串值与类型字面量不匹配而抛出类型错误。
解决方案对比
  • 使用联合字符串字面量而非类型关键词命名参数
  • 在解析层提前进行类型归一化转换
  • 关闭特定字段的严格类型校验

3.3 多层嵌套结构中 ?type 的失效问题

在复杂的数据结构处理中,查询参数 `?type` 常用于动态指定数据类型或行为模式。然而,在多层嵌套对象或数组中,该参数可能因作用域隔离而失效。
典型失效场景
当请求路径携带 `?type=json` 时,若解析逻辑仅作用于顶层结构,深层嵌套字段将无法继承类型语义,导致类型推断错误。

{
  "data": {
    "items": [
      { "id": 1, "config?type=text": { "value": "..." } }
    ]
  }
}
上述结构试图在嵌套层级中传递类型提示,但多数解析器忽略路径中的查询语法,视其为普通键名。
解决方案对比
方案适用性局限性
预解析全路径高性能开销大
上下文透传 type中需统一解析规范

第四章:工程化实践中的最佳策略

4.1 接口契约设计中 ?type 的合理使用规范

在 RESTful 接口设计中,查询参数 ?type 常用于资源的分类过滤。合理使用该参数可提升接口的可读性与可维护性。
使用场景与语义明确性
?type 应仅用于标识资源的业务类型或状态分类,避免用于控制返回字段或分页逻辑。例如:
GET /api/orders?type=pending
表示获取待处理订单,语义清晰。
类型值的约束建议
推荐使用预定义的枚举值,避免自由字符串输入,防止注入风险。可用如下约定:
  • pending:待处理
  • completed:已完成
  • cancelled:已取消
结合内容协商更佳
对于复杂类型需求,建议结合 Accept 头或路径版本化,而非过度依赖 ?type 扩展。

4.2 数据访问层中处理可空类型的防御编程

在数据访问层中,数据库字段常允许为 NULL,而 Go 等语言的原生类型不支持空值,直接映射可能导致运行时 panic。使用指针类型或 sql.Null* 类型是常见解决方案。
使用 sql.NullString 防御空值
var name sql.NullString
err := db.QueryRow("SELECT name FROM users WHERE id = ?", 1).Scan(&name)
if err != nil {
    log.Fatal(err)
}
if name.Valid {
    fmt.Println("Name:", name.String)
} else {
    fmt.Println("Name is NULL")
}
sql.NullString 包含 String 和 Valid 两个字段,Valid 标识数据库值是否非空,避免空值解引用错误。
推荐实践
  • 对可能为空的字段统一使用 sql.NullInt64、sql.NullBool 等类型
  • 在 DAO 层尽早判断有效性,防止空值向上传播
  • 结合 ORM 时注意标签配置,如 gorm:"default:null"

4.3 API 响应建模时的安全类型声明技巧

在设计API响应模型时,安全的类型声明能有效防止数据解析异常与潜在注入风险。应优先使用强类型结构,避免任意类型(any)的滥用。
使用泛型约束响应结构

interface ApiResponse<T> {
  code: number;
  message: string;
  data: T extends object ? T : never;
}
该泛型接口确保data字段必须为对象类型,通过条件类型限制非法原始值传入,提升类型安全性。
字段级安全声明策略
  • 对敏感字段如password、token应标记为never或使用Omit排除
  • 必填字段明确声明,可选字段添加?并配合默认值处理
  • 枚举类型替代字符串字面量,防止非法值注入

4.4 结合 PHPStan 实现 ?type 的静态验证闭环

在现代 PHP 项目中,`?type`(可空类型)的广泛使用提升了类型声明的表达能力,但也带来了潜在的空值处理风险。通过集成 PHPStan,可在编码阶段实现对可空类型的静态分析闭环。
配置 PHPStan 启用严格模式

parameters:
  level: 8
  checkNullables: true
  ignoreErrors:
    - '#Call to method .* on null#'
该配置启用最高检查级别并开启可空性检测,确保调用可能为 `null` 的对象方法时触发警告。
类型推导与错误预防
  • PHPStan 能自动推导联合类型中的 ?string、?int 等场景
  • 在未进行空值判断前调用属性或方法,将被标记为静态错误
  • 结合泛型与可空嵌套类型(如 ?UserEntity),提升复杂结构的安全性

第五章:未来展望:从 ?type 到更完善的类型体系

随着现代编程语言对类型安全需求的不断提升,动态类型系统中的模糊性正逐步被更严谨的结构所取代。以 TypeScript 为例,其通过引入条件类型、映射类型和模板字面量类型,显著增强了类型表达能力。
类型推导的智能化演进
现代编译器已能基于上下文自动推导复杂类型。例如,在函数重载与泛型结合的场景中:

function parse<T extends string>(input: T): T extends 'json' ? {data: any} : string;
const result = parse('json'); // 类型为 { data: any }
这种条件类型机制使 API 能根据输入动态返回精确输出类型,极大提升了类型覆盖率。
零运行时开销的类型验证
通过静态分析工具(如 tsc 或 SWC),类型检查可在构建阶段完成。以下配置可启用严格模式:
  • strictNullChecks: true
  • noImplicitAny: true
  • useUnknownInCatchVariables: true
这些选项有效防止了常见类型漏洞,尤其是在大型协作项目中。
跨语言类型协议的统一趋势
表格展示了主流语言在类型特性上的收敛方向:
语言支持泛型支持类型推导条件类型
TypeScript✅✅✅
Rust✅✅部分(via traits)
Python✅(typing.Generic)有限否
图:主流语言类型系统功能对比
Python、Selenium实现问卷星自动填写(内含适配个人问卷的方法) 使用Python、Selenium实现问卷星自动填写,内含适配个人问卷的方法。 阅读详情

相关推荐

告别手动归档:基于Allegro Skill的XTools一键生成Gerber与生产文件实践

本文详细介绍了基于Allegro Skill的XTools工具如何实现一键生成Gerber与生产文件,大幅提升PCB设计效率。通过自动化流程,解决了传统手动归档中的重复劳动、人为失误和标准不统一等问题,特别适合需要频繁输出生产文件的工程师。文章包含安装配置、实战操作、问题排查及进阶技巧,帮助用户快速掌握这一高效工具。

weixin_30505225的博客 461

PyTorch 3.0 C++算子注册陷阱曝光,90%开发者都忽略的底层细节

掌握PyTorch 3.0 C++前端的算子注册关键技巧,避开常见陷阱。详解自定义算子注册流程、CUDA算子集成方法及运行时性能优化,适用于高性能模型部署场景。揭示90%开发者忽略的底层细节,提升框架扩展能力,值得收藏。

LiteTrans的博客 1002

19-5 ACC 自适应巡航控制系统需求

本专题由深圳季连AIgraphX李博及团队出品,主要讲解ACC自适应巡航控制系统的开发与仿真测试。具体说来,包括ACC标准/法规分析、系统需求、系统架构、软件需求、软件架构、算法建模、验证场景分析、仿真实验搭建等内容。 本节主要讲ACC系统需求。

AIgraphX 1089

你真的懂Java 20的for循环模式匹配吗?90%开发者忽略的关键细节曝光

掌握Java 20模式匹配for循环的变量用法,提升代码可读性与安全性。详解其在集合遍历中的应用场景,通过类型判断与自动解构简化逻辑,避免冗余强转。核心优势在于减少样板代码、降低出错风险。开发者进阶必看,值得收藏。

CodeWhim的博客 397

微带线,带状线和接地共面波导的区别

微带线,带状线和接地共面波导的区别

sky_ying的博客 3万+

水下井口装置及钻杆建模

内容:海上油气资源开采的过程中,通常会由海上钻井平台下入钻杆连接到海底井口装置。OrcaFlex软件可进行各种海洋工程结构动态分析,通过各项数据的输入,能够很方便地进行水下井口装置及钻杆建模。直接使用软件New Line及new vessel功能,再设置模型的各项参数(几何属性、弯曲刚度、轴线刚度、扭转刚度、泊松比等)即可建成井口装置及钻杆模型。 设置管线的几何属性:主要包括管线的内外径、壁厚、...

s0302017的博客 1145

【Dify数据导出避坑宝典】:90%开发者忽略的格式细节全曝光

掌握检索结果的 Dify 导出格式,避免数据迁移常见陷阱。本文详解其在AI应用与知识库场景的应用,解析JSON结构、字段映射与编码规范,提升导出效率与兼容性。关键细节全曝光,值得收藏。

BytePerch的博客 1027

单相PWM整流器搭建训练——(一)拓扑原理介绍

单相整流器是一种将交流电转换为直流电的设备,主要由变压器、整流元件和滤波电路组成。变压器将输入的交流电压转换为适合整流的较低电压,整流元件(如二极管)利用其单向导电性将交流电转换为脉动直流电,最后滤波电路去除脉动直流电中的纹波,输出较为平滑的直流电,从而实现交流到直流的转换,广泛应用于各类电源设备中。

DikouNass的博客 1587

行为树如何实现跨平台序列化?90%开发者忽略的关键细节曝光

掌握行为树的序列化实现跨平台兼容的关键方法,解决游戏AI在多端同步的难题。详解JSON与二进制格式选择、节点状态持久化策略及反序列化安全性处理,提升系统稳定性与加载效率,值得收藏。

VarFlow的博客 796

高德地图 搜索和点击定位

高德地图vue

weixin_45474673的博客 1943

LayaBox CommandBuffer描边使用详细

项目需要使用LayaBox做一个给3D物体动态描边的一个功能,前前后后踩了一些坑算是把这个东西给做出来了把我改好的代码贴上,分享给大家。 (1)想要使用描边你的引擎版本必须 >=2.9.0 (2)你必须下载 Laya官方的BlurShader库才能使用这个功能,下载地址:https://github.com/layabox/layaair-demo/tree/master/h5/3d/ts/LayaAir3D_PostProcess/BlurShader 下载完之后把BlurShader放到自己项目的

小智队长 1735

为什么顶尖团队都在用Protobuf反射?90%开发者忽略的优势曝光

掌握Protobuf反射序列化,高效解决多类型消息处理难题。适用于微服务通信、动态协议解析等场景,通过反射机制实现通用编解码,提升开发效率与系统扩展性。90%顶尖团队已采用的技术方案,值得收藏。

Algorhythm的博客 272

逆向学习:从已上线微信小游戏反推Cocos工程结构(以切水果跑酷为例)

本文以“切水果跑酷”为例,详细介绍了如何通过逆向分析已上线的微信小游戏,反推其基于Cocos Creator的原始工程结构。文章深入拆解了编译后的目录骨架、资源加载逻辑与依赖关系,并重点解析了微信平台API的调用特征,为开发者提供了一种高效学习游戏架构与设计模式的实用方法。

kk1234的博客 1073

C++17 any类型检查终极指南:90%开发者忽略的关键细节曝光

掌握C++17 any的类型检查技巧,解决类型安全难题。详解std::any_cast与type_info应用,覆盖异常处理、运行时类型查询等关键场景,提升代码健壮性。90%开发者忽略的细节全解析,值得收藏

ByteShoal的博客 285

计算机控制技术及应用

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

深度学习工具包 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")

联合类型使用陷阱曝光,90%的PHP程序员都忽略的3个关键细节

掌握PHP 8.0联合类型(T1|T2)的正确用法,避开类型判断错误、方法重写冲突与文档缺失三大陷阱。详解适用场景与最佳实践,提升代码健壮性与可维护性,值得收藏。

ProceSeed的博客 703

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

Java 10 var类型推断陷阱曝光:90%开发者忽略的编译隐患

掌握Java 10局部变量类型推断var的正确用法,避开编译隐患。详解var在局部变量声明中的适用场景与限制,揭示类型推断失败的常见原因及规避策略。提升代码可读性与安全性,90%开发者忽略的细节全解析,值得收藏。

CompiShoal的博客 276

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

交集类型使用陷阱曝光,90%的PHP开发者都踩过的坑你中了几个?

掌握PHP 8.1交集类型使用技巧,避开常见陷阱。详解接口组合、泛型约束等适用场景,揭示类型安全与代码复用的核心优势。90%开发者忽略的关键细节全解析,值得收藏

GatherLume的博客 376

为什么你的Dify知识库导入总是失败?90%人忽略的4个细节曝光

掌握Dify知识库的导入导出技巧,解决90%人遇到的失败问题。揭秘文件格式、编码方式、元数据配置和批量操作中的4个关键细节,提升导入成功率。适用于AI训练、企业知识管理等场景,确保数据高效流转。值得收藏

PixelWander的博客 1590

为什么90%的开发者都在Dify+Spring AI集成上踩坑?真相终于曝光

掌握Dify与Spring AI的API适配技巧,轻松实现AI能力无缝集成。详解常见错误、适配核心方法及微服务场景下的最佳实践,提升开发效率3倍以上。避坑指南已整理完毕,值得收藏。

LogicGap的博客 753

医疗护理Agent的提醒频率该设多少?90%从业者忽略的关键数据曝光

揭秘医疗护理 Agent 的提醒频率设置秘诀,解决患者依从性差与过度打扰难题。结合临床场景与用户行为数据,分析最佳提醒间隔与个性化配置方法,提升护理效率30%以上。90%从业者忽视的关键优化点曝光,值得收藏。

InitFlow的博客 757

为什么你的AZ-204代码提交失败?90%考生忽略的4项技术细节曝光

掌握MCP AZ-204代码提交要求,避开常见失败陷阱。本文揭示90%考生忽略的4项技术细节,涵盖真实考试场景、命名规范、路径配置与自动验证机制。精准合规提交,大幅提升通过率,值得收藏。

BreakVein的博客 723

Docker Offload任务分配陷阱曝光:90%工程师都忽略的调度盲区

揭秘Docker Offload的任务分配调度盲区,解决微服务部署中的资源浪费与延迟问题。适用于高并发容器化场景,通过智能调度策略提升负载均衡效率,避免节点过载。90%工程师忽略的关键优化点,值得收藏。

FastCompile的博客 285

MCP考试成绩复议真相曝光:90%考生忽略的3个关键时间节点

揭秘MCP考试成绩复议关键细节,90%考生忽略的3个时间节点决定成败。掌握申请窗口、材料提交与审核反馈周期,提升复议成功率。适用于成绩异常或临近通过线的考生,方法实用高效,值得收藏。

ByteShoal的博客 947

SITS大会嘉宾演讲视频如何秒速下载?3个被90%工程师忽略的官方通道曝光

快速获取SITS大会嘉宾演讲视频下载资源!揭秘3个官方直连通道,支持高清无水印、批量导出与离线观看,专为工程师高效学习设计。绕过第三方限制,安全稳定提速90%,值得收藏。

PoliVein的博客 398

PHP跨域安全陷阱曝光(90%程序员忽略的Access-Control-Allow-Origin漏洞)

快速掌握PHP跨域解决方法,避免常见安全漏洞。详解Access-Control-Allow-Origin配置陷阱及正确写法,适用于前后端分离项目,保障接口安全。提升开发规范,值得收藏。

SimTrans的博客 1074

MCP vs REST API性能生死局:20万TPS压测数据曝光,90%工程师忽略的3个协议层瓶颈

揭秘高并发场景下MCP协议与传统REST API性能对比及性能调优指南:基于20万TPS压测实测,定位序列化、连接复用、消息头冗余三大协议层瓶颈。适用于IoT、实时信令等低延迟场景,提升吞吐3.2倍,降低P99延迟67%,值得收藏。

BytePerch的博客 403
上一篇: Laravel 10队列失败处理(专家级故障排查清单限时公开)
下一篇: 【PHP性能优化秘籍】:利用str_replace数组实现毫秒级文本替换
IterStream
博客等级 码龄1年 152粉丝 2112原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值