2019-04-10
楼下一个男人病得要死,那间隔壁的一家唱着留声机,对面是弄孩子。楼上有两人狂笑;还有打牌声。河中的船上有女人哭着她死去的母亲。人类的悲欢并不相通,我只觉得他们吵闹。
–鲁迅
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,有什么区别?
Monitor.Pulse()
或者 Monitor.PulseAll()
因为线程开启结束需要额外的开销,线程池可以简化这一步骤,一个被维护的线程池会在后台运行,对刚加入的任务进行排队。线程执行完不会被立即销毁,通过这种方式我们既可以在后台执行任务,又可以免除线程创建和销毁所带来的开销。
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);
}
}
可触及的 (Reachability) JS 的垃圾清理是自上而下单向运行的,所有不能被 Root 访问到的对象都是可以被清理的对象,这相比引用计数 (Reference Count) 的方法有很多优势,比如说可以处理相互引用的对象,比如说能在不访问孤岛就能整体剔除 (Unreachable island) 但是缺点是必须从头开始。
优化:
扩展:有什么优化方法是 JS 没有用到但是 c# 用到的?
引用项,如果一个变量没有任何引用的时候就可以被回收,GC 会寻找合适的时机对其进行回收。
GC 不能回收非托管资源,对于非托管资源一般都实现了IDisposable接口,然后使用using关键字进行资源的回收。
怎么才能手动触发垃圾清理? GC.Collect()
扩展:什么是非托管资源 (Unmanaged Resources),怎么使用非托管资源?
就和 Java 的重写方法一样,直接声明多个一样的函数,带有不同的变量。
用外部的泛型声明好,就是用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
.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/node
的stream
实现
正常时可以用 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...
};
适用于组件 (component) 和指令 (directive) 的生命周期:
适用于指令的生命周期:
扩展:一个组件的生命周期调用顺序是什么?
ngOnChanges
> ngOnInit
> ngDoCheck
> ngAfterContentInit
> ngAfterContentChecked
> ngAfterViewInit
> ngAfterViewChecked
> ngOnDestroy
扩展:依赖注入有什么好处
依赖注入的本质是控制反转 (Inversion of control, IoC) 原则。使用依赖注入之后应用的接口会实现松耦合,在接口不变的前提下,我们可以任意替换组件的具体实现。
扩展:注册 Provider 的时候 UseClass 和 UseExisting 有什么区别
UseExisting 会使用单一实例。
自上而下更新,当其中一个组件发生变化的时候所有的子组件都会被依次检查,这是 Default 模式的检查。
扩展:Angular 的默认更新模式是什么
Default
扩展:还有什么更新模式,如果切换更新模式
OnPush 区别是当 OnPush 的输入没有变化的时候,所有子组件的检查都会被跳过。
changeDetection: ChangeDetectionStrategy.OnPush
扩展:如何 detach
组件,如何回到检查队列中
constructor(private ref: ChangeDetectorRef) {
ref. ...
}
扩展:用这样的模式如何实现频繁变化需要手动触发更新的组件。
ref.detach();
...do
ref.reattach();