Angular25 组件的生命周期钩子
1 生命周期钩子概述
组件共有9个生命周期钩子
1.1 生命周期的执行顺序
技巧01:测试时父组件传递对子组件的输入属性进行初始化操作
- import { Component, Input, SimpleChanges, OnInit, OnChanges, DoCheck, AfterContentChecked, AfterViewInit, AfterContentInit, AfterViewChecked, OnDestroy } from '@angular/core';
- let logIndex : number = 1;
- @Component({
- selector: 'life',
- templateUrl: './life.component.html',
- styleUrls: ['./life.component.scss']
- })
- export class LifeComponent implements OnInit, OnChanges, DoCheck,
- AfterContentInit, AfterContentChecked, AfterViewInit,
- AfterViewChecked, OnDestroy {
- @Input()
- name : string;
- logIt(msg : String) {
- console.log(`#${logIndex++} - ${msg}`);
- }
- constructor() {
- this.logIt("name属性在constructor里面的值为: " + this.name);
- }
- ngOnInit() {
- this.logIt("ngOnInit");
- }
- ngOnChanges(changes : SimpleChanges){
- this.logIt("name属性在ngOnChanges里面的值为: " + this.name);
- }
- ngDoCheck() {
- this.logIt("ngDoCheck");
- }
- ngAfterContentInit() {
- this.logIt("ngAfterContentInit");
- }
- ngAfterContentChecked() {
- this.logIt("ngAfterContentChecked");
- }
- ngAfterViewInit() {
- this.logIt("ngAfterViewInit");
- }
- ngAfterViewChecked() {
- this.logIt("ngAfterViewChecked");
- }
- ngOnDestroy() {
- this.logIt("ngOnDestroy");
- }
- }
TS
2 ngOnChanges
2.1 可变对象和不可变对象
在JavaScript中string类型是不可变对象,自定义的对象是可变对象;例如:
var a = "hello"; -> 变量a中存储的是字符串“hello”对应的内存地址
a = "warrior"; -> 变量a中存储的是字符串“warrior”对应的内存地址
结论:将不同的字符串赋值给同一个变量时,变量的值会发生改变;所以string类型是不可变类型【PS: 跟Java一样】
var user : {name : string} = {name : "warrior"}; -> 变量user中存储的是对象{name : "warrior"}对应的内存地址
user.name = "fury"; -> 变量user中还是存储的对象{name : "fury”}对应的内存地址,而且{name : "warrior"}和{name : "fury”}是同一个对象,所以他们的内存地址相同,故变量user中存储的值没有发生改变,改变的仅仅是变量user所指向的那个对象中的内容而已
结论:修改一个对象的内容并不会改变这个对象的内存地址,所以对象是可变对象
2.2 ngOnChanges
当输入属性的值发生改变时就会触发ngOnChanges
技巧01:如果输入属性的类型是一个对象时,需要区分是可变对象还是不可变对象,只有不可变对象时才会触发ngOnChanges;总之记住只要输入属性的值发生改变才会触发ngOnChanges
技巧02:ngOnChanges方法需要传入一个 SimpleChanges 类型的参数,可以利用该参数来查看输入属性改变前后的值,以及是否是初次赋值
技巧03:JSON.stringfy() 方法在将数据转化成JSON时可以进行格式化,例如
- ngOnChanges(simpleChanges : SimpleChanges) {
- console.log(JSON.stringify(simpleChanges, null, 2));
- }
2.2.1 子组件代码
- <div class="panel panel-primary">
- <div class="panel-heading">子组件</div>
- <div class="panel-body">
- <p>问候语:{{greeting}}</p>
- <p>姓名:{{user.name}}</p>
- <p>年龄:{{age}}</p>
- <p>
- 消息:<input type="text" name="message" [(ngModel)]="message" />
- </p>
- </div>
- <div class="panel-footer">{{currentDate | date : "yyyy-MM-dd HH:mm:ss"}}</div>
- </div>
HTML
- import { Component, OnInit, EventEmitter, Output, Input, OnChanges, SimpleChanges } from '@angular/core';
- @Component({
- selector: 'child',
- templateUrl: './child.component.html',
- styleUrls: ['./child.component.scss']
- })
- export class ChildComponent implements OnInit, OnChanges {
- @Input()
- greeting : string;
- @Input()
- user : {name : string};
- @Input()
- age : number;
- message : string;
- currentDate : Date;
- constructor() { }
- ngOnInit() {
- this.currentDate = new Date();
- setInterval(() => {
- this.currentDate = new Date();
- }, 1000);
- }
- ngOnChanges(simpleChanges : SimpleChanges) {
- console.log(JSON.stringify(simpleChanges, null, 2));
- }
- }
TS
2.2.2 父组件代码
- <div class="panel panel-primary">
- <div class="panel-heading">父组件</div>
- <div class="panel-body">
- <p>
- 问候语:<input type="text" name="greeting" [(ngModel)]="greeting" />
- </p>
- <p>
- 姓名:<input type="text" name="name" [(ngModel)]="user.name" />
- </p>
- <p>
- 年龄:<input type="number" [(ngModel)]="age" />
- </p>
- <child [greeting]="greeting" [user]="user" [age]="age"></child>
- </div>
- <div class="panel-footer">{{currentDate | date : "yyyy-MM-dd HH:mm:ss"}}</div>
- </div>
HTML
- import { Component, OnInit } from '@angular/core';
- @Component({
- selector: 'parent',
- templateUrl: './parent.component.html',
- styleUrls: ['./parent.component.scss']
- })
- export class ParentComponent implements OnInit {
- greeting : string = "Hello";
- user : {name : string} = {name : "王杨帅"};
- age : number = 8;
- currentDate : Date;
- constructor() { }
- ngOnInit() {
- this.currentDate = new Date();
- setInterval(() => {
- this.currentDate = new Date();
- }, 1000);
- }
- }
TS
2.2.3 效果图
3 ngDoCheck
3.1 变更检测机制
angular中由zone.js去负责监听浏览器中所有异步事件(事件[单击、双击]、定时器、ajax)来保证模板和组件属性的变化时同步的;
只要zone.js检测到有异步事件发生时所有监测机制是默认检测机制的组件都会触发ngDoCheck
应用:当输入属性的类型是可变对象时,即使可变对象的内容发生了变化 ngOnchanges 也不会被调用,但是 ngDoCheck 会被调用;所以我们可以利用 ngDoCheck 来检测可变对象的变化
坑01:zone.js检测到任何一个组件有异步事件发生都会让所有采用默认变更检测机制的组件执行 ngDoCheck,所以 ngDoCheck 方法要慎用,而且逻辑不能太复杂,不然会影响性能
3.2 变更检测策略
3.2.1 default
angular默认的变更检测策略
如果所有的组件都是默认的变更检测策略,那么当一个组件发生改变时angular会对所有的组件进行变更检查
3.2.2 onPush
待更新...
3.3 代码汇总
3.3.1 父组件代码
- <div class="panel panel-primary">
- <div class="panel-heading">父组件</div>
- <div class="panel-body">
- <p>
- 问候语:<input type="text" name="greeting" [(ngModel)]="greeting" />
- </p>
- <p>
- 姓名:<input type="text" name="name" [(ngModel)]="user.name" />
- </p>
- <p>
- 年龄:<input type="number" [(ngModel)]="age" />
- </p>
- <child [greeting]="greeting" [user]="user" [age]="age"></child>
- </div>
- <div class="panel-footer">{{currentDate | date : "yyyy-MM-dd HH:mm:ss"}}</div>
- </div>
HTML
- import { Component, OnInit } from '@angular/core';
- @Component({
- selector: 'parent',
- templateUrl: './parent.component.html',
- styleUrls: ['./parent.component.scss']
- })
- export class ParentComponent implements OnInit {
- greeting : string = "Hello";
- user : {name : string} = {name : "王杨帅"};
- age : number = 8;
- currentDate : Date;
- constructor() { }
- ngOnInit() {
- this.currentDate = new Date();
- // setInterval(() => {
- // this.currentDate = new Date();
- // }, 1000);
- }
- }
TS
3.3.2 子组件代码
- <div class="panel panel-primary">
- <div class="panel-heading">子组件</div>
- <div class="panel-body">
- <p>问候语:{{greeting}}</p>
- <p>姓名:{{user.name}}</p>
- <p>年龄:{{age}}</p>
- <p>
- 消息:<input type="text" name="message" [(ngModel)]="message" />
- </p>
- </div>
- <div class="panel-footer">{{currentDate | date : "yyyy-MM-dd HH:mm:ss"}}</div>
- </div>
HTML
- import { Component, OnInit, EventEmitter, Output, Input, OnChanges, SimpleChanges } from '@angular/core';
- import { DoCheck } from '@angular/core/src/metadata/lifecycle_hooks';
- @Component({
- selector: 'child',
- templateUrl: './child.component.html',
- styleUrls: ['./child.component.scss']
- })
- export class ChildComponent implements OnInit, OnChanges, DoCheck {
- @Input()
- greeting : string;
- @Input()
- user : {name : string};
- oldName : string; // 存储上一次的值
- changeNum : number = 0; // 非本组件触发ngDoCheck方法的次数
- changeDetected : boolean; // 是否是本组件触发ngDoCheck方法
- @Input()
- age : number;
- message : string;
- currentDate : Date;
- constructor() { }
- ngOnInit() {
- this.currentDate = new Date();
- // setInterval(() => {
- // this.currentDate = new Date();
- // }, 1000);
- }
- ngOnChanges(simpleChanges : SimpleChanges) {
- console.log(JSON.stringify(simpleChanges, null, 2));
- }
- ngDoCheck() : void {
- // 如果检测到是本组件的输入属性变化
- if (this.user.name !== this.oldName) {
- this.changeDetected = true;
- console.log("ngDoCheck: user.name 从 "+ this.oldName +" 变成了 "+ this.user.name +" ");
- this.oldName = this.user.name;
- }
- if (this.changeDetected) {
- this.changeNum = 0; // 本组件触发的ngDoCheck就进行清零操作
- } else { // 非本组件触发的ngDoCheck方法就进行加一操作
- this.changeNum = this.changeNum + 1;
- console.log("ngDoCheck: user.name没有变化,ngDoCheck方法被调用了" + this.changeNum + "次");
- }
- this.changeDetected = false;
- }
- }
TS
3.3.3 效果展示
4 ngAfterViewInit 和 ngAfterViewChecked
4.1 父组件调用子组件的方法
这两个钩子是在组件的模板已经完全组装好后才会被调用,所以在这两个钩子中不能修改和模板相关的数据信息
4.1.1 利用模板变量实现
在父组件的视图模板中为子组件添加一个模板变量,然后在父组件中就可以利用这个模板变量来调用子组件的方法了
4.1.2 利用子组件的实例实现
在父组件的视图模板中为子组件添加一个模板变量,然后在组件类中利用@ViewChild来实例化一个子组件实例,再通过这个实例在父组件类中调用子组件的方法
4.2 调用顺序
4.2.1 组件中这两个钩子的调用顺序
组件被加载 -> 视图初始化钩子
-> 视图变更检测钩子
-> 视图变更检测钩子
技巧01:组件被调用时先要执行视图初始化钩子,再执行视图变更检测钩子,而且视图初始化钩子只会被调用一次
4.2.2 父子组件中的调用顺序
父组件被加载 -> 子组件被加载 -> 子组件视图初始化钩子 -> 父组件视图初始化钩子
-> 子组件视图变更检测钩子 -> 父组件视图变更检测钩子
-> 子组件视图变更检测钩子 -> 父组件视图变更检测钩子
技巧01:先执行执行子父组件的视图初始化钩子 -> 再子父组件的视图变更检测钩子 -> 循环调用子父组件的视图变更检测钩子
技巧02:视图变更检测钩子的调用是先调用子组件的再调用父组件的
技巧03:视图初始化钩子的调用是先调用子组件的再调用父组件的
坑01:这两个钩子都是在视图组装好之后触发的
4.2.3 修改数据
视图初始化钩子和视图变更检测钩子中不能修改和视图相关的数据信息 -> 可以利用一个定时器来实现,因为利用定时器可以让操作在另外一个JavaScript运行周期中运行
4.2.4 代码汇总
》父组件
- <div class="panel panel-primary">
- <div class="panel-heading">父组件</div>
- <div class="panel-body">
- <child #child1></child>
- <child #child2></child>
- <button (click)="child2.greeting('Zeus')">调用子组件child2的方法</button>
- <br />
- <p>{{info}}</p>
- </div>
- <div class="panel-footer">{{currentDate | date : "yyyy-MM-dd HH:mm:ss"}}</div>
- </div>
HTML
- import { Component, OnInit, ViewChild } from '@angular/core';
- import { ChildComponent } from './child/child.component';
- import { AfterViewInit, AfterContentChecked } from '@angular/core/src/metadata/lifecycle_hooks';
- @Component({
- selector: 'parent',
- templateUrl: './parent.component.html',
- styleUrls: ['./parent.component.scss']
- })
- export class ParentComponent implements OnInit, AfterViewInit, AfterContentChecked {
- @ViewChild("child1")
- child1 : ChildComponent;
- info : string;
- currentDate : Date;
- constructor() { }
- ngOnInit() {
- this.currentDate = new Date();
- // setInterval(() => {
- // this.currentDate = new Date();
- // }, 1000);
- setInterval(() => {
- this.child1.greeting("Warrior");
- }, 5000);
- }
- ngAfterViewInit() : void {
- console.log("父组件视图初始化完毕");
- // this.info = "good boy"; // 视图初始化钩子中不能修改和视图相关的数据信息
- // setTimeout(() => { // 上面一行代码的解决办法
- // this.info = "王杨帅";
- // }, 5000);
- }
- ngAfterContentChecked() : void {
- console.log("父组件视图变更检测完毕")
- this.info = "good boy"; // 视图变更检测钩子中可以修改和视图相关的数据信息
- }
- }
TS
》子组件
- <div class="panel panel-primary">
- <div class="panel-heading">子组件</div>
- <div class="panel-body">
- </div>
- <div class="panel-footer">{{currentDate | date : "yyyy-MM-dd HH:mm:ss"}}</div>
- </div>
HTML
- import { Component, OnInit, DoCheck, EventEmitter, Output, Input, OnChanges, SimpleChanges, AfterViewInit, AfterContentChecked } from '@angular/core';
- @Component({
- selector: 'child',
- templateUrl: './child.component.html',
- styleUrls: ['./child.component.scss']
- })
- export class ChildComponent implements OnInit, AfterViewInit, AfterContentChecked {
- currentDate : Date;
- constructor() { }
- ngOnInit() {
- this.currentDate = new Date();
- // setInterval(() => {
- // this.currentDate = new Date();
- // }, 1000);
- }
- greeting(info : string) : void {
- console.log("Hello " + info);
- }
- ngAfterViewInit() : void {
- console.log("子组件视图初始化完毕");
- }
- ngAfterContentChecked() : void {
- console.log("子组件视图变更检测完毕")
- }
- }
TS
5 ngAfterContentInit 和 ngAfterContentChecked
5.1 内容投影
5.1.1 需求
如何将父组件的数据传递到子组件
5.1.2 方案
》利用路由解决
》利用子组件的输入属性解决
》利用服务解决
》利用投影解决 【推荐】
5.1.3 投影编程步骤
》子组件的视图
在子组件的视图中添加 ng-content 标签
》父组件视图
在父组件中添加子组件标签,并在子组件标签内编写需要进行投影的代码;当系统运行后会自动将需要投影的代码投影到子组件的 ng-content 标签里面
技巧01:ng-content 仅仅是一个占据位置的标签,系统运行后投影的内容会代替 ng-content 的位置
》如何实现多个投影
为子组件的每个 ng-content 标签添加 select 属性
技巧01: select 的属性值格式是 “.属性值”
在父组件视图中使用子组件的内部利用class为其指定投影到那个 ng-content
》代码汇总
- <div class="panel panel-primary">
- <div class="panel-heading">子组件</div>
- <div class="panel-body">
- <div style="border: 1px solid red;">
- <ng-content select=".red"></ng-content>
- </div>
- <hr />
- <div style="border: 1px solid green">
- <ng-content select=".green"></ng-content>
- </div>
- </div>
- <div class="panel-footer">{{currentDate | date : "yyyy-MM-dd HH:mm:ss"}}</div>
- </div>
子组件HTML
- <div class="panel panel-primary">
- <div class="panel-heading">父组件</div>
- <div class="panel-body">
- <child>
- <div class="red">
- 我是父组件传过来的数据【放到子组件的红框中】
- </div>
- <div class="green">
- 我是父组件传过来的数据02【放到子组件的绿框中】
- </div>
- </child>
- </div>
- <div class="panel-footer">{{currentDate | date : "yyyy-MM-dd HH:mm:ss"}}</div>
- </div>
父组件HTML
5.2 执行顺序
5.2.1 同一组件中这两个钩子的调用顺序
先调用投影内容初始化钩子 -> 再调用投影内容变更检测钩子
5.2.2 父子组件中的这两个钩子的调用顺序
先调用父组件中的钩子 -> 再调用子组件的的钩子
技巧01:投影内容相关的两个钩子在父子组件中的调用顺序和视图相关的两个钩子在父子组件中的调用顺序恰恰相反
5.2.3 修改数据
投影相关的两个钩子可以修改和视图相关的数据信息
愿意:投影相关的两个钩子是在视图组装完毕之前调用的,而视图相关的两个钩子是在视图组装完毕后调用的
5.2.4 代码汇总
》父组件代码
- <div class="panel panel-primary">
- <div class="panel-heading">父组件</div>
- <div class="panel-body">
- <child>
- <div class="red">
- 我是父组件传过来的数据【放到子组件的红框中】
- </div>
- <div class="green">
- 我是父组件传过来的数据02【放到子组件的绿框中】
- </div>
- </child>
- </div>
- <div class="panel-footer">{{currentDate | date : "yyyy-MM-dd HH:mm:ss"}}</div>
- </div>
HTML
- import { Component, OnInit, ViewChild } from '@angular/core';
- import { ChildComponent } from './child/child.component';
- import { AfterViewInit, AfterContentChecked, AfterContentInit, AfterViewChecked } from '@angular/core/src/metadata/lifecycle_hooks';
- @Component({
- selector: 'parent',
- templateUrl: './parent.component.html',
- styleUrls: ['./parent.component.scss']
- })
- export class ParentComponent implements OnInit,
- AfterContentInit, AfterContentChecked,
- AfterViewInit, AfterViewChecked {
- @ViewChild("child1")
- child1 : ChildComponent;
- currentDate : Date;
- constructor() { }
- ngOnInit() {
- this.currentDate = new Date();
- // setInterval(() => {
- // this.currentDate = new Date();
- // }, 1000);
- }
- ngAfterContentInit() : void {
- console.log("父组件投影内容初始化完毕");
- }
- ngAfterContentChecked() : void {
- console.log("父组件投影内容变更检测完毕");
- }
- ngAfterViewChecked() : void {
- console.log("父组件视图内容变更检测完毕");
- }
- ngAfterViewInit() : void {
- console.log("父组件视图初始化完毕");
- }
- }
TS
》子组件代码
- <div class="panel panel-primary">
- <div class="panel-heading">子组件</div>
- <div class="panel-body">
- <div style="border: 1px solid red;">
- <ng-content select=".red"></ng-content>
- </div>
- <hr />
- <div style="border: 1px solid green">
- <ng-content select=".green"></ng-content>
- </div>
- <p>{{info}}</p>
- </div>
- <div class="panel-footer">{{currentDate | date : "yyyy-MM-dd HH:mm:ss"}}</div>
- </div>
HTML
- import { Component, OnInit, DoCheck,AfterViewChecked, EventEmitter, AfterContentInit, Output, Input, OnChanges, SimpleChanges, AfterViewInit, AfterContentChecked } from '@angular/core';
- @Component({
- selector: 'child',
- templateUrl: './child.component.html',
- styleUrls: ['./child.component.scss']
- })
- export class ChildComponent implements OnInit,
- AfterContentInit, AfterContentChecked,
- AfterViewInit, AfterViewChecked {
- currentDate : Date;
- info : string;
- constructor() { }
- ngOnInit() {
- this.currentDate = new Date();
- // setInterval(() => {
- // this.currentDate = new Date();
- // }, 1000);
- }
- ngAfterContentInit() : void {
- console.log("子组件投影内容初始化完毕");
- // this.info = "warrior"; // 投影内容初始化完毕时可以修改视图相关数据信息
- }
- ngAfterContentChecked() : void {
- console.log("子组件投影内容变更检测完毕");
- this.info = "fury"; // 投影内容变更检测完毕时可以修改视图相关数据信息
- }
- ngAfterViewChecked() : void {
- console.log("子组件视图内容变更检测完毕");
- // this.info = "warrior";
- }
- ngAfterViewInit() : void {
- console.log("子组件视图初始化完毕");
- }
- }
TS
5.2.5 效果展示
Angular25 组件的生命周期钩子的更多相关文章
- Vue_(组件)实例生命周期钩子
Vue生命周期中文文档 传送门 Vue生命周期:Vue实例从创建到销毁的过程,称为Vue的生命周期: Vue生命周期钩子:又称为Vue生命周期钩子方法/函数,是Vue为开发者提供的方法,我们可以通过这 ...
- 通俗易懂了解Vue组件的生命周期
1.前言 在使用vue2.0进行日常开发中,我们总有这样的需求,我就想在页面刚一加载出这个表格组件时就发送请求去后台拉取数据,亦或者我想在组件加载前显示个loading图,当组件加载出来就让这个loa ...
- Vue项目的创建、路由、及生命周期钩子
目录 一.Vue项目搭建 1.环境搭建 2.项目的创建 3.pycharm配置并启动vue项目 4.vue项目目录结构分析 5.Vue根据配置重新构建依赖 二.Vue项目创建时发生了什么 三.项目初始 ...
- [Vuejs] 组件 v-if 和 v-show 切换时生命周期钩子的执行
v-if 初始渲染 初始值为 false 组件不会渲染,生命周期钩子不会执行,v-if 的渲染是惰性的. 初始值为 true 时,组件会进行渲染,并依次执行 beforeCreate,created, ...
- Angular组件生命周期——生命周期钩子
生命周期钩子介绍: 1.ngOnChange:响应组件输入值发生变化时触发的事件. 2.ngOnInit:用于数据绑定输入属性之后初始化组件,在第一次ngOnChange之后被调用. a. 组件构造后 ...
- Vue ---- 组件文件分析 组件生命周期钩子 路由 跳转 传参
目录 Vue组件文件微微细剖 Vue组件生命周期钩子 Vue路由 1.touter下的index.js 2.路由重定向 3.路由传参数 补充:全局样式导入 路由跳转 1. router-view标签 ...
- Vue 组件生命周期钩子
Vue 组件生命周期钩子 # 1)一个组件从创建到销毁的整个过程,就称之为组件的生命周期 # 2)在组件创建到销毁的过程中,会出现众多关键的时间节点, 如: 组件要创建了.组件创建完毕了.组件数据渲染 ...
- 简单记录一下vue生命周期及 父组件和子组件生命周期钩子执行顺序
首先,vue生命周期可以用下图来简单理解 当然这也是官方文档的图片,详细的vue周期详解请参考这里 然而当同时存在父子组件的时候生命周期钩子是如何执行的呢? 请看下文: 加载渲染过程父beforeCr ...
- Vue生命周期 钩子函数和组件传值
Vue生命周期 钩子函数 每个 Vue 实例在被创建时都要经过一系列的初始化过程——例如,需要设置数据监听.编译模板.将实例挂载到 DOM 并在数据变化时更新 DOM 等. 同时在这个过程中也会运行一 ...
随机推荐
- 关于15桥梁课程1&2的笔记以及待做事项的梳理
1.指针所占用的空间是固定的 2.void *malloc(sizeof(int)); (这玩意耗时间,老师说通过内存池解决) free(p);free(p); 两次free()报错,正确的做法: ...
- 脚本工具---自动解析mysql建表语句,生成sqlalchemy表对象声明
常规建表语句: CREATE TABLE `test_table` ( `id` int(11) NOT NULL, `name` char(64) NOT NULL, `password` char ...
- openfaas k8s 集成
备注 k8s 1.6 以下版本与k8s 1.6 以上版本会有一些简单的区别 1. 克隆k8s 部署文档 https://github.com/openfaas/faas-netes 2. 创 ...
- openfaas 简单试用
1. 安装 faas-cli 参考以前文章,或者使用官方的shell脚本 2. 简单例子 mkdir rong cd rong faas-cli new rong --lang python / ...
- Eclipse 进入前选择Workspace
如果选择了默认的Workspace会有一个问题. 打开一个workspace的时候,再次打开eclipse会报错,提示当前workspace正在被使用,然后让选择workspace. 最好的方法是每次 ...
- lbypmall系统备份恢复
打开phpmyadmin 1.数据库创建,在服务器上创建lbypmall数据库,排序规则utf8_general_ci 2.mysqldump -u root -p lbypmall > lby ...
- 找到最大或最小的N个元素
问题: 想在某个集合中找到最大或最小的N个元素 解决方案: heapq 模块中有两个函数 nlargest() 和 nsmallest() 它们正是我们需要的.例如: import heapq n ...
- nginx 端口转发
nginx 端口转发 默认nginx监听的端口是8080,想通过配置nginx访问80直接跳转到nginx,以下是配置方法: [root@localhost vhost]# cat tomcat.jo ...
- N个节点的二叉树有多少种形态(卡特兰数)
N个节点的二叉树有多少种形态 这是一道阿里的面试题.其实算不上新鲜,但是我之前没关注过,如今碰到了,就顺便探讨下这个问题吧:) 拿到这个题,首先想到的是直接写出表达式肯定不行,所以有必要从递推入手 ...
- 1024 Palindromic Number
题意: 给出一个数N(N<=10^10),最多可操作K次(K<=100),每次操作为这个数和其反转之后的数相加,若得到的结果为回文数,则输出:若在K次迭代后仍然不是回文数,在输出第K次操作 ...