2014年7月28日 星期一

FreeBSD架設網頁伺服器,Apache,PHP,MySQL,phpmyadmin

Port位置
/usr/ports/www/apache24
/usr/ports/databases/mysql56-server
/usr/ports/www/mod_php55阿帕契的PHP套件
/usr/ports/lang/php55
/usr/ports/lang/php55-extensions函式庫
/usr/ports/databases/phpmyadmin

編輯/etc/rc.conf開機啟動
apache24_enable="YES"
mysql_enable="YES"

編輯apache設定檔
/usr/local/etc/apache24/httpd.conf

依個人喜好修改
依個人喜好修改
ServerRoot "/usr/local"
ServerAdmin you@your.address
ServerName www.example.com:80
DocumentRoot "/usr/local/www/apache24/data"網頁根目錄
Listen :80監聽埠

首頁預設名稱
DirectoryIndex index.php index.html

加入PHP支援
AddType application/x-httpd-php .php
AddType application/x-httpd-php-source .phps
LoadModule php5_module        libexec/apache24/libphp5.so

加入phpMyAdmin支援
Alias /phpmyadmin "/usr/local/www/phpMyAdmin"

<Directory "/usr/local/www/phpMyAdmin">
Options None
AllowOverride None
Require all granted
</Directory>

語言選項
AddDefaultCharset On

做一個目錄
mkdir /usr/local/www/phpMyAdmin/config
hmod o+w /usr/local/www/phpMyAdmin/config權限不對沒辦法用
chmod o+r /usr/local/www/phpMyAdmin/config.inc.php
這檔案應該是從config.inc.php.sample還是 config.sample.inc.php或是/usr/local/etc/php.ini-development複製來的,忘了,內容好像都一樣

MYSQL設定ROOT密碼
/usr/local/bin/mysqladmin -u root password

登入MYSQL設定讓遠端可以連線
mysql -u root -p
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%'IDENTIFIED BY 'mypassword' WI
TH GRANT OPTION;

複製MYSQL設定檔
cp /usr/local/share/mysql/my-default.cnf /etc/my.cnf

啟動apach、mysql
/usr/local/etc/rc.d/mysql-server start
/usr/local/sbin/apachectl start

寫一個index.php丟進網頁根目錄 /usr/local/www/apache24/data
<? php 
phpinfo();
?>

用瀏覽器有看到PHP資訊就是apache架設成功且可以正常解析PHP
再瀏覽IP/phpmyadmin/網頁,出現登入畫面表示phpmyadmin安裝成功,
可以登入看到MYSQL內建資料庫表示資料庫架設成功。

httpd,80Port mysqld,3306

FreeBSD使用MPD5架設VPN(PPTP協定)

參考參考2參考3參考4

Port位置 /usr/ports/net/mpd5/
複製範例,最終檔名為mpd.conf
cp /usr/local/etc/mpd5/mpd.conf.sample mpd.conf

設置參數/usr/local/etc/mpd5/mpd.conf
startup:
        # configure mpd users
        set user foo bar admin
        set user foo1 bar1
網頁登入,帳號:foo,密碼:bar,可修改

預設協定改為PPTP
default:
        #load dialup
        load pptp_server

找到pptp_server
# Define dynamic IP address pool.
        set ippool add pool1 192.168.2.50 192.168.2.99
此為要發給連進來的使用者的IP範圍

# Specify IP address pool for dynamic assigment.
        set ipcp ranges 192.168.2.1/32 ippool pool1設定mask,只須改ranges後面的IP
        set ipcp dns 168.95.1.1設定DNS
        #set ipcp nbns 192.168.1.4這不知道是啥,沒什麼作用,不註解好像也無所謂

# Configure PPTP
        set pptp self 172.16.0.151外網IP

設定VPN帳號,複製範例
cp /usr/local/etc/mpd5/mpd.secret.sample mpd.secret

編輯,格式為帳號 “密碼” 發給IP(若IP欄空白會自動發給)
vpntest         "a123456"  192.168.2.99

編輯/etc/rc.conf,開機啟動
mpd_enable="YES"

啟動
/usr/local/etc/rc.d/mpd5 start

到此為止已經可以連進VPN了,但無法連外網,
VPN伺服器有兩張網卡的話可以用PF架設NAT,將封包再轉到外網網卡。
若是只有一張網卡,一樣開啟PF,將送進來的封包再轉出去,
連進來的使用者網卡都是ng開頭,只需要改/etc/pf.conf為
if_int="ng*"
就可以再轉出去

使用5005、5006、1723port

FreeBSD架設NAT,使用PF(Packet Filter,封包過濾器)

需有兩張網路卡,對外(WAN),對內(LAN)
目前10.0 RELEASE核心預設就有PF,但還是需重新編譯核心,加入ALTQ,此功能不知是否必須,但若不加入,會一直出現訊息

重新編譯核心
cd /sys/amd64/conf

複製一個核心
cp GENERIC GENERIC_1

編輯GENERIC_1,加入ALTQ
options         ALTQ
options         ALTQ_CBQ        # Class Based Queuing (CBQ)
options         ALTQ_RED        # Random Early Detection (RED)
options         ALTQ_RIO        # RED In/Out
options         ALTQ_HFSC       # Hierarchical Packet Scheduler (HFSC)
options         ALTQ_PRIQ       # Priority Queuing (PRIQ)

開始編譯
config GENERIC_1
cd ../compile/ GENERIC_1
make depend all install

編輯/etc/rc.conf
ifconfig_em0="inet 172.16.0.151 netmask 255.255.255.0"對外網卡
ifconfig_em1="inet 192.168.2.1 netmask 255.255.255.0"對內網卡
pf_enable="YES"開機啟動PF
gateway_enable="YES"架NAT要開啟此項

編輯/etc/pf.conf
此檔案預設是沒有的,可以新增或cp /usr/share/examples/pf/pf.conf範例檔案
這個檔案也可以訂定各種封包過濾規則
if_ext="em0"對外網卡
if_int="em1"對內網卡
net_lan="192.168.2.1/24"內網區段mask

轉送封包
set skip on lo0
nat on $if_ext from $net_lan -> ($if_ext:0)
no nat on $if_ext from !$net_lan to any

這兩條規則會將試圖從外網連進來的擋掉
block in on $if_ext
pass out

接下來內網電腦就可以指向對內網卡的IP, bsd會將送進來的封包從對外網卡轉出去,外部送進來的轉送到來源端

FreeBSD建置Samba網路分享目錄

參考
參考2
參考3

Port位置 /usr/ports/net/samba36
/usr/local/etc/smb.conf.sample
這個檔案是設定檔範例,複製一份改為smb.conf.
cp /usr/local/etc/smb.conf.sample /usr/local/etc/smb.conf

修改設定檔
Global全域設定
workgroup,工作群組
server string,伺服器名稱
hosts allow = 192.168.1. 192.168.2. 127.
可限制連線IP,第四碼不填代表0~255,最後的127不知是啥
log file,紀錄檔路徑

Share Definitions分享設定,格式為
[public]對外的目錄名稱
   comment = %h Shared Public Directory註解
   path = /usr/home/samba/public在本機的路徑 
   public = yes是否公開
   writeable = yes是否可寫
   read only = no是否唯讀
   valid users = userName限制使用者

建立使用者、群組,samba登入密碼要另外設定
adduser
smbpasswd –a userName

設定開機啟動
/etc/rc.conf
samba_enable="YES"

啟動
/usr/local/etc/rc.d/samba start

使用tcp 445 139port(smbd)、udp 137 138(nmbd)

FreeBSD建置Git Server

參考
參考2
--bare參數參考
無法Push參考

Port位置 /usr/port/devel/git
加入使用者,此為外部連進來的帳密
adduser

在家目錄增加.ssh目錄
mkdir -p /home/git/.ssh

加入SSH密鑰
touch /home/git/.ssh/authorized_keys

修改權限
chmod 0700 /home/git/.ssh
chmod 0600 /home/git/.ssh/authorized_keys

修改啟動參數 /etc/rc.conf
git_daemon_enable="YES"
git_daemon_flags="--syslog --export-all"

若是無法啟動改為
git_daemon_flags="--syslog --export-all --reuseaddr --detach"

啟動daemon
/usr/local/etc/rc.d/git_daemon start

創建專案目錄並初始化倉庫
su git
cd /home/git/
mkdir project.git
cd project.git
git --bare init

git@[gitserver]:/home/git/project.git BSD帳號名稱@伺服器位置,可以是domain:專案位置
無法Push在專案倉庫執行這行
git config --bool core.bare true

占用9418port

SSH可用Root登入

參考
編輯 /etc/ssh/sshd_config
原本
#PermitRootLogin no

改為
PermitRootLogin yes

FreeBSD語系更改為UTF-8

預設為C Shell下只要修改 /etc/csh.cshrc 增加以下敘述即可
setenv LC_CTYPE en_US.ISO8859-1
setenv LC_ALL zh_TW.UTF-8
setenv LANG zh_TW.UTF-8

Port Tree

參考1
參考2

Portsnap Proxy Host
/etc/portsnap.conf

取得最新Port tree
portsnap fetch extract

更新Port tree
portsnap fetch update

常用指令,在一開始時確認完所有Config,安裝後清除暫存
make config-recursive install clean

反安裝
make deinstall clean

2014年7月20日 星期日

讓程式具有系統管理員權限

參考網站
加入一個"應用程式資訊清單",加入後檔名為app.manifest
這段是使用者帳戶控制層級,檔案裡的註解有提示,有三種層級,
一般使用者:asInvoker
管理員:requireAdministrator
最高權限:highestAvailable
<requestedExecutionLevel level="asInvoker" uiAccess="false" />

同步化TcpListener實作,利用網路傳送資料

伺服器端:
using System.Net;
using System.Net.Sockets;

//監聽所有可以達到本機的IP位置;9000port
IPEndPoint ipEndPoint = new IPEndPoint(IPAddress.Any, 9000);
TcpListener listener = new TcpListener(ipEndPoint);
listener.Start();

//無窮迴圈等待客戶端
while (true)
{
    TcpClient tcpClient = listener.AcceptTcpClient();

    //連上了就開始處理
    if (tcpClient.Connected)
    {
        //資料流指向tcpClient(客戶端)傳來的資料
        NetworkStream networkStream = tcpClient.GetStream();

        //傳進來是位元組
        byte[] receiveByte = new byte[tcpClient.ReceiveBufferSize];

        // ReceiveBufferSize好像是固定數值,真正讀到的長度Read()會回傳
        int resdByteLength = 
            networkStream.Read(receiveByte, 0, tcpClient.ReceiveBufferSize);

        //編碼成看得懂的字串
        string receiveString = 
            Encoding.Default.GetString(receiveByte, 0, resdByteLength);

        //在Connected區塊裡都是連接狀態,可以再發訊息給客戶端,
        //也是利用網路資料流的方式,離開後又回到無窮迴圈等下一次客戶端連線
    }
}
發送端:
using System.Net;
using System.Net.Sockets;

//伺服器端位置
IPAddress ipAddress = IPAddress.Parse("127.0.0.1");
IPEndPoint ipEndPoint = new IPEndPoint(ipAddress, 9000);
TcpClient tcpClient = new TcpClient();

//連接伺服器
tcpClient.Connect(ipEndPoint);

if(tcpClient.Connected)
{
    //編碼成byte讓網路流傳遞
    string sendString = "這是要發送的訊息";
    byte[] sendByte = Encoding.Default.GetBytes(sendString);
    NetworkStream networkStream = tcpClient.GetStream();
    networkStream.Write(sendByte, 0, sendByte.Length);
}

Windows Management Instrumentation (WMI)

WMI包含的範圍很廣,參閱MSDN
左邊的選單就一堆,幾個比較實用的
using System.Management;

ManagementObjectSearcher searcher =
    new ManagementObjectSearcher("SELECT * FROM Win32_ComputerSystem");
foreach (ManagementObject wmi in searcher.Get())
{
    //取得電腦名稱
    string computerName = wmi["Name"].ToString();
}

searcher = new ManagementObjectSearcher("SELECT * FROM Win32_BIOS");
foreach (ManagementObject wmi in searcher.Get())
{
    //取得BIOS序號
    string biosSerialNumber = wmi["SerialNumber"].ToString();
}

關閉應用程式幾種方式

//會通知所有的訊息幫浦,在處理訊息之後,關閉所有應用程式視窗。
Application.Exit();

//結束在目前的執行緒上的訊息迴圈,並關閉執行緒上的所有視窗。
Application.ExitThread();

//結束這個處理序,並將指定的結束代碼授予基礎作業系統。
Environment.Exit(Environment.ExitCode);
參考網站
Environment.Exit是最強制結束的

2014年6月3日 星期二

Windows Services結合WCF呼叫

Windows Services可以常駐於背景,結合WCF後會開啟一個socket供client端呼叫,
建置時Services端要先建好,否則client端會呼叫不到,
先建立服務專案,C# -> Windows -> Windows服務

編寫一些程式碼,這邊用一個文字檔紀錄,主要部分
namespace Service_with_WCF
{
    public partial class ServicePart : ServiceBase
    {
        protected override void OnStart(string[] args)
        {
            StreamWriter sw = new StreamWriter(@"C:\log.txt");
            sw.WriteLine("服務啟動  " + DateTime.Now.ToString());
            sw.Close();
        }
    }
}
服務必須被"安裝"之後才能執行,加入一個服務安裝類別

屬性設置,依個人喜好,Visual Studio有說明提示


加入WCF部分,注意:是新增在服務底下的新項目,不是新增專案

WCF加入後會有一個介面(Interface)類別,一個實體類別以及app.config
介面定義了外部要呼叫的方法名稱,以下為主要部份
namespace Service_with_WCF
{
    [ServiceContract]
    public interface IWCF_Service
    {
        [OperationContract]
        string DoWork(string name);
    }

    public class WCF_Service : IWCF_Service
    {
        public string DoWork(string name)
        {
            return "Hello" + name;
        }
    }
}
app.config最重要的部分在於"呼叫位置",系統會自動產生,其他部分依情況修改
 <add baseAddress="http://localhost:8732/Design_Time_Addresses/Service_with_WCF/WCF_Service/" />

加入一個安裝專案佈署此服務

在服務類別宣告ServiceHost物件,其實就是WCF物件
namespace Service_with_WCF
{
    public partial class ServicePart : ServiceBase
    {
        protected override void OnStart(string[] args)
        {
            ServiceHost host = new ServiceHost(typeof(WCF_Service));
            host.Open();

            StreamWriter sw = new StreamWriter(@"C:\log.txt");
            sw.WriteLine("服務啟動  " + DateTime.Now.ToString());
            sw.Close();
        }
    }
}

安裝專案的自訂動作 -> 應用程式資料夾 -> 加入輸出,把剛剛做的服務加進來

建置,佈署,第一次要手動啟動服務,
可以看到剛剛建立的ExampleService已經成功佈署完成

加入Client端的新專案,這邊用主控台應用程式,
專案 -> 加入服務參考 -> 輸入服務位置就可以看到剛剛佈署的Host

撰寫Client端程式碼,宣告一個服務的Client
namespace Client
{
    class Program
    {
        static void Main(string[] args)
        {
            ServiceReference1.WCF_ServiceClient serviceClient = new ServiceReference1.WCF_ServiceClient();
            string resultStr = serviceClient.DoWork(" Sean");
            Console.WriteLine(resultStr);

            Console.Read();
        }
    }
}

成功的呼叫了服務端的方法

2014年3月30日 星期日

冰雪奇緣 Frozen


老實說我是聽到他的主題歌才看電影的,
好一陣子沒看動畫片了,這次真的有驚豔到,
3D技術的突破,劇情方面也很引人入勝。

華爾街之狼 The Wolf of Wall Street


李奧納多在本片的演技真不是蓋的,主角如此的生活,如此狂傲,不正是大部分人所追求的嗎?

2014年3月12日 星期三

吉他用弦心得

小弟我練吉他的時間雖然沒有很長,換的弦也都是便宜貨,
目前還在找最適合我的弦,打算把市面上的弦都試過,下面是我有用過的弦,
小弟並不是很專業的人士,這些僅供參考,
因為我很容易留手汗,所以弦鏽得特別快,對這方面會比較要求。

Daddario:
這牌子我蠻喜歡的,便宜又好用,又不容易生鏽
●EJ26(11-52) 磷青銅
●EZ 900(10-50)黃銅,這款是舊版,現在應該買不到了

Martin :
一開始都是用這牌的,市面上最容易看到的牌子
●M170(10-47)黃銅,換上去過兩天就開始鏽了,也容易斷
●M130(115-47)銀弦,這款好像用不到兩個禮拜就斷了
MSP 4050 SP(11-52)磷青銅,這套弦是暗金色的,目前使用中

Kerly Strings:
又稱冰火弦,很普通,沒什麼特別感覺,生鏽速度普通
●Earthtones(10-48)黃銅
●KQXA (11-52)磷青銅

John Pearse:
也是很普通
●500XL(11-50)磷青銅

2014年3月11日 星期二

Martin MSP 4050 SP

這套弦是金色的,不是黃銅那種黃金,而是暗金,蠻特別的~!!



2014年3月3日 星期一

五月天 彩虹 吉他彈唱 (Mayday guitar cover)

琴齡:1年7個月
Key:F
Capo:0
Play:F
作曲:阿信/梁伯君
作詞:阿信
錄影:iPhone5s
錄音:ZOOM H1

2014年2月18日 星期二

Null 值

參考文章參考文章-2
資料庫裡面如果有Null會發生什麼事呢?我的物件、參數指向Null又是如何?
Null只能用IsNull之類的方法檢測,並傳回Bool,
這意味者其他的運算子都不能用了,
Null和空字串又不一樣,空字串至少還是"有值"的,可以進行比對,
所以除非特別需要,不然把資料庫裡面的Null都替代掉吧!

重構-改善既有的程式碼 & 向範式前進

重構-改善既有的程式碼(Refactoring: Improving The Design of Existing Code)
作者:Martin Fowler, Kent Beck, John Brant, William Opdyke, don Roberts
譯者:侯捷/熊節
出版社:碁峰資訊
ISBN:9861547533



重構-向範式前進 (Refactoring to Patterns)
作者:Joshua Kerievsky
譯者:侯捷/陳裕城
出版社:碁峰資訊
ISBN:9861814027


這兩本重構作者不一樣,第一本藍色是講比較基礎的,但是都相當實用,
其實在看這兩本之前,我根本不知道什麼是重構,
但是就有自己的一套方法、風格編排程式碼,
看了之後,發現作者和我的想法很接近,
不論是程式的可讀性,想表達清晰邏輯的意圖,
第一本用很短的時間,大約兩天就看完了,其實沒學到什麼,
因為那已經是我的本能了,裡面超過一半的重構手法我都已經用過。

第二本的難度就比較高了,所謂的範式就是GOF的設計模式,
我也是大概翻過而已,主要是看原本沒有,到有設計模式的演化,
裡面程式碼都算有點難度的,要細讀會花很多時間。

這兩本共同點就是"從無到有"的概念,
大型的軟體,一開始就要導入設計模式,如果沒有,程式碼將是一團糟;
中小型的軟體,可以先導入簡單的抽象,若是一開始就大量使用設計模式,
只會有兩個結果,一個是很有用,另一個是很沒用,
若是未來的變化先被猜到了,擴展將是相當容易,
若是沒猜中,要擴展比沒有設計更難,需要大規模的重新撰寫。

一開始不導入,以重構來實現設計模式,是最具有彈性,且最適用於現況改變的方式,
依照不同情況導入不同模式,這個想法相當有前衛性,I Like!

2014年2月17日 星期一

DateTime 結構

參考文章
參考文章-2

這蠻厲害的,各種格式都有,我也來備份一個,很多時候都會用到日期,
值得注意的是月份的 M 是大寫
DateTime dt = DateTime.Now;
string[] strDT = new string[17];
strDT[1] = dt.ToString();//2009/5/25 下午 05:35:21 
strDT[2] = dt.ToFileTime().ToString();//127756416859912816 
strDT[3] = dt.ToFileTimeUtc().ToString();//127756704859912816 
strDT[4] = dt.ToLocalTime().ToString();//2009/5/25 下午 05:35:21 
strDT[5] = dt.ToLongDateString().ToString();//2009年2月28日 
 strDT[6] = dt.ToLongTimeString().ToString();//下午 05:35:21 
strDT[7] = dt.ToOADate().ToString();//39882.6654489321 
strDT[8] = dt.ToShortDateString().ToString();//2009/5/25 
strDT[9] = dt.ToShortTimeString().ToString();//下午 05:35
strDT[10] = dt.ToUniversalTime().ToString();//2009/5/25 上午 09:35:21 
 
strDT[1] = dt.Year.ToString();//2009 
strDT[2] = dt.Date.ToString();//2009/5/26 上午 12:00:00
strDT[3] = dt.DayOfWeek.ToString();//Saturday 
strDT[4] = dt.DayOfYear.ToString();//146 
strDT[5] = dt.Hour.ToString();//13 
strDT[6] = dt.Millisecond.ToString();//441 
strDT[7] = dt.Minute.ToString();//30 
strDT[8] = dt.Month.ToString();//2 
strDT[9] = dt.Second.ToString();//28 
strDT[10] = dt.Ticks.ToString();//632667942284412864 
strDT[11] = dt.TimeOfDay.ToString();//16:25:334412864 
strDT[1] = dt.ToString();//2009/5/26 上午 12:28:21 
strDT[2] = dt.AddYears(1).ToString();//2010/5/26 上午 12:28:21 
strDT[3] = dt.AddDays(1.1).ToString();//2009/5/27 上午 12:28:21 
strDT[4] = dt.AddHours(1.1).ToString();//2009/5/26 上午 01:28:21 
strDT[5] = dt.AddMilliseconds(1.1).ToString();//2009/5/26 上午 12:29:21  
strDT[6] = dt.AddMonths(1).ToString();//2009/6/26 上午 12:28:21 
strDT[7] = dt.AddSeconds(1.1).ToString();//2009/5/26 上午 12:28:22 
strDT[8] = dt.AddMinutes(1.1).ToString();//2009/5/26 上午 12:29:21  
strDT[9] = dt.AddTicks(1000).ToString();//2009/5/26 上午 12:28:21 
strDT[10] = dt.CompareTo(dt).ToString();//0 
//strDT[11] = dt.Add(?).ToString(); //? = TimeSpan Value
strDT[1] = dt.Equals("2009-2-28 16:11:04").ToString();//False 
strDT[2] = dt.Equals(dt).ToString();//True 
strDT[3] = dt.GetHashCode().ToString();//1535674321 
strDT[4] = dt.GetType().ToString();//System.DateTime 
strDT[5] = dt.GetTypeCode().ToString();//DateTime 
    
strDT[1] = dt.GetDateTimeFormats('s')[0].ToString();//2009-05-26T00:28:21
strDT[2] = dt.GetDateTimeFormats('t')[0].ToString();//上午 12:28
strDT[3] = dt.GetDateTimeFormats('y')[0].ToString();//2009年5月
 strDT[4] = dt.GetDateTimeFormats('D')[0].ToString();//2009年5月26日
 strDT[5] = dt.GetDateTimeFormats('D')[1].ToString();//2009年05月26日 

 IFormatProvider culture = new System.Globalization.CultureInfo("zh-CN", true);
strDT[6] = dt.GetDateTimeFormats('D', culture)[2].ToString();//星期二, 2009-05-26
strDT[7] = dt.GetDateTimeFormats('D', culture)[3].ToString();//星期二, 2009年5月26日

 strDT[8] = dt.GetDateTimeFormats('M')[0].ToString();//5月26日
 strDT[9] = dt.GetDateTimeFormats('f')[0].ToString();//2009年5月26日 上午 12:42 
strDT[10] = dt.GetDateTimeFormats('g')[0].ToString();//2009/5/26 上午 12:42
strDT[11] = dt.GetDateTimeFormats('r')[0].ToString();//Tue, 26 May 2009 00:42:05 GMT

strDT[1] = string.Format("{0:d}", dt);//2009/5/26 
strDT[2] = string.Format("{0:D}", dt);//2009年5月26日 
 strDT[3] = string.Format("{0:f}", dt);//2009年5月26日 上午 12:42
strDT[4] = string.Format("{0:F}", dt);//2009年5月26日 上午 12:42:05
strDT[5] = string.Format("{0:g}", dt);//2009/5/26 上午 12:42 
strDT[6] = string.Format("{0:G}", dt);//2009/5/26 上午 12:42:05
strDT[7] = string.Format("{0:M}", dt);//5月26日 
 strDT[8] = string.Format("{0:R}", dt);//Tue, 26 May 2009 00:42:05 GMT
strDT[9] = string.Format("{0:s}", dt);//2009-05-26T00:42:05
strDT[10] = string.Format("{0:t}", dt);//上午 12:42
strDT[11] = string.Format("{0:T}", dt);//上午 12:42:05
strDT[12] = string.Format("{0:u}", dt);//2009-05-26 00:42:05Z 
strDT[13] = string.Format("{0:U}", dt);//2009年5月25日 下午 04:42:05
strDT[14] = string.Format("{0:Y}", dt);//2009年5月
 strDT[15] = string.Format("{0}", dt);//2009/5/26 上午 12:42:05 
strDT[16] = string.Format("{0:yyyyMMddHHmmssffff}", dt); //200905260042057892

Using、Dispose、Close、Connection Pooling...之間的恩怨情仇

參考文章-1
參考文章-2
參考文章-3
參考文章-4

做資料庫專題時,Connection物件實在讓我頭大,到底要用哪個方式結束資料庫連線呢?

首先來看:

Close
關閉了連線,連線字串還在屬性裡,連線資訊被丟進Connection Pooling,
若此物件不為區域變數的話不會被GC回收。

Dispose、Using
其實是做一樣的事情,語法稍有不同而已,
執行了Close,並將連線字串清除,連線資訊被丟進Connection Pooling,
但物件本體也不指向Null,所以...可能會被回收吧?

Null
如果把物件明確地指向Null,下次垃圾車來的時候一定會被回收。

嗯...所以說如果頻繁使用的話,Close可能會是比較好的選擇,
Dispose、Using,會不斷的創建、銷毀物件,
若是很急切的想釋放記憶體,那就指向Null吧!

2014年2月10日 星期一

通訊錄管理

開發環境:
.NET Framework 4.5.1
Visual Studio 2013
Access 2010
C#

下載位置:點選後按右下角下載 http://goo.gl/SFNlKj


2014年2月7日 星期五

2014年2月5日 星期三

度量衡換算工具

開發環境:
.NET Framework 4.5.1
Visual Studio 2013
Access 2010
C#

下載位置:點選後按右下角下載 http://goo.gl/SFNlKj


2014年2月4日 星期二

Software Ideas Modeler 類別圖、流程圖繪製軟體

左邊圖案拉一拉就可以畫出來了,完整度還蠻高的,
也可以輸出成各種通用格式,實用的軟體!
官網連結

2014年2月3日 星期一

SQL LIKE語句,萬用字元的處置

原文在此
避開中括弧   _  %  等萬用字元,用Replace()置換
            inquireStr = inquireStr.Replace("[", "[[]");
            inquireStr = inquireStr.Replace("_", "[_]");
            inquireStr = inquireStr.Replace("%", "[%]");

天眼跟蹤 Cold Eyes


好緊張刺激,讓人想從頭看到尾,果然還是警察片最好看!
女主角臉色蒼白病懨懨的樣子也太正,壞人也太帥,隊長痞痞的也好酷!

戰爭遊戲 Ender's Game


剛開始看的時候覺得蠻唬人的,全地球的命運交給小孩,應該只是特效好看而已吧!
沒想到最後面15分鐘才是最好看的,如果主角事先知道了,就不會採用那樣的戰術,結果可能完全不同!

2014年1月28日 星期二

TryParse,讓轉型更加安全

            //轉換前
            string s = "";
            
            //轉換後
            double d;

            //此方法傳回bool
            //若s為Null或不可轉為double的值,傳回false
            bool b = double.TryParse(s, out d);

            if (b) 
            {
                //do something...
            }
參考原文MSDN
這真是太棒了,不用再寫一大堆驗證使用者輸入的程式碼,
只要判斷傳回值就可以做下一步了,
效能的話很多人測出來都不一樣,有興趣再去查查吧。

2014年1月27日 星期一

OleDbCommandBuilder出現 INSERT INTO 陳述式的語法錯誤

原文在此
原本用SQL Sever都沒這問題,一換Access馬上不行,
其實我看不太懂,總之就是類似跳脫字元那種意思,中括弧Access不認得

加上:
            cb.QuotePrefix = "[";
            cb.QuoteSuffix = "]";

2014年1月26日 星期日

DataTable.Select()

Select()傳回的是DataRow[]
我沒注意用DataTable接,編譯還不會出錯,
結果一直得不到要的數據,

欄位=條件

中間的運算子可以改變,也可用AND OR
模糊查詢運算子用 LIKE,條件前後加%
條件若是字串要加單引號
            //假設前面都已經載入資料,且有個名為dataTable的DataTable
            //這邊把字串前後拆開,可以搜尋不同欄位和條件,增加靈活性
            string s = type + " Like '%" + inquireStr + "%'";
            DataRow[] dataRow = dataTable.Select(s);

            //這是暫時用的,職責是傳回查詢結果
            DataTable dataTable_tmp = dataTable.Clone();

            //用迴圈把DataRow[]一個個加進暫時用的Table
            foreach(DataRow addRow in dataRow)
            {
                dataTable_tmp.ImportRow(addRow);
            }

            return dataTable_tmp;

鋼鐵墳墓 Escape

史特龍和阿諾這兩個也太會演了,
劇情蠻緊張的,
不過美式英雄主義還是有,
例如壞人的子彈都打不到主角~

二維List

最近在做資料庫專題的時候突發奇想,
能不能把List<T>疊起來做成陣列,
依照網路上的資料整理了一下
等於是{9,8;
             6,5}

           //這就是 List 陣列
            List<List<string>> ss = new List<List<string>>();

            //加入9、8再加入6、5
            List<string> s = new List<string> { "9", "8" };          
            ss.Add(s);
            s = new List<string> { "6", "5" };
            ss.Add(s);

            //用2個 foreach 取出來
            foreach (List<string> a in ss)
            {
                foreach (string b in a)
                {
                    Console.WriteLine(b);
                }
            }
            Console.Read();

2014年1月19日 星期日

決戰終點線 RUSH


F1賽車題材的電影,精彩的競速場面是賣點之一,
但貫穿全片的是兩人的友誼,個性完全不同的兩人,
一個是放蕩不羈的浪子,一個中規中矩理性思考,
兩人都有賽車的才華,從最初的互相敵視、扯後腿,到後面的相知,相當值得一看。

2014年1月18日 星期六

五月天 知足 吉他彈唱 (Mayday guitar cover)




很慢,很慢,很慢的歌,請用平靜的心欣賞!

琴齡:1年6個月
Key:C#(原調C)
Capo:1(原調0)
Play:C
作曲:阿信
作詞:阿信
錄影:iPhone5s
錄音:ZOOM H1 

沒對到焦
這首歌也可以彈的很簡單,但是想挑戰一下間奏的部分,
冬天的關係,練滑弦的時候受傷了好幾次~

2014年1月16日 星期四

編程創藝-編寫出卓越的程式碼

作者:Pete Goodlif
譯者:蔡學鏞
出版社:碁峰資訊
ISBN:9789861818382

這本書有一半不是在說技術方面的東西,而是某些比技術更重要的東西,
一些細節部分別的書根本不會提及,這本書倒是讓我開了眼界,
不講艱澀的語法,不講設計模式,
前半段是對個人修養、如何打造"卓越"的程式碼,
後半段講求各式軟體架構、團隊合作。
目前還沒遇過大型團隊的專案,所以後面的部分其實看不太下去,
日後技術更成熟了,接了大型專案,這本書值得再回頭看。

重點筆記:
1、莫非定律:凡是有可能會出錯的事,都一定會出錯,所有的狀況都要以最壞來做設想。
2、寫每一行時都三思,可能會有什麼錯誤?
3、程式設計的目標是清晰,不是精簡。
4、變數的宣告最好與它的使用位置接近。
5、程式碼的撰寫風格,力求一致。
6、變數通常為名詞;方法通常為動詞;類別則見機行事。
7、文件化的程式碼:最高境界!程式碼清晰到不須註解、文件。
8、避免神奇數字,任何數字都應該要設為變數。
9、註解要說明為什麼這麼做,而不是說明這段在幹嘛,這可以靠閱讀程式碼得知。
10、測試越早進行越好,等到最後一堆物件耦合了,那才是地獄...
11、正確的程式碼遠比速度快的重要,快速地得到錯誤的結果毫無意義。
12、迪米特法則,善用封裝維持安全的程式碼。
13、團隊、謙虛、提升、體貼、熱情
14、程式碼是給人讀的,不是給機器讀的。

題外佳句:
1、不可按表面斷定是非,要按公平斷是非 <新約聖經>
2、鏗鏘有力之文必定簡潔 <小威廉斯特倫克>
3、想寫出好東西,源頭和基礎在於明智的想法 <賀瑞斯>
4、卜人之未卜,乃當世聖明 <奧斯卡.王德爾>
5、熱愛真理,寬恕錯誤 <福泰爾>
6、人總會犯錯,悔過就是聖人,不改就是惡魔 <班傑明.富蘭克林>
7、任何人膽敢用超乎自己力量的裝置,都會身陷危險 <JRR.托爾金>
8、我從來沒有失敗過,我只是發現了一萬種行不通的方法 <湯瑪斯.愛迪生>
9、你經歷多年建造的建築物,在一夜之間可能被摧毀,無論如何,仍要繼續建造 <德雷莎修女>
10、人生要不是大膽的冒險,便是一無所獲 <海倫.凱勒>
11、越是尋找安全感,擁有的安全感就越少 <博恩.崔西>
12、跳出極度複雜,就是極度簡單 <溫斯頓.邱吉爾>
13、成功公式中最重要的一個因素,就是知道如何與人相處 <西歐多爾.羅斯福>
14、如果你沒有被批評過的話,那證明你沒做過多少事 <唐納德.拉姆斯菲爾德>
15、你希望人怎樣待你,你也要怎樣待人 <路加福音>

二分搜尋法

最近接觸到二分搜尋法,雖然沒有說明得很深入,但基於研究的精神,還是實作了一個出來

開發環境:
.NET Framework 4.5.1
Visual Studio 2013
C#

下載位置:點選後按右下角下載 http://goo.gl/SFNlKj

UI介面:

流程圖:

程式碼片段:

2014年1月15日 星期三

Google縮址服務

之前要貼網址有時候都一大坨,貼在LINE等通訊軟體上,看了就不想點
不過利用Google縮址服務可以解決這個問題

連結:http://goo.gl/



超簡單,把原網址複製貼上,短網址就出現了,還有歷史紀錄可以查詢