Wednesday, December 30, 2020

Android issue index

Can not perform this action after onSaveInstanceState

https://www.jianshu.com/p/94f903bfd9f6

https://blog.csdn.net/edisonchang/article/details/49873669

https://blog.csdn.net/ranxiedao/article/details/8214936?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-2.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromBaidu-2.control

FragmentTransaction的commit和commitAllowingStateLoss的區別 

FragmentTransaction的提交方法

sqlite: Error Code : 5 (SQLITE_BUSY) (database is locked (code 5): , while compiling: PRAGMA journal_mode)

JAVA泛型通配符T,E,K,V区别,T以及Class,Class的区别

泛型是Java SE 1.5的新特性,泛型的本质是参数化类型

在Java SE 1.5之前,没有泛型的情况的下,通过对类型Object的引用来实现参数的“任意化”,“任意化”带来的缺点是要做显式的强制类型转换,而这种转换是要求开发者对实际参数类型可以预知的情况下进行的。对于强制类型转换错误的情况,编译器可能不提示错误,在运行的时候才出现异常,这是一个安全隐患。

泛型概念

操作的数据类型被指定为一个参数

参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口、泛型方法。

Java语言引入泛型的好处是安全简单


Class<T>在实例化的时候,T要替换成具体类

Class<?>它是个通配泛型,?可以代表任何类型   

<? extends T>受限统配,表示T的一个未知子类。

<? super T>下限统配,表示T的一个未知父类。


Reference:

https://www.jianshu.com/p/95f349258afb

https://github.com/LucienYang/FanxingDemo/tree/master/src/com/lyang/demo/fanxing

Monday, December 21, 2020

java static

 static variable are stored in class common memory

 引用 (reference)










From: https://openhome.cc/Gossip/Java/Static.html

Friday, December 18, 2020

簡體 科技 翻譯

文件句柄  https://baike.baidu.com/item/%E6%96%87%E4%BB%B6%E5%8F%A5%E6%9F%84

Saturday, December 12, 2020

this

this 所綁定的物件並非是函式宣告的時候所定義,而是在呼叫函式時的時機去決定 this 所指向的目標

四個規則如下

1. 預設繫結 -> 就是字面上的預設,若沒有其他三項規則下,通常 this 就是預設繫結也就是綁定到 global object,如上圖 first & second function 的 this 都屬於 global object

2. 隱含繫結 -> 當函式的呼叫是透過物件參考而呼叫的話,this 會被綁定到此物件上,而注意到的是假使是多個物件參考連結,是綁定於最後的物件,而注意到根據函式使用方式,有可能會丟失隱含繫結的綁定


3. 明確繫結 -> 不同於隱含系結須透過物件參考呼叫函式,所有的 JS 函式都可以透過 call(..) & apply(..) 來做 this 綁定


4. 硬繫結 -> 上述的系結方法都有可能遇到預料外的情況如 this 被某個 framework 給覆蓋掉,在 ES5 提供了 bind 來強制綁定,先前寫 react 的大家應該也很常使用到此方法


再來額外會影響到 this 繫結的還有透過 new 所創建出來的物件,以一個 new 的行為建立物件會有以下的行為

1. 建立一個全新的物件

2. 此物件會帶有 constructor function 的 prototype chain

3. 此物件會被設為 constructor function 中的 this

4. 除非函式自帶回傳物件,否則 new 會自動回傳新建的物件

而 this 綁定的優先順序則是從後到頭,也就是 new 物件繫結 > bind > call & apply > obj.function > default

總結

1. 是否為 new 所建立的物件,如果是則以 new 綁定的 this 為主

2. 透過 bind 硬繫結強制綁定函式與其對應的物件,注意到在 bind 參數裡面除了第一個為綁定的物件以外,後續的參數會被預設為綁定函式中的標準參數,技術上來說被稱為 currying

3. 透過 call & apply 明確指定函式運用的物件

4. 預設情況下的 this 為 global object 或者在嚴格模式執行下為 undefined

React 與 bind this 的一些心得

this





Wednesday, December 9, 2020

this 善用的方式

過去我們在寫物件內的函式時,為了確保 this 能夠正確運作會先將它賦予在另一個變數上 (that, self, vm…)。


箭頭函式本就會指向他所生成的物件上,所以可以不需要另外指向另一個物件。




不可使用的情況

apply, call, bind this 

在 Arrow function 中是被綁定的,所以套用 call 的方法時是無法修改 this。

func2.call(family); //{ming: "小明"}


不能用在建構式

由於 this 的是在物件下建立,所以箭頭函式不能像 function 一樣作為建構式的函式,如果嘗試使用此方法則會出現錯誤 (... is not a constructor)。


DOM 事件監聽

同先前說的, this 是指向所建立的物件上,如果是用在監聽 DOM 上一樣會指向 window,所以無法使用在此情境。



Prototype 中使用 this

一樣是 this 的問題,如果原型上新增一個箭頭函式,並嘗試使用 this 的話會指向全域。







綁定的 this 不同





綁定到其定義時所在的物件,我們要了解一般函式在建立時是在 window 下,所以在 window 下使

用箭頭函式自然會指向 window,要確實將箭頭函式宣告在物件內部,這樣 this 才會指向該物件。 



這個範例稍作複雜些,但只是要解釋不同建立方式的差異,注意:如果 不是 建立在物件內的函式,並不會影響箭頭函示的 this:

func() 是最外層的函式,他對於內層的箭頭不會有影響。
func2() 是包覆在內層的函式,但由於箭頭函式不是在物件內,所以沒有影響。
func3() 是呼叫在物件內的函式,因此箭頭函式會是使用它所在的物件。

縮寫的函式

另外注意:物件縮寫形式的函式也是屬於 function,所以依然能夠產生作用域。



Friday, December 4, 2020

Circular Linked List

 






insert_node

=====================================================================

void insert_node(Node **start, int insert_after_value, int value)
{
	Node *current = *start; 
	
	do {
		if(insert_after_value == current->data) {
			Node *new_node = (Node*)malloc(sizeof(Node));	
			new_node->data = value;
			new_node->next = NULL;
			if(current->next == *start) {
				current->next = new_node;
				new_node->next = *start;
				break;
			}
			else {
				new_node->next = current->next;
				current->next = new_node;
				break;
			}
		}
		current = current->next;
	}while(current != *start);
}
=====================================================================
add_node
=====================================================================
void add_node(Node **start, int value)
{
	Node *new_node = (Node*)malloc(sizeof(Node));
	new_node->data = value;
	new_node->next = NULL;
	
	if(*start == NULL) {
		*start = new_node;
		(*start)->next = *start;
		return;
	}
	else {
		Node *current;	
		current = *start;
		while(current->next != *start) {
			current = current->next;
		}
		current->next = new_node;
		new_node->next = *start;
		return;
	}
}
=====================================================================
delete node
=====================================================================
void delete_node(Node **start, int value)
{
	Node *current = *start;
	Node *temp;

	if(value == current->data) {
		*start = current->next;
		(*start)->prev = NULL;
		free(current);
		return;
	}
	
	while(current != NULL) {
		if(current->next->data == value) {
			temp = current->next;
			current->next = current->next->next;	
			if(current->next != NULL)
				current->next->prev = current;
			free(temp);
			return;
		}
		current = current->next;
	}
}
=====================================================================
print
=====================================================================
void print_list(Node *node)
{
	Node *first_node = node;
	printf("%d ", node->data);
	node = node->next; 
	
	while(node != NULL) {
		if(node == first_node) break;
		printf("%d ", node->data); 
		node = node->next;
	}
	printf("%d\n", node->data);
}

=====================================================================
free
=====================================================================
void free_list(Node *node)
{
	int total_node = 1;
	Node *first = node;
	node = node->next;
	while(node != first) {
		node = node->next;
		total_node++;
	}

	Node *current = first;
	Node *temp;
	int i;
	for(i = 0; i < total_node; i++) {
		temp = current;
		current = current->next;
		free(temp);
	}
}
=====================================================================
inverse_print_list
=====================================================================
void inverse_print_list(Node *node)
{
	printf("Inverse List:\n");
	while(node != NULL) {
		printf("%d ", node->data); 
		node = node->prev;
	}
	printf("\n");
}
=====================================================================
main
=====================================================================
#include <stdio.h>
#include <stdlib.h>

typedef struct node
{
	int data;
	struct node *next;
	struct node *prev;
}Node;

void add_node(Node **start, int value);
void print_list(Node *node);
void insert_node(Node **start, int insert_after_value, int value);
void delete_node(Node **start, int value);
void inverse_print_list(Node *node);
void free_list(Node *node);

int main(int argc, char* argv[])
{
	// create first node "head"
	Node *head = NULL;
	add_node(&head, 5);
	add_node(&head, 128);
	add_node(&head, 41);

	// insert non-exist node, linked list would not have changed
	insert_node(&head, 77, 92);
	// insert after node of data 128
	insert_node(&head, 128, 84); 
	// insert after the last node
	insert_node(&head, 41, 97);

	// delete the first node
	delete_node(&head, 5);
	// delete the node of data 41
	delete_node(&head, 41);
	// delete the last node
	delete_node(&head, 97);

	print_list(head);
	
	Node *last = head;
	while(last->next != NULL) {
		last = last->next;
	}
	inverse_print_list(last);
	
	free_list(head);

	return 0;	
}
=====================================================================

Wednesday, December 2, 2020

Framework Design Guidelines 筆記 (3) : 情節驅動設計

 關鍵詞彙

  • scenario-driven design(情節驅動設計)
  • use cases(使用案例)
  • test-driven development, TDD(測試驅動開發)

  • 框架設計師經常犯的錯誤,是先以各種設計方法論來設計物件模型,然後為這些設計好的 API 撰寫範例程式。問題是,大多數的設計方法(包括物件導向設計)都是以可維護性為主要考量,而未著重在 API 的易用性;它們非常適合用來設計僅供內部使用的程式架構,但不適合用來設計大型框架的共用 API 層。
    • DO 先為主要情節撰寫範例程式碼,然後再從這些範例程式發展出對應的物件模型。

Framework Design Guidelines 筆記 (2) : 漸進式框架

 表示法

  • DO: 表示強烈建議、務必遵守的設計原則。
  • CONSIDER: 建議考慮這麼做。
  • DO NOT: 禁止事項。
  • AVOID: 儘量避免的做法。
  • DO 設計框架時要兼顧功能強大與容易使用。

    如 Alan Kay 所說:「簡單的東西就要有簡單的設計,而碰到複雜的情況時也應該要能應付。」(Simple things should be simple and complex things should be possible.)
  • DO 設計時應考量廣大開發人員的各種程式設計風格、需求、以及不同的技術水平。
  • DO 設計時應考量支援各種程式語言。

 漸進式框架
  • 一套框架要能同時兼顧各類開發人員、需求、和程式語言,是相當困難且昂貴的事業。以往,開發軟體元件的廠商是針對特定開發族群和特定需求來提供多種解決方案,例如微軟的 Visual Basic、MFC、ATL 等等。

    這些特定用途的 APIs 雖然強大好用,卻有個主要缺點:當開發人員要從目前的技術領域移向另一塊領域時,學習曲線會非常陡峭,因為那等於是要學習另一套新的東西。

    比較好的解決方式,是提供所謂的漸進式框架(progressive framework)。這種框架的特色是兼顧各類型的開發人員,且適用範圍較廣,從比較簡單的需求到進階的應用都能應付。

    .NET Framework 即屬於漸進式框架,它有單一的程式撰寫模型,支援廣泛類型的應用需求與技術層次,學習曲線也較為緩和,能夠由簡入繁、循序漸進。

Framework Design Guidelines 筆記 (1) : 優良框架的特徵

撰寫一般的 app code 時,多以結果導向,即程式能跑、功能正確就行,至於 end users 看不到的程式碼,自己想怎麼寫就怎麼寫。尤其在專案時程很趕,與時間賽跑的情況下(哪個案子不是這樣?),哪還有閒功夫去琢磨:這個變數怎麼命名比較好、那些 code 是否要抽離成共用類別或函式、有哪些 patterns 可以 reuse 呢?

優良框架的特徵

1. 優良的框架一定很精簡

大部分的框架都不缺功能,因為只要需求明確,增加功能就很容易。 另一方面,當開發過程中出現時程壓力、功能蔓延(feature creep)等問題,或想要滿足每一項枝微末節的需求時,簡單性(simplicity)通常就會被犧牲掉。 如果多考慮一下設計的複雜性,你會發現,把目前版本的一些功能砍掉,並將時間花在思考下一個版本該如何設計才適當,這麼做通常會有比較好的結果。 如框架設計師常說的:「功能隨時可以加,但要將它移除可就難了。」

2. 優良的框架須付出較高的設計成本

框架設計應該是開發流程中的一項明確且專屬的工作,因為這項工作需要謹慎規劃、組織人力、並有效執行,它不應流於實作過程中的附屬產品。

3. 優良的框架充滿權衡取捨

沒有所謂「完美設計」這種東西。設計其實就是一連串的權衡取捨,然後做出正確決定。你得瞭解各種選項的優點和缺點。如果在設計時都沒有碰到需要取捨的情況,那不是你發現銀彈了,而是可能很多重要的地方都沒考慮到。

4. 優良的框架會善用既有成果

5. 優良的框架能持續演進

6. 優良的框架易於整合

7. 優良的框架具備一致性


Framework Index

Framework Design Guidelines 筆記 (1) : 優良框架的特徵

Framework Design Guidelines 筆記 (2) : 漸進式框架

Framework Design Guidelines 筆記 (3) : 情節驅動設計

Framework Design Guidelines 筆記 (4): 低門檻原則


ONIE Index

 在 KVM x86_64虚拟机上安装 ONIE

ONIE:用户指南

ONIE设计规格 概述

操作系统设计

x86 CPU架构设计

ipmitool

Description

这个程序能够使你通过一个kernel设备驱动或者一个远程系统,利用 IPMI v1.5 或 IPMIv2.0 来管理本地系统的任何一个智能平台管理接口 (IPMI) 功能。

这些功能包括打印 FRU (现场可替换装置) 信息、LAN 配置、传感器读数、以及远程机架电源控 制。

一个本地系统接口的IPMI管理功能需要一个兼容 IPMI 的 kernel 驱动程序被安装以及配置。

在 linux 中,这个驱动叫做 OpenIPMI,他被 包括在了标准化分配中。

在 Solaris 系统中,这个驱动叫做 BMC,他被包括在了 Solaris 10 中。

远程控制的管理需要授权以及配置 IPMI-over-LAN 接口。根据每个系统独特的需要,它可以通过系统接口来使 LAN 接口使用 ipmitool。


Reference

https://lockless.github.io/2018/09/17/IPMI-Command/#more

n8n index

 【n8n免費本地端部署】Windows版|程式安裝x指令大補帖  【一鍵安裝 n8n】圖文教學,獲得無限額度自動化工具&限時免費升級企業版功能