Jekyll2020-07-26T12:03:22+10:00https://jerry153fish.github.io/feed.xmlJerry’s blogJerry's Blog
Jerryjerry153fish@gmail.comK8s study notes2020-02-22T00:00:00+11:002020-02-22T00:00:00+11:00https://jerry153fish.github.io/2020/02/22/k8s-study-note<h2 id="introduction">Introduction</h2>
<p>This is the second part of kubernetes study notes. History:</p>
<ol>
<li>From google Brog system</li>
</ol>
<h3 id="resource">Resource</h3>
<h4 id="scope">scope</h4>
<ol>
<li>Namespace level
<ol>
<li>eg: kubeadmin, k8s, kube-system</li>
</ol>
</li>
<li>Cluster level
<ol>
<li>eg: role</li>
</ol>
</li>
<li>Metadata level
<ol>
<li>eg: HPA</li>
</ol>
</li>
</ol>
<h4 id="types">types</h4>
<ol>
<li>workload
<ol>
<li>Pod</li>
<li>Deployment</li>
<li>RC, RS</li>
<li>DaemonSet</li>
<li>Job / CronJob</li>
</ol>
</li>
<li>service discovery and loadbalance
<ol>
<li>service</li>
<li>ingress</li>
</ol>
</li>
<li>storage and configuration
<ol>
<li>volume</li>
<li>CSI</li>
</ol>
</li>
<li>special
<ol>
<li>secret</li>
<li>configMap</li>
<li>downwardAPI : outside info into containers</li>
</ol>
</li>
</ol>
<h3 id="pod">Pod</h3>
<p>Smallest resource in k8s</p>
<h4 id="compulsory-fields">compulsory fields</h4>
<ol>
<li>apiVersion ( string ): eg v1, app/v1</li>
<li>kind ( string ): eg Pod, Deployment</li>
<li>metadata ( object )
<ol>
<li>name ( string )</li>
</ol>
</li>
<li>containers ( object[] )
<ol>
<li>name ( string )</li>
<li>image ( string )</li>
</ol>
</li>
</ol>
<h4 id="important-fields">important fields</h4>
<ol>
<li>metadata
<ol>
<li>namespace</li>
</ol>
</li>
<li>containers
<ol>
<li>ImagePullPolicy
<ol>
<li>IfNotPresent</li>
<li>Never</li>
<li>Always</li>
</ol>
</li>
<li>Ports</li>
<li>Command</li>
<li>WorkingDir</li>
</ol>
</li>
</ol>
<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">apiVersion</span><span class="pi">:</span> <span class="s">v1</span>
<span class="na">kind</span><span class="pi">:</span> <span class="s">Pod</span>
<span class="na">metadata</span><span class="pi">:</span>
<span class="na">name</span><span class="pi">:</span> <span class="s">nginx-pod</span>
<span class="na">spec</span><span class="pi">:</span>
<span class="na">containers</span><span class="pi">:</span>
<span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">nginx-pod</span>
<span class="na">image</span><span class="pi">:</span> <span class="s">nginx</span>
<span class="na">ports</span><span class="pi">:</span>
<span class="pi">-</span> <span class="na">containerPort</span><span class="pi">:</span> <span class="m">80</span>
</code></pre></div></div>
<h3 id="lifecycle">Lifecycle</h3>
<p>bc -> init Cs -> Main C ( start -> liveness ( readness ) -> stop )</p>
<p><img src="/assets/img/k8s/pod_lifecycle.png" alt="life cycle" /></p>
<h4 id="init-container">Init Container</h4>
<ol>
<li>under linux namespace so can access resource which main container can not</li>
<li>start one by one ( previous full stop ) after network and volume init ( basic container jobs )</li>
<li>If fails, the Pod will fail</li>
</ol>
<h4 id="main-container-probe--iterant-">Main container Probe ( iterant )</h4>
<ol>
<li>Actions
<ol>
<li>ExecAction: exec command inside container</li>
<li>TCPSocketAction: check ports open or not</li>
<li>HTTPGetAction: check return code between 2xx and 3xx</li>
</ol>
</li>
<li>Types
<ol>
<li>LivenessProbe: check container is running or not if fails Pod will fail</li>
<li>ReadnessProbe: check service ready or not if fails all the services will delete the Pod ip</li>
</ol>
</li>
</ol>
<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">apiVersion</span><span class="pi">:</span> <span class="s">v1</span>
<span class="na">kind</span><span class="pi">:</span> <span class="s">Pod</span>
<span class="na">metadata</span><span class="pi">:</span>
<span class="na">name</span><span class="pi">:</span> <span class="s">nginx-pod</span>
<span class="na">spec</span><span class="pi">:</span>
<span class="na">containers</span><span class="pi">:</span>
<span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">nginx-pod</span>
<span class="na">image</span><span class="pi">:</span> <span class="s">nginx</span>
<span class="na">ports</span><span class="pi">:</span>
<span class="pi">-</span> <span class="na">containerPort</span><span class="pi">:</span> <span class="m">80</span>
<span class="na">readnessProbe</span><span class="pi">:</span>
<span class="na">httpGet</span><span class="pi">:</span>
<span class="na">port</span><span class="pi">:</span> <span class="m">80</span>
<span class="na">path</span><span class="pi">:</span> <span class="s">/index.html</span>
<span class="na">initialDelaySeconds</span><span class="pi">:</span> <span class="m">1</span>
<span class="na">periodSeconds</span><span class="pi">:</span> <span class="m">3</span>
</code></pre></div></div>
<h4 id="status">Status</h4>
<ol>
<li>Pending: Pod Yaml been submitted to k8s. API objects been created and saved into etcd. But container not been created for some reason. eg: scheduler</li>
<li>Running: Pod has been scheduled and bind to a node. All containers inside Pod are created and ready to service.</li>
<li>Succeeded: All container inside Pod runs successfully, usually for one time job</li>
<li>Failed: At least one container inside Pod fails</li>
<li>Unknown: Pod stats not update by kubelet to api-server, usually means communication between master and nodes issue</li>
</ol>
<h3 id="controller">Controller</h3>
<p>Controller -> state machine</p>
<ol>
<li>ReplicationController And ReplicaSet</li>
<li>Development</li>
<li>DaemonSet</li>
<li>StateFulSet</li>
<li>Job / Cronjob</li>
<li>Horizontal Pod Autoscaling</li>
</ol>
<h4 id="rc-and-rs">RC and RS</h4>
<ol>
<li>RC -> RS</li>
<li>RS support selector label</li>
<li>maintain user defined replic number</li>
</ol>
<h4 id="development">Development</h4>
<ol>
<li>support declarative statement ( apply ) to create Pod and RS, NB: Deployment -> RS -> Pods</li>
<li>roll-update and rollback
<ol>
<li>update -> create a new rs -> decrease old rs replic number and increase new rs replic number until old one replic number become zero</li>
<li>rollback reverse process as update</li>
</ol>
</li>
<li>scale up and scale down</li>
<li>pause and continue Deployment</li>
</ol>
<p><em>create</em></p>
<blockquote>
<p><code class="language-plaintext highlighter-rouge">kubectl apply -f xxx.yaml --record</code></p>
</blockquote>
<p><em>scale</em></p>
<blockquote>
<p><code class="language-plaintext highlighter-rouge">kubectl scale deployment nameOfDeployment --replicas 10</code></p>
</blockquote>
<p><em>autoscale</em></p>
<blockquote>
<p><code class="language-plaintext highlighter-rouge">kubectl autoscale nameOfDeployment --min 2 --max 15 --cpu-percent=80</code></p>
</blockquote>
<p><em>update image</em></p>
<blockquote>
<p><code class="language-plaintext highlighter-rouge">kubectl set image deployment/nameOfDeployment nginx=nginx:1.9.1</code></p>
</blockquote>
<p><em>rollback</em></p>
<blockquote>
<p><code class="language-plaintext highlighter-rouge">kubectl rollout undo deployment/nameOfDeployment</code></p>
</blockquote>
<h4 id="daemonset">DaemonSet</h4>
<p>ensure all ( some ) nodes have at lease one running</p>
<p>eg:</p>
<ol>
<li>storage: <code class="language-plaintext highlighter-rouge">ceph</code> <code class="language-plaintext highlighter-rouge">glusterd</code></li>
<li>logs: <code class="language-plaintext highlighter-rouge">fluentd</code> <code class="language-plaintext highlighter-rouge">logstash</code></li>
<li>monitor <code class="language-plaintext highlighter-rouge">collectd</code> <code class="language-plaintext highlighter-rouge">new replic</code> <code class="language-plaintext highlighter-rouge">gmond</code></li>
</ol>
<h4 id="job--cronjob">Job / CronJob</h4>
<p>CronJob -> run a Job in certain time</p>
<p><em>CronJob spec</em></p>
<ol>
<li><code class="language-plaintext highlighter-rouge">spec.scheduler</code> - same as Cron min hour day month weekday</li>
<li><code class="language-plaintext highlighter-rouge">spec.jobTemplate</code> - Job template</li>
</ol>
<h4 id="statefulset">StateFulSet</h4>
<ol>
<li>persistent storage</li>
<li>persistent network identifiers</li>
<li>deploy in order from 0 to n-1 and the previous pod must be ready and running</li>
<li>delete in order from n-1 to 0</li>
</ol>
<h4 id="horizontal-pod-autoscaling">Horizontal Pod Autoscaling</h4>
<h3 id="services">Services</h3>
<ol>
<li>With <strong>Label selector</strong>, match a group of pods to provide outside access.</li>
<li>Only support 4 layers ( IP and port )of loadbalance not 7 layers, but with ingress can support 7 layers</li>
</ol>
<h4 id="types-1">Types</h4>
<ol>
<li>ClusterIP (default): assign cluster internal ip ( restrict access within cluster ) to service</li>
<li>NodePort: Bind a node port above Cluster IP to service for each node, port number > 30000</li>
<li>LoadBalance: use cloud-provider add a loadbalance to NodePort( NodeIP:NodePort ), so it can be accessed outside cluster</li>
</ol>
<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">apiVersion</span><span class="pi">:</span> <span class="s">v1</span>
<span class="na">kind</span><span class="pi">:</span> <span class="s">Service</span>
<span class="na">metadata</span><span class="pi">:</span>
<span class="na">name</span><span class="pi">:</span> <span class="s">nginx-svc</span>
<span class="na">spec</span><span class="pi">:</span>
<span class="na">type</span><span class="pi">:</span> <span class="s">LoadBalancer</span>
<span class="na">selector</span><span class="pi">:</span>
<span class="na">app</span><span class="pi">:</span> <span class="s">nginx</span>
<span class="na">ports</span><span class="pi">:</span>
<span class="pi">-</span> <span class="na">name</span><span class="pi">:</span> <span class="s">http</span>
<span class="na">port</span><span class="pi">:</span> <span class="m">8081</span>
<span class="na">targetPort</span><span class="pi">:</span> <span class="m">80</span>
<span class="na">externalIPs</span><span class="pi">:</span>
<span class="pi">-</span> <span class="s">192.168.99.102</span> <span class="c1"># minikube IP, usually cloud provider</span>
</code></pre></div></div>
<ol>
<li>ExternalName: import out-cluster service into cluster, so it can be access</li>
</ol>
<h4 id="kube-proxy-and-vip">Kube-proxy and VIP</h4>
<p>Each node has kube-proxy running inside and will provide a virtual ip for each service. 1.1 <code class="language-plaintext highlighter-rouge">iptables</code> -> 1.14 <code class="language-plaintext highlighter-rouge">ipvs</code></p>
<p><em>ipvs</em></p>
<ol>
<li>kube-proxy will regularly monitor <code class="language-plaintext highlighter-rouge">services</code> and <code class="language-plaintext highlighter-rouge">endpoints</code> then call <code class="language-plaintext highlighter-rouge">netlink</code> to create or update ipvs rules.</li>
<li>ipvs can provide multiple loadbalance algorithm
<ol>
<li>rr - round robin</li>
<li>lc - least connection</li>
<li>dh - destination hash</li>
<li>sh - source hash</li>
<li>sed - least delay</li>
<li>nq - not queued</li>
</ol>
</li>
<li>if install IPVS module will fallback to iptables</li>
</ol>
<h3 id="ingress">Ingress</h3>
<p>ingress -> nodePort</p>
<p><a href="https://kubernetes.github.io/ingress-nginx/">https://kubernetes.github.io/ingress-nginx/</a></p>
<h3 id="configmap">configMap</h3>
<div class="language-sh highlighter-rouge"><div class="highlight"><pre class="highlight"><code>kubectl create configmap nameOfconfigMap <span class="nt">--from-file</span><span class="o">=</span>PathToFile
</code></pre></div></div>Jerryjerry153fish@gmail.comIntroduction This is the second part of kubernetes study notes. History: From google Brog system Resource scope Namespace level eg: kubeadmin, k8s, kube-system Cluster level eg: role Metadata level eg: HPA types workload Pod Deployment RC, RS DaemonSet Job / CronJob service discovery and loadbalance service ingress storage and configuration volume CSI special secret configMap downwardAPI : outside info into containers Pod Smallest resource in k8s compulsory fields apiVersion ( string ): eg v1, app/v1 kind ( string ): eg Pod, Deployment metadata ( object ) name ( string ) containers ( object[] ) name ( string ) image ( string ) important fields metadata namespace containers ImagePullPolicy IfNotPresent Never Always Ports Command WorkingDir apiVersion: v1 kind: Pod metadata: name: nginx-pod spec: containers: - name: nginx-pod image: nginx ports: - containerPort: 80 Lifecycle bc -> init Cs -> Main C ( start -> liveness ( readness ) -> stop ) Init Container under linux namespace so can access resource which main container can not start one by one ( previous full stop ) after network and volume init ( basic container jobs ) If fails, the Pod will fail Main container Probe ( iterant ) Actions ExecAction: exec command inside container TCPSocketAction: check ports open or not HTTPGetAction: check return code between 2xx and 3xx Types LivenessProbe: check container is running or not if fails Pod will fail ReadnessProbe: check service ready or not if fails all the services will delete the Pod ip apiVersion: v1 kind: Pod metadata: name: nginx-pod spec: containers: - name: nginx-pod image: nginx ports: - containerPort: 80 readnessProbe: httpGet: port: 80 path: /index.html initialDelaySeconds: 1 periodSeconds: 3 Status Pending: Pod Yaml been submitted to k8s. API objects been created and saved into etcd. But container not been created for some reason. eg: scheduler Running: Pod has been scheduled and bind to a node. All containers inside Pod are created and ready to service. Succeeded: All container inside Pod runs successfully, usually for one time job Failed: At least one container inside Pod fails Unknown: Pod stats not update by kubelet to api-server, usually means communication between master and nodes issue Controller Controller -> state machine ReplicationController And ReplicaSet Development DaemonSet StateFulSet Job / Cronjob Horizontal Pod Autoscaling RC and RS RC -> RS RS support selector label maintain user defined replic number Development support declarative statement ( apply ) to create Pod and RS, NB: Deployment -> RS -> Pods roll-update and rollback update -> create a new rs -> decrease old rs replic number and increase new rs replic number until old one replic number become zero rollback reverse process as update scale up and scale down pause and continue Deployment create kubectl apply -f xxx.yaml --record scale kubectl scale deployment nameOfDeployment --replicas 10 autoscale kubectl autoscale nameOfDeployment --min 2 --max 15 --cpu-percent=80 update image kubectl set image deployment/nameOfDeployment nginx=nginx:1.9.1 rollback kubectl rollout undo deployment/nameOfDeployment DaemonSet ensure all ( some ) nodes have at lease one running eg: storage: ceph glusterd logs: fluentd logstash monitor collectd new replic gmond Job / CronJob CronJob -> run a Job in certain time CronJob spec spec.scheduler - same as Cron min hour day month weekday spec.jobTemplate - Job template StateFulSet persistent storage persistent network identifiers deploy in order from 0 to n-1 and the previous pod must be ready and running delete in order from n-1 to 0 Horizontal Pod Autoscaling Services With Label selector, match a group of pods to provide outside access. Only support 4 layers ( IP and port )of loadbalance not 7 layers, but with ingress can support 7 layers Types ClusterIP (default): assign cluster internal ip ( restrict access within cluster ) to service NodePort: Bind a node port above Cluster IP to service for each node, port number > 30000 LoadBalance: use cloud-provider add a loadbalance to NodePort( NodeIP:NodePort ), so it can be accessed outside cluster apiVersion: v1 kind: Service metadata: name: nginx-svc spec: type: LoadBalancer selector: app: nginx ports: - name: http port: 8081 targetPort: 80 externalIPs: - 192.168.99.102 # minikube IP, usually cloud provider ExternalName: import out-cluster service into cluster, so it can be access Kube-proxy and VIP Each node has kube-proxy running inside and will provide a virtual ip for each service. 1.1 iptables -> 1.14 ipvs ipvs kube-proxy will regularly monitor services and endpoints then call netlink to create or update ipvs rules. ipvs can provide multiple loadbalance algorithm rr - round robin lc - least connection dh - destination hash sh - source hash sed - least delay nq - not queued if install IPVS module will fallback to iptables Ingress ingress -> nodePort https://kubernetes.github.io/ingress-nginx/ configMap kubectl create configmap nameOfconfigMap --from-file=PathToFileDocker study notes2019-11-22T00:00:00+11:002019-11-22T00:00:00+11:00https://jerry153fish.github.io/2019/11/22/aws-sys-devops<h3 id="introduction">Introduction</h3>
<p>This is the first part of kubernetes study note. The part include the basic concepts of docker. How some docker command works</p>
<p>It is all about how to the <strong>border</strong> of the executable image</p>
<ol>
<li>Linux namespace</li>
<li>Linux CGroup</li>
<li>Union file group</li>
</ol>
<h3 id="namespace">Namespace</h3>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>docker run -it busybox ps -a
</code></pre></div></div>
<p>这种技术,就是 Linux 里面的 Namespace 机制。而 Namespace 的使用方式也非常有意思:它其实只是 Linux 创建新进程的一个可选参数。我们知道,在 Linux 系统中创建线程的系统调用是 clone(),比如:</p>
<p>int pid = clone(main_function, stack_size, SIGCHLD, NULL);
这个系统调用就会为我们创建一个新的进程,并且返回它的进程号 pid。</p>
<p>而当我们用 clone() 系统调用创建一个新进程时,就可以在参数中指定 CLONE_NEWPID 参数,比如:</p>
<p>int pid = clone(main_function, stack_size, CLONE_NEWPID | SIGCHLD, NULL);
这时,新创建的这个进程将会“看到”一个全新的进程空间,在这个进程空间里,它的 PID 是 1。之所以说“看到”,是因为这只是一个“障眼法”,在宿主机真实的进程空间里,这个进程的 PID 还是真实的数值,比如 100。</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>
#### Process namespace
分类 系统调用参数 相关内核版本
Mount namespaces CLONE_NEWNS Linux 2.4.19
UTS namespaces CLONE_NEWUTS Linux 2.6.19
IPC namespaces CLONE_NEWIPC Linux 2.6.19
PID namespaces CLONE_NEWPID Linux 2.6.24
Network namespaces CLONE_NEWNET 始于Linux 2.6.24 完成于 Linux 2.6.29
User namespaces CLONE_NEWUSER 始于 Linux 2.6.23 完成于 Linux 3.8)
#### Network namespace
</code></pre></div></div>
<p>sudo ip netns add test1
sudo ip netns add test2
sudo ip link add veth-test1 type veth peer name veth-test2
sudo ip link set veth-test1 netns test1
sudo ip link set veth-test2 netns test2
sudo ip netns exec test1 ip addr add 192.168.77.1/24 dev veth-test1
sudo ip netns exec test2 ip addr add 192.168.77.2/24 dev veth-test2</p>
<p>sudo ip netns exec test1 ip link set dev veth-test1 up
sudo ip netns exec test2 ip link set dev veth-test2 up
sudo ip netns exec test1 ping 192.168.77.2
sudo ip netns exec test2 ping 192.168.77.1
```</p>Jerryjerry153fish@gmail.comIntroduction This is the first part of kubernetes study note. The part include the basic concepts of docker. How some docker command works It is all about how to the border of the executable image Linux namespace Linux CGroup Union file group Namespace docker run -it busybox ps -a 这种技术,就是 Linux 里面的 Namespace 机制。而 Namespace 的使用方式也非常有意思:它其实只是 Linux 创建新进程的一个可选参数。我们知道,在 Linux 系统中创建线程的系统调用是 clone(),比如: int pid = clone(main_function, stack_size, SIGCHLD, NULL); 这个系统调用就会为我们创建一个新的进程,并且返回它的进程号 pid。 而当我们用 clone() 系统调用创建一个新进程时,就可以在参数中指定 CLONE_NEWPID 参数,比如: int pid = clone(main_function, stack_size, CLONE_NEWPID | SIGCHLD, NULL); 这时,新创建的这个进程将会“看到”一个全新的进程空间,在这个进程空间里,它的 PID 是 1。之所以说“看到”,是因为这只是一个“障眼法”,在宿主机真实的进程空间里,这个进程的 PID 还是真实的数值,比如 100。 #### Process namespace 分类 系统调用参数 相关内核版本 Mount namespaces CLONE_NEWNS Linux 2.4.19 UTS namespaces CLONE_NEWUTS Linux 2.6.19 IPC namespaces CLONE_NEWIPC Linux 2.6.19 PID namespaces CLONE_NEWPID Linux 2.6.24 Network namespaces CLONE_NEWNET 始于Linux 2.6.24 完成于 Linux 2.6.29 User namespaces CLONE_NEWUSER 始于 Linux 2.6.23 完成于 Linux 3.8) #### Network namespace sudo ip netns add test1 sudo ip netns add test2 sudo ip link add veth-test1 type veth peer name veth-test2 sudo ip link set veth-test1 netns test1 sudo ip link set veth-test2 netns test2 sudo ip netns exec test1 ip addr add 192.168.77.1/24 dev veth-test1 sudo ip netns exec test2 ip addr add 192.168.77.2/24 dev veth-test2 sudo ip netns exec test1 ip link set dev veth-test1 up sudo ip netns exec test2 ip link set dev veth-test2 up sudo ip netns exec test1 ping 192.168.77.2 sudo ip netns exec test2 ping 192.168.77.1 ```Docker study notes2019-11-16T00:00:00+11:002019-11-16T00:00:00+11:00https://jerry153fish.github.io/2019/11/16/Docker-study-notes-1<h3 id="introduction">Introduction</h3>
<p>This is the first part of kubernetes study note. The part include the basic concepts of docker. How some docker command works</p>
<p>It is all about how to the <strong>border</strong> of the executable image</p>
<ol>
<li>Linux namespace</li>
<li>Linux CGroup</li>
<li>Union file group</li>
</ol>
<h3 id="namespace">Namespace</h3>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>docker run -it busybox ps -a
</code></pre></div></div>
<p>这种技术,就是 Linux 里面的 Namespace 机制。而 Namespace 的使用方式也非常有意思:它其实只是 Linux 创建新进程的一个可选参数。我们知道,在 Linux 系统中创建线程的系统调用是 clone(),比如:</p>
<p>int pid = clone(main_function, stack_size, SIGCHLD, NULL);
这个系统调用就会为我们创建一个新的进程,并且返回它的进程号 pid。</p>
<p>而当我们用 clone() 系统调用创建一个新进程时,就可以在参数中指定 CLONE_NEWPID 参数,比如:</p>
<p>int pid = clone(main_function, stack_size, CLONE_NEWPID | SIGCHLD, NULL);
这时,新创建的这个进程将会“看到”一个全新的进程空间,在这个进程空间里,它的 PID 是 1。之所以说“看到”,是因为这只是一个“障眼法”,在宿主机真实的进程空间里,这个进程的 PID 还是真实的数值,比如 100。</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>
#### Process namespace
分类 系统调用参数 相关内核版本
Mount namespaces CLONE_NEWNS Linux 2.4.19
UTS namespaces CLONE_NEWUTS Linux 2.6.19
IPC namespaces CLONE_NEWIPC Linux 2.6.19
PID namespaces CLONE_NEWPID Linux 2.6.24
Network namespaces CLONE_NEWNET 始于Linux 2.6.24 完成于 Linux 2.6.29
User namespaces CLONE_NEWUSER 始于 Linux 2.6.23 完成于 Linux 3.8)
#### Network namespace
</code></pre></div></div>
<p>sudo ip netns add test1
sudo ip netns add test2
sudo ip link add veth-test1 type veth peer name veth-test2
sudo ip link set veth-test1 netns test1
sudo ip link set veth-test2 netns test2
sudo ip netns exec test1 ip addr add 192.168.77.1/24 dev veth-test1
sudo ip netns exec test2 ip addr add 192.168.77.2/24 dev veth-test2</p>
<p>sudo ip netns exec test1 ip link set dev veth-test1 up
sudo ip netns exec test2 ip link set dev veth-test2 up
sudo ip netns exec test1 ping 192.168.77.2
sudo ip netns exec test2 ping 192.168.77.1
```</p>Jerryjerry153fish@gmail.comIntroduction This is the first part of kubernetes study note. The part include the basic concepts of docker. How some docker command works It is all about how to the border of the executable image Linux namespace Linux CGroup Union file group Namespace docker run -it busybox ps -a 这种技术,就是 Linux 里面的 Namespace 机制。而 Namespace 的使用方式也非常有意思:它其实只是 Linux 创建新进程的一个可选参数。我们知道,在 Linux 系统中创建线程的系统调用是 clone(),比如: int pid = clone(main_function, stack_size, SIGCHLD, NULL); 这个系统调用就会为我们创建一个新的进程,并且返回它的进程号 pid。 而当我们用 clone() 系统调用创建一个新进程时,就可以在参数中指定 CLONE_NEWPID 参数,比如: int pid = clone(main_function, stack_size, CLONE_NEWPID | SIGCHLD, NULL); 这时,新创建的这个进程将会“看到”一个全新的进程空间,在这个进程空间里,它的 PID 是 1。之所以说“看到”,是因为这只是一个“障眼法”,在宿主机真实的进程空间里,这个进程的 PID 还是真实的数值,比如 100。 #### Process namespace 分类 系统调用参数 相关内核版本 Mount namespaces CLONE_NEWNS Linux 2.4.19 UTS namespaces CLONE_NEWUTS Linux 2.6.19 IPC namespaces CLONE_NEWIPC Linux 2.6.19 PID namespaces CLONE_NEWPID Linux 2.6.24 Network namespaces CLONE_NEWNET 始于Linux 2.6.24 完成于 Linux 2.6.29 User namespaces CLONE_NEWUSER 始于 Linux 2.6.23 完成于 Linux 3.8) #### Network namespace sudo ip netns add test1 sudo ip netns add test2 sudo ip link add veth-test1 type veth peer name veth-test2 sudo ip link set veth-test1 netns test1 sudo ip link set veth-test2 netns test2 sudo ip netns exec test1 ip addr add 192.168.77.1/24 dev veth-test1 sudo ip netns exec test2 ip addr add 192.168.77.2/24 dev veth-test2 sudo ip netns exec test1 ip link set dev veth-test1 up sudo ip netns exec test2 ip link set dev veth-test2 up sudo ip netns exec test1 ping 192.168.77.2 sudo ip netns exec test2 ping 192.168.77.1 ```2018 Summary and 2019 Goals2019-01-01T00:00:00+11:002019-01-01T00:00:00+11:00https://jerry153fish.github.io/2019/01/01/2018-Summary<h3 id="events">Events</h3>
<ol>
<li>
<p>Sharon became a Christian</p>
</li>
<li>
<p>Isabelle Janet Chen will be ready to come to the world</p>
</li>
<li>
<p>Left wherewot and join Asdeqlabs</p>
</li>
<li>
<p>For somehow gain weights => 77kg</p>
</li>
</ol>
<h3 id="skills-used-in-last-year">Skills used in last year</h3>
<ol>
<li>
<p>Typescript</p>
</li>
<li>
<p>Java</p>
</li>
<li>
<p>Swift and Object C</p>
</li>
<li>
<p>Python</p>
</li>
<li>
<p>C</p>
</li>
</ol>
<h3 id="knowledge-gained-last-years">Knowledge gained last years</h3>
<ol>
<li>
<p>IOS development</p>
</li>
<li>
<p>Spring Framework</p>
</li>
<li>
<p>MSSQL</p>
</li>
<li>
<p>Gradle</p>
</li>
</ol>
<h3 id="things-leftover">Things leftover</h3>
<ol>
<li>
<p>Books</p>
</li>
<li>
<p>Toy Projects: ToyOS</p>
</li>
<li>
<p>Source Code reading</p>
</li>
</ol>
<h3 id="projects-to-dos">Projects to dos</h3>
<ol>
<li>
<p>Toilet finder</p>
</li>
<li>
<p>Church website builder / API</p>
</li>
<li>
<p>Immigration Information provider</p>
</li>
<li>
<p>More coding</p>
</li>
</ol>Jerryjerry153fish@gmail.comEvents Sharon became a Christian Isabelle Janet Chen will be ready to come to the world Left wherewot and join Asdeqlabs For somehow gain weights => 77kg Skills used in last year Typescript Java Swift and Object C Python C Knowledge gained last years IOS development Spring Framework MSSQL Gradle Things leftover Books Toy Projects: ToyOS Source Code reading Projects to dos Toilet finder Church website builder / API Immigration Information provider More codingSpring Study Notes2018-08-13T00:00:00+10:002018-08-13T00:00:00+10:00https://jerry153fish.github.io/2018/08/13/Spring-study-notes<h3 id="basic-concepts">Basic Concepts</h3>
<ul>
<li>Spring >= Container</li>
<li>DI: dependency injection</li>
<li>Bean</li>
<li>application context: loads bean definitions and wires them together</li>
<li>AOP: aspect- oriented programming</li>
</ul>
<h3 id="spring-modules">Spring modules</h3>
<p><img src="/assets/img/java/spring-components.png" alt="Spring modules" /></p>
<ul>
<li>CORE SPRING CONTAINER</li>
<li>SPRING’S AOP MODULE</li>
<li>DATA ACCESS AND INTEGRATION: abstracts away the boilerplate code</li>
<li>WEB AND REMOTING: MVC and RMI</li>
<li>INSTRUMENTATION : a weaving agent for Tomcat that transforms class files as they’re loaded by the classloader.</li>
<li>TESTING</li>
</ul>
<h3 id="beans">Beans</h3>
<h4 id="spring-beans-vs-java-beans">Spring beans vs Java beans</h4>
<p><strong>Spring beans</strong> POJO classes which develop as a part of spring Application is called Spring bean</p>
<p><strong>java beans</strong></p>
<ul>
<li>A class must be public and contain public default constructor.</li>
<li>each private filed must contain either getter or setter or both method.</li>
<li>A class can implement At most serializable or externalizable interface.</li>
</ul>
<h4 id="configuration">Configuration</h4>
<ul>
<li>Explicit configuration in XML</li>
<li>Explicit configuration in Java</li>
<li>Implicit bean discovery and automatic wiring
<ul>
<li>Component scanning—Spring automatically discovers beans to be created in the application context.</li>
<li>Autowiring—Spring automatically satisfies bean dependencies.</li>
</ul>
</li>
</ul>Jerryjerry153fish@gmail.comBasic Concepts Spring >= Container DI: dependency injection Bean application context: loads bean definitions and wires them together AOP: aspect- oriented programming Spring modules CORE SPRING CONTAINER SPRING’S AOP MODULE DATA ACCESS AND INTEGRATION: abstracts away the boilerplate code WEB AND REMOTING: MVC and RMI INSTRUMENTATION : a weaving agent for Tomcat that transforms class files as they’re loaded by the classloader. TESTING Beans Spring beans vs Java beans Spring beans POJO classes which develop as a part of spring Application is called Spring bean java beans A class must be public and contain public default constructor. each private filed must contain either getter or setter or both method. A class can implement At most serializable or externalizable interface. Configuration Explicit configuration in XML Explicit configuration in Java Implicit bean discovery and automatic wiring Component scanning—Spring automatically discovers beans to be created in the application context. Autowiring—Spring automatically satisfies bean dependencies.2018 todos2018-08-12T00:00:00+10:002018-08-12T00:00:00+10:00https://jerry153fish.github.io/2018/08/12/todos<h3 id="books">Books</h3>
<ul class="task-list">
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />Clean code</li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" />Think in java</li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" />Understand the JVM</li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" />Java concurrency in practice</li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" />Pro C# 33%</li>
</ul>
<h3 id="review">Review</h3>
<ul class="task-list">
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />C#</li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />Java</li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />C/C++</li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />Gradle</li>
</ul>
<h3 id="learn">Learn</h3>
<ul class="task-list">
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />Typescript</li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />Swift</li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />Object C</li>
</ul>
<h3 id="code-read-and-wheel-reinvent">Code Read and Wheel Reinvent</h3>
<ul class="task-list">
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" />JDK Collections</li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" checked="checked" />Vue 10%</li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" />React</li>
</ul>Jerryjerry153fish@gmail.comBooks Clean code Think in java Understand the JVM Java concurrency in practice Pro C# 33% Review C# Java C/C++ Gradle Learn Typescript Swift Object C Code Read and Wheel Reinvent JDK Collections Vue 10% ReactTypescript Study notes2018-04-01T00:00:00+11:002018-04-01T00:00:00+11:00https://jerry153fish.github.io/2018/04/01/Typescript-study-notes<p>This is a collection of advanced javascript knowledge.</p>
<h3 id="array">Array</h3>
<ul>
<li>map parameters</li>
</ul>
<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code>
<span class="p">[</span><span class="dl">'</span><span class="s1">1</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">2</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">3</span><span class="dl">'</span><span class="p">].</span><span class="nx">map</span><span class="p">(</span><span class="nb">parseInt</span><span class="p">)</span> <span class="c1">// [1, NaN, NaN]</span>
<span class="p">[</span><span class="dl">'</span><span class="s1">1</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">2</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">3</span><span class="dl">'</span><span class="p">].</span><span class="nx">map</span><span class="p">((</span><span class="nx">currentValue</span><span class="p">,</span> <span class="nx">index</span><span class="p">,</span> <span class="nx">array</span><span class="p">)</span> <span class="o">=></span> <span class="p">{</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">currentValue</span><span class="p">)</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">index</span><span class="p">)</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">array</span><span class="p">)</span>
<span class="p">})</span>
<span class="c1">// parseInt(1, 0) == parseInt(1, 10) 1</span>
<span class="c1">// parseInt(2, 1) NaN</span>
<span class="c1">// parseInt(3, 2) NaN</span>
</code></pre></div></div>
<ul>
<li>map will only called by initialized array element</li>
</ul>
<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">var</span> <span class="nx">ary</span> <span class="o">=</span> <span class="nb">Array</span><span class="p">(</span><span class="mi">3</span><span class="p">);</span>
<span class="nx">ary</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">=</span><span class="mi">2</span>
<span class="nx">ary</span><span class="p">.</span><span class="nx">map</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">elem</span><span class="p">)</span> <span class="p">{</span> <span class="k">return</span> <span class="dl">'</span><span class="s1">1</span><span class="dl">'</span><span class="p">;</span> <span class="p">});</span>
<span class="c1">// ["1", empty × 2]</span>
</code></pre></div></div>
<ul>
<li>filter will not work on empty elements</li>
</ul>
<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">var</span> <span class="nx">ary</span> <span class="o">=</span> <span class="p">[</span><span class="mi">0</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">];</span>
<span class="nx">ary</span><span class="p">[</span><span class="mi">10</span><span class="p">]</span> <span class="o">=</span> <span class="mi">10</span><span class="p">;</span>
<span class="nx">ary</span><span class="p">.</span><span class="nx">filter</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">x</span><span class="p">)</span> <span class="p">{</span> <span class="k">return</span> <span class="nx">x</span> <span class="o">===</span> <span class="kc">undefined</span><span class="p">;});</span>
</code></pre></div></div>
<ul>
<li>array < > will compare element ony by one but == and === will not</li>
</ul>
<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">var</span> <span class="nx">a</span> <span class="o">=</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">],</span>
<span class="nx">b</span> <span class="o">=</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">3</span><span class="p">],</span>
<span class="nx">c</span> <span class="o">=</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">4</span><span class="p">]</span>
<span class="nx">a</span> <span class="o">==</span> <span class="nx">b</span> <span class="c1">// false</span>
<span class="nx">a</span> <span class="o">===</span> <span class="nx">b</span> <span class="c1">// false</span>
<span class="nx">a</span> <span class="o">></span> <span class="nx">c</span> <span class="c1">// false</span>
<span class="nx">a</span> <span class="o"><</span> <span class="nx">c</span> <span class="c1">// true</span>
</code></pre></div></div>
<ul>
<li>array allow last one be comma</li>
</ul>
<h3 id="operation-precedence">Operation precedence</h3>
<table>
<thead>
<tr>
<th>Precedence</th>
<th>Operator type</th>
<th>Associativity</th>
<th>Individual operators</th>
<th> </th>
</tr>
</thead>
<tbody>
<tr>
<td>20</td>
<td>Grouping</td>
<td>n/a</td>
<td>( … )</td>
<td> </td>
</tr>
<tr>
<td>19</td>
<td>Member Access</td>
<td>left-to-right</td>
<td>… . …</td>
<td> </td>
</tr>
<tr>
<td> </td>
<td> </td>
<td>Computed Member Access</td>
<td>left-to-right</td>
<td>… [ … ]</td>
</tr>
<tr>
<td> </td>
<td> </td>
<td>new (with argument list)</td>
<td>n/a</td>
<td>new … ( … )</td>
</tr>
<tr>
<td> </td>
<td> </td>
<td>Function Call</td>
<td>left-to-right</td>
<td>… ( … )</td>
</tr>
<tr>
<td>18</td>
<td>new (without argument list)</td>
<td>right-to-left</td>
<td>new …</td>
<td> </td>
</tr>
<tr>
<td>17</td>
<td>Postfix Increment</td>
<td>n/a</td>
<td>… ++</td>
<td> </td>
</tr>
<tr>
<td> </td>
<td> </td>
<td>Postfix Decrement</td>
<td> </td>
<td>… –</td>
</tr>
<tr>
<td>16</td>
<td>Logical NOT</td>
<td>right-to-left</td>
<td>! …</td>
<td> </td>
</tr>
<tr>
<td> </td>
<td> </td>
<td>Bitwise NOT</td>
<td> </td>
<td>~ …</td>
</tr>
<tr>
<td> </td>
<td> </td>
<td>Unary Plus</td>
<td> </td>
<td>+ …</td>
</tr>
<tr>
<td> </td>
<td> </td>
<td>Unary Negation</td>
<td> </td>
<td>- …</td>
</tr>
<tr>
<td> </td>
<td> </td>
<td>Prefix Increment</td>
<td> </td>
<td>++ …</td>
</tr>
<tr>
<td> </td>
<td> </td>
<td>Prefix Decrement</td>
<td> </td>
<td>– …</td>
</tr>
<tr>
<td> </td>
<td> </td>
<td>typeof</td>
<td> </td>
<td>typeof …</td>
</tr>
<tr>
<td> </td>
<td> </td>
<td>void</td>
<td> </td>
<td>void …</td>
</tr>
<tr>
<td> </td>
<td> </td>
<td>delete</td>
<td> </td>
<td>delete …</td>
</tr>
<tr>
<td> </td>
<td> </td>
<td>await</td>
<td> </td>
<td>await …</td>
</tr>
<tr>
<td>15</td>
<td>Exponentiation</td>
<td>right-to-left</td>
<td>… ** …</td>
<td> </td>
</tr>
<tr>
<td>14</td>
<td>Multiplication</td>
<td>left-to-right</td>
<td>… * …</td>
<td> </td>
</tr>
<tr>
<td> </td>
<td> </td>
<td>Division</td>
<td> </td>
<td>… / …</td>
</tr>
<tr>
<td> </td>
<td> </td>
<td>Remainder</td>
<td> </td>
<td>… % …</td>
</tr>
<tr>
<td>13</td>
<td>Addition</td>
<td>left-to-right</td>
<td>… + …</td>
<td> </td>
</tr>
<tr>
<td> </td>
<td> </td>
<td>Subtraction</td>
<td> </td>
<td>… - …</td>
</tr>
<tr>
<td>12</td>
<td>Bitwise Left Shift</td>
<td>left-to-right</td>
<td>… « …</td>
<td> </td>
</tr>
<tr>
<td> </td>
<td> </td>
<td>Bitwise Right Shift</td>
<td> </td>
<td>… » …</td>
</tr>
<tr>
<td> </td>
<td> </td>
<td>Bitwise Unsigned Right Shift</td>
<td> </td>
<td>… »> …</td>
</tr>
<tr>
<td>11</td>
<td>Less Than</td>
<td>left-to-right</td>
<td>… < …</td>
<td> </td>
</tr>
<tr>
<td> </td>
<td> </td>
<td>Less Than Or Equal</td>
<td> </td>
<td>… <= …</td>
</tr>
<tr>
<td> </td>
<td> </td>
<td>Greater Than</td>
<td> </td>
<td>… > …</td>
</tr>
<tr>
<td> </td>
<td> </td>
<td>Greater Than Or Equal</td>
<td> </td>
<td>… >= …</td>
</tr>
<tr>
<td> </td>
<td> </td>
<td>in</td>
<td> </td>
<td>… in …</td>
</tr>
<tr>
<td> </td>
<td> </td>
<td>instanceof</td>
<td> </td>
<td>… instanceof …</td>
</tr>
<tr>
<td>10</td>
<td>Equality</td>
<td>left-to-right</td>
<td>… == …</td>
<td> </td>
</tr>
<tr>
<td> </td>
<td> </td>
<td>Inequality</td>
<td> </td>
<td>… != …</td>
</tr>
<tr>
<td> </td>
<td> </td>
<td>Strict Equality</td>
<td> </td>
<td>… === …</td>
</tr>
<tr>
<td> </td>
<td> </td>
<td>Strict Inequality</td>
<td> </td>
<td>… !== …</td>
</tr>
<tr>
<td>9</td>
<td>Bitwise AND</td>
<td>left-to-right</td>
<td>… & …</td>
<td> </td>
</tr>
<tr>
<td>8</td>
<td>Bitwise XOR</td>
<td>left-to-right</td>
<td>… ^ …</td>
<td> </td>
</tr>
<tr>
<td>7</td>
<td>Bitwise OR</td>
<td>left-to-right</td>
<td>… | …</td>
<td> </td>
</tr>
<tr>
<td>6</td>
<td>Logical AND</td>
<td>left-to-right</td>
<td>… && …</td>
<td> </td>
</tr>
<tr>
<td>5</td>
<td>Logical OR</td>
<td>left-to-right</td>
<td>… || …</td>
<td> </td>
</tr>
<tr>
<td>4</td>
<td>Conditional</td>
<td>right-to-left</td>
<td>… ? … : …</td>
<td> </td>
</tr>
<tr>
<td>3</td>
<td>Assignment</td>
<td>right-to-left</td>
<td>… = …</td>
<td> </td>
</tr>
<tr>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
<td>… += …</td>
</tr>
<tr>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
<td>… -= …</td>
</tr>
<tr>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
<td>… **= …</td>
</tr>
<tr>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
<td>… *= …</td>
</tr>
<tr>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
<td>… /= …</td>
</tr>
<tr>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
<td>%= …</td>
</tr>
<tr>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
<td>… «= …</td>
</tr>
<tr>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
<td>… »= …</td>
</tr>
<tr>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
<td>… »>= …</td>
</tr>
<tr>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
<td>… &= …</td>
</tr>
<tr>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
<td>… ^= …</td>
</tr>
<tr>
<td> </td>
<td> </td>
<td> </td>
<td> </td>
<td>… |= …</td>
</tr>
<tr>
<td>2</td>
<td>yield</td>
<td>right-to-left</td>
<td>yield …</td>
<td> </td>
</tr>
<tr>
<td> </td>
<td> </td>
<td>yield*</td>
<td> </td>
<td>yield* …</td>
</tr>
<tr>
<td>1</td>
<td>Comma \ Sequence</td>
<td>left-to-right</td>
<td>… , …</td>
<td> </td>
</tr>
</tbody>
</table>
<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code>
<span class="kd">var</span> <span class="nx">val</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">smtg</span><span class="dl">'</span><span class="p">;</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="dl">'</span><span class="s1">Value is </span><span class="dl">'</span> <span class="o">+</span> <span class="p">(</span><span class="nx">val</span> <span class="o">===</span> <span class="dl">'</span><span class="s1">smtg</span><span class="dl">'</span><span class="p">)</span> <span class="p">?</span> <span class="dl">'</span><span class="s1">Something</span><span class="dl">'</span> <span class="p">:</span> <span class="dl">'</span><span class="s1">Nothing</span><span class="dl">'</span><span class="p">);</span> <span class="c1">// Something</span>
</code></pre></div></div>
<h3 id="string">String</h3>
<ul>
<li>new String will return String object</li>
</ul>
<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">var</span> <span class="nx">a</span> <span class="o">=</span> <span class="k">new</span> <span class="nb">String</span><span class="p">(</span><span class="dl">'</span><span class="s1">a</span><span class="dl">'</span><span class="p">)</span>
<span class="kd">var</span> <span class="nx">b</span> <span class="o">=</span> <span class="nb">String</span><span class="p">(</span><span class="dl">'</span><span class="s1">a</span><span class="dl">'</span><span class="p">)</span>
<span class="nx">a</span> <span class="o">===</span> <span class="dl">'</span><span class="s1">a</span><span class="dl">'</span> <span class="c1">// false</span>
<span class="nx">b</span> <span class="o">===</span> <span class="dl">'</span><span class="s1">a</span><span class="dl">'</span> <span class="c1">// true</span>
</code></pre></div></div>
<h3 id="-vs-">== vs ===</h3>
<ul>
<li>can not compare regex – every regex is unique</li>
</ul>
<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">var</span> <span class="nx">a</span> <span class="o">=</span> <span class="sr">/123/</span><span class="p">,</span> <span class="nx">b</span> <span class="o">=</span> <span class="sr">/123/</span><span class="p">;</span>
<span class="nx">a</span> <span class="o">==</span> <span class="nx">b</span> <span class="c1">// false</span>
<span class="nx">a</span> <span class="o">===</span> <span class="nx">b</span> <span class="c1">// false</span>
</code></pre></div></div>
<ul>
<li>== will perform type convent</li>
</ul>
<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kc">false</span> <span class="o">==</span> <span class="mi">0</span> <span class="c1">// true</span>
<span class="kc">false</span> <span class="o">==</span> <span class="dl">'</span><span class="s1">0</span><span class="dl">'</span> <span class="c1">// true</span>
<span class="kc">undefined</span> <span class="o">==</span> <span class="kc">null</span> <span class="c1">// true</span>
</code></pre></div></div>
<h3 id="prototype-vs-proto-vs-objectgetprototypeof">prototype vs <strong>proto</strong> vs Object.getPrototypeOf</h3>
<ol>
<li>
<p>prototype is a property of a Function object. It is the prototype of objects constructed by that function.</p>
</li>
<li>
<p><strong>proto</strong> is internal property of an object, pointing to its prototype. Current standards provide an equivalent Object.getPrototypeOf(O) method, though de facto standard <strong>proto</strong> is quicker</p>
</li>
<li>
<p>Instanceof relationships by comparing a function’s prototype to an object’s <strong>proto</strong> chain, and you can break these relationships by changing prototype.</p>
</li>
</ol>
<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code>
<span class="kd">function</span> <span class="nx">Test</span><span class="p">()</span> <span class="p">{</span>
<span class="p">}</span>
<span class="kd">var</span> <span class="nx">t1</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Test</span><span class="p">()</span>
<span class="c1">// below all true</span>
<span class="nx">t1</span><span class="p">.</span><span class="nx">__proto__</span> <span class="o">===</span> <span class="nx">Test</span><span class="p">.</span><span class="nx">prototype</span>
<span class="nx">t1</span><span class="p">.</span><span class="nx">__proto__</span><span class="p">.</span><span class="nx">__proto__</span> <span class="o">===</span> <span class="nb">Object</span><span class="p">.</span><span class="nx">prototype</span>
<span class="nx">t1</span> <span class="k">instanceof</span> <span class="nx">Test</span>
<span class="nx">t1</span> <span class="k">instanceof</span> <span class="nb">Object</span>
</code></pre></div></div>
<h4 id="typeof-vs-instanceof">typeof vs instanceof</h4>
<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code>
<span class="k">typeof</span> <span class="kc">null</span> <span class="c1">// "object"</span>
<span class="kc">null</span> <span class="k">instanceof</span> <span class="nb">Object</span> <span class="c1">// false</span>
<span class="nb">Object</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">toString</span><span class="p">.</span><span class="nx">call</span><span class="p">(</span><span class="kc">null</span><span class="p">)</span> <span class="c1">// '[Object Null]'</span>
<span class="k">typeof</span> <span class="p">[]</span> <span class="c1">// "object"</span>
<span class="p">[]</span> <span class="k">instanceof</span> <span class="nb">Object</span> <span class="c1">// true</span>
<span class="nb">Object</span><span class="p">.</span><span class="nx">prototype</span><span class="p">.</span><span class="nx">toString</span><span class="p">.</span><span class="nx">call</span><span class="p">([])</span> <span class="c1">// '[Object, Array]'</span>
</code></pre></div></div>
<h3 id="hasownproperty-will-never-look-for-proto-chain">hasOwnProperty will never look for proto chain</h3>
<h3 id="function">function</h3>
<ul>
<li>function name is read only</li>
</ul>
<p>###</p>Jerryjerry153fish@gmail.comThis is a collection of advanced javascript knowledge. Array map parameters ['1', '2', '3'].map(parseInt) // [1, NaN, NaN] ['1', '2', '3'].map((currentValue, index, array) => { console.log(currentValue) console.log(index) console.log(array) }) // parseInt(1, 0) == parseInt(1, 10) 1 // parseInt(2, 1) NaN // parseInt(3, 2) NaN map will only called by initialized array element var ary = Array(3); ary[0]=2 ary.map(function(elem) { return '1'; }); // ["1", empty × 2] filter will not work on empty elements var ary = [0,1,2]; ary[10] = 10; ary.filter(function(x) { return x === undefined;}); array < > will compare element ony by one but == and === will not var a = [1, 2, 3], b = [1, 2, 3], c = [1, 2, 4] a == b // false a === b // false a > c // false a < c // true array allow last one be comma Operation precedence Precedence Operator type Associativity Individual operators 20 Grouping n/a ( … ) 19 Member Access left-to-right … . … Computed Member Access left-to-right … [ … ] new (with argument list) n/a new … ( … ) Function Call left-to-right … ( … ) 18 new (without argument list) right-to-left new … 17 Postfix Increment n/a … ++ Postfix Decrement … – 16 Logical NOT right-to-left ! … Bitwise NOT ~ … Unary Plus + … Unary Negation - … Prefix Increment ++ … Prefix Decrement – … typeof typeof … void void … delete delete … await await … 15 Exponentiation right-to-left … ** … 14 Multiplication left-to-right … * … Division … / … Remainder … % … 13 Addition left-to-right … + … Subtraction … - … 12 Bitwise Left Shift left-to-right … « … Bitwise Right Shift … » … Bitwise Unsigned Right Shift … »> … 11 Less Than left-to-right … < … Less Than Or Equal … <= … Greater Than … > … Greater Than Or Equal … >= … in … in … instanceof … instanceof … 10 Equality left-to-right … == … Inequality … != … Strict Equality … === … Strict Inequality … !== … 9 Bitwise AND left-to-right … & … 8 Bitwise XOR left-to-right … ^ … 7 Bitwise OR left-to-right … | … 6 Logical AND left-to-right … && … 5 Logical OR left-to-right … || … 4 Conditional right-to-left … ? … : … 3 Assignment right-to-left … = … … += … … -= … … **= … … *= … … /= … %= … … «= … … »= … … »>= … … &= … … ^= … … |= … 2 yield right-to-left yield … yield* yield* … 1 Comma \ Sequence left-to-right … , … var val = 'smtg'; console.log('Value is ' + (val === 'smtg') ? 'Something' : 'Nothing'); // Something String new String will return String object var a = new String('a') var b = String('a') a === 'a' // false b === 'a' // true == vs === can not compare regex – every regex is unique var a = /123/, b = /123/; a == b // false a === b // false == will perform type convent false == 0 // true false == '0' // true undefined == null // true prototype vs proto vs Object.getPrototypeOf prototype is a property of a Function object. It is the prototype of objects constructed by that function. proto is internal property of an object, pointing to its prototype. Current standards provide an equivalent Object.getPrototypeOf(O) method, though de facto standard proto is quicker Instanceof relationships by comparing a function’s prototype to an object’s proto chain, and you can break these relationships by changing prototype. function Test() { } var t1 = new Test() // below all true t1.__proto__ === Test.prototype t1.__proto__.__proto__ === Object.prototype t1 instanceof Test t1 instanceof Object typeof vs instanceof typeof null // "object" null instanceof Object // false Object.prototype.toString.call(null) // '[Object Null]' typeof [] // "object" [] instanceof Object // true Object.prototype.toString.call([]) // '[Object, Array]' hasOwnProperty will never look for proto chain function function name is read only ###Java Review Note 12018-03-19T00:00:00+11:002018-03-19T00:00:00+11:00https://jerry153fish.github.io/2018/03/19/Java-Review-Note-1<h3 id="primitive-type">primitive type</h3>
<ul>
<li>number
<ul>
<li>int : 4 byte</li>
<li>short : 2 byte</li>
<li>long : 8 byte</li>
<li>byte: 1 byte -127 ~ 127</li>
<li>no unsigned type in java</li>
</ul>
</li>
<li>float
<ul>
<li>float 4 byte</li>
<li>double 8 byte</li>
<li>float operation follow IEEE 754
<ul>
<li>Double.POSITIVE_INFINITY</li>
<li>Double.NEGATIVE_INFINITY</li>
<li>Double.NaN</li>
</ul>
</li>
</ul>
</li>
<li>char: unicode</li>
<li>
<p>boolean</p>
</li>
<li>
<p>final vs const (c/c++/c#)</p>
</li>
<li>type converting</li>
</ul>
<p><img src="/assets/img/java/casting.png" alt="type converting" /></p>
<ul>
<li>string
<ul>
<li>immutable</li>
<li>String vs StringBuilder vs StringBuffer</li>
<li>in - <code class="language-plaintext highlighter-rouge">new Scanner(System.in)</code> vs <code class="language-plaintext highlighter-rouge">Console</code> which can only read one line
<ul>
<li>password visible vs array</li>
</ul>
</li>
</ul>
</li>
<li>BigInteger and BigDecimal
<ul>
<li>valueOf
<ul>
<li><code class="language-plaintext highlighter-rouge">BigInteger test = BigInteger.valueOf(100);</code></li>
</ul>
</li>
<li>can not use operation such as * /
<ul>
<li>Java not support operation override</li>
<li>need to use add or multiply</li>
</ul>
</li>
</ul>
</li>
</ul>
<h3 id="package-and-import">Package and import</h3>
<ul>
<li>package vs path</li>
</ul>Jerryjerry153fish@gmail.comprimitive type number int : 4 byte short : 2 byte long : 8 byte byte: 1 byte -127 ~ 127 no unsigned type in java float float 4 byte double 8 byte float operation follow IEEE 754 Double.POSITIVE_INFINITY Double.NEGATIVE_INFINITY Double.NaN char: unicode boolean final vs const (c/c++/c#) type converting string immutable String vs StringBuilder vs StringBuffer in - new Scanner(System.in) vs Console which can only read one line password visible vs array BigInteger and BigDecimal valueOf BigInteger test = BigInteger.valueOf(100); can not use operation such as * / Java not support operation override need to use add or multiply Package and import package vs pathJava Review Note 1 - struts2018-03-19T00:00:00+11:002018-03-19T00:00:00+11:00https://jerry153fish.github.io/2018/03/19/Java-Review-Note-2-struts2<p>Struts2 Web layer MVC.</p>
<h3 id="servlet">Servlet</h3>
<ul>
<li>Handle request</li>
<li>Encapsulate the request parameter</li>
<li>call service</li>
<li>render service result to view</li>
</ul>Jerryjerry153fish@gmail.comStruts2 Web layer MVC. Servlet Handle request Encapsulate the request parameter call service render service result to viewDotNet Study Note 3 - C# Class2018-03-06T00:00:00+11:002018-03-06T00:00:00+11:00https://jerry153fish.github.io/2018/03/06/DotNet-Study-Note-3-C#-Class<p>This is third part of DotNet study notes – quick review for C# language - class.</p>
<h3 id="class">Class</h3>
<p>A class is a user-defined type that is composed of field data (often called member variables)
and members that operate on this data (such as constructors, properties, methods, events, and so forth). Collectively, the set of field data represents the “state” of a class instance (otherwise known as an object)</p>
<p>All classes are provided with a free default constructor and it will be removed as soon as there is a custom constructor with any number of parameters defined.</p>
<p>This keyword that provides access to the current class instance and for a class using a technique termed constructor chaining.</p>
<div class="language-cs highlighter-rouge"><div class="highlight"><pre class="highlight"><code>
<span class="k">class</span> <span class="nc">Person</span>
<span class="p">{</span>
<span class="k">public</span> <span class="kt">int</span> <span class="n">Age</span><span class="p">;</span>
<span class="k">public</span> <span class="kt">string</span> <span class="n">Name</span><span class="p">;</span>
<span class="k">public</span> <span class="nf">Person</span><span class="p">()</span>
<span class="p">:</span> <span class="k">this</span><span class="p">(</span><span class="m">10</span><span class="p">,</span> <span class="s">"jerry"</span><span class="p">)</span>
<span class="p">{}</span>
<span class="k">public</span> <span class="nf">Person</span><span class="p">(</span><span class="kt">int</span> <span class="n">age</span><span class="p">)</span>
<span class="p">:</span> <span class="k">this</span><span class="p">(</span><span class="n">age</span><span class="p">,</span> <span class="s">"jerry"</span><span class="p">)</span>
<span class="p">{}</span>
<span class="k">public</span> <span class="nf">Person</span><span class="p">(</span><span class="kt">string</span> <span class="n">name</span><span class="p">)</span>
<span class="p">:</span> <span class="k">this</span><span class="p">(</span><span class="m">10</span><span class="p">,</span> <span class="n">name</span><span class="p">)</span>
<span class="p">{}</span>
<span class="k">public</span> <span class="nf">Person</span><span class="p">(</span><span class="kt">int</span> <span class="n">age</span><span class="p">,</span> <span class="kt">string</span> <span class="n">name</span><span class="p">)</span>
<span class="p">{</span>
<span class="k">this</span><span class="p">.</span><span class="n">Age</span> <span class="p">=</span> <span class="n">age</span><span class="p">;</span>
<span class="k">this</span><span class="p">.</span><span class="n">Name</span> <span class="p">=</span> <span class="n">name</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>
<h4 id="static">Static</h4>
<ul>
<li>static member</li>
<li>static function</li>
<li>static constructor</li>
</ul>
<h3 id="encapsulation">Encapsulation</h3>
<p>Hide unnecessary implementation details from the object user.</p>
<table>
<thead>
<tr>
<th>C# Access Modifier</th>
<th>May Be Applied To</th>
<th>Meaning in Life</th>
</tr>
</thead>
<tbody>
<tr>
<td>public</td>
<td>Types or type members</td>
<td>Public items have no access restrictions. A public member can be accessed from an object, as well as any derived class. A public type can be accessed from other external assemblies.</td>
</tr>
<tr>
<td>private</td>
<td>Type members or nested types</td>
<td>Private items can be accessed only by the class (or structure) that defines the item.</td>
</tr>
<tr>
<td>protected</td>
<td>Type members or nested types</td>
<td>Protected items can be used by the class that defines it and any child class. However, protected items cannot be accessed from the outside world using the C# dot operator.</td>
</tr>
<tr>
<td>internal</td>
<td>Types or type members</td>
<td>Internal items are accessible only within the current assembly. Therefore, if you define a set of internal types within a .NET class library, other assemblies are not able to use them.</td>
</tr>
<tr>
<td>protected internal</td>
<td>Type members or nested types</td>
<td>When the protected and internal keywords are combined on an item, the item is accessible within the defining assembly, within the defining class, and by derived classes.</td>
</tr>
</tbody>
</table>
<blockquote>
<p>Default Access Modifiers: type members are implicitly private while types are implicitly internal.</p>
</blockquote>
<div class="language-cs highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// same codes</span>
<span class="k">class</span> <span class="nc">Person</span>
<span class="p">{</span>
<span class="nf">Person</span><span class="p">()</span>
<span class="p">{}</span>
<span class="p">}</span>
<span class="k">internal</span> <span class="k">class</span> <span class="nc">Person</span>
<span class="p">{</span>
<span class="k">private</span> <span class="nf">Person</span><span class="p">()</span>
<span class="p">{}</span>
<span class="p">}</span>
</code></pre></div></div>
<blockquote>
<p>private, protected, and protected internal access modifiers can be applied to a nested type. non-nested types can be defined only with the public or internal modifiers</p>
</blockquote>
<ul>
<li>Automatic Properties</li>
</ul>
<p>ValueType: the hidden backing fields will be assigned a safe default value, reference type: NULL</p>
<div class="language-cs highlighter-rouge"><div class="highlight"><pre class="highlight"><code>
<span class="k">class</span> <span class="nc">Person</span>
<span class="p">{</span>
<span class="c1">// default: 0</span>
<span class="k">public</span> <span class="kt">int</span> <span class="n">Age</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="k">set</span><span class="p">;</span> <span class="p">}</span>
<span class="c1">// initialize</span>
<span class="k">public</span> <span class="kt">string</span> <span class="n">Name</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="k">set</span><span class="p">;</span> <span class="p">}</span> <span class="p">=</span> <span class="s">"jerry"</span>
<span class="p">}</span>
</code></pre></div></div>
<ul>
<li>object initializer syntax</li>
</ul>
<div class="language-cs highlighter-rouge"><div class="highlight"><pre class="highlight"><code>
<span class="n">Person</span> <span class="n">p1</span> <span class="p">=</span> <span class="k">new</span> <span class="n">Person</span> <span class="p">{</span> <span class="n">Age</span> <span class="p">=</span> <span class="m">3</span><span class="p">;</span> <span class="n">Name</span> <span class="p">=</span> <span class="s">"Tom"</span> <span class="p">};</span>
</code></pre></div></div>
<ul>
<li>const vs read-only</li>
</ul>
<p>Same: can not be cannot be changed after the initial assignment</p>
<p>diff:</p>
<table>
<tbody>
<tr>
<td>const</td>
<td>read-only</td>
</tr>
<tr>
<td>must be known at compile time and implicitly static</td>
<td>can be determined at runtime and not implicitly static</td>
</tr>
</tbody>
</table>
<div class="language-cs highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">class</span> <span class="nc">Person</span>
<span class="p">{</span>
<span class="c1">// compiled time </span>
<span class="k">const</span> <span class="kt">int</span> <span class="n">DesiredAge</span> <span class="p">=</span> <span class="m">18</span><span class="p">;</span>
<span class="k">readonly</span> <span class="kt">int</span> <span class="n">TargetAge</span><span class="p">;</span> <span class="c1">// as for static read only value if initialize must use static ctor</span>
<span class="k">public</span> <span class="nf">Person</span><span class="p">(</span><span class="kt">int</span> <span class="n">age</span><span class="p">)</span>
<span class="p">{</span>
<span class="c1">// error</span>
<span class="n">DesiredAge</span> <span class="p">=</span> <span class="n">age</span><span class="p">;</span>
<span class="c1">// can be assigned in runtime</span>
<span class="n">TargetAge</span> <span class="p">=</span> <span class="n">age</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>
<h3 id="inheritance">Inheritance</h3>
<p>Build new class definitions based on existing class definitions</p>
<blockquote>
<p>Although constructors are typically defined as public, a derived class never inherits the constructors of a parent class. Constructors are used to construct only the class that they are defined within, although they can be called by a derived class through constructor chaining. <sup id="fnref:1"><a href="#fn:1" class="footnote">1</a></sup></p>
</blockquote>
<ul>
<li>sealed</li>
</ul>
<p>The compiler will not allow you to derive from this type eg utility class</p>
<h3 id="polymorphism">Polymorphism</h3>
<p>Treat related objects in a similar manner</p>
<ul>
<li>virtual and override vs Member Shadowing</li>
</ul>
<h4 id="abstract-class">Abstract class</h4>
<p>When a class has been defined as an abstract base class (via the abstract keyword), it may define any number of abstract members. Abstract members can be used whenever you want to define a member that does not supply a default implementation but must be accounted for by each derived class.</p>
<p>Class Casting</p>
<div class="language-cs highlighter-rouge"><div class="highlight"><pre class="highlight"><code>
<span class="k">class</span> <span class="nc">Person</span>
<span class="p">{}</span>
<span class="k">class</span> <span class="nc">Teacher</span><span class="p">:</span> <span class="n">Person</span>
<span class="p">{}</span>
<span class="k">class</span> <span class="nc">Student</span><span class="p">:</span> <span class="n">Person</span>
<span class="p">{}</span>
<span class="c1">// implicit casting</span>
<span class="n">Person</span> <span class="n">t1</span> <span class="p">=</span> <span class="k">new</span> <span class="nf">Teacher</span><span class="p">();</span>
<span class="n">Person</span> <span class="n">s1</span> <span class="p">=</span> <span class="k">new</span> <span class="nf">Student</span><span class="p">();</span>
<span class="c1">// explicit casting</span>
<span class="c1">// is evaluated at runtime, not compile time</span>
<span class="n">Teacher</span> <span class="n">t2</span> <span class="p">=</span> <span class="p">(</span><span class="n">Teacher</span><span class="p">)</span><span class="n">t1</span><span class="p">;</span>
<span class="c1">// as keyword</span>
<span class="n">t1</span> <span class="k">as</span> <span class="n">Teacher</span><span class="p">;</span> <span class="c1">// return Teacher reference type</span>
<span class="n">t1</span> <span class="k">as</span> <span class="n">Student</span><span class="p">;</span> <span class="c1">// return null</span>
<span class="n">t1</span> <span class="k">is</span> <span class="n">Teacher</span> <span class="n">t2</span><span class="p">;</span> <span class="c1">// if is assign to t2</span>
<span class="n">t1</span> <span class="k">is</span> <span class="n">Student</span> <span class="n">t2</span><span class="p">;</span> <span class="c1">// if not return false</span>
</code></pre></div></div>
<blockquote>
<p>System.Object</p>
</blockquote>
<p>In the .NET universe, every type ultimately derives from a base class named System.Object, which can be represented by the C# object keyword.</p>
<table>
<thead>
<tr>
<th>Instance Method of Object Class</th>
<th>Meaning in Life <sup id="fnref:1:1"><a href="#fn:1" class="footnote">1</a></sup></th>
</tr>
</thead>
<tbody>
<tr>
<td>Equals()</td>
<td>By default, this method returns true only if the items being compared refer to the same item in memory. Thus, Equals() is used to compare object references, not the state of the object. Typically, this method is overridden to return true only if the objects being compared have the same internal state values (that is, value-based semantics). Be aware that if you override Equals(), you should also override GetHashCode(), as these methods are used internally by Hashtable types to retrieve subobjects from the container. Moreover the ValueType class overrides this method for all structures, so they work with value-based comparisons.</td>
</tr>
<tr>
<td>Finalize()</td>
<td>This method (when overridden) is called to free any allocated resources before the object is destroyed.</td>
</tr>
<tr>
<td>GetHashCode()</td>
<td>This method returns an int that identifies a specific object instance. By default, System.Object.GetHashCode() uses your object’s current location in memory to yield the hash value.</td>
</tr>
<tr>
<td>ToString()</td>
<td>This method returns a string representation of this object, using the <namespace>.<type name=""> format (termed the fully qualified name). This method will often be overridden by a subclass to return a tokenized string of name/value pairs that represent the object’s internal state, rather than its fully qualified name.</type></namespace></td>
</tr>
<tr>
<td>GetType()</td>
<td>This method returns a Type object that fully describes the object you are currently referencing. In short, this is a Runtime Type Identification (RTTI) method available to all objects.</td>
</tr>
<tr>
<td>MemberwiseClone()</td>
<td>This method exists to return a member-by-member copy of the current object, which is often used when cloning an object.</td>
</tr>
</tbody>
</table>
<blockquote>
<p>System.Exception</p>
</blockquote>
<div class="language-cs highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="k">class</span> <span class="nc">Exception</span> <span class="p">:</span> <span class="n">ISerializable</span><span class="p">,</span> <span class="n">_Exception</span>
<span class="p">{</span>
<span class="c1">// Public constructors</span>
<span class="k">public</span> <span class="nf">Exception</span><span class="p">(</span><span class="kt">string</span> <span class="n">message</span><span class="p">,</span> <span class="n">Exception</span> <span class="n">innerException</span><span class="p">);</span>
<span class="k">public</span> <span class="nf">Exception</span><span class="p">(</span><span class="kt">string</span> <span class="n">message</span><span class="p">);</span>
<span class="k">public</span> <span class="nf">Exception</span><span class="p">();</span>
<span class="c1">// ....</span>
<span class="c1">// Methods</span>
<span class="k">public</span> <span class="k">virtual</span> <span class="n">Exception</span> <span class="nf">GetBaseException</span><span class="p">();</span>
<span class="k">public</span> <span class="k">virtual</span> <span class="k">void</span> <span class="nf">GetObjectData</span><span class="p">(</span><span class="n">SerializationInfo</span> <span class="n">info</span><span class="p">,</span> <span class="n">StreamingContext</span> <span class="n">context</span><span class="p">);</span>
<span class="k">public</span> <span class="k">virtual</span> <span class="n">IDictionary</span> <span class="n">Data</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="p">}</span>
<span class="k">public</span> <span class="k">virtual</span> <span class="kt">string</span> <span class="n">HelpLink</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="k">set</span><span class="p">;</span> <span class="p">}</span>
<span class="k">public</span> <span class="n">Exception</span> <span class="n">InnerException</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="p">}</span>
<span class="k">public</span> <span class="k">virtual</span> <span class="kt">string</span> <span class="n">Message</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="p">}</span>
<span class="k">public</span> <span class="k">virtual</span> <span class="kt">string</span> <span class="n">Source</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="k">set</span><span class="p">;</span> <span class="p">}</span>
<span class="k">public</span> <span class="k">virtual</span> <span class="kt">string</span> <span class="n">StackTrace</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="p">}</span>
<span class="k">public</span> <span class="n">MethodBase</span> <span class="n">TargetSite</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="p">}</span>
<span class="c1">//....</span>
<span class="p">}</span>
</code></pre></div></div>
<p>The Exception interface allows a .net exception to be processed by an unmanaged codebase (such as a CoM application), while the ISerializable interface allows an exception object to be persisted across boundaries (such as a machine boundary).</p>
<table>
<thead>
<tr>
<th>System.Exception Property</th>
<th>Meaning in Life</th>
</tr>
</thead>
<tbody>
<tr>
<td>Data</td>
<td>This read-only property retrieves a collection of key-value pairs (represented by an object implementing IDictionary) that provide additional, programmer-defined information about the exception. By default, this collection is empty.</td>
</tr>
<tr>
<td>HelpLink</td>
<td>This property gets or sets a URL to a help file or web site describing the error in full detail.</td>
</tr>
<tr>
<td>InnerException</td>
<td>This read-only property can be used to obtain information about the previous exceptions that caused the current exception to occur. The previous exceptions are recorded by passing them into the constructor of the most current exception.</td>
</tr>
<tr>
<td>Message</td>
<td>This read-only property returns the textual description of a given error. The error message itself is set as a constructor parameter.</td>
</tr>
<tr>
<td>Source</td>
<td>This property gets or sets the name of the assembly, or the object, that threw the current exception.</td>
</tr>
<tr>
<td>StackTrace</td>
<td>This read-only property contains a string that identifies the sequence of calls that triggered the exception. As you might guess, this property is useful during debugging or if you want to dump the error to an external error log.</td>
</tr>
<tr>
<td>TargetSite</td>
<td>This read-only property returns a MethodBase object, which describes numerous details about the method that threw the exception (invoking ToString() will identify the method by name).</td>
</tr>
</tbody>
</table>
<h4 id="interface">interface</h4>
<p>An interface is nothing more than a named set of abstract members.</p>
<ul>
<li>no data fields</li>
<li>no constructors</li>
<li>no implementation</li>
<li>can have property, event, indexer</li>
<li>as parameters / return values</li>
</ul>
<h3 id="ienumerable-and-ienumerator-interfaces">IEnumerable and IEnumerator Interfaces</h3>
<div class="language-cs highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="k">interface</span> <span class="nc">IEnumerable</span>
<span class="p">{</span>
<span class="n">IEnumerator</span> <span class="nf">GetEnumerator</span><span class="p">();</span>
<span class="p">}</span>
<span class="k">public</span> <span class="k">interface</span> <span class="nc">IEnumerator</span>
<span class="p">{</span>
<span class="kt">bool</span> <span class="nf">MoveNext</span> <span class="p">();</span>
<span class="kt">object</span> <span class="n">Current</span> <span class="p">{</span> <span class="k">get</span><span class="p">;}</span>
<span class="k">void</span> <span class="nf">Reset</span> <span class="p">();</span>
<span class="p">}</span>
<span class="c1">// eg</span>
<span class="k">public</span> <span class="n">People</span> <span class="p">:</span> <span class="n">IEnumerable</span>
<span class="p">{</span>
<span class="k">private</span> <span class="n">Person</span><span class="p">[]</span> <span class="n">pArray</span> <span class="p">=</span> <span class="k">new</span> <span class="n">Person</span><span class="p">[</span><span class="m">2</span><span class="p">];</span>
<span class="k">public</span> <span class="nf">People</span><span class="p">()</span>
<span class="p">{</span>
<span class="n">pArray</span><span class="p">[</span><span class="m">0</span><span class="p">]</span> <span class="p">=</span> <span class="k">new</span> <span class="n">Person</span><span class="p">{</span> <span class="n">Age</span> <span class="p">=</span> <span class="m">3</span><span class="p">,</span> <span class="n">Name</span> <span class="p">=</span> <span class="s">"jerry"</span> <span class="p">};</span>
<span class="n">pArray</span><span class="p">[</span><span class="m">1</span><span class="p">]</span> <span class="p">=</span> <span class="k">new</span> <span class="n">Person</span><span class="p">{</span> <span class="n">Age</span> <span class="p">=</span> <span class="m">4</span><span class="p">,</span> <span class="n">Name</span> <span class="p">=</span> <span class="s">"tom"</span> <span class="p">};</span>
<span class="p">}</span>
<span class="k">public</span> <span class="n">IEnumerator</span> <span class="nf">GetEnumerator</span><span class="p">()</span>
<span class="p">{</span>
<span class="c1">// Return the array object's IEnumerator.</span>
<span class="k">return</span> <span class="n">pArray</span><span class="p">.</span><span class="nf">GetEnumerator</span><span class="p">();</span>
<span class="p">}</span>
<span class="c1">// or by yield</span>
<span class="k">public</span> <span class="n">IEnumerator</span> <span class="nf">GetEnumerator</span><span class="p">()</span>
<span class="p">{</span>
<span class="k">foreach</span> <span class="p">(</span><span class="n">Person</span> <span class="n">p</span> <span class="k">in</span> <span class="n">pArray</span><span class="p">)</span>
<span class="p">{</span>
<span class="k">yield</span> <span class="k">return</span> <span class="n">p</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>
<h3 id="the-icloneable-interface">The ICloneable Interface</h3>
<div class="language-cs highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="k">interface</span> <span class="nc">ICloneable</span>
<span class="p">{</span>
<span class="kt">object</span> <span class="nf">Clone</span><span class="p">();</span>
<span class="p">}</span>
<span class="k">public</span> <span class="k">class</span> <span class="nc">Person</span> <span class="p">:</span> <span class="n">ICloneable</span>
<span class="p">{</span>
<span class="k">public</span> <span class="kt">int</span> <span class="n">Age</span> <span class="p">{</span> <span class="k">set</span><span class="p">;</span> <span class="k">get</span><span class="p">;</span> <span class="p">}</span>
<span class="k">public</span> <span class="kt">string</span> <span class="n">Name</span> <span class="p">{</span> <span class="k">set</span><span class="p">;</span> <span class="k">get</span><span class="p">;</span> <span class="p">}</span>
<span class="k">public</span> <span class="nf">Person</span><span class="p">(</span><span class="kt">int</span> <span class="n">age</span><span class="p">,</span> <span class="kt">string</span> <span class="n">name</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">Age</span> <span class="p">=</span> <span class="n">age</span><span class="p">;</span>
<span class="n">Name</span> <span class="p">=</span> <span class="n">name</span><span class="p">;</span>
<span class="p">}</span>
<span class="k">public</span> <span class="nf">Person</span><span class="p">()</span> <span class="p">{}</span>
<span class="k">public</span> <span class="kt">object</span> <span class="nf">Clone</span><span class="p">()</span> <span class="p">=></span> <span class="k">new</span> <span class="nf">Person</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="n">Age</span><span class="p">,</span> <span class="k">this</span><span class="p">.</span><span class="n">Name</span><span class="p">);</span>
<span class="c1">// or use MemberwiseClone from object need to implement deep clone</span>
<span class="k">public</span> <span class="kt">object</span> <span class="nf">Clone</span><span class="p">()</span> <span class="p">=></span> <span class="k">this</span><span class="p">.</span><span class="nf">MemberwiseClone</span><span class="p">();</span>
<span class="p">}</span>
</code></pre></div></div>
<h3 id="the-icomparable-interface">The IComparable Interface</h3>
<p>Allows an object to be sorted based on some specified key</p>
<div class="language-cs highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">public</span> <span class="k">interface</span> <span class="nc">IComparable</span>
<span class="p">{</span>
<span class="kt">int</span> <span class="nf">CompareTo</span><span class="p">(</span><span class="kt">object</span> <span class="n">o</span><span class="p">);</span>
<span class="p">}</span>
<span class="c1">// eg</span>
<span class="k">public</span> <span class="k">class</span> <span class="nc">Person</span> <span class="p">:</span> <span class="n">IComparable</span>
<span class="p">{</span>
<span class="k">public</span> <span class="kt">int</span> <span class="n">Age</span> <span class="p">{</span> <span class="k">set</span><span class="p">;</span> <span class="k">get</span><span class="p">;</span> <span class="p">}</span>
<span class="k">public</span> <span class="kt">string</span> <span class="n">Name</span> <span class="p">{</span> <span class="k">set</span><span class="p">;</span> <span class="k">get</span><span class="p">;</span> <span class="p">}</span>
<span class="c1">// CompareTo Implementation</span>
<span class="kt">int</span> <span class="n">IComparable</span><span class="p">.</span><span class="nf">CompareTo</span><span class="p">(</span><span class="kt">object</span> <span class="n">obj</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">Person</span> <span class="n">tempP</span> <span class="p">=</span> <span class="n">obj</span> <span class="k">as</span> <span class="n">Person</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span> <span class="n">temP</span> <span class="p">==</span> <span class="k">null</span><span class="p">)</span>
<span class="k">throw</span> <span class="k">new</span> <span class="nf">ArgumentException</span><span class="p">(</span><span class="s">"Parameter is not a Car!"</span><span class="p">);</span>
<span class="k">if</span> <span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="n">Age</span> <span class="p">></span> <span class="n">temP</span><span class="p">.</span><span class="n">Age</span><span class="p">)</span>
<span class="c1">// comes before temP</span>
<span class="k">return</span> <span class="m">1</span><span class="p">;</span>
<span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="n">Age</span> <span class="p"><</span> <span class="n">temP</span><span class="p">.</span><span class="n">Age</span><span class="p">)</span>
<span class="c1">// comes after temP</span>
<span class="k">return</span> <span class="p">-</span><span class="m">1</span><span class="p">;</span>
<span class="k">else</span>
<span class="k">return</span> <span class="m">0</span><span class="p">;</span>
<span class="c1">// or steamline the previous CompareTo in this case Int</span>
<span class="k">if</span> <span class="p">(</span><span class="n">temp</span> <span class="p">!=</span> <span class="k">null</span><span class="p">)</span>
<span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="n">Age</span><span class="p">.</span><span class="nf">CompareTo</span><span class="p">(</span><span class="n">temp</span><span class="p">.</span><span class="n">CarID</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="c1">// usage</span>
<span class="n">Array</span><span class="p">.</span><span class="nf">sort</span><span class="p">(</span><span class="n">people</span><span class="p">);</span>
</code></pre></div></div>
<h3 id="icomparer-interface">IComparer Interface</h3>
<p>IComparer is typically not implemented on the type you of sorting but on any number of helper classes.</p>
<div class="language-cs highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">interface</span> <span class="nc">IComparer</span>
<span class="p">{</span>
<span class="kt">int</span> <span class="nf">Compare</span><span class="p">(</span><span class="kt">object</span> <span class="n">o1</span><span class="p">,</span> <span class="kt">object</span> <span class="n">o2</span><span class="p">);</span>
<span class="p">}</span>
<span class="c1">// person name Comparer</span>
<span class="k">public</span> <span class="n">PersonNameComparer</span> <span class="p">:</span> <span class="n">IComparer</span>
<span class="p">{</span>
<span class="kt">int</span> <span class="n">IComparer</span><span class="p">.</span><span class="nf">Compare</span><span class="p">(</span><span class="kt">object</span> <span class="n">o1</span><span class="p">,</span> <span class="kt">object</span> <span class="n">o2</span><span class="p">)</span>
<span class="p">{</span>
<span class="n">Person</span> <span class="n">p1</span> <span class="p">=</span> <span class="n">o1</span> <span class="k">as</span> <span class="n">Person</span><span class="p">;</span>
<span class="n">Person</span> <span class="n">p2</span> <span class="p">=</span> <span class="n">o2</span> <span class="k">as</span> <span class="n">Person</span><span class="p">;</span>
<span class="k">if</span><span class="p">(</span><span class="n">p1</span> <span class="p">==</span> <span class="k">null</span> <span class="p">||</span> <span class="n">p2</span> <span class="p">==</span> <span class="k">null</span><span class="p">)</span>
<span class="k">throw</span> <span class="k">new</span> <span class="nf">ArgumentException</span><span class="p">(</span><span class="s">"Parameter is not a Person!"</span><span class="p">);</span>
<span class="k">return</span> <span class="n">String</span><span class="p">.</span><span class="nf">Compare</span><span class="p">(</span><span class="n">p1</span><span class="p">.</span><span class="n">Name</span><span class="p">,</span> <span class="n">p2</span><span class="p">.</span><span class="n">Name</span><span class="p">);</span>
<span class="p">}</span>
<span class="p">}</span>
<span class="c1">// usage</span>
<span class="n">Array</span><span class="p">.</span><span class="nf">Sort</span><span class="p">(</span><span class="n">people</span><span class="p">,</span> <span class="k">new</span> <span class="nf">PersonNameComparer</span><span class="p">());</span>
</code></pre></div></div>
<h3 id="reference">Reference</h3>
<div class="footnotes">
<ol>
<li id="fn:1">
<p>Christian N 2018, <strong>Professional C# 7 and . NET Core 2. 0</strong>, https://www.amazon.com/Pro-NET-Core-Andrew-Troelsen/dp/1484230175 <a href="#fnref:1" class="reversefootnote">↩</a> <a href="#fnref:1:1" class="reversefootnote">↩<sup>2</sup></a></p>
</li>
</ol>
</div>Jerryjerry153fish@gmail.comThis is third part of DotNet study notes – quick review for C# language - class. Class A class is a user-defined type that is composed of field data (often called member variables) and members that operate on this data (such as constructors, properties, methods, events, and so forth). Collectively, the set of field data represents the “state” of a class instance (otherwise known as an object) All classes are provided with a free default constructor and it will be removed as soon as there is a custom constructor with any number of parameters defined. This keyword that provides access to the current class instance and for a class using a technique termed constructor chaining. class Person { public int Age; public string Name; public Person() : this(10, "jerry") {} public Person(int age) : this(age, "jerry") {} public Person(string name) : this(10, name) {} public Person(int age, string name) { this.Age = age; this.Name = name; } } Static static member static function static constructor Encapsulation Hide unnecessary implementation details from the object user. C# Access Modifier May Be Applied To Meaning in Life public Types or type members Public items have no access restrictions. A public member can be accessed from an object, as well as any derived class. A public type can be accessed from other external assemblies. private Type members or nested types Private items can be accessed only by the class (or structure) that defines the item. protected Type members or nested types Protected items can be used by the class that defines it and any child class. However, protected items cannot be accessed from the outside world using the C# dot operator. internal Types or type members Internal items are accessible only within the current assembly. Therefore, if you define a set of internal types within a .NET class library, other assemblies are not able to use them. protected internal Type members or nested types When the protected and internal keywords are combined on an item, the item is accessible within the defining assembly, within the defining class, and by derived classes. Default Access Modifiers: type members are implicitly private while types are implicitly internal. // same codes class Person { Person() {} } internal class Person { private Person() {} } private, protected, and protected internal access modifiers can be applied to a nested type. non-nested types can be defined only with the public or internal modifiers Automatic Properties ValueType: the hidden backing fields will be assigned a safe default value, reference type: NULL class Person { // default: 0 public int Age { get; set; } // initialize public string Name { get; set; } = "jerry" } object initializer syntax Person p1 = new Person { Age = 3; Name = "Tom" }; const vs read-only Same: can not be cannot be changed after the initial assignment diff: const read-only must be known at compile time and implicitly static can be determined at runtime and not implicitly static class Person { // compiled time const int DesiredAge = 18; readonly int TargetAge; // as for static read only value if initialize must use static ctor public Person(int age) { // error DesiredAge = age; // can be assigned in runtime TargetAge = age; } } Inheritance Build new class definitions based on existing class definitions Although constructors are typically defined as public, a derived class never inherits the constructors of a parent class. Constructors are used to construct only the class that they are defined within, although they can be called by a derived class through constructor chaining. 1 sealed The compiler will not allow you to derive from this type eg utility class Polymorphism Treat related objects in a similar manner virtual and override vs Member Shadowing Abstract class When a class has been defined as an abstract base class (via the abstract keyword), it may define any number of abstract members. Abstract members can be used whenever you want to define a member that does not supply a default implementation but must be accounted for by each derived class. Class Casting class Person {} class Teacher: Person {} class Student: Person {} // implicit casting Person t1 = new Teacher(); Person s1 = new Student(); // explicit casting // is evaluated at runtime, not compile time Teacher t2 = (Teacher)t1; // as keyword t1 as Teacher; // return Teacher reference type t1 as Student; // return null t1 is Teacher t2; // if is assign to t2 t1 is Student t2; // if not return false System.Object In the .NET universe, every type ultimately derives from a base class named System.Object, which can be represented by the C# object keyword. Instance Method of Object Class Meaning in Life 1 Equals() By default, this method returns true only if the items being compared refer to the same item in memory. Thus, Equals() is used to compare object references, not the state of the object. Typically, this method is overridden to return true only if the objects being compared have the same internal state values (that is, value-based semantics). Be aware that if you override Equals(), you should also override GetHashCode(), as these methods are used internally by Hashtable types to retrieve subobjects from the container. Moreover the ValueType class overrides this method for all structures, so they work with value-based comparisons. Finalize() This method (when overridden) is called to free any allocated resources before the object is destroyed. GetHashCode() This method returns an int that identifies a specific object instance. By default, System.Object.GetHashCode() uses your object’s current location in memory to yield the hash value. ToString() This method returns a string representation of this object, using the . format (termed the fully qualified name). This method will often be overridden by a subclass to return a tokenized string of name/value pairs that represent the object’s internal state, rather than its fully qualified name. GetType() This method returns a Type object that fully describes the object you are currently referencing. In short, this is a Runtime Type Identification (RTTI) method available to all objects. MemberwiseClone() This method exists to return a member-by-member copy of the current object, which is often used when cloning an object. System.Exception public class Exception : ISerializable, _Exception { // Public constructors public Exception(string message, Exception innerException); public Exception(string message); public Exception(); // .... // Methods public virtual Exception GetBaseException(); public virtual void GetObjectData(SerializationInfo info, StreamingContext context); public virtual IDictionary Data { get; } public virtual string HelpLink { get; set; } public Exception InnerException { get; } public virtual string Message { get; } public virtual string Source { get; set; } public virtual string StackTrace { get; } public MethodBase TargetSite { get; } //.... } The Exception interface allows a .net exception to be processed by an unmanaged codebase (such as a CoM application), while the ISerializable interface allows an exception object to be persisted across boundaries (such as a machine boundary). System.Exception Property Meaning in Life Data This read-only property retrieves a collection of key-value pairs (represented by an object implementing IDictionary) that provide additional, programmer-defined information about the exception. By default, this collection is empty. HelpLink This property gets or sets a URL to a help file or web site describing the error in full detail. InnerException This read-only property can be used to obtain information about the previous exceptions that caused the current exception to occur. The previous exceptions are recorded by passing them into the constructor of the most current exception. Message This read-only property returns the textual description of a given error. The error message itself is set as a constructor parameter. Source This property gets or sets the name of the assembly, or the object, that threw the current exception. StackTrace This read-only property contains a string that identifies the sequence of calls that triggered the exception. As you might guess, this property is useful during debugging or if you want to dump the error to an external error log. TargetSite This read-only property returns a MethodBase object, which describes numerous details about the method that threw the exception (invoking ToString() will identify the method by name). interface An interface is nothing more than a named set of abstract members. no data fields no constructors no implementation can have property, event, indexer as parameters / return values IEnumerable and IEnumerator Interfaces public interface IEnumerable { IEnumerator GetEnumerator(); } public interface IEnumerator { bool MoveNext (); object Current { get;} void Reset (); } // eg public People : IEnumerable { private Person[] pArray = new Person[2]; public People() { pArray[0] = new Person{ Age = 3, Name = "jerry" }; pArray[1] = new Person{ Age = 4, Name = "tom" }; } public IEnumerator GetEnumerator() { // Return the array object's IEnumerator. return pArray.GetEnumerator(); } // or by yield public IEnumerator GetEnumerator() { foreach (Person p in pArray) { yield return p; } } } The ICloneable Interface public interface ICloneable { object Clone(); } public class Person : ICloneable { public int Age { set; get; } public string Name { set; get; } public Person(int age, string name) { Age = age; Name = name; } public Person() {} public object Clone() => new Person(this.Age, this.Name); // or use MemberwiseClone from object need to implement deep clone public object Clone() => this.MemberwiseClone(); } The IComparable Interface Allows an object to be sorted based on some specified key public interface IComparable { int CompareTo(object o); } // eg public class Person : IComparable { public int Age { set; get; } public string Name { set; get; } // CompareTo Implementation int IComparable.CompareTo(object obj) { Person tempP = obj as Person; if ( temP == null) throw new ArgumentException("Parameter is not a Car!"); if (this.Age > temP.Age) // comes before temP return 1; else if (this.Age < temP.Age) // comes after temP return -1; else return 0; // or steamline the previous CompareTo in this case Int if (temp != null) return this.Age.CompareTo(temp.CarID); } } // usage Array.sort(people); IComparer Interface IComparer is typically not implemented on the type you of sorting but on any number of helper classes. interface IComparer { int Compare(object o1, object o2); } // person name Comparer public PersonNameComparer : IComparer { int IComparer.Compare(object o1, object o2) { Person p1 = o1 as Person; Person p2 = o2 as Person; if(p1 == null || p2 == null) throw new ArgumentException("Parameter is not a Person!"); return String.Compare(p1.Name, p2.Name); } } // usage Array.Sort(people, new PersonNameComparer()); Reference Christian N 2018, Professional C# 7 and . NET Core 2. 0, https://www.amazon.com/Pro-NET-Core-Andrew-Troelsen/dp/1484230175 ↩ ↩2