QUnit是一個基于JQuery的單元測試Unit Testing 框架。雖然是基于JQuery但用來
測試純Javascript代碼。
用來運行Javascript單元測試用例的html頁面是這樣的:
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>QUnit test runner</title> <link rel="stylesheet" href="lib/qunit-1.10.0.css"> </head> <body> <div id="qunit"></div> <div id="qunit-fixture"></div> <script src="lib/qunit-1.10.0.js"></script> <!--test code goes here--> </body> </html> |
假設我們有如下簡單的javascript代碼simpleMath.js,實現基本的數學操作,階乘,平均數。
SimpleMath = function() { }; SimpleMath.prototype.getFactorial = function (number) { if (number < 0) { throw new Error("There is no factorial for negative numbers"); } else if (number == 1 || number == 0) { // If number <= 1 then number! = 1. return 1; } else { // If number > 1 then number! = number * (number-1)! return number * this.getFactorial(number-1); } } SimpleMath.prototype.signum = function (number) { if (number > 0) { return 1; } else if (number == 0) { return 0; } else { return -1; } } SimpleMath.prototype.average = function (number1, number2) { return (number1 + number2) / 2; } |
如對getFactorial函數,我們可以編寫以下3種測試用例:
正數,零,負數
// Factorial testing module module("Factorial", { setup: function() { this.simpleMath = new SimpleMath(); }, teardown: function() { delete this.simpleMath; } }); test("calculating factorial for a positive number", function() { equal(this.simpleMath.getFactorial(3), 6, "Factorial of three must equal six"); }); test("calculating factorial for zero", function() { equal(this.simpleMath.getFactorial(0), 1, "Factorial of zero must equal one"); }); test("throwing an error when calculating the factorial for a negative number", function() { raises(function() { this.simpleMath.getFactorial(-10) }, "There is no factorial for negative numbers ..."); }); |
上面的代碼中,module中有setup, teardown可以讓我們事前事后做一些操作,使用斷言equal期望3的階乘結果是6,如果您有接觸過Java或C#平臺的單元測試,應該不能理解。然后我們把2個js腳本文件引入到上面html中
<script src="src/simpleMath.js"></script>
<script src="tests/simpleMathTest.js"></script>
最終我們在瀏覽器中打開這個html,結果也就是顯示出來了。
如上圖,我們看到7個測試用例,全部有通過了,點擊前2個用例,顯示出斷言的結果。常見的斷言還有ok( truthy [, message ] ), deepEqual( actual, expected [, message ] ),如下是ok:
ok(true, "true passes");
ok(4==4, "4 must equal 4");
ok("some string", "Non-empty string passes");
QUnit也有支持異步ajax的測試方法asyncTest,由于篇幅有限,在這兒不多介紹了。寫這篇文章的時候,QUnit是v1.14.0版本了。未來可能還有新版本。更多內容,請可以參考API文檔。
希望對您軟件開發有幫助。
互聯網的快速發展,給
web開發人員帶來了前所未有的挑戰。對于前端開發,前端開發er所需要編寫的js早已不是那些寥寥幾行的視覺效果代碼。代碼量的大增,多人協同,人員素質懸殊不齊,這都需要一個標準,來對代碼的規范性進行控制。Jasmine作為一個前端團隊使用的
測試框架,便運應而生。
1、jasmine簡介
jasmine是一個用來編寫Javascript測試的框架,它不依賴于任何其它的javascript框架。它有擁有靈巧而明確的語法可以讓你輕松的編寫測試代碼。目前最新的版本為2.0.0。
在jasmine中,一個典型的
單元測試起始于一個全局函數describe,describe包含了N個it函數,一個it函數包含N個斷言。
一個基本的測試代碼如下:
復制代碼
describe("A suite", function() {
it("contains spec with an expectation", function() {
expect(true).toBe(true);
});
});
復制代碼
2、下載jasmine
大家可以點擊下面的鏈接進行下載:
https://github.com/pivotal/jasmine/tree/master/dist
推薦下載2.0.0版本的壓縮包。
解壓之后,我們進入文件目錄下的lib\jasmine-2.0.0,這下面通常包括以下這些文件。
這些文件是我們進行js測試所需要的。
3、jasmine的依賴
jasmine的運行依賴4個部分:
1) 運行環境
瀏覽器(ie,Firefox,chrome)
2) 源文件
開發人員編寫的js腳步
3) 測試文件
符合jasmineAPI的測試腳本
4) 輸出結果
基于網頁輸出或控制臺輸出
4、jasmine的使用
我們在項目中新建
test.html文件,主體代碼如下:
<!DOCTYPE html> <html> <head> <meta http-equiv="content-type" content="text/html;charset=utf-8"> <title>jasmine-js單元測試框架</title> <link rel="stylesheet" href="jasmine/jasmine.css"> <script src="jasmine/jasmine.js"></script> <script src="jasmine/jasmine-html.js"></script> <script src="jasmine/boot.js"></script> </head> <body> <div> <p>js單元測試</p> </div> <script src="src.js"></script> <script src="test.js"></script> </body> </html> |
在頁面中我們引入了5個js文件和1個css文件。
jasmine.js : jasmine框架的核心文件。
jasmine-html.js : 用于網頁結果輸出的js文件。
boot.js : jasmine框架的的啟動腳本。值得注意的是,這個腳本的執行應該在jasmine.js加載完成之后。
src.js : 我們的業務邏輯腳本。
test.js : jasmine測試腳本。
jasmine.css :控制網頁結果輸出的樣式文件。
我們來看看src.js文件,我們定義了一個showName的函數
function showName(name){
return 'my name is '+name;
}
我們在test.js內進行測試腳本的編寫:
describe('just a test',function(){ it('test showName',function(){ var a='ck'; var exp='my name is ck'; expect(exp).toEqual(showName(a)); }); }); |
瀏覽器端運行test.html文件,輸出如下:
這表明我們的腳本順利通過了測試。
我們修改test.js文件
var exp='my name is mm';
再次運行test.html文件,輸入如下:
可以看到jasmine把錯誤信息都打印了出來。
通過這個簡單例子,我們可以看到,使用jasmine來進行單元測試是非常方便的。
5、API
describe(string,function)
全局函數,接收兩個參數
string:函數的描述
function:測試組函數
It(string,function)
一個測試specs,接收兩個參數
string:spces的名稱
function:spces函數
beforeEach(function)
定義在一個describe的所有it執行前做的操作
afterEach(function)
定義在一個describe的所有it執行后做的操作
toBe
等同于===,比較變量
toEqual
處理變量,數組,對象等等
toMatch
使用正則式進行匹配
toBeDefined
是否已聲明且賦值
toBeUndefined
是否未聲明
toBeNull
是否null
toBeTruthy
如果轉換為布爾值,是否為true
toBeFalsy
如果轉換為布爾值,是否為false
toContain
數組中是否包含元素(值)。只能用于數組,不能用于對象
toBeLessThan
數值比較,小于
toBeGreaterThan
數值比較,大于
toBeCloseTo
數值比較時定義精度,先四舍五入后再比較
toThrow
檢驗一個函數是否會拋出一個錯誤
it("toThrow檢驗一個函數是否會拋出一個錯誤", function() { var foo = function() { return 1 + 2; }; var bar = function() { return a + 1; }; expect(foo).not.toThrow(); expect(bar).toThrow(); }); |
jasmine中還有一個強大的spy函數,用它可以監控函數的調用情況,因為涉及的內容比較多且文章只是起到拋磚引玉的作用,所以我就不一一列舉了,大家感興趣可以到官網進行深入了解。
說說正常的代碼吧
1)
<span style="font-size:14px;">package com.medivh.app; public class Person { public String sub(String username) { String sub = username.substring(3); return sub; } public int add(int a,int b) { return a+b; } }</span> |
2:
<span style="font-size:14px;">package com.medivh.app; import org.junit.Test; import junit.framework.Assert; import android.test.AndroidTestCase; public class PersonTest extends AndroidTestCase { @Test public void testSub() throws Exception { Person p = new Person(); p.sub(null); } public void testAdd() throws Exception { Person p = new Person(); int result = p.add(1, 4); Assert.assertEquals(result, 6); } } </span> |
2)AndroidManifest.xml
<span style="font-size:14px;"><?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.medivh.app" android:versionCode="1" android:versionName="1.0"> <application android:icon="@drawable/ic_launcher" android:label="@string/app_name"> <activity android:name=".MainActivity" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <span style="color:#FF0000;"><uses-library android:name="android.test.runner" /></span> </application> <uses-sdk android:minSdkVersion="8" /> <span style="color:#FF0000;"><instrumentation android:name="android.test.InstrumentationTestRunner" android:targetPackage="com.medivh.app" android:label="Tests for My App" /></span> </manifest> </span> |
3)測試
右鍵項目Run as.. Android Junit Test 就會出結果
開始的時候犯迷糊結果各種出錯:
No instrumentation runner found for the launch, using android.test.InstrumentationTestRunner
First does not specify a android.test.InstrumentationTestRunner instrumentation or does not declare uses-library android.test.runner in its AndroidManifest.xml
is not configured correctly for running tests
到網上各種查,發現配置沒錯啊。最后才發現問題出在我居然眼睛進沙子一般修改了bin下面的AndroidManifest.xml,可能是我前面打開了這個目錄,結果就隨意打開了它修改了它。希望大家以后小心行事。
編寫
android業務代碼的時候,我們需要
測試其正確性,那就用進行各種測試,很多時候,我們都是用的 System.out.println("XXXXX") 來進行驗證,但有時候,我們肉眼也不一定就能判斷的準確,所以可以考慮用下
junit。
JUnit是個自動化
單元測試工具,能夠根據你需要測試的類及其接口自動生成該類的單元測試案例,你只要根據你的需要,就輸入必要的測試數據就行了,系統運行后自動判斷運行是否成功。
下面我來介紹下如何使用JUnit來測試android項目。
由于android系統已經集成了JUnit框架,所以我們無需導入JUnit的jar包。
1、在AndroidManifest.xml文件中聲明使用JUnit測試的包名 及加載JUnit類庫代碼,如下
如上圖,<uses-library>標簽 作用是指定該應用程序必須鏈接的共享類庫。這個元素告訴系統該應用程序包的類裝載器中所包含的類庫代碼。
<instrumentation> 可以理解為一種沒有圖形界面的,具有啟動能力的,用于監控其他類(用Target Package聲明)的工具類。任何想成為Instrumentation的類必須繼承android.app.Instrumentation。
我們需要測試的就是項目 net.thinkeye.junitest 包下的類。
2、寫好的業務類:src/net/thinkeye/junitest/PersonService.java
package net.thinkeye.junitest; /** * 業務類,代碼很簡單 * @author Johnny */ public class PersonService { /** * 取Person的方法 * 因為使用了String的substring方法,當傳入字段為空時即報異常 * @param name */ public void getPerson(String name){ name = name.substring(8); } /** * 添加Person方法 * 可以使用Assert.assertEquals來測試其返回值的正確性 * @param a * @param b * @return */ public int addPerson(int a,int b){ return a+b; } } |
3、測試類,src/net/thinkeye/test/JTest.java 需繼承 android.test.AndroidTestCase 類
package net.thinkeye.test; import junit.framework.Assert; import net.thinkeye.junitest.PersonService; import android.test.AndroidTestCase; /** * 測試類,需繼承android.test.AndroidTestCase類 * @author Johnny * */ public class JTest extends AndroidTestCase{ /** * 測試getPerson方法 * @throws Exception */ public void testGetPerson() throws Exception{ PersonService ps = new PersonService(); ps.getPerson(null); } /** * 測試addPerson方法 * @throws Exception */ public void testAddPerson()throws Exception{ PersonService ps = new PersonService(); int t = ps.addPerson(2, 4); System.out.println(t); Assert.assertEquals(6, t);//junit.framework.Assert的作用判斷t值是否等于6 } } |
4、完成以上的步驟就可以開始測試了,如下圖
當傳入null時報異常
輸入的字符串正確時通過了測試!
addPerson方法的測試
上面就是簡單的測試例子,附上代碼:
今天把
Linux的網絡配置總結了一下,雖然并不難但是是個比較重要的基礎。然后我也不知到自己以后是否會做運維,但是我知道自己比較喜歡刨根問底。還有就是我非常珍惜我曾經掌握過的這些運維的技能。今天突然間問自己,Linux網絡配置的那個文件路徑是什么。突然間小心臟又繃緊了,我發現記憶已經開始模糊了。雖然陸續有把之前運維的筆記整理上來,但是每次都有種寫遺書的淡淡地憂傷在里面。突然間又想暴粗口了。。。。。
一、網絡基本配置
首先就是/etc/sysconfig/network-scripts/ifcfg-eth0這個配置文件。這里的eth0就是我們的網卡名字,也是默認的名字。我們先來看看這個配置文件,如下(以我自己機子為例子):
DEVICE="eth0"
BOOTPROTO="dhcp"
HWADDR="60:EB:69:BA:19:03"
NM_CONTROLLED="yes"
ONBOOT="yes"
TYPE="Ethernet"
UUID="10372dbd-9192-405d-b567-6cb32642acfa"
由于是自家用的小電腦,配置比較簡單。我們來一個一個介紹一下先:
DEVICE:這個是網卡的名字,不是特別重要
BOOTPROTO:這個一共有4個值分別是none、static、bootp、dhcp。none值主要是在網卡綁定的時候用到的,一般不使用。static值配置靜態ip,一般我們在配服務器的時候就使用static(畢竟服務器要是經常ip變動,我相信
騰訊肯定會被勞資們拆了)。bootp值也不常用,它是指通過bootp協議獲取ip。bootp是一種udp/ip的協議,具體可以再去了解一下。dhcp值這個一般自家用,就是通過dhcp獲取ip。
HWADDR:這個是網卡MAC地址
NM_CONTROLLED:這里的前綴NM是指NetworkManager,是一款Linux自帶的網絡管理工具。yes就是說這個網卡受到NM的控制,no就是不受它控制。一般做服務器配靜態ip都會把這里設成no,然后NM的開機啟動也要用chkconfigoff掉。
ONBOOT:這個是指開機的時候是否啟動這個網卡,yes就是開機啟動,no就是不啟動。
TYPE:網卡類型
UUID:這個是全球唯一標識,沒有用的東西。
由于我電腦用的是dhcp,所以補充一些簡單的配置字段:
IPADDR=192.168.1.10//ip地址
NETMASK=255.255.255.0//子網掩碼
GATEWAY=192.168.1.1//默認網關
PEERDNS:是否指定DNS。如果使用DHCP協議,默認為yes。
yes:如果DNS設置,修改/etc/resolv.conf中的DNS
no:不修改/etc/resolv.conf中的DNS
DNS{1,2}:DNS地址。當PEERDNS為yes時會被寫入/etc/resolv.conf中
USERCTL:用戶權限控制
yes:非root用戶允許控制該網絡接口
no:非root用戶不運行控制該網絡接口
IPV6INIT:是否執行IPv6
yes:支持IPv6
no:不支持IPv6
IPV6ADDR:IPv6地址/前綴長度
二、獻給那些windows運維人員
在我實習的時候,我看到有很多運維window的員工適應不了windows運維到Linux運維的轉變。畢竟也上了一些年紀,然后確實轉變挺大的。所以我這里給上一個setup命令,可以在Linux下面提供window的圖形化界面配置。希望可以幫助到一些人:
非常棒吧,(*^__^*)。除了Networkconfiguration之后,還可以對防火墻、開機啟動等各方面的配置。配置完之后,會自動在對應的配置文件中進行修改。具體的使用不難,大家自己摸索一下吧。
三、網絡配置進階——網卡綁定
這個綁定分為2種:單網卡綁定多個ip和多網卡綁定單個ip
單網卡綁定多個ip
使用情景:
比如公司使用不同的運營商。為了提高系統穩定性,會為網卡綁定兩個ip。或者像一臺服務器運行多個小型網站站點,也會需要綁定多個ip地址。
具體配置(非常簡單):
首先因為我環境比較特殊,先進行下面的配置:
1、把ifcfg-eth0配置為靜態ip地址(192.168.11.10)
2、serviceNetworkManagerstop關閉掉NM
然后我們在當前的配置目錄下執行cpifcfg-eth0ifcfg-eth0:0利用原來的配置,創建新的子網卡文件各個配置文件如下:
ifcfg-eth0
DEVICE="eth0"
BOOTPROTO="static"
IPADDR="192.168.11.10"
HWADDR="60:EB:69:BA:19:03"
NM_CONTROLLED="yes"
ONBOOT="yes"
TYPE="Ethernet"
UUID="10372dbd-9192-405d-b567-6cb32642acfa"
ifcfg-eth0:0
DEVICE="eth0:0"
BOOTPROTO="static"
IPADDR="192.168.11.11"
HWADDR="60:EB:69:BA:19:03"
NM_CONTROLLED="yes"
ONBOOT="yes"
TYPE="Ethernet"
UUID="10372dbd-9192-405d-b567-6cb32642acfa"
最后重啟一下網絡,查看一下效果:
多網卡綁定單個ip
使用情景:
這個一般是提高網絡的高可用性,當一塊網卡出現問題的時候使用第二快網卡。雖然聽起來好像很夸張,但是像思科的路由器也會裝有備用電源或者CPU(不是我們電腦的cpu,是路由器的)
具體配置:
1、第一步先給兩個網卡配置文檔加上SLAVE=yes,把它變成奴隸。然后設置MASTER=bond0,告訴它你的主人是bond0。但是這里注意每個網卡都要設置BOOTPROTO=none。
范例:
DEVICE=eth0
ONBOOT=yes
BOOTPROTO=none
MASTER=bond0
SLAVE=yes
2、創建他們的主人bond0(ifcfg-bond0)。
范例:
DEVICE=bond0
BOOTPROTO=static
IPADDR=10.1.3.210
NETMASK=255.255.255.0
GATEWAY=10.1.3.254
ONBOOT=yes
3、修改/etc/modprobe.d/dist.conf加入下面內容:
aliasbond0bonding
optionsbond0miimon=100mode=1
mode=0:表示loadbalancing(round-robin)為負載均衡方式,兩塊網卡都在工作。
mode=1:表示fault-tolerance(active-backup)提供冗余功能,工作方式是主備的工作方式,其中一塊網卡在工作(若eth0斷掉),則自動切換到另一個塊網卡(eth1做備份)。
最后servicenetworkrestart驗證一下吧。
1、df -sg
說明:查看各分區的使用情況
2、du /local/notesdata/ | sort -nr | more
說明:按占用空間大小降序列出/local/notesdata文件夾下所有目錄的空間占用情況
3、du -a /local/notesdata/ | sort -nr | more
說明:按占用空間大小降序列出/local/notesdata文件夾下所有目錄和文件的空間占用情況
用du -sg 可看出當前文件夾的大小(以G為單位);
用du -sg filename 可看出當前文件夾下所有文件或文件夾的大小(以G為單位);
du -sk ,du -sm 則分別以KB,MB為單位。
例子:
root# ls -l
total 8
-rwxr-xr-x 1 root system 42 7月28 19時54
test.sh
-rw-r--r-- 1 root system 0 7月28 19時44 test_date
drwxrwxrwx 3 root system 256 7月27 08時47 webalizer-2.21-02-src
用 ls -l 查看時, 是以byte為單位顯示的, 如42 表示 test.sh的實際大小,256表示 webalizer-2.21-02-src 該目錄的大小為256byte(注意,不是指該目錄下文件的大小)
用du -sk 查看結果:
root# du -sk
3748 .
用du -sk * 查看結果:
root# du -sk *
4 test.sh
0 test_date
3744 webalizer-2.21-02-src
現在是早晨6點鐘。已經醒來的我正在總結到底是什么事情使得我的起床鬧鈴提前了這么多。故事剛開始的時候,
手機鈴聲恰好停止。又困又煩躁的我看了下手機,看看是不是我自己瘋了把鬧鐘調得這么早,居然是早晨5點。然而不是,而是我們的監控系統顯示,Plumbr服務出故障了。
作為這個領域的經驗豐富的老鳥,我打開了咖啡機,這是正確解決問題的第一步。一杯咖啡在手之后,現在我可以開始處理故障了。首先要懷疑的是應用程序本身,因為它在崩潰之前一點異常也沒有。應用程序日志中沒有錯誤,沒有警告,也沒有任何可疑的信息。
我們部署的監控系統發現進程已經掛掉了并重啟了服務。由于現在咖啡因已經流淌在我的血液中了,我開始變得信心十足。果然在30分鐘后,我在/var/log/kern.log日志中發現了下面的信息:
Jun 4 07:41:59 plumbr kernel: [70667120.897649] Out of memory: Kill process 29957 (
java) score 366 or sacrifice child
Jun 4 07:41:59 plumbr kernel: [70667120.897701] Killed process 29957 (java) total-vm:2532680kB, anon-rss:1416508kB, filers:0kB
很明顯我們被
Linux內核給坑了。你知道的,Linux里面有許多邪惡的怪物(也叫作守護進程)。這些守護進程是由幾個內核作業所看管的,其中的一個猶為惡毒。所有的現代Linux內核中都會有一個內存不足終結者(Out of memory Killer, OOM Killer)的內建機制,在內存過低的情況下,它會殺掉你的進程。當探測到這一情況時,這個終結者會被激活,然后挑選出一個進程去終結掉。選擇目標進程使用的是一套啟發式算法,它會計算所有進程的分數,然后選出那個分數最低的進程。
理解”Out of memory killer“
默認情況下,Linux內核會允許進程請求的內存超出實際可用內存的大小。這在現實世界中是有意義的,因為大多數進程其實并不會用到所有分配給它的內存(注:同一時間內不會全用到)。和這個問題最類似的就是運營商了。他們承諾賣給用戶的都是100Mb的帶寬,這實際上遠遠超出了他們的網絡容量。他們賭的就是用戶實際上并不會同時用完分配給他們的下載上限。一個10Gb的連接可以很輕松地承載100個以上的用戶,這里的100是通過簡單的數學運算得出的(10G/100M)。
這個做法的一個很明顯的副作用就是,萬一有一個程序正走上了一條耗盡內存的不歸路怎么辦。這會導致低可用內存的情況,也就是沒有內存頁能夠再分配給進程了。你可能也碰到過這種情況,沒有root帳戶你是殺不掉這種頑固的進程的。為了解決這一情況,終結者被激活了,并找出了要終結的進程。
關于"Out of memory killer"參數的調整,可以參考下這篇
文章。
是誰觸發了Out of memory killer?
雖然現在已經知道發生了什么,但還是搞不清楚到底是誰觸發了這個終結者,然后在早晨5點鐘把我吵醒。進一步的分析后找到了答案:
[*] /proc/sys/vm/overcommit_memory中的配置允許內存的超量使用——該值設置為1,這意味著每個malloc()請求都會成功。
[*] 應用程序運行在一臺EC2 m1.small的實例上。EC2的實例默認是禁用了交換分區的。
這兩個因素正好又趕上了我們服務的突然的流量高峰,最終導致應用程序為了支持這些額外的用戶而不斷請求更多的內存。內存超量使用的配置允許這個貪心的進程不停地申請內存,最后會觸發這個內存不足的終結者,它就是來履行它的使命的。去殺掉了我們的程序,然后在大半夜把我給叫醒。
示例
當我把這個情況描述給工程師的時候,有一位工程師覺得很有意思,因此寫了個小的測試用例來重現了這個問題。你可以在Linux下編譯并運行下面這個代碼片段(我是在最新的穩定版Ubuntu上運行的)。
package eu.plumbr.demo; public class OOM { public static void main(String[] args){ java.util.List l = new java.util.ArrayList(); for (int i = 10000; i < 100000; i++) { try { l.add(new int[100_000_000]); } catch (Throwable t) { t.printStackTrace(); } } } } |
然后你就會發現同樣的一個 Out of memory: Kill process <PID> (java) score <SCORE> or sacrifice child信息。
注意的是,你可能得調整下交換分區以及堆的大小,在我這個測試用例中,我通過-Xm2g設置了2G大小的堆,同時交換內存使用的是如下的配置:
swapoff -a
dd if=/dev/zero of=swapfile bs=1024 count=655360
mkswap swapfile
swapon swapfile
解決方案?
這種情況有好幾種解決方案。在我們這個例子中,我們只是把系統遷移到了一臺內存更大的機器上(褲子都脫了就讓我看這個?)我也考慮過激活交換分區,不過咨詢了工程師之后我想起來JVM上的GC進程在交換分區下的表現并不是很理想,因此這個選項就作罷了。
還有別的一些方法比如OOM killer的調優,或者將負載水平分布到數個小的實例上,又或者減少應用程序的內存占用量。
前幾天重新安裝了系統,正好需要恢復一下數據庫。
如果軟件也損失了,那么需要重新安裝一下數據庫軟件。
很多人抱怨我的新書很少關于Windows的內容,實際上,Windows和Linux/Unix上的操作沒有什么不同,Windows本身就是一個仿Unix的系統。
那么好吧,我還是用一個系列的
文章介紹一下我所使用的Windows系統,以及我所認為的數據庫系統無關性。
大家可以跟隨我看一下這樣一個過程。
首先開啟一個cmd命令行窗口。
開始->運行->cmd
我的Oracle軟件備份在D:/oracle :
D:/>dir oracle
驅動器 D 中的卷是 PRIVAT
卷的序列號是 94B0-FD3B
D:/oracle 的目錄
2006-08-16 14:14 <DIR> .
2006-08-16 14:14 <DIR> ..
2006-08-16 14:14 <DIR> ora10gR2
0 個文件 0 字節
3 個目錄 941,744,128 可用字節
我的數據文件位于D:/oradata下:
D:/>dir d:/oradata
驅動器 D 中的卷是 PRIVAT
卷的序列號是 94B0-FD3B
d:/oradata 的目錄
2006-08-16 14:25 <DIR> .
2006-08-16 14:25 <DIR> ..
2005-09-12 16:40 <DIR> flash_recovery_area
2005-09-12 16:40 <DIR> EYGLE
0 個文件 0 字節
4 個目錄 941,744,128 可用字節
現在讓我們用oradim創建一個實例,實際上也就是創建一個Windows服務:
C:/>oradim -new -sid eygle
實例已創建。
我們用net命令可以查看系統啟動了哪些服務,我們看到Oracle的服務已經啟動:
C:/>net start
已經啟動以下 Windows 服務:
...............
O&O Defrag
OracleServiceeygle
Plug and Play
Print Spooler
...............
命令成功完成。
如果你的系統裝了一些Unix增強工具,那么可以通過grep過濾一下:
C:/>net start |grep Oracle
OracleServiceeygle
此時我們就可以通過啟動實例,掛接原有數據庫,啟動Oracle數據庫了。當然你可能還有一些其他工作需要完成,比如重建口令文件等。
如果你想刪除這個服務,那么也很簡單:
C:/>oradim -delete -sid eygle
實例已刪除。
當然做好備份仍然是最重要的,我見過有的企業將文件分散在很多邏輯分區上,結果隨系統崩潰丟失了部分文件,損失也是相當慘重的。
在Linux/Unix上不需要服務來啟動實例,也就不存在這樣類似的操作。不過在命令行操作,一切都是類似的。
SCIM應該是最好的中文輸入法了,它與搜狗差不多,下面介紹它的安裝方法:
1)終端輸入:sudo apt-get remove scim
這一步是刪除安裝系統的時候裝的那個scim,實際是個假的,我這里不可以用
2)sudo apt-get install scim
這一步安裝scim輸入法。完了系統會自己裝上,中間會有提示,直接y就行了
3)sudo apt-get install scim-chinese
這一步是安裝中文輸入法,前面那一步只是下載一個可以運行輸入法的平臺,現在是在這個具體平臺上安裝中文輸入
4) sudo gedit /etc/X11/Xsession.d /95xinput
這個步驟是新建一個95xinput的文件,該文件的具體內容如下:
/usr/bin/scim -d XMODIFIERS="@im=SCIM" export XMODIFIERS export GTK_IM_MODULE=scim |
把以上內容復制到新建的95xinput文件中,然后,確定無誤后,保存,退出gedit編輯器
5)exit 退出終端
6)Logout,重新登錄,然后用Ctrl+Space就可以激活中文輸入法啦
1.進入mysql,修改 mysql這個database下的user數據表 將root用戶對應的記錄只保留一條host為localhost的記錄;
然后將root用戶對應的host屬性由localhost改為%
再執行命令 flush privileges;
2.修改/etc/mysql/my.cnf
老的版本中
>skip-networking => # skip-networking
新的版本中
>bind-address=127.0.0.1 => bind-address= 你機器的IP
這樣就可以允許其他機器訪問MySQL了。