เพิ่งได้เจอมาคือว่า..ลง CentOS 6.5 มี HDD 1 TB ใช้ default แบ่งได้คือ lv_root = 50GB , lv_home = ที่เหลือ ประเด็นคือส่วนมากผมลงโปรแกรมไว้ /opt/ ปรากฏว่า lv_root เต็ม ทีนี้ต้องขยาย
Step 1
# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/vg_repo-lv_root 148G 113G 29G 80% /
tmpfs 499M 0 499M 0% /dev/shm
/dev/sda1 485M 156M 304M 34% /boot
/dev/mapper/vg_repo-lv_home 47G 181M 45G 1% /home
Step 2
#cd /
#cp -Ra /home /home.bak # Make a backup of home
#umount /home
#lvm lvremove /dev/vg_<hostname>/lv_home (Remove the logical volume for home)
#lvm lvresize -l+100%FREE /dev/vg_<hostname>/lv_root (Resize the root logical volume so it uses 100% of the now free space)
#resize2fs /dev/vg_<hostname>/lv_root (Resize the filesystem to use the whole logical volume)
#mv /home.bak /home (Restore the backup)
Step 3
#lvdisplay
#lvcreate -n lv_home -l 100%FREE VolGroup
#mke2fs -j /dev/VolGroup/lv_home
#mount /dev/VolGroup/lv_home /home
เสร็จ......
*******เพิ่มเติม*******
# comment out /home
แก้ไข /etc/fstab โดย คอมเม้น /home
* ถ้า boot ไม่ขึ้น
1. mount -o remount,rw / (เพื่อให้แก้ไขได้ ไม่งั้นจะ readonly)
2. แก้ไข /etc/fstab โดย คอมเม้น /home
วันอาทิตย์ที่ 21 กันยายน พ.ศ. 2557
วันพฤหัสบดีที่ 4 กันยายน พ.ศ. 2557
ติดต่อ Big Data (Hadoop) ผ่าน Jdbc ด้วย Hive และ Impala
บ้านเรายังไม่ค่อยตื่นตัวเรื่อง Big Data กันสักเท่าไหร่ แต่พอดีผมได้มีโอกาสทำงานกับข้อมูลเดือนละหลักพันล้าน record / ใช้พวก relation database เอาไม่อยู่ครับ query ง่าย ๆ ใช้เวลากันครึ่งค่อนวันเลยทีเดียว เจ้า Big Data เลยเป็นอีกทางเลือก มาลองดูกันว่าจะเข้าไปคุยกับมันยังไงดี ในที่นี้เป็น Cloudera Pack (Hadoop,hive,impala...)
- library ที่ต้องใช้
1. Jdbc Hive ตัวอย่างการเขียน ดึงข้อมูลมาแสดง
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class HiveConnection {
private static final String driver = "org.apache.hive.jdbc.HiveDriver";
private static final int hive_port = 10000;
private static final String host = "127.0.0.1";
private static final String db = "hadoopdb";
public static Connection getConnection() throws ClassNotFoundException, SQLException {
Class.forName(driver);
return DriverManager.getConnection("jdbc:hive2://" + host + ":" + hive_port + "/" + db);
}
public static void main(String[] args) {
System.out.println("\n=============================================");
System.out.println("start....");
Connection con = null;
try {
con = getConnection();
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("select * from table_name");
while (rs.next()) {
System.out.println("-" + rs.getString(1));
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
con.close();
} catch (Exception e) {
}
}
}
}
2. Jdbc Impala ตัวอย่างการเขียน ดึงข้อมูลมาแสดง
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class ImpalaConnection {
private static final String driver = "org.apache.hive.jdbc.HiveDriver";
private static final int impala_port = 21050;
private static final String host = "127.0.0.1";
private static final String db = "hadoopdb";
public static Connection getConnection() throws ClassNotFoundException, SQLException {
Class.forName(driver);
return DriverManager.getConnection("jdbc:hive2://" + host + ":" + impala_port + "/" + db + ";auth=noSasl");
}
public static void main(String[] args) {
System.out.println("\n=============================================");
System.out.println("start....");
Connection con = null;
try {
con = getConnection();
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("select * from table_name");
while (rs.next()) {
System.out.println("-" + rs.getString(1));
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
con.close();
} catch (Exception e) {
}
}
}
}
วันอาทิตย์ที่ 13 กรกฎาคม พ.ศ. 2557
เขียน shell script อย่างง่ายๆ ไว้ใช้งาน
- อธิบาย คำสั่งที่สร้างขึ้น
Step1 Set Java Home
Step2 เข้าไปที่ Path /home/test และ ลบ ไฟล์ที่นามสกุล .class ทั้งหมด
Step3 Compile ClassMyClassA.java
Step4 Clear หน้าจอ
Step5 สั่งรัน Class MyClassA และส่ง Param เข้าไปใน Class ด้วย
Step6 พิมพ์คำว่า Good bye....
- บันทึกไฟล์นี้ด้วยชื่ออะไรก็ได้ นามสกุลเป็น .sh แล้วอย่าลืมเปลี่ยน chmod เป็น +x ด้วยนะครับ
*** สั่งรัน shell script ดังนี้ ./xxxx.sh
*** อาจจะตั้งเวลาใน crontab สั่งใช้เรียกงาน sh นี้ก็ได้ครับ อย่างการทำ script สำหรับการ backup ข้อมูลใน Database
#!/bin/sh
JAVA_HOME=/opt/่java/jdk1.6.0_51
PATH=/opt/java/jdk1.6.0_51/bin:$PATH
cd /home/test/
rm *.class
javac MyClassA.java
clear
java MyClassA Param1 Param2 Param3
echo "Good bye..."
Step1 Set Java Home
Step2 เข้าไปที่ Path /home/test และ ลบ ไฟล์ที่นามสกุล .class ทั้งหมด
Step3 Compile ClassMyClassA.java
Step4 Clear หน้าจอ
Step5 สั่งรัน Class MyClassA และส่ง Param เข้าไปใน Class ด้วย
Step6 พิมพ์คำว่า Good bye....
- บันทึกไฟล์นี้ด้วยชื่ออะไรก็ได้ นามสกุลเป็น .sh แล้วอย่าลืมเปลี่ยน chmod เป็น +x ด้วยนะครับ
*** สั่งรัน shell script ดังนี้ ./xxxx.sh
*** อาจจะตั้งเวลาใน crontab สั่งใช้เรียกงาน sh นี้ก็ได้ครับ อย่างการทำ script สำหรับการ backup ข้อมูลใน Database
#!/bin/sh
JAVA_HOME=/opt/่java/jdk1.6.0_51
PATH=/opt/java/jdk1.6.0_51/bin:$PATH
cd /home/test/
rm *.class
javac MyClassA.java
clear
java MyClassA Param1 Param2 Param3
echo "Good bye..."
การเขียนโปรแกรม..เรียกใช้งาน command linux (ตัวอย่าง การ grep log)
- ถ้าเราเข้า ssh จะค้าหาข้อความที่อยู่ใน log เราก็ต้องใช้ command ---> grep 'xxxxx' /logfile_path
- แล้วถ้าต้องการเขียนโปรแกรมไปหาเองล่ะ... ตัวอย่างข้างล่างเลย ไม่เน้นอธิบาย เน้นให้อ่านโค๊ด
public static String grep(String keyword) {
try {
String logpath = "/home/test/server.log";
List<String> commands = new ArrayList<String>();
commands.add("/bin/sh");
commands.add("-c");
commands.add("grep '" + keyword + "' " + logpath);
ProcessBuilder pb = new ProcessBuilder(commands);
pb.redirectErrorStream(true);
Process process = pb.start();
BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line = null;
StringBuilder sb = new StringBuilder();
while ((line = br.readLine()) != null) {
sb.append(line).append("\n");
}
return sb.toString();
} catch (IOException ex) {
Logger.getLogger(GrepLogLinux.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}
- แล้วถ้าต้องการเขียนโปรแกรมไปหาเองล่ะ... ตัวอย่างข้างล่างเลย ไม่เน้นอธิบาย เน้นให้อ่านโค๊ด
public static String grep(String keyword) {
try {
String logpath = "/home/test/server.log";
List<String> commands = new ArrayList<String>();
commands.add("/bin/sh");
commands.add("-c");
commands.add("grep '" + keyword + "' " + logpath);
ProcessBuilder pb = new ProcessBuilder(commands);
pb.redirectErrorStream(true);
Process process = pb.start();
BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line = null;
StringBuilder sb = new StringBuilder();
while ((line = br.readLine()) != null) {
sb.append(line).append("\n");
}
return sb.toString();
} catch (IOException ex) {
Logger.getLogger(GrepLogLinux.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}
เข้ารหัสแบบใช้ Private Key
ชุดข้อวความ "y781iGR57Q8CuuTbjEtSzg==" นี้ถือว่าเป็นกุญแจในการเข้าและถอดรหัส
เข้ารหัส
package test;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.KeySpec;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;
public class Encrypt {
private Cipher ecipher;
private final String secret = "y781iGR57Q8CuuTbjEtSzg==";
public Encrypt() {
try {
byte[] salt = {
(byte) 0xA9, (byte) 0x9B, (byte) 0xC8, (byte) 0x32,
(byte) 0x56, (byte) 0x35, (byte) 0xE3, (byte) 0x03
};
int iterationCount = 19;
KeySpec keySpec = new PBEKeySpec(secret.toCharArray(), salt, iterationCount);
SecretKey key = SecretKeyFactory.getInstance("PBEWithMD5AndDES").generateSecret(keySpec);
ecipher = Cipher.getInstance(key.getAlgorithm());
AlgorithmParameterSpec paramSpec = new PBEParameterSpec(salt, iterationCount);
ecipher.init(Cipher.ENCRYPT_MODE, key, paramSpec);
} catch (Exception ex) {
Logger.getLogger(Encrypt.class.getName()).log(Level.SEVERE, null, ex);
}
}
public String testEncrypt() {
try {
String str = "Hello World";
byte[] utf8 = str.getBytes("UTF8");
byte[] enc = ecipher.doFinal(utf8);
return new sun.misc.BASE64Encoder().encode(enc);
} catch (Exception ex) {
Logger.getLogger(Encrypt.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}
public static void main(String[] args) {
Encrypt encrypt = new Encrypt();
System.out.println(encrypt.testEncrypt());
}
}
ถอดรหัส
package test;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.KeySpec;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;
public class Decrypt {
private Cipher dcipher;
private final String secret = "y781iGR57Q8CuuTbjEtSzg==";
public Decrypt() {
try {
byte[] salt = {
(byte) 0xA9, (byte) 0x9B, (byte) 0xC8, (byte) 0x32,
(byte) 0x56, (byte) 0x35, (byte) 0xE3, (byte) 0x03
};
int iterationCount = 19;
KeySpec keySpec = new PBEKeySpec(secret.toCharArray(), salt, iterationCount);
SecretKey key = SecretKeyFactory.getInstance("PBEWithMD5AndDES").generateSecret(keySpec);
dcipher = Cipher.getInstance(key.getAlgorithm());
AlgorithmParameterSpec paramSpec = new PBEParameterSpec(salt, iterationCount);
dcipher.init(Cipher.DECRYPT_MODE, key, paramSpec);
} catch (Exception ex) {
Logger.getLogger(Decrypt.class.getName()).log(Level.SEVERE, null, ex);
}
}
public String testDecrypt() {
try {
String str = "GdMOJDcTyBXFTK7yXmqIGw==";
byte[] dec = new sun.misc.BASE64Decoder().decodeBuffer(str);
byte[] utf8 = dcipher.doFinal(dec);
return new String(utf8, "UTF8");
} catch (Exception ex) {
Logger.getLogger(Decrypt.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}
public static void main(String[] args) {
Decrypt decrypt = new Decrypt();
System.out.println(decrypt.testDecrypt());
}
}
เข้ารหัส
package test;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.KeySpec;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;
public class Encrypt {
private Cipher ecipher;
private final String secret = "y781iGR57Q8CuuTbjEtSzg==";
public Encrypt() {
try {
byte[] salt = {
(byte) 0xA9, (byte) 0x9B, (byte) 0xC8, (byte) 0x32,
(byte) 0x56, (byte) 0x35, (byte) 0xE3, (byte) 0x03
};
int iterationCount = 19;
KeySpec keySpec = new PBEKeySpec(secret.toCharArray(), salt, iterationCount);
SecretKey key = SecretKeyFactory.getInstance("PBEWithMD5AndDES").generateSecret(keySpec);
ecipher = Cipher.getInstance(key.getAlgorithm());
AlgorithmParameterSpec paramSpec = new PBEParameterSpec(salt, iterationCount);
ecipher.init(Cipher.ENCRYPT_MODE, key, paramSpec);
} catch (Exception ex) {
Logger.getLogger(Encrypt.class.getName()).log(Level.SEVERE, null, ex);
}
}
public String testEncrypt() {
try {
String str = "Hello World";
byte[] utf8 = str.getBytes("UTF8");
byte[] enc = ecipher.doFinal(utf8);
return new sun.misc.BASE64Encoder().encode(enc);
} catch (Exception ex) {
Logger.getLogger(Encrypt.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}
public static void main(String[] args) {
Encrypt encrypt = new Encrypt();
System.out.println(encrypt.testEncrypt());
}
}
ถอดรหัส
package test;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.KeySpec;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;
public class Decrypt {
private Cipher dcipher;
private final String secret = "y781iGR57Q8CuuTbjEtSzg==";
public Decrypt() {
try {
byte[] salt = {
(byte) 0xA9, (byte) 0x9B, (byte) 0xC8, (byte) 0x32,
(byte) 0x56, (byte) 0x35, (byte) 0xE3, (byte) 0x03
};
int iterationCount = 19;
KeySpec keySpec = new PBEKeySpec(secret.toCharArray(), salt, iterationCount);
SecretKey key = SecretKeyFactory.getInstance("PBEWithMD5AndDES").generateSecret(keySpec);
dcipher = Cipher.getInstance(key.getAlgorithm());
AlgorithmParameterSpec paramSpec = new PBEParameterSpec(salt, iterationCount);
dcipher.init(Cipher.DECRYPT_MODE, key, paramSpec);
} catch (Exception ex) {
Logger.getLogger(Decrypt.class.getName()).log(Level.SEVERE, null, ex);
}
}
public String testDecrypt() {
try {
String str = "GdMOJDcTyBXFTK7yXmqIGw==";
byte[] dec = new sun.misc.BASE64Decoder().decodeBuffer(str);
byte[] utf8 = dcipher.doFinal(dec);
return new String(utf8, "UTF8");
} catch (Exception ex) {
Logger.getLogger(Decrypt.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}
public static void main(String[] args) {
Decrypt decrypt = new Decrypt();
System.out.println(decrypt.testDecrypt());
}
}
วันจันทร์ที่ 16 มิถุนายน พ.ศ. 2557
การเข้ารหัส รหัสผ่านก่อนลงใน LDAP และการถอดรหัส รหัสผ่านก่อนนำไปใช้
Authen ผ่าน LDAP แล้ว ทำการ synchronize ข้อมูลล่าสุดไปลง Database ซึ่งใน Field ของ Password ไม่สามารถนำไปใช้ได้ทันที หากต้องแปลงให้อยู่ในรูปของ MD5 (Hex Code) ก่อน
ตัวอย่าง Method แปลง รหัสของเราก่อนเก็บลง LDAP
public static String digestMd5(final String password) {
String base64;
try {
MessageDigest digest = MessageDigest.getInstance("MD5");
digest.update(password.getBytes());
base64 = new BASE64Encoder().encode(digest.digest());
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
return "{MD5}" + base64;
}
อินพุท
1234
ผลลัพธ์
{MD5}gdyb21LQTcIANtvYMT7QVQ==
ผลลัพธืนี้จะถูกเก็บลง LDAP โดยไม่สามารถแปลงกลับมาเป็น 1234 ได้
ตัวอย่าง Method ถอดรหัสที่นำมาจาก LDAP แล้วแปลงเป็น Hex
public static String base64ToHex(String base64) {
try {
base64 = base64.substring(5, base64.length());
byte[] bytes = new BASE64Decoder().decodeBuffer(base64);
StringBuilder sb = new StringBuilder();
for (int i = 0; i < bytes.length; i++) {
sb.append(Integer.toString((bytes[i] & 0xff) + 0x100, 16).substring(1));
}
return sb.toString();
} catch (IOException ex) {
Logger.getLogger(Ldap.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}
อินพุท
{MD5}gdyb21LQTcIANtvYMT7QVQ==
ผลลัพธ์
81dc9bdb52d04dc20036dbd8313ed055
วันพุธที่ 9 เมษายน พ.ศ. 2557
ชนิดของข้อมูล ในภาษาจาวา
ชนิดของข้อมูล (Data Type) ในภาษาจาวาแบ่งเป็นสองประเภทใหญ่ๆ คือ
1. ชนิดข้อมูลแบบพื้นฐาน (Primitive data type) หมายถึงชนิดข้อมูลที่สามารถเก็บข้อมูลที่เป็นข้อมูลทั่วไปหรือข้อมูลพื้นฐาน มีทั้งหมด 8 ตัว ได้แก่ boolean, char, byte, short, int, long, float,double
ชนิดข้อมูลพื้นฐาน (Primitive Data Type) ชนิดข้อมูลพื้นฐานในภาษาจาวาแบ่งออกเป็น 4 กลุ่ม ดังนี้
Logical ได้แก่ boolean
Textual ได้แก่ char
Integral ได้แก่ byte,short,int และ long
Floating-point ได้แก่ float และ double
ชนิดข้อมูล สำหรับ ค่าที่เป็นไปได้
byte ตัวเลขจำนวนเต็มเล็กๆ ใช้พื้นที่เก็บเพียงแค่ 1 ไบต์ -128 ถึง 127
short ตัวเลขจำนวนเต็ม (ใช้พื้นที่เก็บ 16 บิต หรือ 2 ไบต์) -32,768 ถึง 32,767
int ตัวเลขจำนวนเต็มทั่วไป (ใช้พื้นที่เก็บ 32 บิต หรือ 4 ไบต์) -2,147,483 ถึง 2,147,483,647
long ตัวเลขจำนวนเต็มขนาดใหญ่ (ใช้พื้นที่เก็บ 64 บิต หรือ 8 ไบต์) -9,223,372,036,845,775,808 ถึง 9,223,372,036,845,775,807
float ตัวเลขทศนิยมทั่วไป (ใช้พื้นที่เก็บ 32 บิต หรือ 4 ไบต์) 1.4e-45 ถึง 3.4028235e+38
double ตัวเลขทศนิยมขนาดใหญ่ (ใช้พื้นที่เก็บ 64 บิต หรือ 8 ไบต์) 4.9e-324 ถึง1.7976931348623157e+308
char ตัวอักษรทุกชนิด ตามมาตรฐาน 16-bit Unicode ตัวอักษรต่างๆ
boolean ค่าความเป็นจริงทางตรรกะ (ใช้พื้นที่เก็บ 1 บิต) มี 2 ค่าเท่านั้นคือ true กับ false
2. ชนิดข้อมูลแบบอ้างอิง (Reference data type) มีความแตกต่างกับชนิดข้อมูลพื้นฐาน ที่ว่าชนิดข้อมูลชนิดนี้อยู่ในรูปแบบหนึ่ง ซึ่งการเข้าถึง(ใช้งาน)ข้อมูลเป็นการอ้างถึง มากกว่าการเข้าถึงข้อมูลโดยตรง เก็บข้อมูลไว้ 2 ส่วน คือ
2.1 Execution Stack เก็บค่าอ้างอิงที่ชี้ไปยัง Heap memory
2.2 Heap Memory เก็บข้อมูลที่เรียกว่าออปเจ็ค ที่สร้างขึ้นมาจากคลาส
1. ชนิดข้อมูลแบบพื้นฐาน (Primitive data type) หมายถึงชนิดข้อมูลที่สามารถเก็บข้อมูลที่เป็นข้อมูลทั่วไปหรือข้อมูลพื้นฐาน มีทั้งหมด 8 ตัว ได้แก่ boolean, char, byte, short, int, long, float,double
ชนิดข้อมูลพื้นฐาน (Primitive Data Type) ชนิดข้อมูลพื้นฐานในภาษาจาวาแบ่งออกเป็น 4 กลุ่ม ดังนี้
Logical ได้แก่ boolean
Textual ได้แก่ char
Integral ได้แก่ byte,short,int และ long
Floating-point ได้แก่ float และ double
ชนิดข้อมูล สำหรับ ค่าที่เป็นไปได้
byte ตัวเลขจำนวนเต็มเล็กๆ ใช้พื้นที่เก็บเพียงแค่ 1 ไบต์ -128 ถึง 127
short ตัวเลขจำนวนเต็ม (ใช้พื้นที่เก็บ 16 บิต หรือ 2 ไบต์) -32,768 ถึง 32,767
int ตัวเลขจำนวนเต็มทั่วไป (ใช้พื้นที่เก็บ 32 บิต หรือ 4 ไบต์) -2,147,483 ถึง 2,147,483,647
long ตัวเลขจำนวนเต็มขนาดใหญ่ (ใช้พื้นที่เก็บ 64 บิต หรือ 8 ไบต์) -9,223,372,036,845,775,808 ถึง 9,223,372,036,845,775,807
float ตัวเลขทศนิยมทั่วไป (ใช้พื้นที่เก็บ 32 บิต หรือ 4 ไบต์) 1.4e-45 ถึง 3.4028235e+38
double ตัวเลขทศนิยมขนาดใหญ่ (ใช้พื้นที่เก็บ 64 บิต หรือ 8 ไบต์) 4.9e-324 ถึง1.7976931348623157e+308
char ตัวอักษรทุกชนิด ตามมาตรฐาน 16-bit Unicode ตัวอักษรต่างๆ
boolean ค่าความเป็นจริงทางตรรกะ (ใช้พื้นที่เก็บ 1 บิต) มี 2 ค่าเท่านั้นคือ true กับ false
2. ชนิดข้อมูลแบบอ้างอิง (Reference data type) มีความแตกต่างกับชนิดข้อมูลพื้นฐาน ที่ว่าชนิดข้อมูลชนิดนี้อยู่ในรูปแบบหนึ่ง ซึ่งการเข้าถึง(ใช้งาน)ข้อมูลเป็นการอ้างถึง มากกว่าการเข้าถึงข้อมูลโดยตรง เก็บข้อมูลไว้ 2 ส่วน คือ
2.1 Execution Stack เก็บค่าอ้างอิงที่ชี้ไปยัง Heap memory
2.2 Heap Memory เก็บข้อมูลที่เรียกว่าออปเจ็ค ที่สร้างขึ้นมาจากคลาส
สมัครสมาชิก:
บทความ (Atom)
