MindMap Gallery Mind map of goals
This clear mind map on objectives outlines key steps to achieving them, including aspects such as gold land, three-dimensional, and backend. Each aspect further divides into specific implementation steps and considerations, providing us with a comprehensive project management blueprint. This problem-centered graphical thinking tool effectively promotes memory, information organization, and stimulates innovation in information technology applications.
Edited at 2022-02-03 15:22:00Mục Tiêu
Kiến Thức
Lập Trình
Fullstack Developer
Front-End
HTML/CSS
Responsive
JS
DATA TYPE
LET: không được gọi ngoài phạm vi block
VAR: được gọi ngoài phạm vi block
CONST: không được gọi ngoài phạm vi block
thông thường phải khai báo biến mới được gán giá trị cho biến. Thì đối với VAR chúng ta được quyền gán giá trị rồi mới khai báo biến, vì trình biên dịch sẽ tự động đưa khai báo lên trên đầu khi trình biên dịch chạy. Còn đối với LET và CONST thì không.
Quy tắc đặt tên biến
Tên biến có thể bao gồm chữ cái, số, dấu gạch dưới ( _ ) và kí tự đô la ( $ )
Tên biến không thể bắt đầu bằng số, phải bắt đầu bằng một chữ cái hoặc dấu gạch dưới hoặc dấu đô la
Tên biến phân biệt chữ hoa và chữ thường. Vì vậy tenbien và TenBien là 2 biến khác nhau
không được (không thể) đặt trùng với các từ khóa của Javascript
BUILD-IN FUNCTION
console.log('...')console.warn('..'): in cảnh báoconsole.error('..'): in lỗi
confirm (''): có nút OK và Cancle
prompt(''): ngoài việc có OK và Cancle nó còn có ô nhập liệu
setTimeout(function() { //code }, 1000): Sau 1000 milisecond (1s) thì dòng lệnh sẽ được thực thi
setInterval(function(){ //code }, 1000) :Dòng lệnh sẽ được thực thi liên tục sau một khoảng thời gian là 1000 milisecond (1s)
Toán tử
So sánh (Comparison)
== (không phân biết được chuỗi và số 1 vẫn bằng '1' => SAI). Chỉ so sánh giá trị
=== so sánh cả giá trị và datatype
TRUTHY
Bất cứ giá trị nào trong Javascript khi chuyển đổi sang kiểu dữ liệu boolean mà có giá trị true thì ta gọi giá trị đó là Truthy.
FALSY
Bất cứ giá trị nào trong Javascript khi chuyển đổi sang kiểu dữ liệu boolean mà có giá trị false thì ta gọi giá trị đó là Falsy.
6 giá trị: false, 0, '', null,undefined, NaN
document.all chuyển sang boolean sẽ là false. typeof document.all sẽ trả về undefined
STRING
Một số trường hợp sử dụng backslash (\)\' hoặc \" thêm dấu nháy
Làm việc với chuỗi: myString = 'Hoc JS tai F8!'
myString.length => 14
myString.indexOf('JS',start_position ) => 4
myString.lastIndexOf('JS')
myString.search('JS') => vị trí
myString.slice(start,end) hoặc myString.slice(start) => cắt
myString.replace('JS','Javascript') => ghi đè
myString.toUpperCase() và myString.toLowerCase()
myString.trim(): loại bỏ khoảng trống đầu và cuối
var languages = 'JS, PHP, Ruby'languages.split(', ') => ['JS','PHP','Ruby']=> Cắt chuỗi ra thành một mảng
myString.charAt(0) => H
NUMBER
var million = 1000000;var million = 1e6; // tương tự: 1000000var billion = 2e9; // tương tự: 2000000000
Làm việc với đối tượng Number
Number.isFinite(): Xác định xem giá trị đã cho có phải là số hữu hạn hay không. Trả về boolean
Number.isInteger(8): Xác định xem giá trị đã cho có phải là số nguyên hay không. Trả về boolean
Number.parseFloat(): Chuyển đổi chuỗi đã cho thành một số dấu phẩy động
vd: Number.parseFloat('238,21') // 238 Number.parseFloat('34 56 78') // 34 Number.parseFloat('18 is my age') // 18
Number.parseInt(): Chuyển đổi chuỗi đã cho thành một số nguyên
Number.prototype.toFixed(): Chuyển đổi và trả về chuỗi đại diện cho số đã cho, có số chữ số chính xác sau dấu thập phân
vd: var numberObject = 1234.56789; numberObject.toFixed(); // '1235' numberObject.toFixed(1); // '1234.6' numberObject.toFixed(6); // '1234.567890'
Number.prototype.toString() Chuyển đổi và trả về số đã cho dưới dạng chuỗi
ARRAY
Lặp các phần tử trong mảng, tốt nhất nên dùng vòng lặp FOR IN => chỉ chạy những phần tử có trong mảng (không bao gồm phần tử rỗng)
Để kiểm tra 1 object có phải array hay không => languages.isArray(..)
Làm việc với Array: var languages = ['Javascript', 'PHP', 'Ruby', null, function(){..},..];
toString
languages.join('pattern') => các phần tử trong array được viết gần nhau và cách nhau bởi pattern. Chuyển từ mảng sang chuỗi
languages.pop(): xóa phần tử ở cuối mảng và trả về phần tử đã xóa
languages.push('word', 'word1',...): thêm 1 hoặc nhiều phần tử vào cuối mảng
languages.shift(): xóa đi phần tử ở đầu mảng và trả về phần tử đã xóa
languages.unshift('word', 'word1',...): thêm phần tử vào đầu mảng
* languages.splice(indexStart, deleteCount) - Xóa* languages.splice(indexStart, deleteCount, 'word') - Chèn
languages.concat(languages2): chèn
languages.slice(indexStart, indexEnd) (nếu không có End thì cắt từ Start đến hết và trả về các element bị cắt) => Có thể dùng hàm này như một cách copy mảng
Các hàm của Array
courses.forEach(function(course,index){ console.log(course,index)})
every(): giúp kiểm tra tất cả phần tử trong mảng có thỏa mã điều kiện nào đó hay không. Nếu tất cả đều thỏa thì trả về True, ngược lại chỉ cần một phần tử không thỏa thì sẽ trả về False
// Danh sách mảngconst ages = [32, 33, 16, 40]; // Kiểm traconsole.log(ages.every(checkAge)) // Returns false // Hàm kiểm tra giá trị truyền vào có lớn hơn 20 khôngfunction checkAge(age) { return age > 20;}
array.every(function(currentValue, index, arr), thisValue)
currentValue - giá trị của phần tử hiện tại.index - chỉ số của phần tử hiện tại.arr - mảng mà phần tử hiện tại thuộc về.thisValue - tham số không bắt buộc. Nếu được truyền vào thì thisValue sẽ được sử dụng làm giá trị của this, nếu không được truyền vào thì giá trị this là "undefined".
some(): Hàm some trong js có nhiệm vụ lặp qua tất cả các phần tử của mảng, mỗi lần lặp nó sẽ truyền giá trị của phần tử đang lặp vào hàm callback. Chỉ cần hàm callback return true là hàm some sẽ return true. Ngược lại, nếu duyệt hết mảng mà không có return true nào thì hàm some sẽ return false.
find(): tìm phần tử đầu tiên và dừng lại
filter() => tìm tất cả phần tử có trong mảng
courses.map((course) => {..}) => lấy ra một mảng các phần tử có trong mảng courses và được truyền các phần tử course vào trong function để xử lý.
reduce(function(){..}, initValue): được sử dụng để thực thi một hàm lên các phần tử của mảng (từ trái sang phải) với một biến tích lũy để thu về một giá trị duy nhất. Là một phương thức quan trọng hay sử dụng trong lập trình hàm. => Thực thi công việc function như một vòng lặp for với giá trị khởi tạo initValue
arr.reduce(callback( accumulator, currentValue[, index[, array]] ) { // return result from executing something for accumulator or currentValue}[, initialValue])- accumulator biến tích lũy, được trả về sau mỗi lần gọi hàm callback.- currentValue phần tử của mảng đang được xử lý.- index (Optional) chỉ số của phần tử trong mảng đang được xử lý.- array (Optional) mảng hiện tại gọi hàm reduce().=> Giá trị trả về chính là giá trị của accumulator sau lần gọi hàm callback cuối cùng.
const data = [5, 10, 15, 20, 25];const res = data.reduce((total,currentValue) => { return total + currentValue;});console.log(res); // 75
data = [11, 21, 19, 18, 46]const reducer = (accumulator, currentValue) => accumulator + currentValueresult = data.reduce(reducer, 29) => gán giá trị ban đầu cho accumulator=29console.log(result) // 144
Hàm - FUNCTION
Đối tượng argument
chỉ xuất hiện bên trong function, khi sử dụng arguments thì cho phép hàm sử dụng hàm nhiều hoặc không có tham số, tùy chỉnh.
vd: function writeLog(){ console.log(arguments);}writeLog('Log 1','Log 2',...)
Hai function trùng tên khi thực thi thì function sau cùng sẽ ghi đè function trước.
OBJECT
Object Constructor
Định nghĩa object constructor function User(firstName, lastName){ this.firstName = firstName; this.lastName = lastName; this.getName = function(){ return `${this.firstName} ${this.lastName}` } }
Sử dụng object constructor var author = new User('Toan','Le') var boss = new User('Vinh','Le')
VÒNG LẶP
for/in - Lặp qua key của đối tượng
for/of - Lặp qua value của đối tượng
break: thoát vòng lặp ngay lập tức
continue: bỏ qua các giá trị ngoại lệ và tiếp tục vòng lặp
INCLUDES METHOD
Phương thức này được sử dụng cho cả String và Array Array.prototype.includes String.prototype.includes
title.includes('aa') hoặc title.includes('aa',position)=> Kiểm tra xem trong chuỗi title có chứa chuỗi 'aa' không, nếu có trả về TRUE, không thì trả về FALSE
HTML DOM
Có 3 thành phần chính - Mỗi thành hần là một node
Element
Có thể chứa các attribute
id
class
tag,...
- Lấy element có chứa id = 'heading' => document.getElementById('heading')- CSS SELECTOR (class thì dùng '.', id dùng '#') => document.querySelector('.heading')hoặc document.querySelector('.heading:first-child') (lấy element đầu tiên) document.querySelector('.heading:nth-child(2)') (lấy element thứ 2) - document.querySelectorAll('.heading') (lấy tất cả các element có chứa class='heading' in ra dưới dạng NodeList (khá giống HTML Collection)- Lấy element có chứa class = 'heading' => document.getElementsByClassName('heading')- Lấy element theo thẻ tag => document.getElementByTagName('p')
Chỉ có 2 phương thức đầu là sẽ sẽ về trực tiếp chuỗi HTML, đều trả về 1 element
3 phương thức kia sẽ trả về HTML Collection (như 1 mảng)=> Cách giải quyết tình huống đó cho 3 phương thức còn lại:document.getElementsByTagName('h1')[0] (thêm chỉ mục)
HTML COLLECTION
document.forms: truy xuất ra các thẻ form có chứa thuộc tính 'id' trong chuỗi HTML
document.forms.heading: truy xuất form có thuộc tính id là 'heading'
document.forms[0]: dạng HTML Collection
document.anchors: trả về tất cả các thẻ <a> có thuộc tính 'name'
document.images: trả về tất cả các hình ảnh
HTML WRITE
document.write('hello') => cho phép truy xuất các Element của DOM, tức là tác động vào file HTML, thêm dòng text 'hello' vào vị trí được chỉ định trong chuỗi HTML của <body>
Attribute
Trước tiên để thao tác được với các Attribute thì phải tìm ra được Element của attribute đó.
Thêm attribute headingElement.title = 'heading'hoặc headingElement.setAttribute('class','heading')(title chỉ được gán 'heading' khi đang thực thi lệnh, còn nếu xem source code trên brower thì thẻ <h1> sẽ không có thuộc tính title
Lấy Value của 1 attribute headingElement.getAttribute('class') headingElement.getAttribute('title') => heading
Text
INNER TEXT
là khi sử dụng getter để lấy giá trị, thì nội dung chúng ta lấy được sẽ là nội dung trên trình duyệt
TEXTCONTENT
là sẽ trả về nội dung thật mà đã khai báo ở DOM
Sửa text //setter headingElement.textContent = 'New heading' //getter headingElement.textContent
INNER HTML
là lấy nội dung bên trong
Tìm element var boxElement = document.querySelector('.box')Thêm 1 element boxElement.innerHTML = '<h1>Heading</h1>'=> Thêm 1 element <h1>, đồng thời cũng thêm một text node 'Heading'
OUTER HTML
là lấy luôn cả thẻ chứa class 'box' và tất cả nội dung trong nó, thường dùng để ghi đè nội dung trong DOM
HTML DOM không phải của JS, mà JS chỉ cung cấp phần tử 'document' để truy xuất các phương thức của HTML DOM.
DOM API chạy trên môi trường Web API
Server chỉ xử lý và lưu trữ Website và JS thì không có DOM. Nhưng khi chạy trên Brower thì DOM hoạt động => Đó là vì trên Brower có Web API, mà Web API lại có chứa DOM trong đó.
Đối tượng Document đứng ở vị trí đầu, khi mà trình duyệT đọc hết chuỗi HTML thì trình duyệt sẽ tạo ra DOM và lưu hết vào biến Document. Đã được tích hợp sẵn trên Web API. Là đại diện cho toàn bộ website.
DOM CSS
Sinh ra những dòng CSS Inline
var boxElement = document.querySelector('.box')boxElement.style.width = '100px'boxElement.style.height = '200px'boxElement.style.backgroundColor = 'red'
=> Rút gọn:Object.assign(boxElement.style,{ width: '100px' height: '200px' backgroundColor: 'red'})
CLASSLIST PROPERTY
<div class = 'box box-1 box-2'> </div>var boxElement = document.querySelector('.box')boxElement.classList => Sinh ra 1 DOMTokenList => Đối tượng này giúp chúng ta có thể quản lý được class của đối tượngboxElement.classList[0] => boxboxElement.classList[1] => box-1
add: có thể thêm thuộc tính class vào element boxElement.classList.add('nameClass1','nameClass2',...)
contains: kiểm tra 1 class có nằm trong element hay không boxElement.classList.contains('className') => true/false
remove: có thể xóa thuộc tính class trong element boxElement.classList.remove('nameClass1')
toggle: nếu đã có 1 class ở element thì nó sẽ xóa bỏ class đó, còn nếu không có thì nó sẽ thêm vào. boxElement.classList.toggle('nameClass1')
DOM EVENTS
Là những sự kiện diễn ra ở phía người dùng khi truy cập trang web
Các sự kiện sẽ ảnh hưởng đến tất cả các class cha của nó. Những sự kiện như vậy gọi là 'sự kiện nổi bọt'.
PREVENT DEFAULT
giúp ngăn chặn các hành vi mặc định của trình duyệt trên một thẻ HTML
STOPPROPAGATION
loại bỏ sự kiện nổi bọt
- Click<h1 onclick='console.log(Math.random())'>DOM Events</h1>=> Khi click vào dòng 'DOM Events' sẽ sinh ra một số ngẫu nhiên.
- Hover<h1 onmouseover='console.log(Math.random())'>DOM Events</h1>
EVENT LISTENER
Tương tự DOM Event, cũng lắng nghe các sự kiện từ bàn phím và chuột.
Có thể ghi đè lại sự kiện của DOM
var btn = document.getElementById('btn')=> btn.addEventListener('click', function(e){ //do something})
- Sử dụng DOM trong trường hợp muốn sử dụng hoạt động nào đó à không có nhu cầu gỡ bỏ hoạt động mặc định đi, cú pháp ngắn gọn- Còn khi muốn xử lý nhiều việc khi 1 event xảy ra, khi cú pháp quá nhiều rồi thì nên sử dụng Event Listener.
JSON
Là 1 định dạng dữ liệu (chuỗi). Có thể thể hiện đa số các kiểu dữ liệu có trong JS bằng cách Mã hóa và Giải mã
từ các kiểu dữ liệu khác sang JSON (Stringify)
var arr = ["Javascript","PHP"]+ Chuyển Array sang JSON => JSON.stringify(arr) =>'["Javascript","PHP"]'
chuyển từ JSON về kiểu dữ liệu khác (Parse)
var json = '1'+ Chuyển json sang Số => JSON.parse(json) var json = '"abc"'+ Chuyển json sang Chuỗi => JSON.parse(json)
PROMISE
Synch (đồng bộ): đồng bộ là viết trước chạy trước, viết sau chạy sau.
Asynch (bất đồng bộ)
setTimeout
setInterval
fetch
XMLHttpRequest
I/O
Promise sinh ra để giải quyết
Các vấn đề trong quá trình lập trình bất đồng bộ. Trước khi dùng Promise thì thường dùng Callback, và callback thường có vấn đề là Callback hell. Promise được sinh ra trong phiên bản ES6
Callback hell (vấn đề khi sử dụng callback): vd như callback lồng callback quá nhiều. Để call back bên trong thực thi thì callback bên ngoài phải được thực thi xong.
dễ nhìn, dễ đọc hơn so với callback hell
Promise không thay thế callback, nó chỉ giải quyết các vấn đề phức tạp khi dùng callback, như callback hell.
//Promise là Object Constructor var promise = new Promise( //Excutor function(resolve,reject){ // Logic // nếu thành công thì gọi resolve() // nếu thất bại thì gọi reject() reject('Co loi!) } )
+ Khi mà chúng ta gọi 'new Promise' thì function bên trong Promise sẽ được thực thi trước cả việc gán cho biến promise.
+ Function bên trong Promise luôn có 2 tham số là resolve và reject. Hàm trả về luôn luôn phải gọi resolve() hoặc reject(), nếu không sẽ bị treo máy (Memory leak: rò rỉ bộ nhớ)
promise .then(function(){...}) .catch(function(error){console.log(error)}) .finally(function(){...})
+ Đối tượng promise trả về 3 phương thức: then(), catch(), finally(). Ba phương thứ này đều nhận 1 callback (function) ở bên trong.
+ Khi Promise trả về resolve() thì then() được gọi, trả về reject() thì catch() được gọi. Còn finally() đều được gọi khi 1 trong 2 thành phần trên được trả về
+ Các hàm như then() có thể lặp lại nhiều lần. Công việc 1 nếu hoàn thành xong sẽ trả về một giá trị và giá trị này sẽ được gán cho function 2 thực hiện công việc ở hàm then() thứ 2. Nếu không có giá trị trả về sẽ return ra undefined
Có trường hợp trong đoạn then() ở giữa bị reject (tức là có lỗi) thì những đoạn then() phía dưới không được thực hiện, bắn lỗi ra ngay lập tức => thì dùng hàm catch() để bắt lỗi ngay lập tức.
Theo thông thường để sử dụng được các hàm resolve, reject của Promise thì phải khai báo. Đôi khi thực tế mà chúng ta muốn làm một công việc mà xác định nó thành công luôn, vd như có 1 dữ liệu là mảng,... muốn thể hiện nó dưới dạng Promise => Có thể tạo nhanh
var promise = Promise.resolve('Success!')hay Promise.reject)
Dù thành công hay thất bại thì giá trị trả về của nó vẫn luôn là 1 Promise
Promise.all: giúp chạy song song các Promise. Tức là thường dùng promise để chạy các sự kiện phụ thuộc nhau. Nhưng bây giờ cần xử lý các logic bất đồng bộ nhưng không phụ thuộc nhau, chúng ta muốn chạy nó song song mà vẫn muốn lấy kết quả kết hợp với nhau để thực hiện công việc => dùng Promise.all
var promise1 = new Promise( function(resolve){ setTimeout(function(){ resolve([1]) },2000) } ) var promise2 = new Promise( function(resolve){ setTimeout(function(){ resolve([2,3]) },5000) } )=> Promise.all([promise1, promise2]) .then(function(result){ // trả về một mảng chứa 2 phần tử tương ứng là của promise1 và promise2 console.log(result[0]) //[1] console.log(result[1]) //[2] }) .catch()
Có 3 trạng thái
Pending: chờ xem trả về thành công hay thất bại
Fulfilled: sau khi biết thành công rồi thì ở trạng thái này
Rejected: sau khi biết thất bại rồi thì ở trạng thái này
ES6 - Javascript Ecmascript 6
TEMPLATE LITERALS (TEMPLATE STRING)
Khai báo chuỗi ký tự trong `` (template string)
CLASSES
class Course{ construcor(name,price){ this.name = name this.price = price }}
ENHANCED OBJECT LITERAL
var name = 'JS' var price = 1000=> Thông thường var course = { name: name, price: price getName: function(){...} }=> Theo Enhance var course = { name, price, getName(){...} }
DEFAULT PARAMETER VALUES
- Theo quy tắc cũ- Nếu log rỗng sẽ gán giá trị mặc địnhfunction logger(log){ if(typeof log == 'undefine'){ log = 'Gia tri mac dinh' } console.log(log)}- Theo ES6function logger(log = 'Gia tri mac dinh'){ console.log(log) }
DESTRUCTURING
- Bình thường thì var array = ['JS','PHP','Ruby'] var a = array[0] var b = array[1] var c = array[2] console.log(a,b,c) => Dùng Destructuring var array = ['JS','PHP','Ruby'] var [a,b,c] = arrayhoặc var [a, ,c] => lấy được a và c console.log(a,b,c)
REST PARRAMETER
Ví dụ dùng Destructuring lấy ra 1 phần tử trong mảng: var array = ['JS','PHP','Ruby'] var [a, , ] = array console.log(a)
Vậy là vẫn còn các phần tử còn lại, và chúng ta muốn lấy tất cả các phần tử còn lại ngoại trừ các phần tử đã Constructuring như 'a' thì ta dùng toán tử 3 dấu chấm '...'rest=> var [a,...rest] = array console.log(a) // JS console.log(rest) // ['PHP','Ruby']
SPREAD
var array1 = ['JS','PHP','Ruby']var array2 = ['ReactJS','Dart']+ Để nối chuỗi 2 với chuỗi 1 thông thường ta hay nghĩ đến Concat, thì với Spread ta có thể: var array3 = [...array2, ...array1] // nối mảng 2 trước sau dó đến mảng 1/
vd: override var defaultConfig = { api: 'http://cafebiz.vn', version: 'v1', other: 'other' } => var excerciseConfig = { ...defaultConfig, api: 'http://baitap.vn' }=> Các key mà trùng nhau thì chương trình sẽ lấy key được khai báo sau
TAGGED TEMPLATE LITERALS
function highlight(...rest){ console.log(rest) } var brand = 'F8' var course = 'JS'=> highlight`Học lập trình ${course} tại ${brand}!`=> Giá trị trả về: + Mảng chứa các giá trị không chứa biến nội suy: ['Học lập trình ',' tại ','!'] + 'JS' + 'F8' (biến nội suy)
MODULES
Export
- Export defaultexport default logger;export const a = 'log'
Import
- Imort defaultimport logger from './logger.js'- import theo kiểu destructuring.import {a,b,c} from './constants.js'import * as constants from './constant.js'
Để file .js có thể import được file .js khác thì trong file .html khi khai báo đường dẫn js thì cần thêm type='module'
<script type='module' src='...'></script>
OPTOPNAL CHAINING(?.)
Dùng Optional Chaining khi chúng ta không chắc chắn là key mà chúng ta cần tìm có tồn tại trong dữ liệu trả về không.
const obj = { name: 'Toan', cat: { name: 'Mimi' cat2: { name: 'Mimi2' } } }
Có một vấn đề là nếu dữ liệu trên chúng ta lấy từ DB về, ta không biết dữ liệu trả về có phải là 1 object hay có key như trên không
Để kiểm tra, thông thường ta dùng: if(obj.cat && obj.cat.cat2){ //nếu có cat và cat2 mới in console.log(name) }=> Với Optional Chaining: if(obj?.cat?.cat2){ //nếu có cat và cat2 mới in console.log(name) }
FETCH
Sử dụng Fetch để có thể lấy dữ liệu từ phía Back-End trả về.
Sử dụng Fetch để có thể lấy dữ liệu từ phía Back-End trả về
Trang web lấy json cung cấp sẵn: 'jsonplaceholder'
Cách sử dụng fetch: var postAPI = 'https://jsonplaceholder.typicode.com/todos/1'=> fetch(postAPI)
Extension để fake REST API là 'JSON SERVER' (tìm trên github, cần phải cài nodeJS)
NodeJS
Khái niệm
Là một nền tảng web (Web Framework), phát triển mạnh mẽ và chạy đa nền tảng ở phía Server, ngôn ngữ sử dụng là JS
Có thể đáp ứng hệ thống hàng triệu User
Nền tảng độc lập, được xây dựng ở trên Chrome's Javascrit Runtime
Không hỗ trợ lập trình đa luồng
Đa luồng là trong 1 tiến trình thực hiện nhiều công việc
Sử dụng kiến trúc hướng sự kiện Event-driver, cơ chế non-blocking I/O cho ứng dụng nhẹ và hiệu quả
Kiến trúc hướng sự kiện Event-driver (EDA) là một mẫu thiết kế phần mềm cho phép phát hiện các 'sự kiện' theo thời gian thực. Thường được gọi là giao tiếp 'bất đồng bộ'
Blocking và Non-Blocking trong lập trình chủ yếu được đề cập khi muốn miêu tả về cách một chương trình thực hiện các dòng lệnh của nó.
Blocking có nghĩa là các dòng lệnh được thực hiện một cách tuần tự
Non-blocking
Các thư viện thường dùng
expressJS
nodemon: phát hiện sự thay đổi trong code => tự động load lại ứng dụng
Thêm dòng code vào đoạn script của package.js: "start": "nodemon --inspect ./name_app.js"
morgan: có thể phát hiện lỗi mà hệ thống không thông báo trực tiếp trên Client
Để có thể sử dụng thì trong mỗi file cần import thư viện vào bằng cách thêm: var morgan = require('morgan');Và thêm : app.use(morgan('type_name'))* type_name: tham khảo trong trang chính
Template Engine
HANDLEBAR
npm i express-handlebars
Node SASS: Cho phép chúng ta cấu hình từ file SCSS sang file CSS
npm i sass --save-dev
Thêm đoạn mã có định dạng vào dòng script của file package.json "name":"sass [options] <input> [output]", (Có thể không cần thêm tham số option, input, output đều là đường dẫn)
* -w (--watch: xem có sự thay đổi gì không là tự động compile lại, mà không cần chạy lệnh lại)- Để chuyển đổi, vào command promt: npm run name
Ứng dụng
WebSocket Server (chat Onl, Game,..), các chương trình yêu cầu thời gian thực
Dịch vụ đám mây
Các kiến trúc dịch vụ nhỏ nhờ vào khả năng phân tán của nó, từ 1 ứng dụng lớn có thể hân chia ra làm các ứng dụng nhỏ. Sau đó kết nối chúng lại với nhau
Restful API
Nội dung
Module
Khi gọi module thì dùng require
Vd://bar.js module.exports = function(){ console.log('bar!'); }//app.js var bar = require('./bar.js'); bar();
First-Class Function
Js là First-class Function vì:
Có thể đóng vai trò làm tham số của hàm
passFunction(f1);
Có thể đóng vai trò là giá trị trả về từ một hàm
function passFunction(f){ f(); var f2 = function(){ console.log('f2'); } return f2;}
Có thể gán cho một biến
const a = function(){}
OBJECT LITERAL
Là cách khai báo nhanh đối tượng trong JS, các cặp NAME/VALUE được ngăn cách nhau bở dấu phẩy trong cặp ngoặc nhọn.
{'name':'value'}
HÀM KHỞI TẠO VÀ KẾ THỪA PROTOTYPE
Khởi tạo
function Person(name,password){ this.name = name; this.password = password;}
Mở rộng hàm
Person.prototype.getName = function(){ return this.name;}
Tạo ra một hàm chứa biến không thuộc Person
Person.prototype.getLevel = function(){ this.level = level;}
Khai báo thêm biến cho Person
Person.prototype.level = "admin";
Back-End
Spring Framework
Spring là một Framework phát triển các ứng dụng Java
Mục tiêu chính của Spring là giú các ứng dụng dựa trên mô hình sử dụng POJO (Plain Old Java Object - Các đối tượng Java thuần túy)
Trong Java POJO thường được dùng để chỉ các chỉ những object Java bình thường (chính xác hơn là đơn giản là chỉ có Java), chúng không có gì đặc biệt, không theo theo bất kỳ một mô hình, quy ước, nào cả hay nói theo cách khác thì không implement hay extend class nào khác. Đơn giản bao gồm các thuộc tính và các phương thức.
Spring Framework được xây dựng dựa trên 2 nguyên tắc design chính
Dependency Injection
- Khi mà class A sử dụng một số chức năng của class class B, thì có thể nói là class A có quan hệ phụ thuộc với class B.- Trong java, trước khi ta có thể sử dụng method của class khác, ta phải khởi tạo một object của class đấy (hay A cần phải tạo 1 thực thể của B). Vậy ta có thể hiểu, việc chuyển giao nhiệm vụ khởi tạo object đó cho một ai khác và trực tiếp sử dụng các dependency đó được gọi là dependency injection.
Là một dạng Design Pattern được thiết kế với mục đích ngăn chặn sự phụ thuộc giữa các Class. khiến Code dễ hiểu, trực quan hơn nhằm phục vụ cho mục đích bảo trì và nâng cấ code.
Chúng ta chỉ thường gặp ba loại Dependency Injection
Constructor injection: Các dependency (biến phụ thuộc) được cung cấp thông qua constructor (hàm tạo lớp).
Setter injection: Các dependency (biến phụ thuộc) sẽ được truyền vào 1 class thông qua các setter method (hàm setter).
Interface injection: Dependency sẽ cung cấp một Interface, trong đó có chứa hàm có tên là Inject. Các client phải triển khai một Interface mà có một setter method dành cho việc nhận dependency và truyền nó vào class thông qua việc gọi hàm Inject của Interface đó.
Nhiệm vụ của Dependency Injection là
Tạo ra các object.
Biết được class nào cần những object đấy.
Cung cấp cho những class đó những object chúng cần.
Aspect Oriented Programming - AOP (lập trình hướng khía cạnh)
Là kiểu lập trình cho phép chúng ta có thể thêm những đoạn code xử lý mới vào các ứng dụng đã tồn tại mà không cần phải chỉnh sửa code của các ứng dụng đó.
package com.huongdanjava;public class Application { public int sum(int a, int b) { return a + b; } public int sub(int a, int b) { return a - b; }}
Giờ mình muốn thêm vào một đoạn code trong tất cả các phương thức của class Application để mỗi khi ứng dụng gọi các phương thức này, một đoạn log message sẽ được in ra console. Với cách của lập trình hướng đối tượng, mình phải chỉnh sửa từng phương thức của class Application để đạt được đều mình muốn. Lập trình hướng khía cạnh định nghĩa cách dễ dàng hơn để làm điều này mà không cần phải chỉnh sửa code của class Application.
- Với lập trình hướng khía cạnh, chúng ta sẽ tìm cách để mỗi khi các phương thức trong class Application được gọi, chương trình phải gọi đoạn code để in ra log message của chúng ta trước.- Chúng ta có nhiều cách để thực hiện ý tưởng của lập trình hướng khía cạnh, một trong số đó là sử dụng các thư viện có sẵn như Spring AOP, AspectJ,… Để các bạn hiểu rõ hơn, trong bài viết này, mình sẽ sử dụng thư viện AspectJ để giải quyết bài toán mà mình đã đặt ra các bạn nhé!
1. Tạo một Maven project
2. Thêm dependency của thư viện AspectJ
<dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjrt</artifactId> <version>1.8.13</version></dependency>
3. Mình sẽ thêm một class với phương thức main() để sử dụng class Application như sau:
package com.huongdanjava.aspectjexample;public class Example { public static void main(String[] args) { Application application = new Application(); int a = 10; int b = 3; System.out.println(application.sum(a, b)); System.out.println(application.sub(a, b)); }}
4. Giờ mình sẽ sử dụng AspectJ để thêm đoạn code ghi log mỗi khi các phương thức sum() và sub() trong class Application được gọi như sau
package com.huongdanjava.aspectjexample;@Aspectpublic class ApplicationAspect { @Before("execution (* com.huongdanjava.aspectjexample.Application.*(..))") public void allMethods(JoinPoint joinPoint) { System.out.println("Method name: " + joinPoint.getSignature().getName()); }}
@Aspect dùng để khai báo cho AspectJ việc chúng ta cần chèn code vào các class khác và chúng sẽ được khai báo trong class này
Là một bộ khung ứng dụng và bộ chứa đảo ngược điều khiển mã nguồn mở dành cho nền tảng Java.
Spring MVC
Là một Framework được thực hiện trong mô hình MVC của các ứng dụng web. Có nhiệm vụ cung cấp kiến trúc MVC và các Component được sử dụng nhằm phát triển giú các ứng dụng web linh hoạt hơn
@Controller là công nghệ giúp cho Spring MVC được ưa chuộng và mang lại hiệu quả cao. Thành phần Controller trong MVC
- Một lớp được định nghĩa với annotation @Controller sẽ được xem là một controller trong Spring MVC. Đối tượng của lớp này được dùng để xử lý các request đến một trang nào đó được định nghĩa trong lớp này.
- Khi sử dụng @Controller thì giá trị trả về của các phương thức có chứa @Controller sẽ trả về View. Nhưng với một số trường hợp, chúng ta chỉ mong muốn giá trị trả về đơn thuần ở dạng JSON, XML,... mà không cần View gì cả thì ta sẽ cần thêm 1 annotation khác phía dưới @Controller là @ResponseBody.- Đơn giản hơn chúng ta có thể bỏ cả @Controller và @ResonseBody đi và thay thế bằng @RestController
Luồng hoạt động
1: Yêu cầu đầu tiên sẽ được DispatcherServlet nhận.
2: DispatcherServlet sẽ được HandlerMapping ánh xạ yêu cầu của client đến Controller phù hợp.
3: Sau khi thực hiện tiến trình từ yêu cầu của client, nó thực thi các logic được xác định trong controller và cuối cùng trả về đối tượng ModelAndView. quay lại DispatcherServlet.
4: Bây giờ DispatcherServlet gửi Model object đến ViewResolver để có được trang xem thực tế.
5: Cuối cùng DispatcherServlet sẽ truyền đối tượng Model đến trang View để hiển thị kết quả.
Spring Boot
Khái Niệm
- Là một module của Spring Framework, cung cấp các tính năng RAD (Rapid Application Development) – phát triển ứng dụng nhanh.- Giúp cho các lập trình viên chúng ta đơn giản hóa quá trình lập trình một ứng dụng với Spring, chỉ tập trung vào việc phát triển business cho ứng dụng
Kiến thức cần có
Java cơ bản: hàm, biến, loop,…
Lập trình hướng đối tượng (OOP).
Các tính năng của Java.
Collections API: biết cách sử dụng các collection thông dụng.
Ngoài ra, bạn có thể tìm hiểu thêm về Stream API, Asynchronous, Multi threading, File IO.
MicroServices
Microservices là gì?
- Là một kiếu kiến trúc phần mềm. Các module trong phần mềm này được chia thành các service rất nhỏ (microservice). Mỗi service sẽ được đặt trên một server riêng -> dễ dàng để nâng cấp và scale ứng dụng.- Khác biệt với kiến trúc Monolith, hay vì gom tất cả module thành một khối (monolith), ta tách các module thành những service siêu nhỏ. Mỗi service sẽ được đặt trên một server riêng (Có thể dùng server cloud như AWS hoặc Azure), giao tiếp với nhau thông qua mạng (Gửi nhận message qua giao thức HTTP hoặc sử dụng MessageQueue)...
Việc xây dựng phần mềm theo kiến trúc nào hoàn toàn phụ thuộc vào phạm vi bài toán mà ứng dụng đó đặt ra, hiện tại thì theo đánh giá của mình Monolith phù hợp với các ứng dụng cỡ vừa và nhỏ, còn Microservices sẽ phù hợp với những ứng dụng lớn => chúng ta cần cân nhắc cẩn thận khi sử dụng để tránh trường hợp mang dao mổ trâu đi thịt gà
- Một ứng dụng được chia thành một bộ các microservice, mỗi microservice thực chất là một service có thể được triển khai và chạy độc lập. Chúng tách biệt về mặt mã nguồn, về hoạt động và dữ liệu. Mỗi microservice có nơi chứa dữ liệu của riêng của nó và chỉ có nó có quyền truy cập vào vùng dữ liệu này. Do các microservice là độc lập, chúng không giao tiếp trực tiếp với nhau mà qua một thành phần trung gian được gọi là API gateway. Có thể thấy vai trò của API gateway rất quan trọng trong mô hình microservice. Nó là điểm đến và đi của mọi yêu cầu hay phản hồi.
Các đặc trưng
1. Micro-service
Đặc trưng này được thể hiện ngay từ tên của kiến trúc. Nó là microservice chứ không phải là miniservice hay nanoservice. Trên thực tế không tồn tại mô hình kiến trúc cho miniservice hay nanoservice. Từ microservice được sử dụng để giúp người thiết kế có cách tiếp cận đúng đắn. Một ứng dụng lớn cần được chia nhỏ ra thành nhiều thành phần, các thành phần đó cần tách biệt về mặt dữ liệu (database) và phải đủ nhỏ cả về mặt kích cỡ và độ ảnh hưởng của nó trong hệ thống, khi thêm một microservice vào hệ thống cũng nên đảm bảo rằng nó đủ nhỏ để dễ dàng tháo gỡ, xóa bỏ khỏi hệ thống mà không ảnh hưởng nhiều tới các thành phần khác.
2. Tính độc lập
- Các microservice hoạt động tách biệt nhau trong hệ thống, do vậy việc build một microservice cũng độc lập với việc build các microservice khác. Thông thường, để tiện cho việc phát triển và duy trì các microservice, người phát triển nên viết các built script khác nhau cho mỗi microservice.- Do tính tách biệt này mà mỗi microservice đều dễ dàng thay thế và mở rộng. Hơn thế nữa, nó còn giúp việc phát triển các microservice linh động hơn, các microservice có thể được phát triển bởi các team khác nhau, dùng các ngôn ngữ khác nhau và tiến độ phát triển dự án cũng nhanh hơn do không có sự phụ thuộc giữa các team, mỗi team có thể chủ động quản lý phần việc riêng của mình.
3. Tính chuyên biệt
Mỗi microservice là một dịch vụ chuyên biệt, có thể hoạt động độc lập, thông thường mỗi microservice đại diện cho một tính năng mà các công ty/ doanh nghiệp muốn cung cấp tới người dùng, do vậy người thiết kế hệ thống microservice cần hiểu rõ về hoạt động kinh doanh của công ty. Các đầu vào đầu ra và chức năng của mỗi microservice cần được định nghĩa rõ ràng.
4. Phòng chống lỗi
- Mỗi microservice là một dịch vụ chuyên biệt, có thể hoạt động độc lập, thông thường mỗi microservice đại diện cho một tính năng mà các công ty/ doanh nghiệp muốn cung cấp tới người dùng, do vậy người thiết kế hệ thống microservice cần hiểu rõ về hoạt động kinh doanh của công ty. Các đầu vào đầu ra và chức năng của mỗi microservice cần được định nghĩa rõ ràng.- Khi một thành phần trong hệ thống bị lỗi, nó có thể được thay thế bằng các thành phần dự phòng một cách dễ dàng, trong quá trình thay thế thành phần bị lỗi, các thành phần khác vẫn hoạt động bình thường, do vậy hoạt động của toàn bộ hệ thống sẽ không hoặc ít bị gián đoạn.
Ưu điểm
Điều quan trọng nhất là rất dễ nâng cấp và scale up, scale down. Giả sử bạn làm một trang web liên quan tới vận tải, kho bãi. Khi số lượng xe hay hàng hóa tăng lên, chỉ việc nâng cấp server cho service liên quan đến nghiệp vụ kho vận(ngược lại, có thể giảm server nếu cần thiết). Với cloud computing, việc nâng cấp server vô cùng dễ dàng chỉ với vài cú click chuột. Điều này rất khó thực hiện với monolith.
Do tách biệt nên nếu một service bị lỗi, toàn bộ hệ thống vẫn hoạt động bình thường. Với monolith, một module bị lỗi có thể sẽ kéo sập toàn bộ hệ thống.
Các service nằm tách biệt nhau, chúng có thể được sử dụng các ngôn ngữ lập trình riêng, database riêng. VD service xử lý ảnh có thể viết bằng C++, service tổng hợp data có thể viết bằng Python.
Có thể áp dụng được các quy trình tự động hóa, như build, deploy, monitoring,...
Khi chia nhỏ các service, team size sẽ giảm và mọi người sẽ làm việc hiệu quả hơn
Nhược điểm
Các module giao tiếp qua mạng nên có thể tốc độ không cao bằng monolith. Ngoài ra, mỗi module phải tự giải quyết các vấn đề về bảo mật, transaction, lỗi kết nối, quản lý log files.
Việc đảm bảo tính đồng nhất trong dữ liệu sẽ trở nên phức tạp hơn
Sử dụng nhiều service nên việc theo dõi, quản lý các service này sẽ phức tạp hơn
Cần một đội ngũ thật ngon để thiết kế và triển khai bao gồm software architect xịn
Headless Architecture
Kiến trúc này là gì?
- Là kiến trúc mà tách phần logic nghiệp vụ, data ra khỏi phần giao diện. Điều này mang tới nhiều lợi thế so với các mô hình khác.
Ưu điểm
Tăng tốc độ phát triển website do có thể tách các phần với nhau => khả năng phát triển song song
Làm website nhanh hơn
Giúp đội marketing build các campaign dễ dàng hơn
Dễ tùy biến và cá nhân hóa website
Nhược điểm
Java Core
Từ khóa this
Có thể được truyền như một tham số trong phương Constructor
Có thể được dùng để trả về instance của lớp hiện tại.
Có thể được dùng để tham chiếu tới biến instance của lớp hiện tại.
this() có thể được dùng để gọi Constructor của lớp hiện tại. this() phải được khai báo dòng lệnh đầu tiên trong Constructor.
Có thể được dùng để gọi phương thức của lớp hiện tại.
Có thể được truyền như một tham số trong phương thức. Cách dùng này chủ yếu được sử dụng trong sử lý sự kiện.
Từ khóa super
Được sử dụng để tham chiếu trực tiếp đến biến instance của lớp cha gần nhất.
super() được sử dụng để gọi trực tiếp Constructor của lớp cha.
Được sử dụng để gọi trực tiếp phương thức của lớp cha.
Được sử dụng nếu phương thức gi đè một trong các phương thức của lớ cha, thì phương thức bị ghi đè đó có thể được triệu hồi thông qua việc sử dụng từ khóa super.
Trong java là một biến tham chiếu được sử dụng để tham chiếu trực tiếp đến đối đối tượng của lớp cha gần nhất
Bất cứ khi nào tạo ra instance của lớp con, một instance của lớp cha được tạo ra ngầm định, nghĩa là được tham chiếu bởi biến super
Access Modifier (Public > Protected > Private)
Public các thuộc tính hay phương thức có thể truy xuất ra bên ngoài
Protected: các thuộc tính và hương thức không thể truy xuất ra bên ngoài class, nó chỉ được gọi trong class đó và class kế thừa.
Private: các thuộc tính và phương thức không thể truy xuất ra bên ngoài class, nó chỉ được gọi trong phạm vi class đó
Static
Function
Chỉ phụ thuộc vào lớp, không phụ thuộc vào đối tượng
Chỉ có thể truy cập vào các thành phần static
Có thể truy cập bằng tên Class mà không cần bất kì đối tượng nào
Variable
Class
Có lớp static
Một class được đặt là static khi nó là một nested class ( tức là nằm trong một class khác)
Một nested static class có thể được truy cập mà không cần một Object của một outer class
Final
Class
Là lớp mà trong đó các phương thức được tạo ra không thể ghi đè và không thể bị kế thừa
Method
Là phương thức mà lớp con không thể ghi đè
Variable
Biến hằng là biến không thể thay đổi giá trị
Có thể trống hoặc có giá trị lúc khai báo ban đầu. Biến final trong chỉ được khởi tạo trong Constructor
Try/Catch/Finally
Sau khối try không bắt buộc phải có khối catch. Mà có thể thay khối catch băng khối finally
try giúp bao bọc đoạn code có khả năng gây ra lỗi, còn catch sẽ giú xử lý hậu quả khi mà code trên đã chính thức bị lỗi
Tuy nhiên nhiêu đó chưa đủ. Trong Java, đôi khi chúng ta có sử dụng đến một số tài nguyên của hệ thống. Tài nguyên này chính là các resource có khả năng dùngchung giữa các ứng dụng. Đó có thể đơn giản chỉ là một file nào đó. Và bởi vì đây là các resource dùng chung, nên nếu có một tình huống khi ứng dụng của bạn đangmở một resource ra xem, nhưng chẳng may lại gây ra một Exception nào đó trong quá trình này, khi đó ứng dụng thông báo lỗi, và… xong… vô tâm không đóng lại cáiresource ấy. Trường hợp này, hệ thống đang tưởng rằng resource vẫn được quản lý bởi ứng dụng của bạn, nhưng thực chất là ứng dụng của bạn đã chết từ lâu rồi.
OOP - Object Oriented Programming
Khái Niệm
Là một kỹ thuật lập trình cho phép lập trình viên tạo ra các đối tượng trong code trừu tượng hóa các đối tượng thực tế trong cuộc sống.
Các tính chất của OOP
Tính kế thừa (Inheritance)
Là sự liên quan giữa hai class với nhau, trong đó có class cha (superclass) và class con (subclass).
Khi kế thừa class con được hưởng tất cả các phương thức và thuộc tính của class cha. Tuy nhiên,nó chỉ được truy cập các thành viên public và protected của class cha. Nó không được phéptruy cập đến thành viên private của class cha.
Có 3 kiểu kế thừa
Đơn kế thừa
Class B --> Class A
Kế thừa nhiều tầng
Class C --> Class B --> Class A
Kế thừa thứ bậc
Class B --> Class A <-- Class C
Đa kế thừa không được hỗ trợ trong Java nhằm giảm thiểu sự phức tạp và đơn giản hóa ngônngữ. Hãy suy xét kịch bản sau: Có 3 lớp A, B, C. Trong đó lớp C kế thừa từ các lớp A và B. Nếucác lớp A và B có phương thức giống nhau và bạn gọi nó từ đối tượng của lớp con, như vậy khócó thể xác đinh được việc gọi phương thức của lớp A hay B.
Tính đóng gói (Encapsulation)
Là kỹ thuật ẩn dấu thông tin không liên quán và hiển thị ra thông tin liên quan
Mục đích chính là giảm thiểu độ phức tạp phát triển phần mềm
Ví dụ sau về đóng gói trong java với một lớp chỉ có một trường và các phướng thức settervà getter của nó.
Tính đa hình (Polymorphism)
Là một khái niệm mà chúng ta cóthể thực hiện một hành động bằngnhiều cách khác nhau.
Có 2 kiểu đa hình trong Java
Đa hình lúc biên dịch (Compile)
Ví dụ: nạp chồng phương thứcstatic trong java
Đa hình lúc thực thi (Runtime)
Ví dụ: ghi đè phương thức
Tính trừu tượng (Abstraction)
Là tính chất không thể hiện cụ thể
Là một quá trình che dấu các hoạt động bên trong và chỉ thể hiện những tính năng thiết yếucủa đối tượng tới người dùng
Ví dụ: một người sử dụng điện thoại để gửi tin nhắn thì anh ta sẽ nhập nội dung tin nhắn,thông tin người nhận và ấn nút gửi. Khi anh ta bắt đầu gửi tin thì anh ấy không biết nhữnggì diễn ra bên trong quá trình gửi mà chỉ biết được là kết quả của tin nhắn đã được gửiđến người nhận thành công hay chưa. Vì vậy trong ví dụ này, quá trình gửi tin nhắn đãđược ẩn đi và chỉ hiển thị những chức năng mà người dùng cần đó là chức năng nhập nộidung tin nhắn, thông tin người nhận, kết quả gửi tin nhắn thành công hay thất bại. Đóchính là tính trừu tượng
Ưu điểm
Cho phép các dev loại bỏ tínhphức tạp của đối tượng
Tập trung vào những cốt lõi cầnthiết
Cung cấp nhiều tính năng mở rộng
Abstract và Interface
Giống nhau
Đều được sử dụng để có được sự trừu tượng mà ở đó chúng ta có thể khai báo các phương thức trừu tượng.
Khác nhau
Abstract Class có phương thức abstract (không có thân hàm) và phương thức non-abstract (có thân hàm)
Interface chỉ có phương thức abstract. Từ java 8 thì có thêm phương thức default và static
Abstract Class không hỗ trợ đa kế thừa
Interface hỗ trợ đa kế thừa
Abstract Class có các biến final, non-final, static, non-static
Interfacec chỉ có các biến final và static
Abstract Class có thể cung cấp nội dung cài đặt cho phương thức của Interface
Interface không thể cung cấp nội dung cài đặt cho phương thức của Abstract Class
Từ khóa abstract được dùng để khai báo abstract class
Từ khóa interface được dùng để khai báo interface
Ví dụ:public abstract class Shape { public abstract void draw();}
Ví dụ:public interface Drawable { void draw();}
Overloading và Overriding
Nạp chồng phương thức được sử dụng để giúp code của chương trình dễ đọc hơn.
Ghi đè phương thức được sử dụng để cung cấp cài đặt cụ thể cho phương thức được khai báo ở lớp cha.
Nạp chồng được thực hiện bên trong một class.
Ghi đè phương thức xảy ra trong 2 class có quan hệ kế thừa
Nạp chồng phương thức thì tham số phải khác nhau.
Ghi đè phương thức thì tham số phải giống nhau.
Nạp chồng phương thức là ví dụ về đa hình lúc biên dịch.
Ghi đè phương thức là ví dụ về đa hình lúc runtime.
Trong java, nạp chồng phương thức không thể được thực hiện khi chỉ thay đổi kiểu giá trị trả về của phương thức. Kiểu giá trị trả về có thể giống hoặc khác. Giá trị trả về có thể giống hoặc khác, nhưng tham số phải khác nhau.
Giá trị trả về phải giống nhau.
Upcasting
Khi biến tham chiếu của lớp cha thám chiếu tới đối tượng của lớp con thì đó gọi là Upcasting
Các mô hình mạng
MÔ HÌNH OSI
- Là mô hình lý thuyết được đề xuất để tiêu chuẩn hóa giao tiếp các thiết bị qua mạng- Là một mô hình nền tảng thấp nhất- Hiểu được cách làm việc trong một mạng máy tính và làm thế nào chúng truyền dữ liệu được cho nhau
Các thành phần
để kết nối được với các thành phần mạng máy tính => Quan trọng nhất là cạc mạng
Mỗi cạc mạng khi sản xuất sẽ được gán 1 MAC Address (địa chỉ vật lý), được xem như 1 số seri hay số khung máy trong thiết bị
Để giao tiếp và truyền dữ liệu => Được cấp phát thêm địa chỉ IP dùng để định danh một thiết bị máy tính mà nó đang tham gia
Địa chỉ IP được xem như địa chỉ ảo hóa của một thiết bị.
Thông thường, 1 thiết bị có 1 MAC Address 1 IP, nhưng cũng có 1MAC Address liên kết với nhiều IP và ngược lại => Do đó chúng ta cần định danh 1 thiết bị trong mạng máy tính bằng cả hai địa chỉ.
Các ứng dụng trong thiết bị được định danh bằng cổng (PORT)
Các thiết bị có thể chia sẽ, truyền và hoạt động với nhau thì cần thông qua một giao thức
Giao thức là hình thức giao tiếp giữa các máy tính (vd: HTTP)
Cách hoạt động
Mô hình OSI ở chiều chúng ta gửi đi
Layer 7 Application: đóng gói các phương thức HTTP, Cookies, Content-Type,..
Layer 6 Presentaion: dùng để mã hóa các gói dữ liệu mà chúng ta gửi qua bên ngoài (nếu chúng ta dùng HTTP không thì bỏ qua tầng 6, còn nếu dùng HTTPS thì phải thông qua tầng 6 để mã hóa).
Layer 5 Session: cấp phát sessionID để gán vào gói tin của chúng ta. Để mô hình OSI có thể xác định được thứ tự các gói tin khi gửi nhiều gói tin cùng một lúc.
Layer 4 Transport: chia nhỏ các gói tin thành các phân đoạn nhỏ hơn (Secment). Sau khi chia nhỏ thành các Secment, chúng ta thêm vào mỗi phân đoạn 2 thông tin: thông tin về port nguồn và port đích.
Layer 3 Network: Lấy các phân đoạn nhỏ ở Layer 4, và thêm thông tin ở mỗi phân đoạn các IP là IP nguồn và IP đích (IP được lấy bằng cách có sự hỗ của DNS => phân giải tên miền thành các địa chỉ IP rồi gán cho Layer 3)
Layer 2 Data-Link: sau khi đã có IP và PORT thì sẽ chuyển xuống Layer 2, tiếp tục thêm vào mỗi phân đoạn một MAC Address nguồn và một MAC Address đích. Trong một số trường hợp, chúng ta không thể tìm được MAC Address đích, thì có 1 dịch vụ ARP - giúp chúng ta lấy MAC Address từ địa chỉ IP, sau đó chúng ta gắn vào mỗi phân đoạn Secment.
Layer 1 Physical: chuyển các Secment đang có thành dãy nhị phân và truyền đi trên đường truyền mạng (cáp quang truyền đi bằng ánh sáng)
Mô hình OSI ở chiều nhận
Layer 1 Physical: nhận được các tính hiệu nhị phân tại đây
Layer 2 DataLink: sau khi chuyển mã nhị phân thành các phân đoạn Secment, cạc mạng so sánh MAC Address với cái MAC Address vừa nhận được, nếu giống thì chấp nhận và chuyển đến tầng cao hơn để xử lý => Chuyển các phân đoạn đến tầng thứ 3. Còn nếu không khớp thì gói tin đó sẽ bị bỏ qua => Chuyển đến tầng 4
Layer 3 Network: cũng lấy các IP ở mỗi Secment (so sánh các IP đích)
Layer 4 Transport: sử dụng thông tin PORT để xác định được ứng dụng nào mà phân đọan Secment này muốn gửi đến. Tiếp tục gửi các phân đoạn lên tầng cao hơn.
Layer 5 Session: lấy các phân đoạn Secment này gộp lại thành các gói tin lớn hơn và sắp xếp theo thứ tự dựa vào SessionID đã được cấp phát từ thiết bị gửi.
Layer 6 Presentation: là nơi để giải mã các mã hóa (HTTPS) và chuyển package lên lớp cao nhất.
Layer 7 Application: nhận được phản hồi là các dòng mã mà chúng ta có thể biết được các HTTP Header, phương thức,...
MÔ HÌNH TCP/IP
Mô hình TCP/IP khác với mô hình OSI
Mô hình OSI là một mô hình lý thuyết. Theo lý thuyết có nghĩa là không có triển khai thực tế của mô hình mà nó chỉ là một khái niệm và không có bất kì triển khai thực tế nào.
Mặc dù mô hình TCP/IP thực tế hơn và đây là mô hình được sử dụng ngày nay.
Mô hình OSI có 7 lớp, TCP/IP chỉ có 4 lớp
OSI Model TCP/IP Model- Application - Presentation - Application- Session - Transport - Transport- Network - Internet- Datalink - Network Access- Physical
CÁC GIAO THỨC Ở CÁC TẦNG
Application (HTTP, HTTPS, FTP, SMTP, SSH, DNS, DHCP,...)
Transport (TCP và UDP)
Internet (IP, ARP, RARP, IGMP)
Network Access (Hardware bao gồm tất cả các phần cứng như bộ định tuyến, bộ chuyển mạch)
Quy trình làm việc Agile
Agile Headless
Database
MSSQL
MySQL
NoSQL
GraphQL
Blockchain Developer
Front-End
Back-End
Kiến thức nền tảng
Blockchain là gì?
Ethereum là gì?
Kinh Doanh