Miscellaneous Coding of Angular and DotNet

2019-04-10

为 Angular, C# .Net 准备的面试问题

楼下一个男人病得要死,那间隔壁的一家唱着留声机,对面是弄孩子。楼上有两人狂笑;还有打牌声。河中的船上有女人哭着她死去的母亲。人类的悲欢并不相通,我只觉得他们吵闹。
–鲁迅

C#

如何使用 C# 中的多线程功能

class Program
    {
        static void Main(string[] args)
        {
            Thread t1 = new Thread(new ThreadStart(WithOut));
            Thread t2 = new Thread(new ParameterizedThreadStart(With));
            t1.IsBackground = true;
            t2.IsBackground = true;
            t1.Start();
            t2.Start("Hello");
        }

        public static void WithOut()
        {
            // Run
        }

        public static void With(object data)
        {
            // Run with arg
            string str = data as string; // Hello
        }
    } 

扩展:什么是 Sleep,什么是 Wait,有什么区别?

什么是线程池

因为线程开启结束需要额外的开销,线程池可以简化这一步骤,一个被维护的线程池会在后台运行,对刚加入的任务进行排队。线程执行完不会被立即销毁,通过这种方式我们既可以在后台执行任务,又可以免除线程创建和销毁所带来的开销。

class Program
    {
        static void Main(string[] args)
        {
            ThreadPool.QueueUserWorkItem(TestMethod, "Hello");
            Console.ReadKey();
        }

        public static void TestMethod(object data)
        {
            string str = data as string;
            Console.WriteLine(str);
        }
    }

GC

JavaScript 的 GC 是怎么运作的

可触及的 (Reachability) JS 的垃圾清理是自上而下单向运行的,所有不能被 Root 访问到的对象都是可以被清理的对象,这相比引用计数 (Reference Count) 的方法有很多优势,比如说可以处理相互引用的对象,比如说能在不访问孤岛就能整体剔除 (Unreachable island) 但是缺点是必须从头开始。

优化:

扩展:有什么优化方法是 JS 没有用到但是 c# 用到的?

CS 的 GC 是怎么运作的

引用项,如果一个变量没有任何引用的时候就可以被回收,GC 会寻找合适的时机对其进行回收。

GC 不能回收非托管资源,对于非托管资源一般都实现了IDisposable接口,然后使用using关键字进行资源的回收。

怎么才能手动触发垃圾清理? GC.Collect()

扩展:什么是非托管资源 (Unmanaged Resources),怎么使用非托管资源?

TypeScript

如何编写 OverLoad 函数的类型文件

就和 Java 的重写方法一样,直接声明多个一样的函数,带有不同的变量。

如何写自我循环的 TypeScript Nested 类型

用外部的泛型声明好,就是用T来代替本身。然后实现泛型。

扩展:自我循环的类型为什么不能编写

TypeScript 的编译器会先编译每一个类型然后再处理调用,无限循环的类型是不能直接写的。但是如果泛型已经先编译好,就可以实现了。

如何声明下面的函数来检测出错误

const func = (obj, key) => {
    return obj[key].toString();
}
 
let x = { a: 1, b: 2, c: 3, d: 4 };
 
getProperty(x, "a"); // OK
getProperty(x, "m"); // Error

如何声明 on 函数的根据 event 结果不同的函数

.d.ts 的情况下可以进行 overload

on(event: "close", listener: () => void): this;
on(event: "data", listener: (chunk: any) => void): this;
on(event: "end", listener: () => void): this;
on(event: "readable", listener: () => void): this;
on(event: "error", listener: (err: Error) => void): this;
on(event: string | symbol, listener: (...args: any[]) => void): this;

这个例子来自 @types/nodestream 实现

正常时可以用 extend, keyof, A[T] 这样的技术来处理。

type list = {
    close: () => void;
    data: (chunk: any) => void; 
    // rest of them...
}

const on = <T extends keyof list>(event: T, listener: list[T]) => {
    // do something...
};

Angular2

Angular 应用的生命周期都有什么

适用于组件 (component) 和指令 (directive) 的生命周期:

适用于指令的生命周期:

扩展:一个组件的生命周期调用顺序是什么?

ngOnChanges > ngOnInit > ngDoCheck > ngAfterContentInit > ngAfterContentChecked > ngAfterViewInit > ngAfterViewChecked > ngOnDestroy

Angular 的依赖注入怎么使用

扩展:依赖注入有什么好处

依赖注入的本质是控制反转 (Inversion of control, IoC) 原则。使用依赖注入之后应用的接口会实现松耦合,在接口不变的前提下,我们可以任意替换组件的具体实现。

扩展:注册 Provider 的时候 UseClass 和 UseExisting 有什么区别

UseExisting 会使用单一实例。

Angular 是怎么更新子组件的

自上而下更新,当其中一个组件发生变化的时候所有的子组件都会被依次检查,这是 Default 模式的检查。

扩展:Angular 的默认更新模式是什么

Default

扩展:还有什么更新模式,如果切换更新模式

OnPush 区别是当 OnPush 的输入没有变化的时候,所有子组件的检查都会被跳过。

changeDetection: ChangeDetectionStrategy.OnPush

扩展:如何 detach 组件,如何回到检查队列中

constructor(private ref: ChangeDetectorRef) {
    ref. ...
}

扩展:用这样的模式如何实现频繁变化需要手动触发更新的组件。

ref.detach();
...do
ref.reattach();
Go Back

随便看看 :D