根據最新的程式語言排名,以下是 2024 年度排名前 20 的程式語言:
[*.cs] indent_style = space indent_size = 43. 檔案儲存後,格式化會自動遵循這些規則。
GitHub 是一個基於雲端的版本控制和協作平台,主要用於軟體開發。它使用 Git 進行版本控制,讓開發者能夠管理專案的源代碼、跟蹤變更以及與他人協作。
GitHub 適合各類開發者,無論是單獨開發者、開源社區還是企業團隊。它能夠滿足小型專案到大型軟體專案的版本控制和協作需求。
git pull --rebase
git pull --rebase
是從遠端分支拉取最新變更,並將本地的更改重新應用到最新的遠端提交之上,而不是使用傳統的合併。
git pull --rebase
--rebase
?--rebase
可以讓提交歷史保持簡潔,沒有多餘的合併提交。假設你在本地提交了一些更改,而遠端也有新的提交,使用 git pull --rebase
會:
如果在重放本地提交時發生衝突,Git 會要求手動解決衝突:
git add
暫存已解決的文件。git rebase --continue
繼續重放提交。git rebase --abort
回到原狀。git pull --rebase
是保持 Git 提交歷史整潔的重要工具,特別適合多人協作時,能夠避免產生冗餘的合併提交,並保持代碼庫的提交記錄線性。
在 Bash 中,$? 代表上一個執行的命令的退出狀態碼(Exit Status)。這是一個整數值,通常用來判斷上一個命令是否成功執行。
#!/bin/bash
ls
echo "上一個命令的退出狀態碼是: $?"
在這個範例中,ls
命令會列出目錄內容,執行成功後,$?
的值將是 0。
#!/bin/bash
ls /nonexistent-directory
echo "上一個命令的退出狀態碼是: $?"
在這個範例中,ls
嘗試列出不存在的目錄,命令會失敗,$?
的值將是一個非 0 數字。
#!/bin/bash
cp file1.txt /some/directory/
if [ $? -eq 0 ]; then
echo "文件複製成功。"
else
echo "文件複製失敗。"
fi
此範例會根據命令的退出狀態來決定要顯示哪一條訊息。
在 Bash 中,可以使用條件判斷來檢查變數是否為空,以下提供幾種常見的方式:
-z
檢查變數是否為空#!/bin/bash
var=""
if [ -z "$var" ]; then
echo "變數是空的"
else
echo "變數不是空的"
fi
-z
用來檢查變數是否為空,如果變數為空,條件成立。
-n
檢查變數是否不為空#!/bin/bash
var="some value"
if [ -n "$var" ]; then
echo "變數不是空的"
else
echo "變數是空的"
fi
-n
用來檢查變數是否不為空,如果變數有值,條件成立。
#!/bin/bash
var=""
if [ "$var" == "" ]; then
echo "變數是空的"
else
echo "變數不是空的"
fi
這種方式直接將變數與空字串進行比較,來檢查變數是否為空。
在 Shell 中,使用 `>` 可以將指令的標準輸出(stdout)重導向到一個檔案或設備。若檔案已存在,內容會被覆蓋。
echo "Hello" > output.txt
這行指令將 "Hello"
寫入 output.txt
檔案。
使用 `>>` 會將標準輸出附加到指定檔案的末尾,不會覆蓋原有內容。
echo "Hello again" >> output.txt
這行指令會將 "Hello again"
附加到 output.txt
的結尾。
在 Shell 中,`2>` 用於將標準錯誤(stderr)重導向到指定位置。例如:
ls non_existent_file 2> error.log
這行指令會將錯誤訊息寫入 error.log
檔案。
若不想覆蓋錯誤訊息檔案,可使用 `2>>` 將錯誤訊息附加到檔案末尾。
ls non_existent_file 2>> error.log
這行指令會將錯誤訊息附加到 error.log
。
使用 `&>` 可以同時將標準輸出與標準錯誤都重導向到同一個檔案或設備。
command &> all_output.log
這行指令會將 command
的所有輸出(標準輸出與錯誤)寫入 all_output.log
。
`2>&1` 將標準錯誤合併到標準輸出,便於統一管理。例如:
command > output.log 2>&1
這行指令會將標準輸出和錯誤都寫入 output.log
。
若不想顯示任何輸出,可將所有輸出導向到 /dev/null
,如:
command >/dev/null 2>&1
這行指令會將 command
的所有輸出丟棄。
在使用 tee
命令將輸出追加到文件時,可以通過 iconv
將輸出轉換為 UTF-8 編碼,確保文件內容以 UTF-8 保存。以下是具體的指令和範例。
以下是將輸出保存為 UTF-8 編碼的 tee
指令格式:
command | iconv -t utf-8 | tee -a output.txt
-t
代表「目標編碼」。output.txt
文件。以下範例演示如何將 ls
命令的輸出以 UTF-8 編碼寫入到 output.txt
:
ls | iconv -t utf-8 | tee -a output.txt
執行該指令後,output.txt
的內容將以 UTF-8 編碼保存,避免出現編碼錯誤。
在 C++ 中,可以使用 std::array
初始化多維陣列為 0:
#include <iostream>
#include <array>
using namespace std;
int main() {
array<array<int, 4>, 3> arr = {0}; // 初始化所有元素為 0
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 4; j++) {
cout << arr[i][j] << " ";
}
cout << endl;
}
return 0;
}
std::array
是 C++ 標準庫中的容器類別,適合用於大小在編譯期固定的情況。std::array
提供更多的功能和安全性。在 C++ 中,模板 (Template) 是一種泛型編程的工具,允許我們在編寫函數或類別時,不指定具體的資料型別,從而使程式碼更具重用性。模板有助於在單一程式碼中處理不同型別的資料,避免重複的函數或類別定義。
函數模板允許我們撰寫可以處理不同型別的函數。函數模板的語法如下:
template <typename T>
T add(T a, T b) {
return a + b;
}
在此例中,add
函數可以處理任何支持加法操作的型別,如 int
、float
或 double
。
使用時,可以這樣呼叫:
int result = add(3, 4); // 使用 int 型別
double result2 = add(3.5, 2.7); // 使用 double 型別
類別模板允許我們建立可以適用於多種型別的類別。類別模板的語法如下:
template <typename T>
class MyClass {
private:
T data;
public:
MyClass(T data) : data(data) {}
T getData() { return data; }
};
此例中的 MyClass
類別可以使用任何型別的資料作為 data
。
使用時可以這樣:
MyClass<int> obj1(5); // int 型別
MyClass<double> obj2(3.14); // double 型別
模板可以接受多個參數,例如:
template <typename T, typename U>
class Pair {
private:
T first;
U second;
public:
Pair(T first, U second) : first(first), second(second) {}
T getFirst() { return first; }
U getSecond() { return second; }
};
這樣的模板類別可以存儲兩種不同型別的資料:
Pair<int, double> pair1(1, 3.14);
模板特化允許我們對特定型別的模板進行特別定義。例如:
template <>
class MyClass<int> {
public:
MyClass(int data) { /* 特化行為 */ }
};
這段程式碼特化了 MyClass
對 int
型別的行為,使其與其他型別不同。
模板還可以接受非型別的參數,例如常數值:
template <typename T, int Size>
class Array {
private:
T data[Size];
public:
int getSize() const { return Size; }
};
在這裡,Size
是一個非型別參數,表示陣列的大小。
使用範例:
Array<int, 10> arr; // 建立大小為 10 的 int 型別陣列
C++ 模板功能強大,使得程式碼可以更具泛用性並減少重複。了解如何利用函數模板、類別模板及模板特化等技術,將大大提升程式設計的彈性與效能。
在 C++ 中,當兩個類別相互依賴並需要同時引用對方的成員時,直接在各自的 .h
檔案中 #include
對方的定義會造成循環引用問題,導致無法編譯。解決方法是使用「前向宣告」(forward declaration)來避免循環引用。
.h
檔案中只宣告對方類別的存在,不直接包含對方的頭文件。.cpp
檔案中包含對方的頭文件,讓編譯器取得完整的類別定義。
// ClassA.h
#ifndef CLASSA_H
#define CLASSA_H
// 前向宣告 ClassB
class ClassB;
class ClassA {
public:
ClassA();
void setB(ClassB* b); // 設定指向 ClassB 的指標
void showBData(); // 顯示 ClassB 的數據
private:
ClassB* b; // 指向 ClassB 的指標
};
#endif
// ClassB.h
#ifndef CLASSB_H
#define CLASSB_H
// 前向宣告 ClassA
class ClassA;
class ClassB {
public:
ClassB(int data);
int getData(); // 取得數據
void setA(ClassA* a); // 設定指向 ClassA 的指標
void showAInfo(); // 顯示 ClassA 的資訊
private:
int data;
ClassA* a; // 指向 ClassA 的指標
};
#endif
#include "ClassA.h"
#include "ClassB.h"
#include <iostream>
ClassA::ClassA() : b(nullptr) {}
void ClassA::setB(ClassB* b) {
this->b = b;
}
void ClassA::showBData() {
if (b != nullptr) {
std::cout << "ClassB data: " << b->getData() << std::endl;
}
}
#include "ClassB.h"
#include "ClassA.h"
#include <iostream>
ClassB::ClassB(int data) : data(data), a(nullptr) {}
int ClassB::getData() {
return data;
}
void ClassB::setA(ClassA* a) {
this->a = a;
}
void ClassB::showAInfo() {
if (a != nullptr) {
a->showBData();
}
}
ClassA.h
和 ClassB.h
中,我們僅使用前向宣告來指出對方類別的存在,這樣可以避免循環引用。
.cpp
檔案中包含對方的頭文件,保證在使用指標時獲得對方的完整類別定義。在 C++ 中,friend 關鍵字可以用於函數或類別,以允許其他函數或類別訪問類別的私有成員(private)和保護成員(protected)。這樣的設計可讓外部函數或類別進行操作,而不違反封裝原則。
Friend 函數是一種被授權訪問另一類別的私有成員和保護成員的外部函數。在類別內部聲明時,以 friend
關鍵字修飾即可。
範例如下:
#include <iostream> using namespace std; class Box { private: double width; public: Box(double w) : width(w) {} // 聲明 friend 函數 friend void showWidth(Box &b); }; // friend 函數定義,能訪問 Box 類別的私有成員 void showWidth(Box &b) { cout << "Box 寬度: " << b.width << endl; } int main() { Box box(10.5); showWidth(box); // 訪問私有成員 width return 0; }
在此範例中,showWidth
函數雖然是 Box 類別外的普通函數,但因為被聲明為 friend 函數,仍然能夠訪問 Box 類別的私有成員 width
。
Friend 類別允許某一類別訪問另一類別的所有成員。這樣的設置在類別需要緊密協作時非常有用,但使用時應該謹慎,以避免過多暴露內部細節。
範例如下:
#include <iostream> using namespace std; class Square; // 前置聲明 class Rectangle { private: double width, height; public: Rectangle(double w, double h) : width(w), height(h) {} // 聲明 Square 類別為 friend friend class Square; }; class Square { public: double areaOfRectangle(Rectangle &rect) { return rect.width * rect.height; } }; int main() { Rectangle rect(5.0, 3.0); Square square; cout << "矩形面積: " << square.areaOfRectangle(rect) << endl; return 0; }
在此範例中,Square 類別被宣告為 Rectangle 類別的 friend 類別,因此 Square 類別中的成員函數可以直接訪問 Rectangle 類別的私有成員 width
和
height
。
在 C++ 中使用 friend 函數和 friend 類別需謹慎,過多使用會破壞類別的封裝性。因此,friend 關鍵字通常只在設計需要密切配合的類別或函數時使用。
在 .NET C++ 中,可以使用 System::IO
命名空間提供的功能來操作檔案與目錄。
取得目錄中最新的檔案,可以透過讀取所有檔案資訊並比較最後修改日期實現。
以下是一個完整的範例,展示如何取得指定目錄中最新的檔案:
#include "stdafx.h"
#include <iostream>
#include <cliext/vector>
#include <System.IO>
using namespace System;
using namespace System::IO;
using namespace cliext;
int main()
{
try
{
// 指定目錄路徑
String^ directoryPath = "C:\\Your\\Directory\\Path";
// 檢查目錄是否存在
if (!Directory::Exists(directoryPath))
{
Console::WriteLine("目錄不存在: {0}", directoryPath);
return -1;
}
// 取得目錄中的所有檔案
array^ files = Directory::GetFiles(directoryPath);
// 如果目錄中沒有檔案
if (files->Length == 0)
{
Console::WriteLine("目錄中沒有檔案。");
return 0;
}
// 找到最新的檔案
String^ newestFile = nullptr;
DateTime newestTime = DateTime::MinValue;
for each (String^ file in files)
{
// 取得檔案的最後修改時間
DateTime lastWriteTime = File::GetLastWriteTime(file);
// 比較時間並更新最新檔案資訊
if (lastWriteTime > newestTime)
{
newestTime = lastWriteTime;
newestFile = file;
}
}
// 輸出最新檔案資訊
Console::WriteLine("最新檔案: {0}", newestFile);
Console::WriteLine("最後修改時間: {0}", newestTime);
}
catch (Exception^ ex)
{
Console::WriteLine("發生錯誤: {0}", ex->Message);
}
return 0;
}
Directory::GetFiles
方法獲取指定目錄中的所有檔案路徑。File::GetLastWriteTime
方法取得每個檔案的最後修改時間。try-catch
區塊捕獲潛在的異常,例如目錄不存在或無法存取。System.Reflection
是 .NET 框架中的一個命名空間,提供了檢查和操作元數據的工具,使開發者可以在運行時動態檢查類型、方法、屬性等,並動態創建和操縱對象。
Assembly
:表示已加載的程序集,提供加載、探索和反射程序集的方法。Type
:表示一種類型,包括類別、結構、介面等,提供獲取類型信息的功能。MethodInfo
:表示方法資訊,允許開發者檢查方法的屬性並動態調用它們。PropertyInfo
:表示屬性資訊,提供對屬性元數據的存取。FieldInfo
:表示字段資訊,可用於訪問類型的字段。以下是一個使用 System.Reflection
的範例程式,展示如何動態檢查類型和方法,並調用方法。
// 定義一個簡單的範例類別
public class SampleClass {
public string SayHello(string name) {
return $"Hello, {name}!";
}
}
// 使用 Reflection 來動態調用方法
using System;
using System.Reflection;
class Program {
static void Main() {
// 創建 SampleClass 類別的實例
Type sampleType = typeof(SampleClass);
object sampleInstance = Activator.CreateInstance(sampleType);
// 獲取 SayHello 方法資訊
MethodInfo methodInfo = sampleType.GetMethod("SayHello");
// 動態調用 SayHello 方法
object result = methodInfo.Invoke(sampleInstance, new object[] { "World" });
Console.WriteLine(result); // 輸出: Hello, World!
}
}
在上述範例中,我們使用 Activator.CreateInstance
來創建類別的實例,並使用 MethodInfo.Invoke
來調用方法
SayHello
。
以下範例展示了如何使用 Controls->GetEnumerator()
方法來逐一遍歷 .NET 表單中的所有子控制項並批量修改其屬性。
using System;
using System.Drawing;
using System.Windows.Forms;
public class FormExample : Form
{
public FormExample()
{
// 初始化一些控制項
Button button1 = new Button { Text = "Button 1", Location = new Point(10, 10) };
TextBox textBox1 = new TextBox { Location = new Point(10, 50) };
Controls.Add(button1);
Controls.Add(textBox1);
// 使用 GetEnumerator() 遍歷並修改控制項屬性
ModifyControls();
}
private void ModifyControls()
{
var enumerator = Controls.GetEnumerator();
while (enumerator.MoveNext())
{
Control control = (Control)enumerator.Current;
// 設定範例:將所有控制項的背景色設為淺藍
control.BackColor = Color.LightBlue;
// 若控制項為 TextBox,將其設為不可編輯
if (control is TextBox)
{
control.Enabled = false;
}
}
}
// 啟動應用程式
public static void Main()
{
Application.Run(new FormExample());
}
}
**GetEnumerator()**: 利用 `Controls.GetEnumerator()` 方法來取得控制項的列舉器,這樣可以遍歷所有子控制項。
**條件修改**: 在 `while` 迴圈中,對每個 `Control` 物件進行屬性修改,例如將背景色設為淺藍,並根據控制項類型進行特定修改,如將 `TextBox` 設為不可編輯。
**用途**: 這種方法在需要批量修改屬性時非常有效,比如調整 UI 風格或在特定情況下禁用多個控制項。
執行後,所有控制項的背景色會變成淺藍色,且所有 `TextBox` 控制項將被設為不可編輯。
當堆疊追蹤中出現以下錯誤訊息時,開發者可能需要檢查 Message
物件的內容:
at ....MainForm.Dispose(Boolean A_0) at System.Windows.Forms.Form.WmClose(Message& m) at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam) ...
此時需要透過覆寫或檢測 WndProc
方法中的 Message m
來檢查其詳細資訊。
以下提供幾種方法來檢查或記錄 Message
物件的內容。
如果可以存取表單或控制項的原始碼,建議覆寫 WndProc
方法,直接記錄或檢查 Message m
的內容。
protected override void WndProc(ref Message m)
{
try
{
// 記錄 Message 的內容
Console.WriteLine($"Message Details: hWnd={m.HWnd}, Msg={m.Msg}, WParam={m.WParam}, LParam={m.LParam}");
base.WndProc(ref m);
}
catch (Exception ex)
{
Console.WriteLine($"Exception: {ex}");
throw; // 保持原有例外行為
}
}
這段程式碼會在每次接收到訊息時記錄相關資訊,並允許開發者進一步分析。
如果錯誤發生在 Dispose
方法中,可以在方法內加入例外處理來檢查相關資訊。
protected override void Dispose(bool disposing)
{
try
{
if (disposing)
{
// 釋放資源
}
base.Dispose(disposing);
}
catch (Exception ex)
{
Console.WriteLine($"Exception in Dispose: {ex}");
throw;
}
}
這樣可以確保在釋放資源時不會忽略重要的錯誤資訊。
如果無法確定錯誤發生的位置,可以透過全域例外處理來記錄堆疊追蹤和相關資訊。
AppDomain.CurrentDomain.UnhandledException += (sender, args) =>
{
Exception ex = (Exception)args.ExceptionObject;
Console.WriteLine($"Unhandled Exception: {ex}");
Environment.Exit(1);
};
可以使用 Visual Studio 將斷點設置在 WndProc
或 Dispose
方法中,並檢查 Message
物件的內容。
HWnd
:接收訊息的視窗句柄。Msg
:訊息的 ID。WParam
:附加訊息資訊(字參數)。LParam
:附加訊息資訊(長參數)。WndProc
或修改程式碼需小心,避免影響現有行為。Message
的座標或 ID 不固定,可考慮加入條件判斷來篩選需要的訊息。在 .NET C++/CLI 中,WmClose(Message& m)
是 System.Windows.Forms.Form
的內部保護方法,無法直接覆寫。不過,可以透過覆寫 WndProc
方法來攔截並處理 WM_CLOSE
訊息,以達到類似覆寫 WmClose
的效果。
#include <Windows.h>
#include <System.Windows.Forms.h>
using namespace System;
using namespace System::Windows::Forms;
public ref class CustomForm : public Form
{
protected:
// 模擬 WmClose 行為的覆寫
void WmClose(Message% m)
{
// 在這裡加入自定義的 WM_CLOSE 行為
if (MessageBox::Show("確定要關閉視窗嗎?", "確認", MessageBoxButtons::YesNo) == DialogResult::Yes)
{
// 繼續調用基底行為以進行正常關閉
this->Form::WndProc(m);
}
else
{
// 阻止關閉視窗
return;
}
}
// 覆寫 WndProc,攔截 WM_CLOSE 訊息並調用 WmClose
virtual void WndProc(Message% m) override
{
const int WM_CLOSE = 0x0010;
if (m.Msg == WM_CLOSE)
{
WmClose(m); // 調用自定義的 WmClose 方法
}
else
{
// 處理其他訊息
Form::WndProc(m);
}
}
};
[STAThread]
int main(array<String^>^ args)
{
Application::EnableVisualStyles();
Application::SetCompatibleTextRenderingDefault(false);
CustomForm^ form = gcnew CustomForm();
form->Text = "覆寫 WmClose 行為範例";
Application::Run(form);
return 0;
}
模擬覆寫 WmClose
方法,在這裡自定義視窗關閉的行為。透過確認對話框詢問使用者是否要關閉視窗。
覆寫 WndProc
方法來攔截 WM_CLOSE
訊息,並將其委派給自定義的 WmClose
方法。
在沒有攔截 WM_CLOSE
的情況下,調用基底類別的 WndProc
方法處理其他訊息。
WmClose
方法僅是模擬覆寫,實際上是透過攔截訊息進行處理。Form::WndProc
以確保基底行為正常運作。大多數現代 Chromebook 支援透過 Crostini 專案來運行 Linux 應用程式。
設定 > 進階 > 開發人員 > 啟用 Linux (Beta)
。sudo apt update
sudo apt install -y dotnet-sdk-7.0
無需在本地安裝任何軟體,即可在 Chromebook 上使用雲端平台運行 .NET 程式。
Chromebook 支援使用容器運行應用程式,您可以透過 Docker 啟動 .NET 環境。
docker pull mcr.microsoft.com/dotnet/runtime:7.0
從 .NET 6 開始,應用程式可以跨多平台運行,包括 Linux。將您的應用程式編譯為跨平台格式並部署至 Chromebook。
dotnet publish -c Release -r linux-x64 --self-contained
Lambda 表達式是一種匿名函數,通常用於簡化代碼,特別是在需要傳遞小型函數或回調的情況下。Lambda 表達式的語法簡潔,可以在一行中定義函數邏輯。Lambda 表達式最常見於 C++、JavaScript、Python 和 C# 等語言。
Lambda 表達式的基本語法通常包括參數、箭頭符號 =>
和函數體,例如:
(參數) => 函數體
具體語法因語言而異,例如:
[capture](parameters) { function body }
lambda parameters: expression
(parameters) => expression
#include <iostream>
#include <vector>
#include <algorithm>
int main() {
std::vector numbers = {1, 2, 3, 4, 5};
// 使用 lambda 表達式來計算偶數的和
int sum = 0;
std::for_each(numbers.begin(), numbers.end(), [&sum](int n) {
if (n % 2 == 0) sum += n;
});
std::cout << "偶數的總和: " << sum << std::endl;
return 0;
}
# 使用 lambda 表達式來計算兩數的和
add = lambda x, y: x + y
print(add(5, 10)) # 輸出: 15
using System;
using System.Collections.Generic;
using System.Linq;
class Program {
static void Main() {
List numbers = new List { 1, 2, 3, 4, 5 };
// 使用 Lambda 表達式篩選出偶數並計算總和
int sum = numbers.Where(n => n % 2 == 0).Sum();
Console.WriteLine($"偶數的總和: {sum}");
}
}
map
、filter
和 reduce
等高階函數來操作集合。SQL(Structured Query Language)是結構化查詢語言,用於管理和操作關聯式數據庫。它是數據庫管理系統中使用最廣泛的語言之一。
-- 查詢數據
SELECT * FROM 表名 WHERE 條件;
-- 插入數據
INSERT INTO 表名 (列1, 列2) VALUES (值1, 值2);
-- 更新數據
UPDATE 表名 SET 列1 = 值1 WHERE 條件;
-- 刪除數據
DELETE FROM 表名 WHERE 條件;
-- 創建表
CREATE TABLE 表名 (
列名1 數據類型,
列名2 數據類型
);
INT
:整數類型。VARCHAR(n)
:變長字元串,最多 n
個字元。DATE
:日期類型。FLOAT
:浮點數類型。BOOLEAN
:布林值(真或假)。MySQL 是一種流行的開源關聯式資料庫管理系統 (RDBMS),使用 SQL 作為查詢語言,適合中小型到大型應用程式。
mysql -u root -p
CREATE DATABASE example_db;
USE example_db;
CREATE TABLE users (id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(50), age INT);
INSERT INTO users (name, age) VALUES ('Alice', 30);
SELECT * FROM users;
SQLite 是一種嵌入式資料庫,無需獨立伺服器進行管理,適合用於輕量級應用程式。
sqlite3 example.db
CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, age INTEGER);
INSERT INTO users (name, age) VALUES ('Alice', 30);
SELECT * FROM users;
name
欄位值是唯一的。name
欄位的長度適中,避免過長影響效能。如設定檔的類型資料表:
CREATE TABLE config_types (
name VARCHAR(50) PRIMARY KEY,
description TEXT
);
INSERT INTO config_types (name, description) VALUES ('general', 'General settings');
SELECT * FROM config_types WHERE name = 'general';
此表格將存放所有「動物」的通用屬性。
欄位名稱 | 資料型態 | 說明 |
---|---|---|
id | INT | 動物的唯一識別碼 |
species | VARCHAR(50) | 動物的種類 |
age | INT | 動物的年齡 |
此表格將繼承 animal 表格的 id,並儲存「貓」的特有屬性。
欄位名稱 | 資料型態 | 說明 |
---|---|---|
id | INT | 對應到 animal 表格的 id |
breed | VARCHAR(50) | 貓的品種 |
favorite_food | VARCHAR(50) | 貓的喜愛食物 |
CREATE TABLE animal ( id INT PRIMARY KEY AUTO_INCREMENT, species VARCHAR(50) NOT NULL, age INT NOT NULL ); CREATE TABLE cat ( id INT PRIMARY KEY, breed VARCHAR(50), favorite_food VARCHAR(50), FOREIGN KEY (id) REFERENCES animal(id) );
INSERT INTO animal (species, age) VALUES ('Cat', 3); INSERT INTO cat (id, breed, favorite_food) VALUES (1, 'Siamese', 'Fish');
動物ID | 種類 | 年齡 |
---|---|---|
1 | Cat | 3 |
動物ID | 品種 | 喜愛食物 |
---|---|---|
1 | Siamese | Fish |
在此範例中,animal
表格儲存了所有動物的共同屬性,而 cat
表格則儲存貓的特有屬性。cat
表格中的 id
是參照
animal
表格的 id
,代表這是一種繼承關係。
SELECT * FROM animal;
這個查詢將返回所有貓的完整資料,包括繼承自 animal 表格的通用屬性。
SELECT animal.id, animal.species, animal.age, cat.breed, cat.favorite_food FROM animal JOIN cat ON animal.id = cat.id;
SELECT * FROM animal WHERE id = 1;
SELECT animal.id, animal.species, animal.age, cat.breed, cat.favorite_food FROM animal JOIN cat ON animal.id = cat.id WHERE cat.breed = 'Siamese';
在這些查詢範例中,我們使用 JOIN
將 animal
表格和 cat
表格結合起來,以取得貓的完整資料。這種方法確保查詢結果包含繼承屬性與特有屬性。
FOREIGN KEY(外鍵)用於建立兩個資料表之間的關聯性,確保資料的參考完整性。例如,一個資料表的欄位值必須參考另一個資料表中的主鍵或唯一值。
CREATE TABLE 子資料表 (
欄位名稱 資料類型,
FOREIGN KEY (外鍵欄位) REFERENCES 父資料表(主鍵欄位)
);
建立一對多的關聯,例如訂單與客戶:
-- 建立父資料表 (customers)
CREATE TABLE customers (
customer_id INT PRIMARY KEY,
name VARCHAR(50)
);
-- 建立子資料表 (orders) 並設定外鍵
CREATE TABLE orders (
order_id INT PRIMARY KEY,
customer_id INT,
order_date DATE,
FOREIGN KEY (customer_id) REFERENCES customers(customer_id)
);
PRIMARY KEY
或 UNIQUE
。ON DELETE
行為。可以透過 ON DELETE
和 ON UPDATE
指定外鍵行為:
CREATE TABLE orders (
order_id INT PRIMARY KEY,
customer_id INT,
order_date DATE,
FOREIGN KEY (customer_id) REFERENCES customers(customer_id)
ON DELETE CASCADE
ON UPDATE CASCADE
);
CASCADE
:同步刪除或更新子資料表中的相關資料。SET NULL
:將子資料表中的外鍵欄位設為 NULL
。RESTRICT
:阻止刪除或更新,預設行為。NO ACTION
:與 RESTRICT
類似,延遲約束檢查。在 MySQL 中,可以使用 COMMENT
來為欄位添加備註。
CREATE TABLE users (
id INT PRIMARY KEY COMMENT '使用者唯一識別碼',
name VARCHAR(50) COMMENT '使用者姓名',
age INT COMMENT '使用者年齡'
);
CREATE TABLE users (
id INT PRIMARY KEY,
name VARCHAR(50),
age INT
) COMMENT = '使用者資料表';
可透過以下語法查詢欄位的備註:
SHOW FULL COLUMNS FROM users;
ALTER TABLE users MODIFY COLUMN name VARCHAR(50) COMMENT '修改後的備註';
COMMENT
,但 SQLite 不支援。COMMENT ON
指令。COMMENT ON COLUMN users.name IS '使用者姓名';
計算兩個 DATETIME 欄位的時間差(單位:秒)。
SELECT * FROM table_name
WHERE TIMESTAMPDIFF(SECOND, datetime_column1, datetime_column2) < 5;
確保時間差為絕對值,避免順序影響。
SELECT * FROM table_name
WHERE ABS(TIMESTAMPDIFF(SECOND, datetime_column1, datetime_column2)) < 5;
若只需比較是否為同一天,可以使用 DATEDIFF。
SELECT * FROM table_name
WHERE DATEDIFF(datetime_column1, datetime_column2) = 0;
適用於支援時間戳記運算的資料庫,如 MySQL。
SELECT * FROM table_name
WHERE ABS(UNIX_TIMESTAMP(datetime_column1) - UNIX_TIMESTAMP(datetime_column2)) < 5;
在 MySQL 中,可使用 FORMAT()
來格式化浮點數。
SELECT FORMAT(123.4567, 2); -- 結果: '123.46'
ROUND()
用於四捨五入至固定小數位數。
SELECT ROUND(123.4567, 2); -- 結果: 123.46
將 FLOAT 轉換為 DECIMAL 以保持固定小數位數。
SELECT CAST(123.4567 AS DECIMAL(10,2)); -- 結果: 123.46
SELECT CONVERT(123.4567, DECIMAL(10,2)); -- 結果: 123.46
SELECT id, FORMAT(price, 2) AS formatted_price FROM products;
建立資料表時可直接設定小數點位數。
CREATE TABLE products (
id INT PRIMARY KEY,
price DECIMAL(10,2) -- 兩位小數
);
取得欄位的最大值。
SELECT MAX(price) AS max_price FROM products;
取得欄位的最小值。
SELECT MIN(price) AS min_price FROM products;
計算欄位的平均值。
SELECT AVG(price) AS avg_price FROM products;
SELECT
MAX(price) AS max_price,
MIN(price) AS min_price,
AVG(price) AS avg_price
FROM products;
SELECT category,
MAX(price) AS max_price,
MIN(price) AS min_price,
AVG(price) AS avg_price
FROM products
GROUP BY category;
對另一個查詢結果求最大值。
SELECT MAX(price) FROM (SELECT price FROM products WHERE category = 'electronics') AS subquery;
排序後取最大值。
SELECT price FROM products WHERE category = 'electronics' ORDER BY price DESC LIMIT 1;
WITH filtered_products AS (
SELECT price FROM products WHERE category = 'electronics'
)
SELECT MAX(price) FROM filtered_products;
幾何平均數(Geometric Mean)計算公式:
GM = (x1 * x2 * ... * xn)^(1/n)
在 SQL 中,可以透過對數運算來計算幾何平均數。
SELECT EXP(AVG(LOG(price))) AS geometric_mean FROM products WHERE price > 0;
使用 POWER()
計算 n 次方根:
SELECT POWER(EXP(SUM(LOG(price))), 1 / COUNT(price)) AS geometric_mean
FROM products WHERE price > 0;
LOG()
會導致錯誤。SELECT EXP(AVG(LOG(price))) AS geometric_mean FROM products WHERE price > 0;
在 MySQL / MariaDB 中,可以使用 STDDEV()
來計算標準差。
SELECT STDDEV(salary) AS salary_stddev FROM employees;
SQL 提供兩種標準差計算方式:
STDDEV_POP()
- 計算母體標準差(Population Standard Deviation)STDDEV_SAMP()
- 計算樣本標準差(Sample Standard Deviation)SELECT
STDDEV_POP(salary) AS population_stddev,
STDDEV_SAMP(salary) AS sample_stddev
FROM employees;
如果 SQL 版本不支援 STDDEV()
,可以使用以下公式:
SELECT SQRT(
SUM(POW(salary - (SELECT AVG(salary) FROM employees), 2)) / COUNT(salary)
) AS salary_stddev
FROM employees;
STDDEV()
可以直接計算標準差。STDDEV_POP()
計算母體標準差,STDDEV_SAMP()
計算樣本標準差。在 SELECT
查詢中,如果定義了 expr1 AS field1
,能否在 expr2
中使用 field1
?
SQL 的執行順序決定了別名不能在同一個 SELECT
內部被再次引用:
SELECT price * 1.1 AS new_price, new_price + 10 AS final_price FROM products; -- 錯誤
Unknown column 'new_price' in 'field list'
可以在子查詢中先計算 new_price
,然後在外部查詢中引用:
SELECT new_price, new_price + 10 AS final_price
FROM (SELECT price * 1.1 AS new_price FROM products) AS subquery;
若 SQL 支援 Common Table Expressions(CTE),可用 WITH
來簡化:
WITH cte AS (
SELECT price * 1.1 AS new_price FROM products
)
SELECT new_price, new_price + 10 AS final_price FROM cte;
如果只是簡單運算,可以直接重複計算(但不推薦,因為可讀性較差):
SELECT price * 1.1 AS new_price, price * 1.1 + 10 AS final_price FROM products;
SELECT
查詢內引用別名。WITH
)來解決。JOIN 用於合併多個資料表的相關資料,根據某個欄位(通常是外鍵)建立關聯。
只返回兩個資料表中符合條件的資料。
SELECT orders.order_id, customers.name
FROM orders
INNER JOIN customers ON orders.customer_id = customers.customer_id;
返回左表的所有資料,若右表沒有對應資料,則顯示 NULL
。
SELECT customers.name, orders.order_id
FROM customers
LEFT JOIN orders ON customers.customer_id = orders.customer_id;
返回右表的所有資料,若左表沒有對應資料,則顯示 NULL
。
SELECT customers.name, orders.order_id
FROM orders
RIGHT JOIN customers ON orders.customer_id = customers.customer_id;
返回左右兩表的所有資料,若沒有匹配則顯示 NULL
。
MySQL 不支援 FULL JOIN,可用 LEFT JOIN
和 RIGHT JOIN
組合模擬。
SELECT customers.name, orders.order_id
FROM customers
LEFT JOIN orders ON customers.customer_id = orders.customer_id
UNION
SELECT customers.name, orders.order_id
FROM customers
RIGHT JOIN orders ON customers.customer_id = orders.customer_id;
返回兩個表的所有可能組合(笛卡兒積)。
SELECT customers.name, products.product_name
FROM customers
CROSS JOIN products;
用於同一個表內部的關聯,如員工的上級關係。
SELECT A.name AS employee, B.name AS manager
FROM employees A
JOIN employees B ON A.manager_id = B.employee_id;
-- abc.sql SOURCE other_file.sql; SOURCE another_file.sql;
-- abc.sql \i other_file.sql \i another_file.sql
#!/bin/bash mysql -u user -p database_name < abc.sql mysql -u user -p database_name < other_file.sql
cat abc.sql other_file.sql another_file.sql > combined.sql mysql -u user -p database_name < combined.sql
SET @param1 = 'value1'; SOURCE other_file.sql;2. 在 `other_file.sql` 中引用變數:
SELECT * FROM table WHERE column = @param1;
\set param1 'value1' \i other_file.sql2. 在 `other_file.sql` 中使用變數:
SELECT * FROM table WHERE column = :'param1';
sed "s/{param1}/value1/g" abc.sql | mysql -u user -p database_name2. 在 SQL 文件中使用佔位符 `{param1}`,由命令列工具替換。
psql -d database_name -v param1=value1 -f abc.sql2. 在 SQL 文件中使用 `:'param1'` 表示變數。
Stored Procedure(預存常式 或 儲存程序)是一組預先編譯並存儲在資料庫中的 SQL 語句,可以透過呼叫執行,提高效率並減少重複代碼。
DELIMITER //
CREATE PROCEDURE GetAllProducts()
BEGIN
SELECT * FROM products;
END //
DELIMITER ;
CALL GetAllProducts();
查詢特定類別的商品:
DELIMITER //
CREATE PROCEDURE GetProductsByCategory(IN category_name VARCHAR(50))
BEGIN
SELECT * FROM products WHERE category = category_name;
END //
DELIMITER ;
呼叫:
CALL GetProductsByCategory('electronics');
計算某個類別的商品總數:
DELIMITER //
CREATE PROCEDURE GetProductCountByCategory(IN category_name VARCHAR(50), OUT total_count INT)
BEGIN
SELECT COUNT(*) INTO total_count FROM products WHERE category = category_name;
END //
DELIMITER ;
呼叫:
CALL GetProductCountByCategory('electronics', @count);
SELECT @count;
DELIMITER //
CREATE PROCEDURE CalculateTotalRevenue()
BEGIN
DECLARE total DECIMAL(10,2);
SELECT SUM(price) INTO total FROM sales;
SELECT total AS total_revenue;
END //
DELIMITER ;
呼叫:
CALL CalculateTotalRevenue();
DELIMITER //
CREATE PROCEDURE CheckStock(IN product_id INT, OUT stock_status VARCHAR(20))
BEGIN
DECLARE stock INT;
SELECT quantity INTO stock FROM inventory WHERE id = product_id;
IF stock > 10 THEN
SET stock_status = 'In Stock';
ELSEIF stock > 0 THEN
SET stock_status = 'Low Stock';
ELSE
SET stock_status = 'Out of Stock';
END IF;
END //
DELIMITER ;
呼叫:
CALL CheckStock(1, @status);
SELECT @status;
DELIMITER //
CREATE PROCEDURE CountDown(IN start_num INT)
BEGIN
DECLARE i INT;
SET i = start_num;
loop_label: LOOP
IF i <= 0 THEN
LEAVE loop_label;
END IF;
SELECT i;
SET i = i - 1;
END LOOP;
END //
DELIMITER ;
呼叫:
CALL CountDown(5);
DROP PROCEDURE IF EXISTS GetAllProducts;
DELIMITER
避免 SQL 語法衝突。在 MySQL 和 MariaDB 中,儲存程序的參數不能直接設定預設值(不像 SQL Server 或 PostgreSQL)。不過,可以使用 IF
條件語句來模擬預設值。
假設我們要查詢 users
表,當參數 user_id
沒有提供時,預設查詢 ID 為 1:
DELIMITER //
CREATE PROCEDURE GetUserById(IN user_id INT)
BEGIN
IF user_id IS NULL THEN
SET user_id = 1; -- 預設值
END IF;
SELECT * FROM users WHERE id = user_id;
END //
DELIMITER ;
CALL GetUserById(NULL); -- 會查詢 id = 1
CALL GetUserById(5); -- 查詢 id = 5
COALESCE()
會在參數為 NULL 時回傳指定的預設值:
DELIMITER //
CREATE PROCEDURE GetUserById(IN user_id INT)
BEGIN
SELECT * FROM users WHERE id = COALESCE(user_id, 1);
END //
DELIMITER ;
CALL GetUserById(NULL); -- 預設為 1
CALL GetUserById(10); -- 查詢 id = 10
如果想要參數可選,可以建立多個 Stored Procedure。例如:
DELIMITER //
CREATE PROCEDURE GetAllUsers()
BEGIN
SELECT * FROM users;
END //
CREATE PROCEDURE GetUserById(IN user_id INT)
BEGIN
SELECT * FROM users WHERE id = user_id;
END //
DELIMITER ;
CALL GetAllUsers(); -- 無參數,查詢所有
CALL GetUserById(3); -- 查詢 id = 3
DEFAULT
值。IF
或 COALESCE()
模擬預設值。MySQL / MariaDB 的 Stored Procedure 不支援 RETURN
回傳查詢結果,但可以使用 OUT
參數來回傳值。
DELIMITER //
CREATE PROCEDURE GetUserCount(OUT user_count INT)
BEGIN
SELECT COUNT(*) INTO user_count FROM users;
END //
DELIMITER ;
CALL GetUserCount(@total);
SELECT @total; -- 顯示用戶數量
如果要回傳一個查詢結果,直接 SELECT
即可:
DELIMITER //
CREATE PROCEDURE GetUserById(IN user_id INT)
BEGIN
SELECT * FROM users WHERE id = user_id;
END //
DELIMITER ;
CALL GetUserById(5); -- 查詢 ID 為 5 的用戶
雖然 MySQL 支援 RETURN
,但只能回傳單一數值,通常用於控制流程:
DELIMITER //
CREATE PROCEDURE GetMaxSalary()
BEGIN
DECLARE max_salary DECIMAL(10,2);
SELECT MAX(salary) INTO max_salary FROM employees;
RETURN max_salary; -- 但這樣在 MySQL 不會直接返回值
END //
DELIMITER ;
CALL
來獲取 RETURN 值,因此建議使用 OUT 參數:DELIMITER //
CREATE PROCEDURE GetMaxSalary(OUT max_salary DECIMAL(10,2))
BEGIN
SELECT MAX(salary) INTO max_salary FROM employees;
END //
DELIMITER ;
CALL GetMaxSalary(@max);
SELECT @max; -- 顯示最高薪資
使用多個 OUT
參數回傳不同的計算結果:
DELIMITER //
CREATE PROCEDURE GetUserStats(OUT total_users INT, OUT avg_age DECIMAL(5,2))
BEGIN
SELECT COUNT(*) INTO total_users FROM users;
SELECT AVG(age) INTO avg_age FROM users;
END //
DELIMITER ;
CALL GetUserStats(@total, @avg);
SELECT @total, @avg; -- 顯示用戶總數與平均年齡
OUT
參數。SELECT
。OUT
參數。RETURN
回傳查詢結果,只適用於流程控制。MySQL Stored Procedure 可以透過 OUT
參數回傳值,然後在 CALL 之外用 SELECT
取得該值。
DELIMITER //
CREATE PROCEDURE GetTotalUsers(OUT total_users INT)
BEGIN
SELECT COUNT(*) INTO total_users FROM users;
END //
DELIMITER ;
CALL GetTotalUsers(@total);
SELECT @total AS UserCount; -- 在 CALL 之外使用回傳值
如果 Stored Procedure 使用 SELECT
回傳結果,不能直接存入變數,但可以用 INSERT INTO ... SELECT
。
DELIMITER //
CREATE PROCEDURE GetMaxSalary()
BEGIN
SELECT MAX(salary) AS max_salary FROM employees;
END //
DELIMITER ;
CREATE TEMPORARY TABLE temp_result (max_salary DECIMAL(10,2));
INSERT INTO temp_result EXECUTE GetMaxSalary();
SELECT max_salary FROM temp_result; -- 在 CALL 之外使用
如果 Stored Procedure 產生的結果需要在變數中存取,可以使用 PREPARE
和 EXECUTE
。
DELIMITER //
CREATE PROCEDURE GetUserById(IN user_id INT)
BEGIN
SELECT name FROM users WHERE id = user_id;
END //
DELIMITER ;
SET @sql = 'CALL GetUserById(5)';
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
OUT
參數回傳單一值,透過 @變數
存取。INSERT INTO ... CALL
存入暫存表。PREPARE
和 EXECUTE
。在 MySQL / MariaDB 中,Stored Function(函數)不能回傳 SELECT
結果集,否則會出現錯誤:
ERROR 1415 (0A000): Not allowed to return a result set from a function
函數不能回傳結果集,但 Stored Procedure 可以。
DELIMITER //
CREATE FUNCTION GetUsers()
RETURNS TABLE
BEGIN
RETURN (SELECT * FROM users); -- 這是不允許的
END //
DELIMITER ;
DELIMITER //
CREATE PROCEDURE GetUsers()
BEGIN
SELECT * FROM users;
END //
DELIMITER ;
CALL GetUsers();
如果只需要回傳單一值(如計數或最大值),可以用 RETURN
。
DELIMITER //
CREATE FUNCTION GetUserCount()
RETURNS INT DETERMINISTIC
BEGIN
DECLARE total INT;
SELECT COUNT(*) INTO total FROM users;
RETURN total;
END //
DELIMITER ;
SELECT GetUserCount();
如果真的需要在函數內回傳多行結果,可以讓函數插入資料到 Temporary Table,然後在外部查詢。
DELIMITER //
CREATE FUNCTION PopulateTempUsers()
RETURNS INT DETERMINISTIC
BEGIN
CREATE TEMPORARY TABLE IF NOT EXISTS temp_users AS (SELECT * FROM users);
RETURN 1;
END //
DELIMITER ;
SELECT PopulateTempUsers();
SELECT * FROM temp_users;
RETURN
。HeidiSQL 是一款免費的開源 SQL 客戶端,支援 MySQL、MariaDB、PostgreSQL 和 MS SQL Server,提供 GUI 來管理資料庫、執行 SQL 查詢、匯入/匯出資料等。
1. 前往官方網站下載 HeidiSQL: https://www.heidisql.com/download.php
2. 執行安裝程式並按照指示完成安裝
3. 開啟 HeidiSQL,設定新連線
1. 開啟 HeidiSQL
2. 點擊「新增」建立新連線
3. 設定:
- 主機名/IP:127.0.0.1 或 遠端伺服器 IP
- 使用者名稱:root 或其他使用者
- 密碼:對應的密碼
- 連接埠:3306(MySQL / MariaDB)
4. 點擊「開啟」連接資料庫
在 HeidiSQL 查詢視窗中輸入 SQL 語句:
SELECT * FROM users WHERE status = 'active';
點擊「執行」按鈕,即可查看結果。
1. 右鍵點擊資料庫 → 選擇「匯出 SQL」
2. 選擇要匯出的資料表
3. 設定匯出格式(.sql、.csv、.json)
4. 點擊「匯出」
1. 打開 HeidiSQL,選擇目標資料庫
2. 點擊「工具」→「執行 SQL 檔案」
3. 選擇 .sql 檔案並執行
1. 進入「工具」→「管理使用者權限」
2. 選擇要管理的使用者
3. 設定資料庫權限(SELECT、INSERT、UPDATE、DELETE 等)
4. 點擊「儲存」
1. 開啟 HeidiSQL。
2. 連接 MySQL 或 MariaDB 伺服器。
3. 在左側的「資料庫」列表中選擇目標資料庫。
1. 在左側的資料庫名稱上點擊右鍵,選擇「建立新的」→「儲存程序」。
2. HeidiSQL 會打開一個新的 SQL 編輯視窗,並提供預設的儲存程序模板。
以下是一個簡單的範例,返回 users 表中的所有資料:
DELIMITER //
CREATE PROCEDURE GetAllUsers()
BEGIN
SELECT * FROM users;
END //
DELIMITER ;
1. 點擊「執行」按鈕(綠色閃電)。
2. 若執行成功,可在左側的「儲存程序」欄位中找到該程序。
CALL GetAllUsers();
傳入參數來篩選數據,例如根據用戶 ID 查詢:
DELIMITER //
CREATE PROCEDURE GetUserById(IN user_id INT)
BEGIN
SELECT * FROM users WHERE id = user_id;
END //
DELIMITER ;
呼叫帶參數的儲存程序:
CALL GetUserById(1);
DROP PROCEDURE IF EXISTS GetAllUsers;
DELIMITER
確保語法正確。CALL
測試儲存程序。多媒體是指同時使用多種媒介(如文字、圖像、音頻、視頻和動畫)來傳達信息和內容的技術。它提供了一種豐富的方式來呈現和交流信息,並在教育、娛樂和廣告等領域得到了廣泛應用。
隨著技術的進步,多媒體技術也在不斷演變。從早期的靜態圖像和音頻到現在的高解析度視頻和虛擬實境(VR),多媒體的表達方式變得越來越豐富和多樣。
多媒體不僅提高了信息傳遞的效率和趣味性,還為用戶創造了更為沉浸式的體驗。未來,隨著技術的進一步發展,多媒體將在更多領域中發揮更大的作用。
OpenCV (Open Source Computer Vision Library) 是一個開源的計算機視覺與機器學習軟件庫,用於即時影像處理與分析。
# 讀取影像並顯示 import cv2 image = cv2.imread("image.jpg") cv2.imshow("Image", image) cv2.waitKey(0) cv2.destroyAllWindows()
Halcon 是由 MVTec 公司開發的一款強大的工業視覺軟體,專為影像處理和機器視覺應用而設計。
Shotcut 是一款免費且開源的影片編輯軟體,支援多種格式且具有許多強大的編輯工具。其特色包括:
適用平台:Windows、Mac、Linux
OpenShot 是一款易於上手的開源影片編輯工具,功能強大且支持多種格式。其主要特點包括:
適用平台:Windows、Mac、Linux
Blender 是一款知名的開源 3D 建模和動畫軟體,內建功能強大的影片編輯器,適合進行影片剪輯和特效製作。其功能包括:
適用平台:Windows、Mac、Linux
Kdenlive 是 Linux 上廣泛使用的開源影片編輯軟體,也支援 Windows。其主要功能包括:
適用平台:Windows、Mac、Linux
Lightworks 提供免費和付費版本,免費版本具備基本編輯功能。其特色包括:
適用平台:Windows、Mac、Linux
以上這些開源影片編輯軟體提供了強大的功能,適合不同層次的影片編輯需求,從簡單的家庭影片剪輯到專業級的影片製作都可以滿足。
軟體名稱 | 大約搜尋量 |
---|---|
OpenShot | 110,000 |
Kdenlive | 90,500 |
Shotcut | 49,500 |
Avidemux | 18,100 |
Losslesscut | 14,800 |
Blender VSE | 10,000 |
Natron | 6,600 |
Cinelerra | 5,400 |
Pitivi | 3,600 |
LiVES | 1,600 |
OpenShot 是一款免費且開源的影片編輯器,專案名稱為 OpenShot/openshot-qt
,主要基於 Python
和 Qt
開發。該專案旨在提供一個易於使用且功能豐富的影片編輯工具,適合不同水平的使用者。
OpenShot 使用 PyQt
作為圖形用戶界面,並結合 libopenshot
(C++ 實現) 來處理影片編輯的核心邏輯。此外,OpenShot 還利用了
FFmpeg
來支援多種格式的解碼與編碼。
OpenShot 適用於需要簡單操作、但功能強大的影片編輯需求的用戶。無論是業餘影片創作者還是教育用途,OpenShot 都提供了靈活的工具和插件,便於進行剪輯和創作。
OpenShot 專案擁有活躍的開源社群,使用者和開發者可以透過 GitHub 貢獻程式碼、報告問題或提交新功能建議。歡迎所有人參與,以協助提升 OpenShot 的功能與穩定性。
使用者可以透過 GitHub 頁面下載源碼,或從 OpenShot 官方網站下載可執行檔。詳細安裝指引和說明文件也可在 GitHub 上找到。
Unity 是一個功能強大的遊戲開發引擎和平臺,專門設計用於創建 2D 和 3D 遊戲、互動應用程式及虛擬現實 (VR) 和增強現實 (AR) 體驗。它提供簡單易用的介面和豐富的工具,適合初學者和專業開發人員使用。
Unity 是一個強大且靈活的開發引擎,為開發者提供了廣泛的應用場景和工具支持。無論是初學者還是專業開發人員,都可以利用 Unity 快速創建高質量的 2D、3D 遊戲及互動應用。
在 Android Studio 中建立一個新的專案,選擇 "Empty Activity" 模板,然後設定專案名稱及其他基本資訊。
在 res/layout/activity_main.xml
檔案中設計簡單的使用者介面,例如包含一個按鈕和一個文字顯示區域:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center">
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="點我" />
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello, World!"
android:layout_marginTop="20dp" />
</LinearLayout>
在 MainActivity.java
中,設定按鈕的點擊事件,使其更改文字顯示區域的內容:
package com.example.simpleapp;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = findViewById(R.id.button);
TextView textView = findViewById(R.id.textView);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
textView.setText("你點了按鈕!");
}
});
}
}
在 Android Studio 中點擊執行按鈕,即可在模擬器或連接的實體裝置上測試應用程式。點擊按鈕後,文字將更改為 "你點了按鈕!"。
iOS 開發主要使用 Xcode,這是 Apple 提供的官方整合開發環境 (IDE)。
學習 iOS 開發需要掌握以下基礎:
以下是一些實用的學習與開發資源:
Xcode 是 Apple 提供的整合開發環境 (IDE),用於 macOS、iOS、watchOS 和 tvOS 應用程式的開發。
可從 Mac App Store 或 Apple 開發者官網下載最新版本的 Xcode。
提升開發效率的實用技巧:
相關學習與參考資源:
Swift 是 Apple 推出的現代化程式語言,用於開發 iOS、macOS、watchOS 和 tvOS 應用程式。
var
和 let
?
和 !
處理值的存在與否if
、switch
、for
、while
func
定義,支援參數標籤與多返回值class
和 struct
Swift 不僅適用於 Apple 生態系統,還可以用於伺服器端開發與跨平台工具。
相關學習與參考資源:
Objective-C 是一種以 C 為基礎的物件導向程式語言,最初由 NeXT 公司開發,後來被 Apple 廣泛用於 macOS 和 iOS 應用程式開發。
Objective-C 的語法結合了 C 和 Smalltalk 的特性,使用 @ 符號來標示語言擴展。
@interface
和 @implementation
[object method]
@property
和 @synthesize
Objective-C 的開發主要使用 Apple 的 Xcode。
以下是一些學習與參考的資源:
GNews是一個由Google開發的新聞聚合平台,旨在幫助用戶獲取最新的全球新聞資訊。它整合了來自各種新聞來源的內容,使用人工智慧技術來個性化推薦用戶感興趣的新聞。
用戶可以通過訪問GNews的網站或下載其應用程式來使用此平台。在平台上,用戶可以選擇感興趣的主題、追蹤特定的新聞來源,並根據自己的需求自訂新聞推送。
GNews是一個強大的新聞聚合工具,透過人工智慧技術,為用戶提供個性化的新聞體驗。隨著新聞資訊的快速變化,GNews幫助用戶快速跟上世界動態,獲取所需的資訊。
Bolt 是一個快速、輕量的 AI 開發框架,專注於提供開發者簡單且高效的工具來建構應用程式。特點包括:
Cursor 是專為 AI 程式開發設計的編輯器工具,提供智能輔助程式碼撰寫與調試功能。特點包括:
v0 是一個基於視覺化開發的 AI 平台,允許使用者透過拖放介面構建模型與應用。特點包括:
Codeium 是一款結合 AI 智能輔助的程式編輯器,專注於提升程式開發效率與準確性。特點包括:
email: [email protected]