fpm演算法
A. 遺傳演算法求解最短路徑問題
#include "stdafx.h"
#include "stdio.h" //標准輸入輸出庫
#include "stdlib.h" //標准函數庫
#include "time.h"
#include "iostream.h"
#include "iomanip.h"
#include "math.h" //數學函數庫
#define MAX 1 //設定求最大適應值
#define MIN 2
#define CHROMLENGTH 15 //染色體長度,注意編碼變化時,要隨時修改
#define MAXNUM 1000
#define Cmax 30 //估計最大值
#define Cmin 0 //估計最小值
int PopSize = 150; //每代最大個體數
int FunctionMode = MIN;
double m_fPc = 0.9; //交叉概率
double m_fPm = 0.009; //變異概率
int MaxGeneration = 20; //最大世代數
int d[150][15]; //找到染色體並拷貝到這個數組中
int s[150][15];
int generation; //世代數
int Best_Index; //最好個體下標
int Worst_Index; //最壞個體下標
struct indivial //定義個體數據結構
{
double chrom[CHROMLENGTH+1]; //染色體
double value; //函數值
double fitness; //適應度
};
struct indivial
BestIndivial; //當代最佳個體
struct indivial
WorstIndivial;
struct indivial
Group[150]; //種群
double Random(double Low, double High)//本函數實現隨機產生Low-High之間的實數 .意思:隨機
{
return((double)rand()/RAND_MAX)*(High-Low)+Low;
}
double Max(double a, double b)
{
if(a>=b) return a;
else return b;
}
void GenerateInitialPopulation()//種群初始化,二進制編碼初始化其中'1'表示路徑頂點在最短路徑中,'0'則反之
{
int i,j;
for(i = 0; i < PopSize; i++)
{
for(j = 1; j < CHROMLENGTH-2; j++)
{
Group[i].chrom[j] = (int)(Random(1,10)<6)?'\0':'\1';
}
Group[i].chrom[CHROMLENGTH-1] = '\1';
Group[i].chrom[0] = '\1';
}
}
void CalculateObjectValue() //計算個體值
{
int i,j,l;
int a[15][15]=
{{0, 3, 5, MAXNUM,MAXNUM,MAXNUM,MAXNUM,4, MAXNUM,MAXNUM,MAXNUM,MAXNUM,MAXNUM,MAXNUM,MAXNUM},
{MAXNUM,0, MAXNUM,9, 5, MAXNUM,MAXNUM,MAXNUM,MAXNUM,MAXNUM,4, MAXNUM,MAXNUM,MAXNUM,MAXNUM},
{MAXNUM,MAXNUM,0, 4, 3, MAXNUM,MAXNUM,MAXNUM,5, MAXNUM,MAXNUM,MAXNUM,MAXNUM,MAXNUM,MAXNUM},
{MAXNUM,MAXNUM,MAXNUM,0, MAXNUM,1, 5, MAXNUM,MAXNUM,MAXNUM,MAXNUM,MAXNUM,2, MAXNUM,MAXNUM},
{MAXNUM,MAXNUM,MAXNUM,MAXNUM,0, 8, 4, MAXNUM,MAXNUM,6, MAXNUM,MAXNUM,MAXNUM,MAXNUM,MAXNUM},
{MAXNUM,MAXNUM,MAXNUM,MAXNUM,MAXNUM,0, MAXNUM,MAXNUM,MAXNUM,MAXNUM,MAXNUM,2, MAXNUM,4, MAXNUM},
{MAXNUM,MAXNUM,MAXNUM,MAXNUM,MAXNUM,MAXNUM,0, MAXNUM,MAXNUM,MAXNUM,MAXNUM,9, MAXNUM,6, MAXNUM},
{MAXNUM,MAXNUM,MAXNUM,MAXNUM,1, MAXNUM,MAXNUM,0, 7, MAXNUM,MAXNUM,MAXNUM,MAXNUM,MAXNUM,MAXNUM},
{MAXNUM,MAXNUM,MAXNUM,MAXNUM,MAXNUM,4, 4, MAXNUM,0, 2, MAXNUM,MAXNUM,MAXNUM,MAXNUM,MAXNUM},
{MAXNUM,MAXNUM,MAXNUM,MAXNUM,MAXNUM,MAXNUM,MAXNUM,MAXNUM,MAXNUM,0, MAXNUM,5, MAXNUM,7, MAXNUM},
{MAXNUM,MAXNUM,MAXNUM,MAXNUM,MAXNUM,MAXNUM,MAXNUM,MAXNUM,MAXNUM,MAXNUM,0, MAXNUM,1 ,MAXNUM,MAXNUM},
{MAXNUM,MAXNUM,MAXNUM,MAXNUM,MAXNUM,MAXNUM,MAXNUM,MAXNUM,MAXNUM,MAXNUM,MAXNUM,0, MAXNUM,MAXNUM,2 },
{MAXNUM,MAXNUM,MAXNUM,MAXNUM,MAXNUM,MAXNUM,MAXNUM,MAXNUM,MAXNUM,MAXNUM,MAXNUM,MAXNUM,0 ,2, 3 },
{MAXNUM,MAXNUM,MAXNUM,MAXNUM,MAXNUM,MAXNUM,MAXNUM,MAXNUM,MAXNUM,MAXNUM,MAXNUM,MAXNUM,MAXNUM,0, 1 },
{MAXNUM,MAXNUM,MAXNUM,MAXNUM,MAXNUM,MAXNUM,MAXNUM,MAXNUM,MAXNUM,MAXNUM,MAXNUM,MAXNUM,MAXNUM,MAXNUM,0 },};
for(i=0; i < PopSize; i++)
{
for(l=0; l<CHROMLENGTH; l++)
{ if(Group[i].chrom[l]!=0)
{
d[i][l]=a[0][l];
s[i][l]=0;
}
}
d[i][0]=0;
s[i][0]=1;
}
for(i=0; i < PopSize; i++)
{
for(l=0; l<CHROMLENGTH-1; l++)
{
int u=0; //
for(j=0; j<CHROMLENGTH; j++)
{
if(!s[i][j]&&Group[i].chrom[j]=='\1')
{
u=j;
}
s[i][u]=1;
for(int w=0; w<CHROMLENGTH; w++)
if(!s[i][w]&&Group[i].chrom[w]=='\1')
{
d[i][w]=d[i][u]+a[u][w];
}
}
}
Group[i].value = d[i][14];
}
}
void CalculateFitnessValue()//根據優化函數值計算出個體適應度
{
int i;
double temp;
for(i=0; i<PopSize; i++)
{
if(FunctionMode==MAX) //求最大值情況
{
if((Group[i].value + Cmin) > 0.0)
{
temp=Cmin + Group[i].value;
}
else
{
temp=0.0;
}
}
else if(FunctionMode==MIN) //求最小值情況
{
if(Group[i].value<Cmax)
{
temp=Cmax-Group[i].value;
}
else
{
temp=0.0;
}
}
Group[i].fitness=temp;
}
}
void FindBestAndWorstIndivial()//從當前群體中找出適應度最好和最差個體
{
int i;
double sum = 0.0;
Best_Index = 0;
Worst_Index = 0;
BestIndivial = Group[0];
WorstIndivial = Group[0];
for(i = 1; i < PopSize; i++)
{
if(Group[i].fitness > BestIndivial.fitness) //適應度高為更優秀個體
{
BestIndivial = Group[i];
Best_Index = i;
}
else if(Group[i].fitness < WorstIndivial.fitness)
{
WorstIndivial = Group[i];
Worst_Index = i;
}
sum += Group[i].fitness;
}
}
void SelectionOperator()//採用比例選擇運算元產生新群體
{
int i, index;
double p,sum = 0.0;
struct indivial *NewGroup = new struct indivial[PopSize];
double *cfitness = new double[PopSize]; //存每個個體的概率
for(i = 0; i < PopSize; i++)
{
sum += Group[i].fitness ;
}
for(i = 0; i < PopSize; i++)
{
cfitness[i] = Group[i].fitness/sum;
}
for(i = 1; i < PopSize; i++) //計算累計概率
{
cfitness[i] = cfitness[i-1] + cfitness[i];
}
int temp=0;
for(i = 1; i < PopSize; i++)
{
if(cfitness[temp] > cfitness[i])
temp = i;
}
for(i = 0; i < PopSize; i++) //輪盤賭選擇
{
p = (double)(rand()%1000)/1000.0;
index = 0;
while(p > cfitness[index])
{
index++;
}
if(index >= 10)
{
NewGroup[i] = Group[temp];
}
else
{
NewGroup[i] = Group[index];
}
}
//將最好個體復制下來,不參與進化
Group[Best_Index] = Group[Best_Index];
for(i = 0; i < PopSize; i++)
{
if(i != Best_Index)
Group[i] = NewGroup[i];
}
delete []cfitness;
delete []NewGroup;
}
void CrossoverOperator()//採用單點交叉方法產生新群體
{
int i,j;
int index;
int point, temp;
double p;
char ch;
for(i=0; i<PopSize; i++)
{
index=i;
}
for(i=0; i<PopSize; i++)
{
point = (int)Random(0,PopSize-i);
temp=index;
index = point+i;
index = temp;
} //對當前個體進行隨機排序
for(i=0; i<PopSize-1; i+=2)
{
p=rand()%1000/1000.0;
if(p < m_fPc)
{
point = (int)Random(0,CHROMLENGTH-1)+1;
for(j = point; j<CHROMLENGTH; j++)
{
if(Group[index].value<MAXNUM&&Group[index+1].value<MAXNUM)
{
ch = (int)Group[index].chrom[j];
Group[index].chrom[j]=Group[index+1].chrom[j];
Group[index+1].chrom[j] = ch;
}
}
}
}
}
void MutationOperator()//隨機產生變異位,進行染色體基因位的變異
{
int i,j;
double p;
for(i = 0; i < PopSize; i++)
{
if(i != Best_Index) //保證當前最優個體不參與進化
{
for(j = 0;j < CHROMLENGTH; j++)
{
p = rand()%1000/1000.0;
if(p < m_fPm)
{
if(Group[i].value<MAXNUM)
{
Group[i].chrom[j] = (Group[i].chrom[j]==0)?1:0;
}
}
}
}
}
}
void PerformEvolution()//用當前最好個體代替最差個體
{
Group[Worst_Index] = BestIndivial;
}
void OutPut()//輸出計算結果
{
cout<<"所有路徑頂點:";
for(int k=0;k<CHROMLENGTH;k++)
{
cout<<setw(3)<<k;
}
cout<<endl;
cout<<"-------------------------------------------------------------------------------"<<endl;
cout<<"最短路徑頂點:";
for(int j=0; j<CHROMLENGTH; j++)
{
cout<<setw(3)<<BestIndivial.chrom[j];
}
cout<<endl;
cout<<"最短路徑長度:";
cout<<setw(3)<<BestIndivial.value;
cout<<endl;
}
void main(void)
{
generation = 0; //意思:一代,代
GenerateInitialPopulation(); //二進制編碼初始化'1'表示路徑頂點在最短路徑中。意思:最初的群體
CalculateObjectValue(); //計算優化函數值. 意思:計算個體值
CalculateFitnessValue(); //根據優化函數值計算出個體適應度
FindBestAndWorstIndivial(); //從當前群體中找出適應度最好和最差個體
while(generation < MaxGeneration)
{
generation++;
SelectionOperator(); //採用比例選擇運算元產生新群體。意思:選擇
CrossoverOperator(); //採用單點交叉方法產生新群體。意思:交叉
MutationOperator(); //隨機產生變異位,進行染色體基因位的變異。意思:突變操作
CalculateObjectValue(); //計算個體值。意思:計算個體值
CalculateFitnessValue(); //根據優化函數值計算出個體適應度。意思:適應度
FindBestAndWorstIndivial(); //從當前群體中找出適應度最好和最差個體。意思:個體
PerformEvolution(); //用當前最好個體代替最差個體。意思:實行進化
}
OutPut(); //輸出計算結果
}
B. 我想學編程,應該學哪一類,求助
原文地址:http://coolshell.cn/articles/4990.html
博文如下:
前言
你是否覺得自己從學校畢業的時候只做過小玩具一樣的程序?走入職場後哪怕沒有什麼經驗也可以把以下這些課外練習走一遍(朋友的抱怨:學校課程總是從理論出發,作業項目都看不出有什麼實際作用,不如從工作中的需求出發)
建議:
不要亂買書,不要亂追新技術新名詞,基礎的東西經過很長時間積累而且還會在未來至少10年通用。
回顧一下歷史,看看歷史上時間線上技術的發展,你才能明白明天會是什麼樣。
一定要動手,例子不管多麼簡單,建議至少自己手敲一遍看看是否理解了里頭的細枝末節。
一定要學會思考,思考為什麼要這樣,而不是那樣。還要舉一反三地思考。
註:你也許會很奇怪為什麼下面的東西很偏Unix/linux,這是因為我覺得Windows下的編程可能會在未來很沒有前途,原因如下:
現在的用戶界面幾乎被兩個東西主宰了,1)Web,2)移動設備iOS或Android。Windows的圖形界面不吃香了。
越來越多的企業在用成本低性能高的Linux和各種開源技術來構架其系統,Windows的成本太高了。
微軟的東西變得太快了,很不持久,他們完全是在玩弄程序員。詳情參見《Windows編程革命史》
所以,我個人認為以後的趨勢是前端是Web+移動,後端是Linux+開源。開發這邊基本上沒Windows什麼事。
啟蒙入門
可以讓你擺脫對底層語言的恐懼感,腳本語言可以讓你很快開發出能用得上的小程序。實踐項目:
處理文本文件,或者csv(關鍵詞pythoncsv,pythonopen,pythonsys)讀一個本地文件,逐行處理(例如wordcount,或者處理log)
遍歷本地文件系統(sys,os,path),例如寫一個程序統計一個目錄下所有文件大小並按各種條件排序並保存結果
跟資料庫打交道(pythonsqlite),寫一個小腳本統計資料庫里條目數量
學會用各種print之類簡單粗暴的方式進行調試
學會用Google(phrase,domain,usereadertofollowtechblogs)
為什麼要學腳本語言,因為他們實在是太方便了,很多時候我們需要寫點小工具或是腳本來幫我們解決問題,你就會發現正規的編程語言太難用了。
2、用熟一種程序員的編輯器(不是IDE)和一些基本工具
Vim/Emacs/Notepad++,學會如何配置代碼補全,外觀,外部命令等。
SourceInsight(或ctag)
使用這些東西不是為了Cool,而是這些編輯器在查看、修改代碼/配置文章/日誌會更快更有效率。
3、熟悉Unix/LinuxShell和常見的命令行
如果你用windows,至少學會用虛擬機里的linux,vmwareplayer是免費的,裝個Ubuntu吧
一定要少用少用圖形界面。
學會使用man來查看幫助
文件系統結構和基本操作ls/chmod/chown/rm/find/ln/cat/mount/mkdir/tar/gzip…
學會使用一些文本操作命令sed/awk/grep/tail/less/more…
學會使用一些管理命令ps/top/lsof/netstat/kill/tcpmp/iptables/dd…
了解/etc目錄下的各種配置文章,學會查看/var/log下的系統日誌,以及/proc下的系統運行信息
了解正則表達式,使用正則表達式來查找文件。
對於程序員來說Unix/Linux比Windows簡單多了。(參看我四年前CSDN的博文《其實Unix很簡單》)學會使用Unix/Linux你會發現圖形界面在某些時候實在是太難用了,相當地相當地降低工作效率。
4、學習Web基礎(HTML/CSS/JS)+伺服器端技術(LAMP)
未來必然是Web的世界,學習WEB基礎的最佳網站是W3School。
學習HTML基本語法
學習CSS如何選中HTML元素並應用一些基本樣式(關鍵詞:boxmodel)
學會用Firefox+Firebug或chrome查看你覺得很炫的網頁結構,並動態修改。
學習使用javascript操縱HTML元件。理解DOM和動態網頁(DynamicHTML:TheDefinitiveReference,3rdEdition-O'ReillyMedia)網上有免費的章節,足夠用了。或參看DOM。
學會用Firefox+Firebug或chrome調試Javascript代碼(設置斷點,查看變數,性能,控制台等)
在一台機器上配置Apache或Nginx
學習php,讓後台PHP和前台HTML進行數據交互,對伺服器相應瀏覽器請求形成初步認識。實現一個表單提交和反顯的功能。
把PHP連接本地或者遠程資料庫MySQL(MySQL和SQL現學現用夠了)
跟完一個名校的網路編程課程(例如:http://www.stanford.e/~ouster/cgi-bin/cs142-fall10/index.php)不要覺得需要多於一學期時間,大學生是全職一學期選3-5門課,你業余時間一定可以跟上
學習一個javascript庫(例如jQuery或ExtJS)+Ajax(非同步讀入一個伺服器端圖片或者資料庫內容)+JSON數據格式。
HTTP:TheDefinitiveGuide讀完前4章你就明白你每天上網用瀏覽器的時候發生的事情了(proxy,gateway,browsers)
做個小網站(例如:一個小的留言板,支持用戶登錄,Cookie/Session,增、刪、改、查,上傳圖片附件,分頁顯示)
買個域名,租個空間,做個自己的網站。
進階加深
1、C語言和操作系統調用
重新學C語言,理解指針和內存模型,用C語言實現一下各種經典的演算法和數據結構。推薦《計算機程序設計藝術》、《演算法導論》和《編程珠璣》。
學習(麻省理工免費課程)計算機科學和編程導論
學習(麻省理工免費課程)C語言內存管理
學習Unix/Linux系統調用(Unix高級環境編程),,了解系統層面的東西。
用這些系統知識操作一下文件系統,用戶(實現一個可以拷貝目錄樹的小程序)
用fork/wait/waitpid寫一個多進程的程序,用pthread寫一個多線程帶同步或互斥的程序。多進程多進程購票的程序。
用signal/kill/raise/alarm/pause/sigprocmask實現一個多進程間的信號量通信的程序。
學會使用gcc和gdb來編程和調試程序(參看我的《用gdb調試程序》)
學會使用makefile來編譯程序。(參看我的《跟我一起寫makefile》)
IPC和Socket的東西可以放到高級中來實踐。
學習WindowsSDK編程(Windows程序設計,MFC程序設計)
寫一個窗口,了解WinMain/WinProcere,以及Windows的消息機制。
寫一些程序來操作WindowsSDK中的資源文件或是各種圖形控制項,以及作圖的編程。
學習如何使用MSDN查看相關的SDK函數,各種WM_消息以及一些常式。
這本書中有很多常式,在實踐中請不要照抄,試著自己寫一個自己的常式。
不用太多於精通這些東西,因為GUI正在被Web取代,主要是了解一下Windows圖形界面的編程。@virushuo說:「我覺得GUI確實不那麼熱門了,但充分理解GUI工作原理是很重要的。包括移動設備開發,如果沒有基礎知識仍然很吃力。或者說移動設備開發必須理解GUI工作,或者在win那邊學,或者在mac/iOS上學」。
2、學習Java
Java的學習主要是看經典的CoreJava《Java核心技術編程》和《Java編程思想》(有兩卷,我僅鏈了第一卷,足夠了,因為Java的圖形界面了解就可以了)
學習JDK,學會查閱JavaAPIDocJavaPlatformSE6
了解一下Java這種虛擬機語言和C和Python語言在編譯和執行上的差別。從C、Java、Python思考一下「跨平台」這種技術。
學會使用IDEEclipse,使用Eclipse編譯,調試和開發Java程序。
建一個Tomcat的網站,嘗試一下JSP/Servlet/JDBC/MySQL的Web開發。把前面所說的那個PHP的小項目試著用JSP和Servlet實現一下。
3、Web的安全與架構
學習HTML5,網上有很多很多教程,以前酷殼也介紹過很多,我在這里就不羅列了。
學習Web開發的安全問題(參考新浪微博被攻擊的這個事,以及Ruby的這篇文章)
學習HTTPServer的rewrite機制,Nginx的反向代理機制,fast-cgi(如:PHP-FPM)
學習Web的靜態頁面緩存技術。
學習Web的非同步工作流處理,數據Cache,數據分區,負載均衡,水平擴展的構架。
實踐任務:
使用HTML5的canvas製作一些Web動畫。
嘗試在前面開發過的那個Web應用中進行SQL注入,JS注入,以及XSS攻擊。
把前面開發過的那個Web應用改成構造在Nginx+PHP-FPM+靜態頁面緩存的網站
4、學習關系型資料庫
你可以安裝MSSQLServer或MySQL來學習資料庫。
學習教科書里資料庫設計的那幾個範式,1NF,2NF,3NF,……
學習資料庫的存過,觸發器,視圖,建索引,游標等。
學習SQL語句,明白表連接的各種概念(參看《SQLJoin的圖示》)
學習如何優化資料庫查詢(參看《MySQL的優化》)
實踐任務:設計一個論壇的資料庫,至少滿足3NF,使用SQL語句查詢本周,本月的最新文章,評論最多的文章,最活躍用戶。
5、一些開發工具
學會使用SVN或Git來管理程序版本。
學會使用JUnit來對Java進行單元測試。
學習C語言和Java語言的codingstandard或codingguideline。(我N年前寫過一篇關C語言非常簡單的文章——《編程修養》,這樣的東西你可以上網查一下,一大堆)。
推薦閱讀《代碼大全》《重構》《代碼整潔之道》
高級深入
1、C++/Java和面向對象
我個人以為學好C++,Java也就是舉手之勞。但是C++的學習曲線相當的陡。不過,我覺得C++是最需要學好的語言了。參看兩篇趣文「C++學習信心圖」和「21天學好C++」
學習(麻省理工免費課程)C++面向對象編程
讀我的「如何學好C++」中所推薦的那些書至少兩遍以上(如果你對C++的理解能夠深入到像我所寫的《C++虛函數表解析》或是《C++對象內存存局(上)(下)》,或是《C/C++返回內部靜態成員的陷阱》那就非常不錯了)
然後反思為什麼C++要干成這樣,Java則不是?你一定要學會對比C++和Java的不同。比如,Java中的初始化,垃圾回收,介面,異常,虛函數,等等。
實踐任務:
用C++實現一個BigInt,支持128位的整形的加減乘除的操作。
用C++封裝一個數據結構的容量,比如hashtable。
用C++封裝並實現一個智能指針(一定要使用模板)。
《設計模式》必需一讀,兩遍以上,思考一下,這23個模式的應用場景。主要是兩點:1)鍾愛組合而不是繼承,2)鍾愛介面而不是實現。(也推薦《深入淺出設計模式》)
實踐任務:
使用工廠模式實現一個內存池。
使用策略模式製做一個類其可以把文本文件進行左對齊,右對齊和中對齊。
使用命令模式實現一個命令行計算器,並支持undo和redo。
使用修飾模式實現一個酒店的房間價格訂價策略——旺季,服務,VIP、旅行團、等影響價格的因素。
學習STL的用法和其設計概念-容器,演算法,迭代器,函數子。如果可能,請讀一下其源碼。
實踐任務:嘗試使用面向對象、STL,設計模式、和WindowsSDK圖形編程的各種技能
做一個貪吃蛇或是俄羅斯方塊的游戲。支持不同的級別和難度。
做一個文件瀏覽器,可以瀏覽目錄下的文件,並可以對不同的文件有不同的操作,文本文件可以打開編輯,執行文件則執行之,mp3或avi文件可以播放,圖片文件可以展示圖片。
學習C++的一些類庫的設計,如:MFC(看看候捷老師的《深入淺出MFC》),Boost,ACE,CPPUnit,STL(STL可能會太難了,但是如果你能了解其中的設計模式和設計那就太好了,如果你能深入到我寫的《STLstring類的寫時拷貝技術》那就非常不錯了,ACE需要很強在的系統知識,參見後面的「加強對系統的了解」)
Java是真正的面向對象的語言,Java的設計模式多得不能再多,也是用來學習面向對象的設計模式的最佳語言了(參看Java中的設計模式)。
推薦閱讀《EffectiveJava》and《Java解惑》
學習Java的框架,Java的框架也是多,如Spring,Hibernate,Struts等等,主要是學習Java的設計,如IoC等。
Java的技術也是爛多,重點學習J2EE架構以及JMS,RMI,等消息傳遞和遠程調用的技術。
學習使用Java做WebService(官方教程在這里)
實踐任務:嘗試在Spring或Hibernate框架下構建一個有網路的WebService的遠程調用程序,並可以在兩個Service中通過JMS傳遞消息。
C++和Java都不是能在短時間內能學好的,C++玩是的深,Java玩的是廣,我建議兩者選一個。我個人的學習經歷是:
深究C++(我深究C/C++了十來年了)
學習Java的各種設計模式。
2、加強系統了解
重要閱讀下面的幾本書:
《Unix編程藝術》了解Unix系統領域中的設計和開發哲學、思想文化體系、原則與經驗。你一定會有一種醍醐灌頂的感覺。
《Unix網路編程卷1,套接字》這是一本看完你就明白網路編程的書。重要注意TCP、UDP,以及多路復用的系統調用select/poll/epoll的差別。
《TCP/IP詳解卷1:協議》-這是一本看完後你就可以當網路黑客的書。了解乙太網的的運作原理,了解TCP/IP的協議,運作原理以及如何TCP的調優。
實踐任務:
理解什麼是阻塞(同步IO),非阻塞(非同步IO),多路復用(select,poll,epoll)的IO技術。
寫一個網路聊天程序,有聊天伺服器和多個聊天客戶端(服務端用UDP對部分或所有的的聊天客戶端進Multicast或Broadcast)。
寫一個簡易的HTTP伺服器。
《Unix網路編程卷2,進程間通信》信號量,管道,共享內存,消息等各種IPC……這些技術好像有點老掉牙了,不過還是值得了解。
實踐任務:
主要實踐各種IPC進程序通信的方法。
嘗試寫一個管道程序,父子進程通過管道交換數據。
嘗試寫一個共享內存的程序,兩個進程通過共享內存交換一個C的結構體數組。
學習《Windows核心編程》一書。把CreateProcess,Windows線程、線程調度、線程同步(Event,信號量,互斥量)、非同步I/O,內存管理,DLL,這幾大塊搞精通。
實踐任務:使用CreateProcess啟動一個記事本或IE,並監控該程序的運行。把前面寫過的那個簡易的HTTP服務用線程池實現一下。寫一個DLL的鉤子程序監控指定窗口的關閉事件,或是記錄某個窗口的按鍵。
有了多線程、多進程通信,TCP/IP,套接字,C++和設計模式的基本,你可以研究一下ACE了。使用ACE重寫上述的聊天程序和HTTP伺服器(帶線程池)
實踐任務:通過以上的所有知識,嘗試
寫一個服務端給客戶端傳大文件,要求把100M的帶寬用到80%以上。(注意,磁碟I/O和網路I/O可能會很有問題,想一想怎麼解決,另外,請注意網路傳輸最大單元MTU)
了解BT下載的工作原理,用多進程的方式模擬BT下載的原理。
3、系統架構
負載均衡。HASH式的,純動態式的。(可以到Google學術里搜一些關於負載均衡的文章讀讀)
多層分布式系統–客戶端服務結點層、計算結點層、數據cache層,數據層。J2EE是經典的多層結構。
CDN系統–就近訪問,內容邊緣化。
P2P式系統,研究一下BT和電驢的演算法。比如:DHT演算法。
伺服器備份,雙機備份系統(Live-Standby和Live-Live系統),兩台機器如何通過心跳監測對方?集群主結點備份。
虛擬化技術,使用這個技術,可以把操作系統當應用程序一下切換或重新配置和部署。
學習Thrift,二進制的高性能的通訊中間件,支持數據(對象)序列化和多種類型的RPC服務。
學習Hadoop。
Hadoop框架中最核心的設計就是:MapRece和HDFS。MapRece的思想是由Google的一篇論文所提及而被廣為流傳的,簡單的
一句話解釋MapRece就是「任務的分解與結果的匯總」。HDFS是Hadoop分布式文件系統(HadoopDistributedFile
System)的縮寫,為分布式計算存儲提供了底層支持。
了解NoSQL資料庫(有人說可能是一個過渡炒作的技術),
不過因為超大規模以及高並發的純動態型網站日漸成為主流,而SNS類網站在數據存取過程中有著實時性等剛性需求,這使得目前NoSQL資料庫慢慢成了人們
所關注的焦點,並大有成為取代關系型資料庫而成為未來主流數據存儲模式的趨勢。當前NoSQL資料庫很多,大部分都是開源的,其中比較知名的
有:MemcacheDB、Redis、TokyoCabinet(升級版為Kyoto
Cabinet)、Flare、MongoDB、CouchDB、Cassandra、Voldemort等。
寫了那麼多,回顧一下,覺得自己相當的有成就感。希望大家不要嚇著,我自己這十來年也在不斷地學習,今天我也在學習中,人生本來就是一個不斷學習和練級的過程。不過,一定有漏的,也有不對的,還希望大家補充和更正。(我會根據大家的反饋隨時更新此文)歡迎大家通過我的微博(@左耳朵耗子)和twitter(@haoel)和我交流。
—–更新2011/07/19—–
1)有朋友奇怪為什麼我在這篇文章開頭說了web+移動,卻沒有在後面提到iOS/Android的前端開發。因為我心裡有一種感覺,移動設備上的UI最終也會被Javascript取代。大家可以用iPhone或Android看看google+,你就會明白了。
2)
有朋友說我這里的東西太多了,不能為了學習而學習,我非常同意。我在文章的前面也說了要思考。另外,千萬不要以為我說的這些東西是一些新的技術,這份攻略
里95%以上的全是基礎。而且都是久經考驗的基礎技術。即是可以讓你一通百通的技術,也是可以讓你找到一份不錯工作的技術。
3)有朋友說學
這些東西學完都40了,還不如想想怎麼去掙錢。我想告訴大家,一是我今年還沒有40歲,二是學無止境啊,三是我不覺得掙錢有多難,難的是怎麼讓你值那麼多
錢?無論是打工還是創業,是什麼東西讓你自己的價值,讓你公司的價值更值錢?別的地方我不敢說,對於互聯網或IT公司來說,技術實力絕對是其中之一。
4)有朋友說技術都是工具,不應該如此痴迷這句話沒有錯,有時候我們需要更多的是抬起頭來看看技術以外的事情,或者是說我們在作技術的時候不去思考為什麼會有這個技術,為什麼不是別的,問題不在於技術,問題在於我們死讀書,讀死書,成了技術的書獃子。
5)對於NoSQL,最近比較火,但我對其有點保守,所以,我只是說了解就可以。對於Hadoop,我覺得其在分布式系統上有巨大的潛力,所以需要學習。對於關系型資料庫,的確是很重要的東西,這點是我的疏忽,在原文里補充。
C. 3D專業名詞解釋大全
3D API (3D應用程序介面)
Application Programming Interface(API)應用程序介面,是許多程序的大集合。3D API能讓編程人員所設計的3D軟體只要調用其API內的程序,從而讓API自動和硬體的驅動程序溝通,啟動3D晶元內強大的3D圖形處理功能,從而大幅度地提高了3D程序的設計效率。幾乎所有的3D加速晶元都有自己專用的3D API,目前普遍應用的3D API有DirectX、OpenGL、Glide、Heidi等。
Direct 3D
微軟公司於1996年為PC開發的API,與Windows 95 、Windows NT和Power Mac操作系統兼容性好,可繞過圖形顯示介面(GDI)直接進行支持該API的各種硬體的底層操作,大大提高了游戲的運行速度,而且目前基本上是免費使用的。由於要考慮與各方面的兼容性,DirectX用起來比較麻煩、在執行效率上也未見得最優,在實際3DS MAX的運用中效果一般,還會發生顯示錯誤,不過總比用軟體加速快。
OpenGL (開放式圖形介面)
是由SGI公司開發的IRIS GL演變而來的復雜3D圖形設計的標准應用程序介面。它的特點是可以在不同的平台之間進行移植;還可以在客戶機/伺服器系統中並行工作。效率遠比Direct 3D高,所以是各3D游戲開發商優先選用的3D API。不過,這樣一來就使得許多精美的3D游戲在剛推出時,只支持3Dfx公司的VOODOO系列3D加速卡,而其它類型的3D加速卡則要等待其生產廠商提供該游戲的補丁程序。由於游戲用的3D加速卡提供的OpenGL庫都不完整,因此,在3DS MAX中也會發生顯示錯誤,但要比Direct 3D強多了!
Heidi
又稱為Quick Draw 3D,是由Autodesk公司提出來的規格。它是採用純粹的立即模式介面,能夠直接對圖形硬體進行控制;可以調用所有顯示卡的硬體加速功能。目前,採用Heidi系統的應用程序包括3D Studio MAX動畫製作程序、Auto CAD和3D Studio VIZ等軟體。Autodesk公司為這些軟體單獨開發WHIP加速驅動程序,因此性能優異是非常明顯的!
Glide
是由3dfx公司開發的Voodoo系列專用的3D API。它是第一個PC游戲領域中得到廣泛應用的程序介面,它的最大特點是易用和穩定。隨著D3D和OpenGL的興起,已逐漸失去了原來的地位。
PowerSGL
是NEC公司PowerVR系列晶元專用的程序介面。
3D特性: Alpha Blending (α混合)
簡單地說這是一種讓3D物件產生透明感的技術。屏幕上顯示的3D物件,每個像素中有紅、綠、藍三組數值。若3D環境中允許像素能擁有一組α值,我們就稱它擁有一個α通道。α值的內容,是記載像素的透明度。這樣一來使得每一個物件都可以擁有不同的透明程度。比如說,玻璃會擁有很高的透明度,而一塊木頭可能就沒什麼透明度可言。α混合這個功能,就是處理兩個物件在螢幕畫面上疊加的時候,還會將α值列入考慮,使其呈現接近真實物件的效果。
Fog Effect (霧化效果)
霧化效果是3D的比較常見的特性,在游戲中見到的煙霧、爆炸火焰以及白雲等效果都是霧化的結果。它的功能就是製造一塊指定的區域籠罩在一股煙霧彌漫之中的效果,這樣可以保證遠景的真實性,而且也減小了3D圖形的渲染工作量。
Attenuation (衰減)
在真實世界中,光線的強度會隨距離的增大而遞減。這是因為受到了空氣中微粒的衍射影響,而在3D Studio MAX中,場景處於理想的「真空」中,理論上無這種現象出現。但這種現象與現實世界不符,因此為了達到模擬真實的效果,在燈光中加入該選項,就能人為的產生這種效果!
Perspective Correction (透視角修正處理)
它是採用數學運算的方式,以確保貼在物件上的部分影像圖,會向透視的消失方向貼出正確的收斂。
Anti-aliasing (抗鋸齒處理)
簡單地說主要是應用調色技術將圖形邊緣的「鋸齒」緩和,邊緣更平滑。抗鋸齒是相對來來說較復雜的技術,一直是高檔加速卡的一個主要特徵。目前的低檔3D加速卡大多不支持反鋸齒。
D. php直播源代碼做開發有什麼優勢
PHP(Hypertext Preprocessor),超文本預處理器,是一種通用性開源腳本語言。它的語法吸取了C語言、Java和Perl的優點,免費、快捷、高效,主要適用於Web開發領域。
目前,全球5000萬互聯網網站60%以上都在使用PHP技術,AlexaTOP500中國網站排名中有394家使用PHP,國內80%以上動態網站使用PHP進行開發,在Web後端語言中PHP全球市場語言佔有率達到80%。
像Facebook、Google、新浪、網路、YouTube、騰訊都在使用PHP。
PHP語言的八大優勢:
1、開放源代碼,所有的PHP源代碼事實上都可以得到。
2、免費性,php和其它技術相比,PHP本身免費且是開源代碼。
3、快捷性,程序開發快,運行快,技術本身學習快。嵌入於HTML:因為PHP可以被嵌入於HTML語言,它相對於其他語言。編輯簡單,實用性強,更適合初學者。
4、跨平台性強,由於PHP是運行在伺服器端的腳本,可以運行在UNIX、LINUX、WINDOWS、Mac OS下。
5、專業專注,PHP支持腳本語言為主,同為類C語言。
6、效率高PHP消耗相當少的系統資源。
7、面向對象,在php4,php5 中,面向對象方面都有了很大的改進,php完全可以用來開發大型商業程序。
8、圖像處理,用PHP動態創建圖像,PHP圖像處理默認使用GD2。且也可以配置為使用image magick進行圖像處理。
PHP的3種常用運行方式:CGI、FastCGI、APACHE2HANDLER。
1、CGI
CGI即通用網關介面(common gatewag interface),它是一段程序,通俗的講CGI就像是一座橋,把網頁和WEB伺服器中的執行程序連接起來,它把HTML接收的指令傳遞給伺服器的執行程序,再把伺服器執行程序的結果返還給HTML頁。CGI 的跨平台性能極佳,幾乎可以在任何操作系統上實現。
2、FastCGI
fast-cgi 是cgi的升級版本,FastCGI像是一個常駐(long-live)型的CGI,它可以一直執行著,只要激活後,不會每次都要花費時間去fork一 次。PHP使用PHP-FPM(FastCGI Process Manager),全稱PHP FastCGI進程管理器進行管理。
但每一個Web 請求PHP都必須重新解析php.ini、重新載入全部擴展並重初始化全部數據結構。使用FastCGI,所有這些都只在進程啟動時發生一次。一個額外的好處是,持續資料庫連接(Persistent database connection)可以工作。
3、APACHE2HANDLER
PHP作為Apache模塊,Apache伺服器在系統啟動後,預先生成多個進程副本駐留在內存中,一旦有請求出現,就立即使用這些空餘的子進程進行處理,這樣就不存在生成子進程造成的延遲了。這些伺服器副本在處理完一次HTTP請求之後並不立即退出,而是停留在計算機中等待下次請求。對於客戶瀏覽器的請求反應更快,性能較高。
如何保護自己的PHP代碼:
1、代碼混淆+加密
就是把代碼base64加密,然後對base64里的字元串進行字元串映射(隨機生成字典混淆)然後eval執行 這種百分之百能被破解還原。
2、混淆亂碼字元
代碼混淆變數還有一些東西 和1原理差不多,不過是把字元串換到 ascii 127到255之間非人類還有編輯器看不懂的字元 ,結果也是百分之百能被破解和還原,只是時間問題。
3、發放opcode
不分發代碼,而是先把PHP代碼預編譯,分發opcode,PHP7以後opcache深度集成這個東西 PHP7以後可以用這個方法保護源碼,但是也會被opcode反編譯回去 也會被破解。
4、混淆+加密+寫PHP擴展
混淆+加密+寫PHP擴展,但是只要是開源的PHP擴展都會被破解,除非自己寫加密演算法,把PHP代碼加密, 然後自己拿C語音寫擴展閉源, 別人不知道你加密思路和破解思路,被破解的可能性很小。