当前位置: 首页 > news >正文

Angular 面试题及详细答案

Angular 面试题及详细答案

Angular 作为 Google 维护的企业级前端框架,其面试考察通常覆盖核心概念、生命周期、依赖注入、状态管理、性能优化等维度。以下整理了高频面试题及深度解析,帮助理解原理而非单纯记忆。

一、基础概念与核心特性

1. Angular 和 AngularJS 的主要区别是什么?

Angular(通常指 Angular 2+,简称 Angular)是 AngularJS(Angular 1.x)的完全重写版本,核心差异如下:

对比维度AngularJS (1.x)Angular (2+)
语言支持仅支持 JavaScript推荐 TypeScript(强类型),也支持 JS
架构模式MVC(Model-View-Controller)组件化架构(Component-Based)
数据绑定双向绑定(基于脏检查)双向绑定(基于 Zone.js)+ 单向绑定([]
依赖注入模块级注入,配置复杂层级注入(模块/组件/指令),API 更清晰
性能脏检查机制,大应用性能差增量变更检测,性能更优
移动支持无原生支持,需第三方框架(如 Ionic 1)原生支持 PWA、移动端适配,可配合 Ionic 4+
生态老旧,社区活跃度低活跃,官方维护路由、表单等模块

2. Angular 的核心模块(Modules)有哪些?各自的作用是什么?

Angular 中模块(NgModule)是组织代码的基本单元,每个 Angular 应用至少有一个根模块(AppModule),核心模块分为:

模块名称作用
BrowserModule浏览器平台必备模块,提供 ngIfngFor 等内置指令,仅根模块导入。
CommonModule包含 BrowserModule 的核心指令(无平台相关代码),子模块导入以复用指令。
FormsModule提供模板驱动表单支持(如 ngModelngForm)。
ReactiveFormsModule提供响应式表单支持(如 FormGroupFormControl),更适合复杂表单。
RouterModule路由核心模块,通过 forRoot()(根模块)/forChild()(子模块)配置路由。
HttpClientModule提供 HTTP 请求能力(替代 AngularJS 的 $http),支持拦截器、TypeScript 类型。

3. 什么是 Angular 组件(Component)?它的核心组成部分有哪些?

组件是 Angular 应用的最小视图单元,负责封装 UI 结构、样式和逻辑,是“页面积木”。一个完整的组件由 4 部分组成:

  1. 装饰器(@Component:定义组件元数据,核心属性包括:

    • selector:组件的 HTML 标签名(如 <app-user>),用于在其他模板中引用。
    • template/templateUrl:组件的 HTML 模板(内联模板/外部文件路径)。
    • styles/styleUrls:组件的 CSS 样式(内联样式/外部文件路径),默认样式隔离(仅作用于当前组件)。
    • providers:在组件层级注入依赖(覆盖模块级注入)。
  2. 类(Class):包含组件的业务逻辑,如数据(property)、方法(method),通过模板绑定与视图交互。

  3. 模板(Template):HTML 结构,通过 Angular 模板语法(如 {{}}[]())绑定类中的数据和事件。

  4. 样式(Styles):组件的样式,支持 scoped(默认)、::ng-deep(穿透子组件样式)等特性。

示例

// user.component.ts
import { Component } from '@angular/core';@Component({selector: 'app-user',template: `<h2>Hello, {{ userName }}!</h2><button (click)="changeName()">Change Name</button>`,styles: [`h2 { color: blue; }`]
})
export class UserComponent {userName = 'Alice'; // 数据changeName() { // 方法this.userName = 'Bob';}
}

二、模板语法与数据绑定

1. Angular 有哪些数据绑定方式?分别用于什么场景?

Angular 提供 4 种核心绑定方式,覆盖“数据从类到视图”“视图到类”“双向同步”的场景:

绑定类型语法示例方向作用场景
插值绑定{{ user.name }}类 → 视图展示类中的数据(文本内容)。
属性绑定<img [src]="imgUrl">类 → 视图绑定 HTML 属性/组件输入属性(如 [disabled])。
事件绑定<button (click)="onClick()">视图 → 类监听 DOM 事件/组件输出事件(如点击、输入)。
双向绑定<input [(ngModel)]="user.name">类 ↔ 视图数据在类和视图间同步(需导入 FormsModule)。

注意:双向绑定本质是“属性绑定 + 事件绑定”的语法糖,等价于 <input [value]="user.name" (input)="user.name = $event.target.value">

2. 什么是 *ngIf*ngFor?它们的区别和注意事项是什么?

两者都是 Angular 内置结构型指令(前缀 * 表示“修改 DOM 结构”):

*ngIf:条件渲染
  • 作用:根据表达式布尔值决定是否在 DOM 中添加/移除元素(而非隐藏)。
  • 示例<div *ngIf="isShow">仅当 isShow 为 true 时显示</div>
  • 注意:频繁切换可能触发 DOM 频繁创建/销毁,性能敏感场景可考虑 [hidden](仅隐藏,DOM 保留)。
*ngFor:循环渲染
  • 作用:根据数组/可迭代对象生成重复的 DOM 元素。
  • 核心语法*ngFor="let item of list; let i = index; trackBy: trackByFn"
  • 注意事项
    1. 必须加 trackBy:默认情况下,数组变化时 *ngFor 会重新渲染所有元素;trackBy 通过唯一标识(如 id)复用 DOM,提升性能。
    2. index 变量:获取当前循环的索引(从 0 开始)。

trackBy 示例

// 组件类
trackByUserId(index: number, user: User): number {return user.id; // 用用户唯一 ID 跟踪
}// 模板
<div *ngFor="let user of userList; trackBy: trackByUserId">{{ user.name }}
</div>

3. 什么是管道(Pipe)?常用的内置管道有哪些?

管道是 Angular 中用于转换模板数据格式的工具(如日期、货币、大小写转换),语法为 {{ 数据 | 管道名: 参数 }}

常用内置管道:
  • date:格式化日期,示例:{{ today | date: 'yyyy-MM-dd HH:mm' }}(输出:2024-05-20 14:30)。
  • currency:格式化货币,示例:{{ price | currency: 'CNY' }}(输出:¥100.00)。
  • uppercase/lowercase:转换大小写,示例:{{ 'hello' | uppercase }}(输出:HELLO)。
  • async:处理异步数据(如 ObservablePromise),自动订阅/取消订阅,避免内存泄漏,示例:{{ user$ | async }}
  • json:将对象转为 JSON 字符串,用于调试,示例:{{ user | json }}
自定义管道:

通过 @Pipe 装饰器定义,需实现 PipeTransform 接口的 transform 方法。示例(首字母大写管道):

import { Pipe, PipeTransform } from '@angular/core';@Pipe({ name: 'firstUpper' }) // 管道名称
export class FirstUpperPipe implements PipeTransform {transform(value: string): string {if (!value) return '';return value[0].toUpperCase() + value.slice(1);}
}// 模板使用:{{ 'angular' | firstUpper }} → 输出 Angular

三、组件通信

1. 父组件如何向子组件传递数据?

通过输入属性(@Input() 实现,步骤如下:

  1. 子组件中用 @Input() 装饰器定义可接收的属性:

    // 子组件:child.component.ts
    import { Input } from '@angular/core';export class ChildComponent {@Input() childName: string; // 父组件可传递的属性@Input('alias') age: number; // 可选:设置别名,父组件用别名传递
    }
    
  2. 父组件模板中通过属性绑定传递数据:

    <!-- 父组件模板 -->
    <app-child [childName]="parentName"  <!-- 无别名:直接用子组件属性名 -->[alias]="parentAge"       <!-- 有别名:用别名传递 -->
    ></app-child>
    
  3. (可选)子组件监听输入属性变化:
    通过 ngOnChanges 生命周期钩子(监听多个属性)或 setter 方法(监听单个属性):

    // 方式1:setter 监听单个属性
    @Input() set childName(name: string) {this._childName = name ? name.trim() : '';
    }
    private _childName: string;// 方式2:ngOnChanges 监听多个属性
    import { OnChanges, SimpleChanges } from '@angular/core';export class ChildComponent implements OnChanges {@Input() childName: string;@Input() age: number;ngOnChanges(changes: SimpleChanges): void {// changes 包含所有变化的输入属性if (changes['childName']) {console.log('childName 变化:', changes['childName'].currentValue);}}
    }
    

2. 子组件如何向父组件传递数据?

通过输出属性(@Output() + EventEmitter 实现,本质是“子组件触发事件,父组件监听事件”:

  1. 子组件中用 @Output() 装饰器定义事件发射器:

    // 子组件:child.component.ts
    import { Output, EventEmitter } from '@angular/core';export class ChildComponent {// 定义输出事件(可选设置别名)@Output() sendMsg = new EventEmitter<string>();// 子组件触发事件,传递数据onClick() {this.sendMsg.emit('Hello from Child!'); // 发送数据}
    }
    
  2. 父组件模板中通过事件绑定监听子组件事件:

    <!-- 父组件模板 -->
    <app-child (sendMsg)="receiveMsg($event)"></app-child>
    
  3. 父组件定义方法接收数据:

    // 父组件:parent.component.ts
    receiveMsg(msg: string): void {console.log('收到子组件消息:', msg); // 输出:收到子组件消息:Hello from Child!
    }
    

3. 非父子组件(如兄弟组件)如何通信?

非父子组件无直接关联,需通过“中间层”传递数据,常用方案有 3 种:

方案1:共享服务(推荐)

通过一个全局/模块级别的服务,利用 Observable(如 Subject)实现事件订阅/发布:

// 共享服务:msg.service.ts
import { Injectable } from '@angular/core';
import { Subject } from 'rxjs';@Injectable({ providedIn: 'root' }) // 全局注入
export class MsgService {private msgSubject = new Subject<string>(); // 私有 Subject(避免外部直接调用)msg$ = this.msgSubject.asObservable(); // 暴露为 Observable(仅允许订阅)// 发送消息的方法sendMsg(msg: string): void {this.msgSubject.next(msg);}
}// 发送方组件(如 Brother1)
export class Brother1Component {constructor(private msgService: MsgService) {}send() {this.msgService.sendMsg('Hi from Brother1!');}
}// 接收方组件(如 Brother2)
export class Brother2Component {constructor(private msgService: MsgService) {}ngOnInit() {// 订阅消息this.msgService.msg$.subscribe(msg => {console.log('Brother2 收到:', msg);});}
}
方案2:通过父组件中转

兄弟组件通过共同的父组件传递:

  • 兄弟 A → 父组件(@Output());
  • 父组件 → 兄弟 B(@Input())。
方案3:状态管理库(大型应用)

NgRx(Angular 官方推荐,基于 Redux 思想),统一管理全局状态,适合复杂应用(如多组件共享大量数据)。

四、生命周期钩子

1. Angular 组件的生命周期钩子有哪些?按执行顺序说明作用。

Angular 组件从“创建”到“销毁”会触发一系列生命周期钩子,核心钩子按执行顺序如下:

钩子名称执行时机核心作用
ngOnChanges输入属性(@Input())变化时触发(首次赋值也触发)监听输入属性变化,处理数据更新逻辑。
ngOnInit组件初始化完成后触发(仅一次)执行初始化逻辑(如调用接口、订阅数据)。
ngDoCheck每次变更检测时触发(频率高)自定义变更检测逻辑(谨慎使用,避免性能问题)。
ngAfterContentInit组件内容投影(<ng-content>)初始化后触发(仅一次)操作投影内容(如获取投影的 DOM 元素)。
ngAfterContentChecked投影内容变更检测后触发监听投影内容的变化。
ngAfterViewInit组件视图(模板)初始化后触发(仅一次)操作组件内部 DOM 元素(如通过 @ViewChild 获取元素)。
ngAfterViewChecked组件视图变更检测后触发监听视图的变化。
ngOnDestroy组件销毁前触发(仅一次)清理资源(如取消 Observable 订阅、清除定时器),避免内存泄漏。

示例:组件初始化时调用接口,销毁时取消订阅:

import { OnInit, OnDestroy } from '@angular/core';
import { Subscription } from 'rxjs';
import { UserService } from './user.service';export class UserComponent implements OnInit, OnDestroy {private userSub: Subscription;ngOnInit() {this.userSub = this.userService.getUser().subscribe(user => {console.log(user);});}ngOnDestroy() {this.userSub.unsubscribe(); // 清理订阅}
}

五、依赖注入(DI)

1. 什么是 Angular 的依赖注入?它的核心作用是什么?

依赖注入(Dependency Injection,DI)是 Angular 的核心设计模式,指**“组件/服务的依赖由框架自动注入,而非手动创建”**。

核心作用:
  1. 解耦:组件无需关心依赖的创建逻辑,只需声明依赖,降低代码耦合度。
  2. 复用:依赖(如服务)可在多个组件间共享,避免重复代码。
  3. 测试友好:可轻松替换依赖的模拟实现(如测试时用模拟服务替代真实接口服务)。
核心概念:
  • 注入器(Injector):负责创建和管理依赖实例的容器,Angular 有三级注入器(根注入器 → 模块注入器 → 组件注入器),层级越细优先级越高。
  • 提供商(Provider):告诉注入器“如何创建依赖实例”,常用 useClass(用类实例化)、useValue(用固定值)、useFactory(用工厂函数)。
  • 依赖令牌(Token):注入器查找依赖的唯一标识(通常是服务类本身)。

2. 如何创建和使用一个服务(Service)?

服务是 Angular 中用于封装共享逻辑(如接口调用、数据处理) 的类,通过 @Injectable 装饰器标记为可注入。

步骤1:创建服务(用 Angular CLI 命令)
ng generate service user  # 生成 user.service.ts
步骤2:定义服务逻辑
// user.service.ts
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
import { User } from './user.model';@Injectable({providedIn: 'root'  // 根注入器:服务实例在整个应用中唯一// 也可设置为模块:providedIn: UserModule → 仅该模块内共享
})
export class UserService {constructor(private http: HttpClient) {} // 注入 HttpClient 依赖// 封装接口调用逻辑getUser(id: number): Observable<User> {return this.http.get<User>(`https://api.example.com/users/${id}`);}
}
步骤3:在组件中使用服务

组件只需在构造函数中声明依赖,Angular 会自动注入服务实例:

// user.component.ts
import { Component, OnInit } from '@angular/core';
import { UserService } from './user.service';
import { User } from './user.model';@Component({ selector: 'app-user' })
export class UserComponent implements OnInit {user: User;// 声明依赖(无需手动 new UserService())constructor(private userService: UserService) {}ngOnInit() {this.userService.getUser(1).subscribe(user => {this.user = user;});}
}

六、路由(Routing)

1. Angular 路由的核心概念有哪些?如何配置基础路由?

Angular 路由(@angular/router)负责管理组件间的导航,核心概念和配置步骤如下:

核心概念:
  • 路由配置(Route):定义“路径 → 组件”的映射,如 { path: 'user', component: UserComponent }
  • 路由出口(<router-outlet>:路由组件的渲染容器,匹配的组件会替换该标签的内容。
  • 路由链接(<a routerLink="...">:导航链接,替代原生 <a href>(避免页面刷新)。
  • 激活路由(ActivatedRoute):获取当前路由的信息(如参数、查询参数)。
  • 路由守卫(Route Guard):控制路由访问权限(如登录验证)。
基础路由配置步骤:
  1. 导入 RouterModule 和组件:

    // app.module.ts
    import { RouterModule } from '@angular/router';
    import { HomeComponent } from './home.component';
    import { UserComponent } from './user.component';
    
  2. 定义路由配置数组:

    const routes = [{ path: '', redirectTo: '/home', pathMatch: 'full' }, // 默认路由(重定向到首页){ path: 'home', component: HomeComponent }, // 首页路由{ path: 'user/:id', component: UserComponent }, // 带参数的路由(:id 是参数占位符){ path: '**', component: NotFoundComponent } // 通配符路由(匹配未定义的路径,通常用于404页面)
    ];
    
  3. @NgModuleimports 中配置路由:

    @NgModule({imports: [BrowserModule,RouterModule.forRoot(routes) // 根模块用 forRoot()],// ...
    })
    
  4. 在根组件模板中添加 <router-outlet> 和导航链接:

    <!-- app.component.html -->
    <nav><a routerLink="/home">首页</a><a routerLink="/user/1">用户1</a>
    </nav>
    <router-outlet></router-outlet> <!-- 路由组件将在这里渲染 -->
    

2. 如何在组件中获取路由参数?

通过 ActivatedRoute 服务获取路由参数(如 user/:id 中的 id),常用两种方式:

方式1:快照(Snapshot)—— 参数不变时使用

适用于“参数一旦设置就不会变化”的场景(如从列表页进入详情页,参数固定):

// user.component.ts
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';export class UserComponent implements OnInit {userId: string;constructor(private route: ActivatedRoute) {}ngOnInit() {// 从快照中获取参数this.userId = this.route.snapshot.paramMap.get('id');console.log('用户ID:', this.userId);}
}
方式2:订阅(Subscribe)—— 参数可能变化时使用

适用于“同一组件内参数可能变化”的场景(如详情页内切换用户,组件不销毁,仅参数变化):

export class UserComponent implements OnInit {userId: string;constructor(private route: ActivatedRoute) {}ngOnInit() {// 订阅参数变化this.route.paramMap.subscribe(params => {this.userId = params.get('id');console.log('用户ID(更新后):', this.userId);});}
}

补充:获取查询参数(如 user?id=1&name=alice 中的 idname):

// 快照方式
const id = this.route.snapshot.queryParamMap.get('id');
const name = this.route.snapshot.queryParamMap.get('name');// 订阅方式
this.route.queryParamMap.subscribe(queryParams => {const id = queryParams.get('id');
});

七、性能优化

1. Angular 应用有哪些常见的性能优化手段?

Angular 性能优化需从“变更检测、渲染、资源加载”等维度入手,常用手段如下:

  1. 优化变更检测

    • 使用 OnPush 变更检测策略:组件装饰器中设置 changeDetection: ChangeDetectionStrategy.OnPush,仅当输入属性(@Input())引用变化、组件内事件触发或手动调用 markForCheck() 时,才执行变更检测,减少不必要的检测。
    • 避免在模板中调用函数:模板中 {{ getUserName() }} 会在每次变更检测时执行,建议提前计算并存储为属性。
  2. 减少 DOM 操作

    • *ngFortrackBy:复用 DOM 元素,避免频繁重新渲染(见“模板语法”部分)。
    • 虚拟滚动(Virtual Scrolling):使用 @angular/cdk/scrollingCdkVirtualScrollViewport,仅渲染可视区域的列表项(适合万级以上数据)。
  3. 资源优化

    • 懒加载模块(Lazy Loading):路由配置中用 loadChildren 延迟加载模块,减少初始加载体积:
      const routes = [{ path: 'user', loadChildren: () => import('./user/user.module').then(m => m.UserModule) }
      ];
      
    • 压缩代码:通过 Angular CLI 的 --prod 模式(ng build --prod)自动压缩 JS/CSS/HTML,开启 Tree Shaking(移除未使用代码)。
  4. 内存泄漏防护

    • 取消订阅Observable 订阅后,在 ngOnDestroy 中调用 unsubscribe(),或使用 async 管道(自动取消订阅)。
    • 清除定时器setTimeout/setIntervalngOnDestroy 中调用 clearTimeout/clearInterval

八、进阶问题

1. 什么是 Angular 拦截器(Interceptor)?如何实现一个 HTTP 拦截器?

拦截器是 Angular 中用于统一拦截和处理 HTTP 请求/响应的服务(如添加 Token、处理错误、显示加载动画),需实现 HttpInterceptor 接口。

实现步骤:
  1. 创建拦截器类:

    // auth.interceptor.ts(添加请求 Token 的拦截器)
    import { Injectable } from '@angular/core';
    import {HttpRequest,HttpHandler,HttpEvent,HttpInterceptor
    } from '@angular/common/http';
    import { Observable } from 'rxjs';@Injectable()
    export class AuthInterceptor implements HttpInterceptor {constructor() {}// 拦截请求的核心方法intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {// 1. 获取本地存储的 Tokenconst token = localStorage.getItem('token');// 2. 克隆请求并添加 Token 头(请求对象不可变,需用 clone() 修改)if (token) {const authRequest = request.clone({setHeaders: { Authorization: `Bearer ${token}` }});// 3. 继续处理修改后的请求return next.handle(authRequest);}// 无 Token 时,直接处理原请求return next.handle(request);}
    }
    
  2. 在模块中注册拦截器:
    需在 @NgModuleproviders 中用 HTTP_INTERCEPTORS 令牌注册,多个拦截器按注册顺序执行:

    // app.module.ts
    import { HTTP_INTERCEPTORS } from '@angular/common/http';
    import { AuthInterceptor } from './auth.interceptor';@NgModule({providers: [{provide: HTTP_INTERCEPTORS,useClass: AuthInterceptor,multi: true // 允许注册多个拦截器}]
    })
    export class AppModule {}
    

2. 模板驱动表单和响应式表单的区别是什么?如何选择?

Angular 提供两种表单实现方式,核心差异在于“逻辑的存放位置”:

对比维度模板驱动表单(Template-Driven)响应式表单(Reactive)
逻辑位置逻辑在模板中(依赖指令如 ngModel逻辑在组件类中(依赖 FormGroup 等)
数据模型隐式模型(由 ngModel 维护)显式模型(组件类中定义 FormGroup
验证方式模板中添加验证指令(如 required类中定义验证器(如 Validators.required
灵活性简单场景友好,复杂场景难扩展灵活,支持动态表单(如动态添加字段)
测试友好性难测试(需操作 DOM)易测试(直接测试类中的表单模型)
适用场景简单表单(如登录、注册)复杂表单(如多步骤表单、动态字段)
选择建议:
  • 简单表单(字段少、验证逻辑简单):选模板驱动表单,开发速度快。
  • 复杂表单(动态字段、多验证规则、需频繁修改):选响应式表单,可维护性和扩展性更强。

3. 什么是 NgRx?它的核心组成部分有哪些?

NgRx 是 Angular 生态中的状态管理库,基于 Redux 思想和 RxJS,用于统一管理跨组件的全局状态(如用户信息、购物车数据),适合中大型应用。

核心组成部分(遵循“单向数据流”):
  1. Store:存储应用的全局状态(单一数据源),通过 select 方法获取状态,通过 dispatch 方法触发动作。
  2. Action:描述“发生了什么”的纯对象(如 { type: 'user/login', payload: { name: 'Alice' } }),是状态变化的唯一原因。
  3. Reducer:纯函数,接收当前状态和 Action,返回新状态(不修改原状态),公式:(state, action) => newState
  4. Effect:处理副作用(如接口调用、定时器),监听 Action 并触发异步操作,操作完成后派发新的 Action 更新状态。
  5. Selector:纯函数,从 Store 中提取指定状态(如 selectUser 提取用户信息),支持状态缓存和组合。
简单工作流:
  1. 组件通过 store.dispatch(action) 触发动作(如用户点击“登录”)。
  2. Effect 监听该 Action,调用登录接口(副作用),接口成功后派发 loginSuccess Action。
  3. Reducer 接收 loginSuccess Action,更新 Store 中的用户状态。
  4. 组件通过 store.select(selector) 订阅状态变化,更新视图。

以上面试题覆盖了 Angular 从基础到进阶的核心知识点,理解原理并结合实际项目经验,才能在面试中灵活应对。


文章转载自:

http://rtRb3YJR.zpnfc.cn
http://J2iGIXzU.zpnfc.cn
http://JBHFcSTw.zpnfc.cn
http://zNpvGQiP.zpnfc.cn
http://KRRAnrLG.zpnfc.cn
http://1vSLtias.zpnfc.cn
http://bxrMEbmn.zpnfc.cn
http://02IMuptu.zpnfc.cn
http://syrmtEIa.zpnfc.cn
http://fZBiY7Ww.zpnfc.cn
http://Ak34LYcw.zpnfc.cn
http://4jcoqB0u.zpnfc.cn
http://FEIH5F8H.zpnfc.cn
http://59OJM5A9.zpnfc.cn
http://Aj9zc4Qz.zpnfc.cn
http://CG23uiSJ.zpnfc.cn
http://VEqVSCAB.zpnfc.cn
http://TTNsxA9c.zpnfc.cn
http://DbFIde1A.zpnfc.cn
http://WwcSejcV.zpnfc.cn
http://LoxweoHy.zpnfc.cn
http://3S6uC4Ze.zpnfc.cn
http://W6JVoJ9s.zpnfc.cn
http://wPi7uuLR.zpnfc.cn
http://cNj4eHJu.zpnfc.cn
http://PocK1xnm.zpnfc.cn
http://Pyys5k4p.zpnfc.cn
http://vUe6YOLp.zpnfc.cn
http://FQIOUyhp.zpnfc.cn
http://n8kAwLYA.zpnfc.cn
http://www.dtcms.com/a/374865.html

相关文章:

  • AI与AR融合:重塑石化与能源巡检的未来
  • 增强现实光学系统_FDTD_zemax_speos_学习(1)
  • 开学季干货——知识梳理与经验分享
  • Alex Codes团队并入OpenAI Codex:苹果生态或迎来AI编程新篇章
  • The learning process of Decision Tree Model|决策树模型学习过程
  • 六、与学习相关的技巧(下)
  • 《低功耗音频:重塑听觉体验与物联网边界的蓝牙革命》
  • 20250909的学习笔记
  • 金融量化指标--5Sortino索提诺比率
  • 消息三剑客华山论剑:Kafka vs RabbitMQ vs RocketMQ
  • 均值/方差/标注查介绍
  • 深入解析Guava RateLimiter限流机制
  • 开发中使用——鸿蒙子页面跳转到指定Tab页面
  • HarmonyOS实现快递APP自动识别地址
  • AJAX入门-URL
  • 【C++】18. 红⿊树实现
  • 基于Java Spring Boot的云原生TodoList Demo 项目,验证云原生核心特性
  • 记录一次rk3568硬解码时cpu占用率高的问题
  • Electron 跨平台兼容性:处理 OS 差异
  • Docker 学习笔记(五):网络与存储核心原理及实战应用
  • Who Wants To Be King: 1靶场渗透
  • PgSQL监控死元组和自动清理状态的SQL语句执行报错ERROR: division by zero原因分析和解决方法
  • 深入理解 MyBatis-Plus 的 QueryWrapper:动态 SQL 构建的利器
  • 文件的相关概念
  • 注解参数校验
  • AI 测试平台新功能揭秘:自动化测试用例运行的奥秘
  • K8s是什么
  • 开源AI智能客服与AI智能名片在S2B2C商城小程序客服管理中的应用与影响
  • Python + Vue.js:现代全栈开发的完美组合
  • netty-scoket.io路径配置