2018 年 22 个 Angular 专家面试问题及答案

2025-05-24

2018 年 22 个 Angular 专家面试问题及答案

2018 年 22 个 Angular 专家面试问题及答案
这份终极 Angular 高级及专家级面试题清单,可用于招聘新团队成员、自我测试、嘲讽开发主管,或干脆直接忽略。题目来源于khan4019/angular-interview-questions ,并在FullStack.Cafe上解答

最初发表于FullStack.Cafe - 让你的技术面试不再失败

Q1:NgModule 中的“声明”、“提供者”和“导入”有什么区别?

主题:Angular
难度:⭐⭐⭐

  • imports使其他模块的导出声明在当前模块中可用
  • declarations使当前模块中的指令(包括组件和管道)可供当前模块中的其他指令使用。指令、组件或管道的选择器只有在声明或导入后才会与 HTML 匹配。
  • providers是为了让 DI 知道服务和值。它们被添加到根作用域,并被注入到依赖它们的其他服务或指令中。

一种特殊情况providers是延迟加载模块具有自己的子注入器。providers延迟加载模块的默认设置仅提供给该延迟加载模块(而不是像其他模块那样提供给整个应用程序)。

🔗来源: medium.com

Q2:解释“构造函数”和“ngOnInit”之间的区别

主题:Angular
难度:⭐⭐⭐

  • Constructor是类的默认方法,在实例化类时执行,并确保正确初始化类及其子类中的字段。
  • ngOnInit是 Angular 调用的一个生命周期钩子,用于指示 Angular 已完成组件的创建。为了使用这个钩子,我们必须导入 OnInit 接口(实际上,实现 OnInit 接口并非强制要求,但被认为是一种良好做法)。

我们主要使用ngOnInit构造函数进行所有初始化/声明,并避免在构造函数中执行任何操作。构造函数应该仅用于初始化类成员,而不应执行实际的“工作”。

🔗来源: stackoverflow.com

Q3:Angular 6 有什么新功能,为什么我们要升级到它?

主题:Angular
难度:⭐⭐⭐

  • Angular Elements - Angular Elements 是一个项目,它允许您将 Angular 组件包装为 Web 组件并将其嵌入到非 Angular 应用程序中。
  • 新的渲染引擎:Ivy - 提高速度并减小应用程序大小。
  • 可摇树的提供程序- 一种新的、推荐的注册提供程序的方法,直接在 @Injectable() 装饰器中使用新providedIn属性
  • RxJS 6 - Angular 6 现在内部使用 RxJS 6,因此需要您也更新应用程序。RxJS 发布了一个名为 rxjs-compat 的库,即使您或您正在使用的某个库仍在使用“旧”语法,它也允许您将 RxJS 升级到 6.0 版本。
  • ElementRef<T> - 在 Angular 5.0 或更早版本中,其 nativeElement 属性的类型为 any。在 Angular 6.0 中,现在可以更严格地定义 ElementRef 的类型。
  • 动画- 除非您使用 AnimationBuilder,否则 polyfill web-animations-js 对于 Angular 6.0 中的动画来说不再是必需的。
  • i18n——可以拥有“运行时 i18n”,而无需为每个语言环境构建一次应用程序。

🔗资料来源: ninja-squad.com

Q4:什么是AOT?

主题:Angular
难度:⭐⭐⭐

Angular 的 AOT 编译器会在构建过程中预编译应用程序组件及其模板。
使用 AOT 编译的应用程序启动速度更快,原因如下。

  • 应用程序组件立即执行,无需客户端编译。
  • 模板作为代码嵌入在其组件中,因此客户端不需要模板文件请求。
  • 您不需要下载 Angular 编译器,因为它本身就很大。
  • 编译器会丢弃未使用的 Angular 指令,然后摇树工具可以将其排除。

🔗来源: stackoverflow.com

Q5:为什么要使用渲染器方法而不是使用原生元素方法?

主题:Angular
难度:⭐⭐⭐⭐

Angular 是一个平台,浏览器只是我们渲染应用的一种选择。当我们直接访问原生元素时,我们放弃了 Angular 的 DOM 抽象,也失去了在非 DOM 环境中执行的机会,例如:

  • 原生移动端,
  • 原生桌面,
  • 网络工作者
  • 服务器端渲染。

该类Renderer2是 Angular 以服务形式提供的一种抽象,它允许你操作应用的元素而无需直接接触 DOM。我们推荐使用这种方式,因为它可以更轻松地开发那些能够在无法访问 DOM 的环境中渲染的应用,例如在服务器、Web Worker 或原生移动设备上。

🔗资料来源: alligator.io

Q6:Angular 中的 Zone 是什么?

主题:Angular
难度:⭐⭐⭐⭐

NgZone是一个包装器,Zone.js它是一个库,它围绕异步函数创建上下文,以便使其可跟踪。Angular 的变化检测严重依赖于 Zones。

🔗来源: stackoverflow.com

Q7:为什么要在 Angular 应用中使用延迟加载模块?

主题:Angular
难度:⭐⭐⭐⭐

要延迟加载功能模块,我们需要使用loadChildren路由配置中的属性来加载它,并且该功能模块不能导入到应用程序模块中。当应用程序规模不断增长时,延迟加载非常有用。在延迟加载模式下,功能模块将按需加载,因此应用程序的启动速度会更快。

const routes: Routes = [
  {
    path: 'customers',
    loadChildren: 'app/customers/customers.module#CustomersModule'
  },
  {
    path: 'orders',
    loadChildren: 'app/orders/orders.module#OrdersModule'
  },
  {
    path: '',
    redirectTo: '',
    pathMatch: 'full'
  }
];
Enter fullscreen mode Exit fullscreen mode

🔗资料来源: concretepage.com

Q8:组件和指令的生命周期钩子是什么?

主题:Angular
难度:⭐⭐⭐⭐

Angular 中的组件具有生命周期,即从诞生到消亡的一系列不同阶段。我们可以深入这些不同阶段,从而对应用程序进行更细粒度的控制。

  • 构造函数当 Angular 通过在类上调用 new 来创建组件或指令时,会调用此构造函数。
  • ngOnChanges每次组件的输入属性之一发生变化时调用。
  • ngOnInit:当指定组件初始化完成后调用。此钩子仅在第一个 ngOnChanges 之后调用一次。
  • ** ngDoCheck** 当指定组件的变更检测器被调用时调用。它允许我们为指定组件实现自己的变更检测算法。
  • ngOnDestroy该方法将在 Angular 销毁组件之前调用。使用此钩子可以取消订阅可观察对象并分离事件处理程序,以避免内存泄漏。

这些钩子仅针对组件调用,而不针对指令调用。

  • ngAfterContentInit在 Angular 将任何内容投影到组件视图后调用(有关更多信息,请参阅上一节关于内容投影的讲座)。
  • ngAfterContentChecked每次通过 Angular 的变化检测机制检查给定组件的内容时调用。
  • ngAfterViewInit当组件的视图已完全初始化时调用。
  • ngAfterViewChecked每次通过 Angular 的变化检测机制检查给定组件的视图时调用。

🔗来源: codecraft.tv

Q9:如何从准备好的 TemplateRef 插入嵌入视图?

主题:Angular
难度:⭐⭐⭐⭐

您可以使用方法创建嵌入视图,createEmbeddedView然后通过以下方式将该视图附加到 DOM TemplateRef

@Component({
    selector: 'app-root',
    template: `
        <ng-template #template let-name='fromContext'><div>{{name}}</ng-template>
    `
})
export class AppComponent implements AfterViewChecked {
    @ViewChild('template', { read: TemplateRef }) _template: TemplateRef<any>;
    constructor() { }

    ngAfterViewChecked() {
        this.vc.createEmbeddedView(this._template, {fromContext: 'John'});
    }
}
Enter fullscreen mode Exit fullscreen mode

🔗来源: stackoverflow.com

Q10:如何检测 Angular 中的路线变化?

主题:Angular
难度:⭐⭐⭐⭐

在 Angular 中,你可以subscribe将 Rx 事件传递给 Router 实例。因此你可以执行以下操作:

class MyClass {
    constructor(private router: Router) {
        router.subscribe((val) => /*whatever*/ )
    }
}
Enter fullscreen mode Exit fullscreen mode

🔗来源: medium.com

Q11:即时(JIT)编译器一般做什么?

主题:Angular
难度:⭐⭐⭐⭐

JIT 编译器在程序启动运行,并将代码(通常是字节码或某种虚拟机指令)即时(或称为“即时”)编译为通常更快的形式,通常是主机 CPU 的原生指令集。JIT 可以访问动态运行时信息,而标准编译器则无法访问这些信息,因此可以进行更好的优化,例如内联常用函数。

这与传统编译器形成对比,传统编译器在程序首次运行之前将所有代码编译为机器语言。

🔗来源: stackoverflow.com

问题 12:如何创建使用 scss 的应用程序?Angular 6 有什么变化?

主题:Angular
难度:⭐⭐⭐⭐

这是 CLI v1.x 中的样式配置在 .angular-cli.json 文件中的样子。

"defaults": {
  "styleExt": "scss",
  "component": {}
}
Enter fullscreen mode Exit fullscreen mode

但是,如果你查看版本 6 中 angular.json 文件的配置模式,你将不再找到这个配置。要使用 SCSS,只需在项目级别的 angular.json 文件中导入 scss 文件(默认值为“src/styles.scss”),如下所示。

{
  ...
  projects: {
    [your_project_name]: {
      ...
      architect: {
        build: {
          ...
          options: {
            styles:{
              "src/styles.scss"
            }
          }
        }
      }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

🔗来源: medium.com

Q13:什么是 ngUpgrage?

主题:Angular
难度:⭐⭐⭐⭐

NgUpgrade是由 Angular 团队整合的一个库,我们可以在我们的应用程序中使用它来混合和匹配 AngularJS 和 Angular 组件,并桥接 AngularJS 和 Angular 依赖注入系统。

🔗来源: blog.nrwl.io

Q14:什么是反应式编程,它与 Angular 有何关系?

主题:Angular
难度:⭐⭐⭐⭐

响应式编程是使用异步数据流进行编程。RxJs 是 JavaScript 的响应式扩展 (Reactive Extensions for Javascript) 的缩写,它是 JavaScript 可观察对象 (Observables) 的一个实现。可观察对象类似于流 (Stream)(在许多语言中),允许传递零个或多个事件,每个事件都会调用回调函数。Angular 目前以两种不同的方式使用 RxJs 可观察对象:

  • 作为内部实现机制,实现一些核心逻辑,如EventEmitter
  • 作为其公共 API 的一部分,FormsHTTP module

即使您不了解响应式编程或 RxJS,也能使用 Angular 构建最复杂的应用程序。然而,它可以让某些类型的应用程序更易于架构。

🔗来源: github.com/WebPredict

Q15:列举一些 Angular 中的安全最佳实践

主题:Angular
难度:⭐⭐⭐⭐

  1. 为了系统地阻止 XSS 错误,Angular 默认将所有值视为不受信任(清理)
  2. Angular 模板与可执行代码相同:模板中的 HTML、属性和绑定表达式(但不包括绑定的值)都被认为是安全的。为了防止这些漏洞,请使用离线模板编译器(也称为模板注入)。
  3. 避免直接与 DOM 交互,而是尽可能使用 Angular 模板。
  4. 将模板代码注入 Angular 应用程序与将可执行代码注入应用程序相同。因此,请验证服务器端代码中的所有数据,并进行适当的转义,以防止服务器上的 XSS 漏洞。
  5. Angular HttpClient 提供内置支持以防止客户端的 XSRF 攻击。
  6. 服务器可以通过在所有 JSON 响应中添加前缀来防止 XSSI 攻击,使其按照惯例不可执行,即使用众所周知的字符串")]}',\n"。Angular库可以识别此约定,并在进一步解析之前HttpClient自动从所有响应中删除该字符串。")]}',\n"

🔗来源: ordina-jworks.github.io

Q16:我可以将 jQuery 与 Angular 一起使用吗?

主题:Angular
难度:⭐⭐⭐⭐

首先使用 npm 安装 jQuery,如下所示

npm install jquery — save
Enter fullscreen mode Exit fullscreen mode

其次,转到./angular-cli.jsonAngular CLI 项目文件夹根目录下的文件,找到scripts: [] property,并包含 jQuery 的路径,如下所示

“scripts”: [ “../node_modules/jquery/dist/jquery.min.js” ]
Enter fullscreen mode Exit fullscreen mode

现在,要在应用程序的任何地方使用 jQuery,您只需在app.component.ts文件中按如下所示导入它。

import * as $ from jquery;
Enter fullscreen mode Exit fullscreen mode

考虑:

import { Component, OnInit  } from '@angular/core';
import * as $ from 'jquery';
@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  title = 'Look jQuery Animation working in action!';

  public ngOnInit()
  {
    $(document).ready(function(){
        $("button").click(function(){
            var div = $("div");  
            div.animate({left: '100px'}, "slow");
            div.animate({fontSize: '5em'}, "slow");
        });
    });
  }
}
Enter fullscreen mode Exit fullscreen mode

🔗来源: medium.com

Q17:Angular 中与 AngularJS“$watch”等效的是什么?

主题:Angular
难度:⭐⭐⭐⭐⭐

解决方案是setES6 中的语法。该set语法将对象属性绑定到一个函数,当尝试设置该属性时,该函数将被调用。

import { Component, Input } from '@angular/core';
@Component({
  selector: 'example-component',
})
export class ExampleComponent {
  public internalVal = null;
  constructor() {}

  @Input('externalVal')
  set updateInternalVal(externalVal) {
    this.internalVal = externalVal;
  }
}
Enter fullscreen mode Exit fullscreen mode

🔗来源: medium.com

Q18:即时编译 (JiT) 与提前编译 (AoT)。解释一下它们的区别。

主题:Angular
难度:⭐⭐⭐⭐⭐

JIT——在执行 TypeScript 时及时编译它:

  • 在浏览器中编译。
  • 每个文件单独编译。
  • 更改代码后和重新加载浏览器页面之前无需构建。
  • 适合本地开发。

AOT——在构建阶段编译 TypeScript:

  • 由机器本身通过命令行进行编译(更快)。
  • 所有代码一起编译,在脚本中内联 HTML/CSS。
  • 无需部署编译器(Angular 大小的一半)。
  • 更安全,原始来源不公开。
  • 适用于生产构建。

🔗来源: stackoverflow.com

Q19:您知道如何并排运行 angularJS 和 angular 吗?

主题:Angular
难度:⭐⭐⭐⭐⭐

为了并行运行这两个框架并使组件可互操作,Angular 项目附带了一个模块ngUpgrade。该模块基本上充当了适配器外观的角色,因此我们实际上并不会感觉到有两个框架并行运行。

为了实现这一点,需要四个要素协同工作:

  • 依赖注入 - 将 Angular 服务暴露到 Angular 1.x 组件中,反之亦然。
  • 组件嵌套 - Angular 1 指令可以在 Angular 2.x 组件中使用,Angular 2.x 组件也可以使用 Angular 1 指令
  • 内容投影/包含 - Angular 1 组件包含 Angular 2.x 组件,Angular 2.x 组件项目 Angular 1 指令
  • 变化检测 - Angular 1 范围摘要和 Angular >= 2.x 中的变化检测器是交错的

典型的升级过程如下:

  • 包含 Angular 和升级模块
  • 选择要升级的组件并更改其控制器和模板 Angular 2.x 语法(现在这是一个 Angular 2.x 组件)
  • 降级 Angular 2.x 组件以使其在 Angular 1.x 应用中运行
  • 选择要升级的服务,这通常需要很少的改变(特别是如果我们使用 ES2015)
  • 重复步骤 2 和 3(和 4)
  • 将 Angular 1 bootstrap 替换为 Angular 2.x bootstrap

🔗来源: blog.thoughtram.io

Q20:您能提供一些使用 ngZone 的具体示例吗?

主题:Angular
难度:⭐⭐⭐⭐⭐

当您想要使用时会有很多情况NgZone,我可以举两个例子:

  1. 当你想在 Angular 的变化检测之外运行某些操作时。比如说,我们想在用户滚动时进行一些计算,但又不想运行变化检测,那么你可以使用 NgZone:
constructor(private zone:NgZone){
   this.zone.runOutsideOfAngular(()=>{
      window.onscroll = ()=>{
       // do some heavy calculation : 
      }
    })
  }
Enter fullscreen mode Exit fullscreen mode
  1. 与上述情况完全相反,你有一个函数,它以某种方式位于 Angular 区域之外,而你希望它位于其中,就像当第三方库为你做一些事情时,你希望它绑定到你的 Angular 循环中。
this.zone.run(()=>{
    $.get('someUrl').then(()=>{
        this.myViewVariable = "updated";
    })
});
Enter fullscreen mode Exit fullscreen mode

🔗来源: stackoverflow.com

Q21:为什么angular需要使用url段?

主题:Angular
难度:⭐⭐⭐⭐⭐

UrlSegment是 URL两个斜杠之间的部分。它包含与该段相关的路径和矩阵参数

矩阵参数与路径段绑定,而查询参数与 URL 绑定。它们具有不同的语义。

考虑:

localhost:3000/heroes;id=15;foo=foo/bar/baz
// instead of localhost:3000/heroes/bar/baz?id=15&foo=foo
Enter fullscreen mode Exit fullscreen mode

这些参数与 heroes和 URL 绑定。当你访问 route.url 时,你会看到以下内容:

this.route.url.subscribe((url: UrlSegment[]) => {
  let heroes = url[0];
  let heroesMatrix = heroes.parameters();
  // heroes should contain id=15, foo=foo
  let bar = url[1].path; // 15
  let baz = url[2].path; //foo
})
Enter fullscreen mode Exit fullscreen mode

对于矩阵参数,您还可以订阅 params,而不是将它们从 url 中剥离出来。

this.paramSubscription = this.activeRoute.params.subscribe(params => {
  const bar = params['bar'];
  const baz = params['baz'];
});
Enter fullscreen mode Exit fullscreen mode

对于 Angular 应用来说,真正关心这些参数的只有我们开发者。用户并不关心。它不是一个 REST API,我们不应该遵循众所周知的语义。对于我们的 Angular 应用来说,只要我们开发者知道如何使用参数(无论是矩阵还是查询),使用哪个参数都无所谓。

🔗来源: https://stackoverflow.com

Q22:何时使用查询参数而不是矩阵参数?

主题:Angular
难度:⭐⭐⭐⭐⭐


矩阵参数和查询参数之间的差异不仅仅是约定。

主要区别在于:

  • 带有查询参数的 URL 的响应不会被中介/代理缓存(目前)
  • 矩阵参数可以出现在路径中的任何位置
  • 计算相对 uri 是不同的
  • 查询参数通常被滥用来添加新动词,而不是使用资源上的现有方法
  • 矩阵参数不是资源,它们是帮助引用信息空间中难以在层次结构中表示的资源的方面

🔗来源: stackoverflow.com

感谢🙌的阅读,祝你面试顺利!
更多 FullStack 面试问答,请访问👉 www.fullstack.cafe

文章来源:https://dev.to/aershov24/22-expert-angular-interview-questions-and-answers-in-2018-1m1g
PREV
你必须知道的 60 个 Java 和 Spring 面试问题
NEXT
我希望几年前就知道的 Nginx 概念