Home Blog Page 159

Dịch vụ thị trường vận chuyển và giao nhận Landscape 2020

Nối tiếp báo cáo thị trường IT Landscape 2019, báo cáo mới nhất về thị trường vận chuyển và giao nhận 2020 vừa mới ra mắt, thông số trong báo cáo khá khả quan bất chấp dịch bệnh Covid được xem là một trong những đại dịch làm ảnh hưởng nghiêm trọng đến các ngành nghề khác nhau ở hầu hết các quốc gia, đặc biệt là Châu Âu.

Tổng quan về báo cáo Landscape 2020

Theo báo cáo thị trường Vietnam IT Landscape 2020, tuy 6 tháng đầu năm các ngành có xu hướng “tuột dốc” nhưng với tình hình hiện này thì chúng ta có thể thấy rõ nền kinh tế Việt Nam đang dần khởi sắc ở các ngành nghề nói chung và các công ty công nghệ nói riêng. Trong bài báo cáo này, chúng ta sẽ chỉ tập trung đến tình hình của ngành dịch vụ thị trường vận chuyển và giao nhận. Nhìn chung, tại Việt Nam, các dịch vụ vận chuyển khá được ưa chuộng, nhất là các dịch vụ vận chuyển của những công ty công nghệ như Grab, Goviet, Lalamove, Giaohangnhanh… 

Theo báo cáo thị trường vận chuyển và giao nhận 2020, trong năm 2011-2017 (6 năm), các dịch vụ vận chuyển, giao nhận công nghệ trong đó có ứng dụng đi lại chỉ có 2 ứng dụng phát triển đó là Uber và Grab, còn ở ứng dụng giao đồ ăn thì có ông trùm độc quyền Now tại thời điểm này. Ứng dụng vận chuyển hàng hóa thì có Vietnam Post, Viettel Post, Grab Express… đa số là các ứng dụng giao hàng được phân nhánh từ các công ty lớn của nhà nước. Nhưng kể từ năm 2018 trở đi, thì dịch vụ vận chuyển và giao nhận phát triển khá nhanh, các ứng dụng giao nhận, vận chuyển được ào ào ra mắt ví dụ như goviet, be, fastgo… đối với các ứng dụng đi lại. Ứng dụng giao đồ ăn cũng khá khả quan với các ứng dụng Grabfood, Loship, Gofood, Baemin… đã ra đời nhằm đáp ứng nhu cầu ăn uống được giao hàng tận nơi.

thị trường vận chuyển và giao nhận 2020

Xem thêm báo cáo về Thị trường vận chuyển và giao nhận 2020

Dù các ứng dụng giao hàng, vận chuyển phát triển mạnh mẽ là thế nhưng khi đến giai đoạn từ khoảng đầu năm 2020, thời điểm dịch dịch mon men phát triển tại Việt Nam thì thị trường vận chuyển giao nhận 2020 lại có 1 pha “hú hồn” vì dịch. Dịch bệnh đã làm ảnh hưởng rất nhiều đến hành vi của User khi sử dụng dịch vụ giao nhận, cụ thể, theo thống kê, thị trường vận chuyển và giao nhận Landscape 2020, ứng dụng Grab thì trong năm 2019, Grab Express có mức tăng trưởng 97%, Grab Food tăng trưởng tầm 1.800% trong năm.

Nhưng trong năm nay, theo báo cáo thị trường vận chuyển và giao nhận 2020 thì tổng doanh thu từ thị trường đặt xe đã giảm mạnh từ 3,126 triệu $/năm (2019) xuống thấp nhất từ trước đến nay là 2,000 triệu $/năm. Đây là một con số đáng báo động về sự suy thoái trong ngành. Tuy thị trường đặt xe “bê bết” là thế nhưng vẫn còn một thị trường có thể gỡ lại 1 chút, đó là thị trường đặt đồ ăn qua ứng dụng. Vì tình hình dịch bệnh làm thay đổi hành vi người dùng nên thay vì kéo nhau ra ngoài ăn thì mọi người sẽ order đồ ăn để ăn tại chỗ, nền tảng giao đồ ăn “soán ngôi”, tỷ lệ giao đồ ăn tăng vọt.

Dự kiến thị trường giao thực phẩm Đông Nam Á sẽ tăng từ 2 tỷ USD (2018) lên 8 tỷ USD (2025) – theo báo cáo của Google và Singapore Temasek. Trong riêng năm 2020, doanh thu của ngành vận chuyển và giao nhận nói chung tại Việt Nam là 302 triệu USD (tăng 45,9% so với cùng kì năm ngoái, người dùng (User) là 9.5 triệu người (tăng 37.1% so với năm ngoái). Tuy trong thời gian ảnh hưởng dịch bệnh từ thế giới, ngành này tuy có bị ảnh hưởng một ít nhưng may mắn thay chính phủ Việt Nam đã đưa ra những chủ trương phòng bệnh rất hiệu quả nên cũng đỡ được phần nào ảnh hưởng. Ngoài ra, dịch vụ đặt đồ ăn qua ứng dụng đã “gánh team” cho thị trường vận chuyển và giao nhận 2020 tại Việt Nam.

thị trường vận chuyển và giao nhận 2020

Khó khăn từ phía ứng dụng vận chuyển, giao nhận

Mới đây, Grab cũng đã đưa ra thông cáo báo chí rằng sẽ cắt giảm 5% đội ngũ nhân sự trên toàn thế giới trong đó có Việt Nam, tương đương với 360 người. Khi được hỏi tại sao Grab lại có những động thái này dù dịch bệnh đã phần nào nguôi ngoai, CEO của Grab Việt Nam – ông Anthony Tan đã chia sẻ trong tiếc nuối: “Grab phải áp dụng chiến lược bảo toàn nguồn vốn phù hợp hơn để dự phòng cho giai đoạn phục hồi có thể kéo rất dài, cần có một bộ máy tinh gọn hơn để đáp ứng được những thách thức của nền kinh tế hậu COVID-19”. Đồng thời ông cũng cam kết rằng sẽ không để cho sự việc tương tự như việc cắt giảm nhân sự này xảy ra thêm lần nào nữa.

  StackOverflow công bố báo cáo khảo sát Lập trình viên 2019: Python là ngôn ngữ phát triển nhanh nhất

  Báo cáo toàn cảnh thị trường IT Việt Nam 2019 - Các công ty công nghệ tại Việt Nam đang làm gì?

Trong khoảng từ cuối tháng 4 năm nay, Grab đã khuyến khích nhân viên chủ động nghỉ hoặc giảm thời gian làm trong ngày để tránh việc phải cắt giảm nhân sự trong mùa dịch, nhưng dường như chiến dịch ấy vẫn không quá khả quan, chính vì vậy mới xảy ra sự việc cắt giảm 5% nhân viên Grab trong giữa tháng 6. Ông Anthony Tan, chỉ cho biết Việt Nam cũng là 1 trong những nước phải cắt giảm nhân sự nhưng lại không tiết lộ chính xác con số. 

Xem thêm báo cáo về Thị trường vận chuyển và giao nhận 2020

Ngoài việc chia sẻ về sự việc không mong muốn như trên thì ông cũng chia sẻ thêm rằng kể từ tháng 2/2020 thì Grab đã cảm nhận rõ ràng về sự ảnh hưởng mạnh mẽ của dịch đối với dịch vụ vận chuyển và giao nhận. Định hướng cũng Grab trong tình hình này là Grab sẽ tập trung vào những mảng mạnh của công ty như di chuyển, giao nhận và thanh toán, hạn chế những dự án đang phát triển để bảo toàn nguồn vốn lưu động.

Đối với ứng dụng đặt xe Be, đại diện phía Be cũng cho biết, các hoạt động dịch vụ của Be cũng bị ảnh hưởng kể từ sau Tết Nguyên đán năm nay. Nhìn chung, các công ty của ngành dịch vụ vận chuyển và giao nhận đều có khó khăn chung trong tình hình hiện tại.

thị trường vận chuyển và giao nhận 2020

Khó khăn từ phía tài xế

Chia sẻ thực tế với các phóng viên các tờ báo lớn, một tài xế của ứng dụng xe ôm công nghệ Be cho hay vào thời điểm trước dịch, thông thường mỗi ngày anh có thể chạy với năng suất 20-25 chuyến/ngày, tính thêm cả điểm thưởng từ app thì thu nhập của các tài xế Be giao động trong khoảng từ 300.000-400.000 đồng/ngày. Nhưng trong thời điểm dịch bùng phát thì thu nhập của các tài xế bị ảnh hưởng trầm trọng, cụ thể là các chuyến xe giảm từ 25 chuyến/ngày còn 5 chuyến/ngày, dẫn đến việc không thể nhận thưởng, thu nhập giảm mạnh, sau khi trừ hết tất cả chi phí thì tiền thu về chỉ ở khoảng 30.000/ngày. 

Đó là đối với tài xế của ứng dụng Be, còn với ứng dụng có quy mô lớn hơn như Grab thì các tài xế chia sẻ, vào thời điểm trước dịch, lượng người dùng sử dụng Grab rất mạnh mẽ. Hầu như lúc nào mở ứng dụng Grab Driver lên cũng sẽ có khách ngay lập tức, một ngày có thể nhận đến 30-40 chuyến nếu chịu khó chạy liên tục cả ngày, nhưng khi dịch đến thì dù có mở app cả ngày vẫn chỉ có 2, 3 chuyến.

Không riêng gì các dịch vụ vận chuyển 2 bánh, những khó khăn ấy còn bao trùm lên cả các tài xế xe hơi công nghệ, khó khăn sẽ càng nặng trĩu hơn nếu những tài xế xe hơi này phải trả góp ngân hàng tiền mua xe. Khó khăn này chồng chất lên khó khăn kia làm những người lao động trong thị trường vận chuyển và giao nhận trở nên điêu đứng.

  Báo cáo thị trường IT 2020: Việt Nam sẽ trở thành quốc gia IT với nhiều chỉ số trong top thế giới

Trong mùa dịch này, khi may mắn bắt được một chuyến xe thì sự lo lắng vẫn luôn thường trực trong tâm trí của các tài xế xe ô tô vì không gian trong xe ô tô rất kín và khoảng cách ngồi giữa tài xế và hành khách cũng rất gần.

May mắn thay, trong báo cáo về thị trường vận chuyển và giao nhận 2020 thì chúng ta vẫn thấy những chỉ số khả quan, các chỉ số đã gia tăng đáng kể trong năm 2020 dù bị ảnh hưởng từ dịch bệnh.

thị trường vận chuyển và giao nhận 2020

Nguyên nhân của những thông số khả quan này phải kể đến công của thị trường ứng dụng giao đồ ăn và ứng dụng vận chuyển hàng hóa.

Dịch bệnh nổ ra làm thay đổi thói quen người tiêu dùng, chính vì thế thị trường giao đồ ăn và vận chuyển hàng hóa có dịp lên ngôi. Nguồn khách hàng chính của 2 thị trường này đến từ lao động khối văn phòng là chính, thay vì ra ngoài ăn thì mọi người lại có xu hướng mời gọi nhau ăn cùng 1 quán, sau đó đặt giao đồ ăn đến ăn tại ngay chỗ làm.

Cùng chung hoàn cảnh với thị trường giao thực phẩm, thị trường giao hàng cũng được ưa chuộng vì trong thời gian giãn cách mọi người ở nhà có nhu cầu shopping online hoặc gửi đồ đều sử dụng dịch vụ giao hàng như lalamove, ahamove, 60 giây, giao hàng tiết kiệm, giao hàng nhanh… thậm chí đôi khi đơn hàng quá tải, các ứng dụng giao hàng không chuyển hàng đến khách kịp nên phải tuyển thêm rất nhiều shipper trong mùa dịch. Vì tính tiện dụng cao nên việc đặt đồ ăn và giao hàng khá bùng nổ trong mùa dịch này, dẫn đến 1 cơ hội mới, 1 xu hướng sử dụng dịch vụ vận chuyển và giao nhận mạnh mẽ hơn.

Giải pháp

Trong bối cảnh tình hình hiện tại, các công ty, doanh nghiệp dịch vụ vận chuyển và giao nhận rất tất bật trong việc tuyên truyền các giải pháp tự bảo vệ bản thân cho cánh tài xế để có thể phòng ngừa và tránh lây nhiễm nguồn dịch bệnh không mong muốn khi tác nghiệp.

Giải pháp chung của các doanh nghiệp dịch vụ vận chuyển, giao nhận như Grab, Be, Goviet, Lalamove, Ahamove, Giao Hàng Nhanh, Giao Hàng Tiết Kiệm… là:

  • Khuyến khích/ bắt buộc tài xế luôn đeo khẩu trang khi ra đường
  • Rửa tay bằng dung dịch diệt khuẩn thường xuyên
  • Đối với các chuyến giao nhận hàng hóa, đồ ăn tài xế chủ động đặt đồ cần giao trước địa chỉ được yêu cầu giao tới, đứng cách xa 3 mét và gọi khách xuống nhận hàng.
  • Liên hệ ngay đến các cơ quan y tế và tổng đài của công ty nếu cảm thấy không khỏe trong người hoặc có dấu hiệu dịch bệnh.

Đối với các tài xế không tuân thủ các quy tắc phòng chống trên thì sẽ bị các ứng dụng giao hàng phát bằng nhiều hình thức khác nhau và nặng nhất là khóa tài khoản, không cho các tài xế ấy hoạt động nữa.

Bên cạnh đó, ứng dụng Be đã có kế hoạch cho việc “sống chung với lũ” nhằm giúp doanh nghiệp có thể duy trì qua mùa dịch và thúc đẩy hoạt động kinh doanh của thị trường. Còn đối với ứng dụng Grab, tình hình kinh tế của Grab cũng vẫn duy trì khá cân bằng nhờ có những bước đi hợp lý.

Tổng kết thị trường vận chuyển và giao nhận 2020

Theo báo cáo của Vietnam IT Landscape 2020 cho thấy thị trường vận chuyển và giao nhận Landscape 2020, dù nhu cầu sử dụng dịch vụ vận chuyển giao nhận có thay đổi và giảm mạnh, tuy nhiên ngành này vẫn “ăn điểm” so với những ngành khác nhờ có dịch vụ giao đồ ăn và giao hàng hóa tận nơi. Phần lớn người dùng trong thị trường này chỉ chuyển cách thức sử dụng dịch vụ chứ không hẳn là từ bỏ thế nên thông số trong báo cáo Vietnam IT Landscape 2020 đã thể hiện sự tăng trưởng từ năm này sang năm khác là hoàn toàn hợp lý.

Các bạn có thể truy cập vào báo cáo Vietnam IT Landscape 2020 hoặc nhấn nút xem báo cáo dưới đây để có thể tìm hiểu thêm các thông số báo cáo không chỉ của riêng thị trường vận chuyển và giao nhận 2020 mà còn nhiều ngành liên quan đến công nghệ khác nữa!

Nguồn tổng hợp từ TopDev

Có thể bạn muốn xem:

Xem thêm việc làm IT hấp dẫn từ TopDev!

Tạo slider component trong React Native bằng PanResponder

Tạo một Slider component trong React Native bằng cách sử dụng PanResponder là một cách tuyệt vời để học cách xử lý các cử chỉ người dùng trong ứng dụng di động. PanResponder cho phép bạn nắm bắt và phản ứng với các sự kiện vuốt và kéo của người dùng. Dưới đây là một ví dụ đơn giản về cách bạn có thể tạo một slider component bằng PanResponder.

Tạo Slider Component

Tạo một tệp mới với tên Slider.js trong thư mục dự án của bạn và sao chép đoạn mã dưới đây vào:

import React, { useState, useRef } from 'react';
import { View, Animated, PanResponder, StyleSheet } from 'react-native';

const Slider = ({ width = 300, height = 40 }) => {
  const [position, setPosition] = useState(new Animated.Value(0));
  const panResponder = useRef(
    PanResponder.create({
      onStartShouldSetPanResponder: () => true,
      onMoveShouldSetPanResponder: () => true,
      onPanResponderGrant: () => {
        position.setOffset(position._value);
        position.setValue(0);
      },
      onPanResponderMove: Animated.event(
        [null, { dx: position }],
        { useNativeDriver: false }
      ),
      onPanResponderRelease: () => {
        position.flattenOffset();
      },
    })
  ).current;

  const sliderWidth = width - height;

  return (
    <View style={[styles.container, { width, height }]}>
      <View style={styles.track} />
      <Animated.View
        {...panResponder.panHandlers}
        style={[
          styles.thumb,
          {
            transform: [
              {
                translateX: position.interpolate({
                  inputRange: [0, sliderWidth],
                  outputRange: [0, sliderWidth],
                  extrapolate: 'clamp',
                }),
              },
            ],
          },
        ]}
      />
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    justifyContent: 'center',
    backgroundColor: '#ddd',
    borderRadius: 20,
    overflow: 'hidden',
  },
  track: {
    height: 4,
    backgroundColor: '#888',
    position: 'absolute',
    left: 0,
    right: 0,
  },
  thumb: {
    width: 40,
    height: 40,
    backgroundColor: '#FFF',
    borderRadius: 20,
    borderWidth: 1,
    borderColor: '#888',
    position: 'absolute',
  },
});

export default Slider;

Sử dụng Slider Component trong Ứng Dụng

Trong tệp chính của bạn (ví dụ: App.js), bạn có thể sử dụng Slider component như sau:

import React from 'react';
import { SafeAreaView, StyleSheet } from 'react-native';
import Slider from './Slider';

const App = () => {
  return (
    <SafeAreaView style={styles.container}>
      <Slider />
    </SafeAreaView>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  },
});

export default App;

Giải Thích và Tinh Chỉnh

  • PanResponder.create: Đây là cách bạn tạo một PanResponder mới. Nó có nhiều sự kiện khác nhau để lắng nghe các cử chỉ của người dùng.
  • Animated.Value: Đây là giá trị động mà bạn có thể thay đổi và liên kết với các thuộc tính của các thành phần khác.
  • onPanResponderMove: Sự kiện này được kích hoạt khi người dùng di chuyển ngón tay của họ. Trong trường hợp này, chúng ta sử dụng Animated.event để di chuyển thumb của slider theo ngón tay.
  • interpolate: Chúng ta sử dụng interpolate để đảm bảo giá trị của slider nằm trong phạm vi cho phép.

Bạn đã tạo thành công một Slider component đơn giản trong React Native bằng cách sử dụng PanResponder. Bạn có thể tùy chỉnh thêm component này để phù hợp với nhu cầu của ứng dụng của mình, chẳng hạn như thay đổi màu sắc, thêm nhãn giá trị, hoặc kết hợp với các logic khác trong ứng dụng.

Xem thêm các việc làm React Native hấp dẫn tại TopDev

Bài viết liên quan:

  9 ứng dụng tuyệt vời được viết bằng React Native

  Những lý do ảnh hưởng đến ReactNative performance của bạn

Điểm qua các kiểu navigator của thư viện react-navigation

Bài viết được sự cho phép của tác giả Lưu Bình An
Chúng ta cùng liệt kê qua các dạng navigator, khi nào, dùng ở đâu là hợp lý
  6 Javascript destructuring tricks
  1001 cách tạo Array trong Javascript (Phần 1)

Có rất nhiều thư viện khác nhau để làm navigation với React native, mình khuyến khích các bạn dùng react-navigation của Facebook phát triển cho React Native, nói chung cái gì đã có bản official của chính người sáng lập thì mình cứ đè nó ra xài

Stack

Điểm qua các kiểu navigator của thư viện react-navigation

Khi mở một màn hình mới, nó sẽ sếp chồng lên trên màn hình trước đó. Kiếu sếp bánh tráng.

Theo mặc định, màn hình mới chạy từ cạnh phải -> qua trái màn hình trong iOS, mờ -> đến rõ dần từ dưới lên trong android

API

createStackNavigator(RouteConfigs, StackNavigatorConfig)

Ví dụ

const StackScreens = createStackNavigator(
  {
    Main: { screen: Main },
    Login: { screen: Login }
  },
  {
    headerMode: 'none',
    mode: 'modal'
  }
);

Switch

Với Swtich Navigator chỉ hiển thị 1 màn hình, không có goBack(), phù hợp nhất với flow Authentication, flow này thường sẽ là

  • User mở ứng dụng
  • Ứng dụng load dữ liệu authentication (nếu có) trong AsyncStorage
  • Sau khi load, hiển thị trang chính hoặc màn hình đăng nhập
  • Sau khi user sign out, hiển thị màn hình đăng nhập

API

createSwitchNavigator(RouteConfigs, SwitchNavigatorConfig);

Ví dụ

import { createSwitchNavigator, createStackNavigator } from 'react-navigation';

import {HomeScreen, SignInScreen, OtherScreen, AuthLoadingScreen} from './screens';

const AppStack = createStackNavigator({ Home: HomeScreen, Other: OtherScreen });
const AuthStack = createStackNavigator({ SignIn: SignInScreen });

export default createSwitchNavigator(
  {
    AuthLoading: AuthLoadingScreen,
    App: AppStack,
    Auth: AuthStack,
  },
  {
    initialRouteName: 'AuthLoading',
  }
);

Tham khảo thêm cách implement Authentication Flow

Drawer

Kiểu menu trượt từ bên trái thấy trong Android

Điểm qua các kiểu navigator của thư viện react-navigation

API

createDrawerNavigator(RouteConfigs, DrawerNavigatorConfig);

Ví dụ

  1. TouchableMenuIcon là component luôn hiển thị ở gốc trái của ứng dụng
  2. Chạm vào icon, SideMenu component được hiển thị, style tùy thích
  3. RootStack là một Stack Navigator chứa các màn hình chính của ứng dụng
  4. MyDrawerNavigator tạo ra từ createDrawerNavigator(), sẽ đảm nhiệm việc show side menu, để ý cái props contentComponent
import React, { Component } from 'react';
import { Button, View, Text, Image, TouchableOpacity } from 'react-native';
import { createStackNavigator, createDrawerNavigator } from 'react-navigation';

import {RootStackScreen1, RootStackScreen2, RootStackScreen3} from './screens';


// 1) `TouchableMenuIcon` là component luôn hiển thị ở gốc trái của ứng dụng

class TouchableMenuIcon extends Component {

  toggleDrawer=()=>{    
    this.props.navigationProps.toggleDrawer();
  }
  render() {
    return (
      <View style={{flexDirection: 'row'}}>
        <TouchableOpacity onPress={this.toggleDrawer.bind(this)} >
          <Image
            source={{uri : 'https://reactnativecode.com/wp-content/uploads/2018/04/hamburger_icon.png'}}
            style={{ width: 25, height: 25, marginLeft: 5}}
          />
        </TouchableOpacity>
      </View>
    );
  }
}

// 2) Chạm vào icon, `SideMenu` component được hiển thị, style tùy thích

class SideMenu extends Component {
  render() {
    return (
      <View style={{flex: 1, backgroundColor: 'white'}}>
        <View style={{flexDirection: 'column', marginTop:30, justifyContent: 'space-around'}}>
         <Button
              title="Screen 1"
              onPress={() => {
                this.props.navigation.navigate('RootStackScreen1');
                this.props.navigation.closeDrawer();

              }}
          />
          <Button
              title="Screen 2"
              onPress={() => {
                this.props.navigation.navigate('RootStackScreen2');
                this.props.navigation.closeDrawer();

              }}
            />
          <Button
              title="Screen 3"
              onPress={() => {
                this.props.navigation.navigate('RootStackScreen3');
                this.props.navigation.closeDrawer();

              }}
            />
        </View>
      </View>
    );
  }
}

// 3) `RootStack` là một Stack Navigator chứa các màn hình chính của ứng dụng
const RootStack = createStackNavigator(
  {
    RootStackScreen1: RootStackScreen1,
    RootStackScreen2: RootStackScreen2,
    RootStackScreen3: RootStackScreen3
  },
  {
    initialRouteName: 'RootStackScreen1',  
    navigationOptions: ({ navigation }) => ({
      title: "Root Stack", 
      headerLeft: <TouchableMenuIcon navigationProps={ navigation }/>
    })
  }
);



// 4) `MyDrawerNavigator` tạo ra từ `createDrawerNavigator()`, sẽ đảm nhiệm việc show side menu, để ý cái `props` **contentComponent**

export default MyDrawerNavigator = createDrawerNavigator(  
  {
    RootStack: RootStack,
  },
  {
    contentComponent: SideMenu
  }
);

Bottom Tab

Kiểu tab bar nằm ở dưới màn hình, các màn hình sẽ không được render cho đến khi user focus

Điểm qua các kiểu navigator của thư viện react-navigation

API

createBottomTabNavigator(RouteConfigs, BottomTabNavigatorConfig);

Material Top Tab

Hoạt động tương tự như Bottom Tab, chỉ là menu tab đặt ở phía dưới màn hình

Điểm qua các kiểu navigator của thư viện react-navigation

API

createMaterialTopTabNavigator(RouteConfigs, TabNavigatorConfig);

Ví dụ lấy từ https://reactnavigation.org/docs/

Bài viết gốc được đăng tải tại VuiLapTrinh

Có thể bạn quan tâm:

Xem thêm các việc làm react hấp dẫn tại TopDev

Kỹ thuật phần mềm – Software Engineering là gì? Có nên theo ngành này?

Hãy mở chiếc smartphone của mình ra và các bạn đếm thử xem mình đang sử dụng bao nhiêu ứng dụng để phục vụ nhu cầu cá nhân của bản thân? Có thể bạn chưa để ý nhưng tất cả những ứng dụng đó đều là sản phẩm của lĩnh vực kỹ thuật phần mềm.

Với sự phát triển không ngừng của các thiết bị điện tử ngày nay, ngành nghề này đang ngày một mở rộng và trở nên quen thuộc cũng như gần gũi với cuộc sống của chúng ta hơn bao giờ hết.

Không phải ngẫu nhiên mà nó nằm trong top 5 chuyên ngành ‘nóng hổi’ nhất của ngành Công nghệ Thông tin. Ngoài ra bạn còn có nhiều cơ hội để thử sức ở các vị trí sở hữu mức lương khá hấp dẫn như: thiết kế và phát triển phần mềm, quản lý sản phẩm phần mềm, hỗ trợ phần mềm…

Nếu các bạn đang là học sinh/ sinh viên sắp thi đại học và có ý định chọn sự nghiệp trong ngành công nghệ thông tin cho mình thì bài viết này sẽ giúp bạn tìm hiểu hơn về chuyên ngành thời thượng này!

Kỹ thuật phần mềm là gì?

kỹ thuật phần mềm

Ngành Kỹ thuật Phần mềm (Software Engineering) là một lĩnh vực chuyên về việc phát triển, thiết kế, triển khai và bảo trì các hệ thống phần mềm. Đây là một ngành quan trọng trong lĩnh vực Công nghệ Thông tin, tập trung vào việc áp dụng các nguyên lý kỹ thuật và khoa học máy tính để tạo ra các sản phẩm phần mềm chất lượng cao, hiệu quả và đáng tin cậy đến tay người dùng cuối.

Đối với những bạn thích lập trình thuần túy, thì đây là ngành rất phù hợp với bạn. ‘Phần mềm’, ‘chương trình’ hay ‘ứng dụng’ đều là các sản phẩm của việc lập trình. Là một ngành chuyên nghiên cứu về cách thức hoạt động, quy trình, testing của các phần mềm vi tính nhằm đáp ứng theo nhu cầu của người dùng và khách hàng.

Và chắc bạn cũng biết, chúng ta sử dụng phần mềm mọi lúc mọi nơi: từ ứng dụng văn phòng cơ bản như Microsoft Word, Excel, Powerpoint đến trình duyệt web Chrome, Firefox, Safari hay Facebook, Google search cũng là 1 dạng của ứng dụng, đó là chưa kể các hệ điều hành phổ biến như Windows hay Linux cũng là nhờ nó thôi! Ngành này khá rộng nên ngoài các hướng đi phổ biến như thiết kế chương trình, ứng dụng, website thì lập trình game cũng là 1 hướng khác khá thú vị.

  Kỹ thuật phần mềm vs Khoa học máy tính - Nên chọn ngành nào/

Ngoài lập trình là chính thì kiến thức từ các lĩnh vực lân cận như kỹ thuật máy tính, khoa học máy tính, quản lý, toán học, quản lý dự án, quản lý chất lượng, công thái học phần mềm và kỹ thuật hệ thống cũng rất cần thiết, tùy vào lộ trình của mỗi người. Nhưng đừng lo, các thầy cô sẽ dạy hết những môn này cho bạn trên ghế giảng đường.

Có thể bạn quan tâm: Con gái nên học ngành nào của Công nghệ thông tin?

Kỹ thuật phần mềm là một trong các ngành hot và có điểm xét tuyển cao nhất nhì hiện nay.

Tham khảo ngay Điểm chuẩn ngành CNTT năm 2023

Học ngành Kỹ thuật phần mềm cần chuẩn bị gì?

Toán, toán và rất nhiều kiến thức về toán. Cũng giống như hầu hết các môn hay ngành nào trong lĩnh vực Công nghệ thông tin, các bạn đều phải hiểu rõ và áp dụng toán để giải quyết các vấn đề, bên cạnh đó việc học toán hiệu quả cũng sẽ giúp bộ não bạn rèn luyện tư duy tốt hơn.

Tiếp theo cũng là 1 môn rất quen thuộc nhưng có lẽ không phải bạn học sinh theo ngành kỹ thuật nào cũng giỏi, đó là tiếng Anh. Thực sự tiếng Anh chuyên ngành CNTT ban đầu là 1 môn khó xơi, nhưng bạn nên tập làm quen dần và rèn dũa mỗi ngày. Để tiến xa với ngành thì bạn cũng nên có khả năng đọc hiểu tốt, vì hầu hết các tài liệu quan trọng của ngành CNTT đều được viết bằng tiếng Anh. Ở 1 số trường Đại học còn dạy thêm môn tiếng Nhật. Vì ngoài tiếng Anh thì đây cũng là 1 ngôn ngữ rất hữu ích cho công việc lập trình của bạn sau này.

Cuối cùng nhưng cũng không kém phần quan trọng là kỹ năng tự học, tự tìm tòi. Kiến thức trên giảng đường thường chỉ là phần thiết yếu, để các bạn hiểu rõ về nguyên lý cũng như cách vận hành. Công nghệ ngày nay luôn được cập nhật và cải tiến mỗi ngày, các thầy cô cũng không thể luôn chạy theo xu hướng mới nhất được mà các bạn phải tự tập làm điều đó. Tính tò mò và đam mê luôn là 1 lợi thế lớn.

>> Đọc thêm: Không giỏi máy tính có học công nghệ thông tin được không?

ngành kỹ thuật phần mềm

Ngành Kỹ thuật phần mềm học những gì?

2 năm đầu: Các bạn sẽ được làm quen dần với kiến thức nền tảng cho ngành Công nghệ Thông tin, mình xin liệt kê các môn quan trọng để các bạn chú ý nghiên cứu và học tập kỹ hơn như Toán rời rạc, Giải tích, Đại số tuyến tính, Xác suất thống kê, Vật lý Đại cương đối với các môn đại cương hay các môn chuyên ngành cũng quan trọng không kém như Nhập môn lập trình, Cấu trúc dữ liệu và giải thuật, Lập trình hướng đối tượng, Cơ sở dữ liệu, Nhập môn công nghệ phần mềm. Đây đều là những môn căn bản bắt buộc để bạn học chuyên sâu sau này.

2 năm cuối: Đây là lúc bạn chọn hướng đi nghiên cứu chuyên sâu ngành cho mình, có 2 hướng là Phát triển phần mềm hay Lập trình game tùy vào sở thích và khả năng của bạn.

Tham khảo các nhóm ngành Công nghệ thông tin khác

Chương trình đào tạo của mảng Phát triển phần mềm

1. Kiến thức cơ bản

  • Toán học ứng dụng: Giải tích, Đại số tuyến tính, Xác suất thống kê.
  • Cơ sở dữ liệu: Nguyên lý cơ sở dữ liệu, Hệ quản trị cơ sở dữ liệu, Thiết kế cơ sở dữ liệu.
  • Ngôn ngữ lập trình: C, C++, Java, Python.
  • Cấu trúc dữ liệu và giải thuật: Các loại cấu trúc dữ liệu, thuật toán tìm kiếm và sắp xếp, độ phức tạp của thuật toán.

2. Kiến thức chuyên ngành

  • Phân tích và thiết kế hệ thống: Mô hình hóa yêu cầu, Thiết kế phần mềm, Phương pháp phân tích và thiết kế hướng đối tượng.
  • Phát triển phần mềm: Quy trình phát triển phần mềm, Phương pháp Agile, Scrum.
  • Kiểm thử phần mềm: Kiểm thử đơn vị, Kiểm thử tích hợp, Kiểm thử hệ thống, Kiểm thử chấp nhận.
  • Quản lý dự án phần mềm: Lập kế hoạch, Quản lý rủi ro, Quản lý chất lượng, Quản lý tài nguyên.

3. Kiến thức nâng cao và ứng dụng

  • Công nghệ web: HTML, CSS, JavaScript, Frameworks như Angular, React.
  • Phát triển ứng dụng di động: Android, iOS, Frameworks như React Native, Flutter.
  • Bảo mật phần mềm: Các nguyên lý bảo mật, Mã hóa dữ liệu, Bảo mật mạng.
  • Trí tuệ nhân tạo và học máy: Giới thiệu về AI, Machine Learning cơ bản, Ứng dụng AI trong phát triển phần mềm.

Chương trình đào tạo của mảng Lập trình game

1. Kiến thức cơ bản

  • Toán học ứng dụng: Giải tích, Đại số tuyến tính, Hình học không gian, Toán học cho đồ họa.
  • Ngôn ngữ lập trình: C++, C#, Python.
  • Cấu trúc dữ liệu và giải thuật: Cấu trúc dữ liệu tuyến tính, cây, đồ thị, thuật toán game.

2. Kiến thức chuyên ngành

  • Nguyên lý phát triển game: Thiết kế game, Lập kế hoạch phát triển game, Quy trình sản xuất game.
  • Đồ họa máy tính: Đồ họa 2D và 3D, Rendering, Shaders, OpenGL, DirectX.
  • Lập trình game: Lập trình game 2D, Lập trình game 3D, Các engine game như Unity, Unreal Engine.
  • Thiết kế nhân vật và môi trường: Mô hình hóa 3D, Texturing, Rigging, Animation.

3. Kiến thức nâng cao và ứng dụng

  • Phát triển game đa nền tảng: Phát triển game cho PC, Console, Mobile.
  • AI trong game: Trí tuệ nhân tạo cho game, Hành vi nhân vật, Học máy trong game.
  • Âm thanh và nhạc nền: Thiết kế âm thanh, Nhạc nền cho game.
  • Kiểm thử và tối ưu hóa game: Quy trình kiểm thử game, Tối ưu hóa hiệu suất game, Quản lý lỗi.

>> Tham khảo chương trình đào tạo ngành Kỹ thuật phần mềm tại trường ĐH Công nghệ thông tin TPHCM tại đây.

Học công nghệ thông tin khó không? Những khó khăn khi học CNTT?

Học ngành kỹ thuật phần mềm ra trường làm gì?

Nhu cầu nhân lực cho ngành Kỹ thuật phần mềm là rất lớn, các bạn Kỹ sư phần mềm sau khi ra trường có thể làm việc được ngay trong các dự án vừa và lớn hoặc chọn việc tiếp tục học lên thạc sĩ, tiến sĩ để theo con đường nghiên cứu.

Các công việc cụ thể tiêu biểu có thể kể đến là kỹ sư phát triển phần mềm / game, kỹ sư kiểm thử phần mềm, kỹ sư phân tích và thiết kế phần mềm, kỹ sư bảo trì phần mềm cũng như các vị trí điều hành các cấp trong dự án. Tương ứng với các công việc trên bạn sẽ có cơ hội lớn làm ở các công ty chuyên về phát triển, thiết kế phần mềm / game; công ty tư vấn thiết kế giải pháp CNTT cho doanh nghiệp hay các cơ quan, đơn vị vận hành và phát triển ứng dụng của nhà nước.

Nếu bạn đi theo hướng nghiên cứu thì các viện nghiên cứu và chuyển giao công nghệ lĩnh vực CNTT với vai trò là cán bộ nghiên cứu, ứng dụng CNTT hay trở thành các giảng viên tại các trường đại học, cao đẳng, trung học phổ thông, trung cấp và dạy nghề đào tạo về ngành CNTT.

Học ngành kỹ thuật phần mềm ra trường làm gì?

Nhu cầu việc làm cao, mức lương hấp dẫn cũng như rất nhiều cơ hội làm tại các công ty công nghệ lớn trong và ngoài nước là những mô tả thường thấy cho 1 người kỹ sư phần mềm.

Đương nhiên thành công không phải ai cũng dễ dàng đạt được nếu như không chịu khó học hỏi,  cố gắng và luôn ‘update’ bản thân. Nếu bạn yêu thích lập trình và có khả năng viết code tốt cùng nhiều ý tưởng thú vị cho các dự án của mình thì rõ ràng đây đúng là hướng đi tốt cho bạn đấy! 

Tham khảo thêm các vị trí tuyển dụng software developer hấp dẫn tại Topdev.

Tham khảo series chọn trường cùng TopDev:

SASS là gì?

SASS – hẳn là một thuật ngữ khá quen thuộc đối với dân lập trình, nhưng trước khi hiểu sâu về SASS thì chúng ta cần ôn lại kiến thức CSS trước đã.

Thuật ngữ CSS chắc hẳn không còn gì xa lạ đối với dân lập trình nữa, dù mảng chuyên môn của bạn là gì đi nữa thì ít nhiều vẫn sẽ biết hoặc đã từng học qua CSS cơ bản. CSS không hẳn là một mảng quá khó trong lập trình nhưng nó khá tẻ nhạt, khô khan và dễ chán. 

“Ơn giời” ngoài CSS thì SASS và SCSS đã ra đời để tối ưu hóa hiệu quả, tiết kiệm thời gian và giảm đi sự khô khan của CSS. Phần này mình sẽ tập trung chia sẻ tất tần tật về SASS nhé!

Ngôn ngữ CSS là gì?

Các ngôn ngữ đánh dấu như HTML sẽ cung cấp một dàn bài đầy đủ, nhưng CSS sẽ là ngôn ngữ giúp dàn bài ấy trở nên thu hút hơn nhờ bố cục, hình ảnh, font chữ, màu sắc và cách trình bày. Có thể hiểu người ta dùng CSS để định hình phong cách cho Website và biến một nền tảng lập trình HTML đơn điệu thành một trang Web thu hút hơn giúp tăng chỉ số UX của Web.

SASS

Hiểu rõ khái niệm SASS là gì?

Đừng đặt nặng hay suy nghĩ quá phức tạp về nó, thực chất, đây là bộ tiền xử lý cũng như ngôn ngữ lập trình dùng để hỗ trợ cho nền tảng cơ bản CSS. Nhờ nó bạn sẽ có thể sắp xếp ngôn ngữ của CSS một cách dễ dàng và gọn gàng hơn bao giờ hết, đồng thời bạn cũng sẽ quản lý nhiều tệp biến đã định nghĩa sẵn từ trước. Ngoài ra. SASS khá hữu ích trong việc giúp bạn tiết kiệm dung lượng vì nó sẽ tự động nén tệp CSS lại.

  SASS/SCSS là gì?

  Xây dựng một bộ source SASS thế nào cho đẹp

Hướng dẫn cú pháp SASS cơ bản:

Ngôn ngữ Sass có hai sự lựa chọn cú pháp tùy theo nhu cầu lập trình của bạn:

SASS (Indented): Có sự khác biệt khá rõ ràng với CSS vì ở SASS chú trọng việc thụt lề để định nghĩa chứ không phải giống CSS là sử dụng dấu ngoặc. Bạn có thể chuyển đổi cứ pháp từ CSS sang SASS và ngược lại bằng lệnh sass-convert (chuyển đổi)

SCSS (Sassy CSS): có đến 90% đồng dạng và tuân thủ theo cú pháp ngôn ngữ CSS nhưng được mở rộng ra 1 chút.

Lợi ích của SASS ứng dụng lên CSS

SASS

Điểm ấn tượng đầu tiên của SASS lên CSS đó là nó tiện dụng cho việc đánh máy và nó ngắn hơn ngôn ngữ CSS thông thường. Nó thậm chí chỉ cần sử dụng rất ít những kí tự được xem là bắt buộc của CSS như dấu ngoặc nhọn ({}) và dấu chấm phẩy (;) để viết. Nó tiện dụng đến mức bạn chỉ cần dấu hai chấm (:) và dấu cộng (+) là đủ mà có thế không cần đến @mixin hay @include nào cả. 

Tuy ở ngôn ngử này còn có những lưu ý bắt buộc là khi viết code phải chủ động ghi nhớ thụt đầu dòng (vì thế dân lập trình hay truyền miệng vui nhau rằng SASS là ngôn ngữ “thụt dòng”) nhưng nó cũng khá tiện lợi cho với việc sử dụng mãi những ký tự dễ type nhầm như {, }, ; đấy. 

  SASS và SCSS là gì ? Tìm hiểu cách viết CSS bằng SASS/SCSS

Ngoài ra, do SASS có tính mạch lạc, rõ ràng khá cao nên ngôn ngữ của SASS cũng đồng dạng yêu cầu sự rõ ràng này khi lập trình, ví dụ điển hình là bạn phải đảm bảo không được quên thụt đầu dòng, code thật rõ và lưu ý phải định dạng tốt ngôn ngữ nếu không bạn có thể không hoàn thành được tệp.

Chưa hết đâu nhé! Thậm chí khi sử dụng Sass các bạn sẽ có thể cải thiện được nhược điểm từ trước của CSS về các:

Variable

Các lập trình viên thường sử dụng các Variable (biến) nhằm lưu trữ và tái sử dụng lại tài nguyên. Với cách này, lập trình viên có thể tùy ý tái sử dụng bất kỳ tài nguyên CSS có sẵn nào bằng ký pháp $ để tạo ra 1 biến khác như:

Hàm SASS như thế này:

$font-atack: Helvetica, sans-serif
$primary-color:#333

body
  font: 100% $font-atack
  color: $primary-color

Sẽ trả về kết quả CSS sau:

body { 
 font: 100% Helvetica, sans-serif;
 color: #333;
}

Như vậy, rõ ràng SASS lấy giá trị trong các biến ta đã định nghĩa ở $, trong trường hợp ở ví dụ cụ thể này thì là $front-stack$primary-color rồi output ra thành tệp CSS với cùng giá trị, chức năng được thay thế trong CSS. Đây là điểm cộng lớn vì sẽ giúp toàn trang giữ được tính nhất quán về màu sắc và font chữ.

Nesting

Như các bạn cũng biết tuy cùng là ngôn ngữ lập trình nhưng CSS lại không có chức năng lồng thẻ này trong thẻ kia như HTML. Tuy nhiên khi SASS sẽ giúp các bạn giải quyết vấn đề đó. Ngôn ngữ SASS có chức năng lồng thẻ CSS với nhau để giúp CSS tiêu trừ điểm yếu, nhưng khi bạn lạm dụng nó thì sẽ dẫn đến việc bị lẫn lộn, khó bảo trì hay sửa chữa và đặt biệt nếu bạn quá lạm dụng chức năng này thì đôi khi bạn sẽ tạo ra một sản phẩm khá tệ.

Hàm SASS như thế này:

nav 
  ul 
    margin: 0 
    padding: 0 
    list-style: none
  li 
    display: inline-block
  a 
    display: block 
    padding: 6px 12px 
    text-decoration: none

Sẽ trả về kết quả CSS sau:

nav ul { 
  margin: 0; 
  padding: 0; 
  list-style: none;
}
nav li { 
  display: inline-block; 
}
nav a {
  display: block;
  padding: 6px 12px;
  text-decoration: none; 
}

Bạn dễ dàng thấy bộ chọn nav trong ví dụ này trông như bội số chung được rút ra để ở trên, bạn cũng có thể hiểu bộ chọn thẻ ul, li, a đã được lồng trong nav. Nó đã biến tệp CSS này trở nên dễ nhìn, đọc và hiểu hơn đúng không nào?

Partials

Những file độc lập có thể tự chứa đựng file CSS, trong trường hợp cần thiết bạn có thể gắn nó vào các SASS khác, nó vẫn vận hành tốt mà không bị gián đoạn. Có thể hiểu, nó có cơ chế hoạt động độc lập 1 cách tuyệt vời, bạn có thể thêm bất kì đoạn CSS nào và SASS vẫn làm tốt vai trò của nó, giúp mọi thứ trở nên dễ dàng hơn kể cả việc chỉnh sửa. Những file SASS độc lập bắt đầu bằng dấu gạch ngang dưới ( _ ), để vận hành file bạn dùng chỉ thị @import để thao tác nhé.

Import 

Trong trường hợp muốn tách nhỏ CSS để chỉnh sửa chi tiết, thì rất dễ dàng thấy rõ nhược điểm của CSS ở phần này, đó là sẽ tạo ra request HTTP không cần thiết. SASS có thể khắc phục nhược điểm đó của CSS, khi sử dụng ký pháp @import thay vì nhận lại được request thì SASS sẽ đem file ta có nhu cầu import kết hợp với file đang nhu cầu tách nhỏ => dễ dàng thực hiện dễ dàng.

Mixins

Minxi của hỗ trợ người dùng tái sử dụng các CSS đã được khai báo từ trước thông qua Web. Ngoài ra, người dùng cũng có thể truyền thêm tham số bất kỳ để tạo minxi tùy biến. Ví dụ: 

Hàm SASS như thế này:

=transform($property)
   -webkit-transform: $property
   -ms-transform: $property
   transform: $property

.box 
   +transform (rotate (30deg))

Sẽ trả về kết quả CSS sau:

.box { 
  -webkit-transform: rotate (30deg);
  -ms-transform: rotate (30deg);
  transform: rotate (30deg);
}

Có thể thấy trong ví dụ về transform, mixin được đặt tên là transform theo cú pháp @mixin transform. Ngoài ra ở trong ví dụ còn sử dụng biến tên $property (được đặt trong cặp ngoặc tròn ( )) thể hiện ý nghĩa là bạn có thể truyền transform. Sau khi hoàn thành ký pháp, bạn có thể sử dụng nó như thông thường, đó là khai báo như 1 CSS trên web với cú pháp @include tên mixin là xong.

Extend

Tính năng thừa kế và một trong những đặc điểm nổi bật cũng như tiện lợi nhất của SASS. Điều này cũng là 1 phần  lý do giúp SASS trông gọn gàng hơn hẳn so với các ngôn ngữ khác. Có thể hiểu đơn giản tính thừa kế của nó như thế này, giả dụ bộ chọn thẻ a, b, c, d được định nghĩa là %XYZ, thì nghĩa là đâu %XYZ xuất hiện thì bộ thẻ a, b, c, d cũng sẽ có mặt và thực hiện đúng chức năng của nó. Chức năng này đã giúp nhiều người sử dụng SASS không cần phải viết nhiều tên lớp trong HTML.

Operators

Việc thực hiện các phép toán trong CSS chắc hẳn không còn xa lạ với các Coder vì đơn giản việc tính toán trong CSS rất tiện lợi. SASS cũng có những phép toán tiện lợi như thế ví dụ như phép tính cộng, trừ, nhân, chia và tính phần trăm, độ lớn của aside và article.

Điểm bất cập của SASS

Như các bạn đã biết, khi viết SASS các lập trình viên phải lưu ý thụt đầu dòng, tuy nhiên nếu bạn thụt đầu dòng một cách lộn xộn thì ngôn ngữ SASS sẽ dựa theo những thụt đầu dòng đó mà hiểu nhầm, lồng các selector rối cả lên! Ví dụ như tệp CSS bên dưới:

.element-a    
    color: hotpink    
    .element-b        
        float: left

Sẽ được hiểu và recode như sau:

.element-a {
    color: hotpink;
}
.element-a .element-b {    
    float: left;
}

Rõ ràng lúc này tệp CSS này của bạn đã bị SASS hiểu nhầm và đưa ra một khái niệm mới mất rồi. Chỉ cần bạn lơ là 1 chút với việc thụt đầu dòng, bạn cũng đã thấy sự khác biệt diễn ra ở đây. Khi đó .element-b sẽ vào hẳn một level và nó sẽ trở thành con của .element-a => sai ý nghĩa tệp CSS trước đó. Chính vì thế, điểm bất cập ở đây là bạn phải chú ý khi thụt dòng

Điểm bất lợi tiếp theo là khi sử dụng và làm quen với SASS, có nghĩa là bạn phải học thêm một loại ngôn ngữ mới hoàn toàn chỉ để bổ trợ cho ngôn ngữ chính là CSS. Khác với SCSS, ở SCSS có tự tương đồng về mặt ngôn ngữ, ý nghĩa và chức năng với CSS nên sẽ dễ tiếp cận và làm quen hơn so với SASS.

Vì SASS dùng cách thụt đầu dòng để định nghĩa nên rất khó để xác định vùng chọn ngay mà cần phải tốn thời gian để xác định lại. Ngoài ra ngôn ngữ này không được hỗ trợ nhiều plugin, điều này khá chán khi sử dụng.

Trình dịch từ SASS qua CSS

Hiện tại có 2 trình dịch miễn phí được mọi người sử dụng khá nhiều, đó là trình dịch Koala và trình dịch Laravel Mix. Cả 2 đều có thể giúp bạn biên dịch từ SASS sang thuần CSS.

Có thể bạn muốn xem thêm:

Tham khảo các vị trí tuyển lập trình CSS mới nhất cho bạn

Viết và Deploy một Lambda Function trên Netlify

Bài viết được sự cho phép của tác giả Lưu Bình An

Lambda function là gì?

Giải thích về Serverless bạn đọc bài trước có đăng

Nếu bạn chỉ có một trang blog như thế này, viết bằng Gatsby, không có backend làm sao bạn có thể có được tính năng cho phép user đăng ký nhận bản tin? Ví dụ dùng dịch vụ của MailChimp đi.

Chúng ta ko thể đưa API key vào trang frontend được, hiển nhiên quá mà! Ai cũng có thể lấy được cái key này thì sao.

Chúng ta phải thông qua một bên ở giữa, là Lambda function trên Netlify, chúng ta đưa key này cho Netlify, nó sẽ có trách nhiệm bảo mật key này và truyền thông tin tới MailChimp

Chữ Lambda được phát minh đầu tiên bởi Amazon AWS, sau này Netlify cũng dùng luôn tên này, nó là kiểu các hàm trung gian, giúp chúng ta giao tiếp với phía server (vì đây là dạng serverless, chúng ta dùng dịch vụ của nó cung cấp, giống như vua chúa, nếu muốn giao tiếp với anh thì chú cứ thông qua thái dám, họ sẽ truyền tin tới cho anh)

Cứ dùng trang mặc định của Gatsby

Viết và Deploy một Lambda Function trên Netlify

Tạo một thư mục bên trong source code, nó sẽ chứa toàn bộ các hàm sẽ giao tiếp với Lambda. Thư mục này đặt đâu cũng được, cứ đặt vào dưới thư mục gốc tên functions

Mỗi file chỉ chứa 1 function

test.js

exports.handler = function(event, context, callback) {
}

Mỗi function sẽ nhận 3 parameter

  • event: chứa post data, header
  • context: function này được call ở đâu, thông tin user hiện tại
  • callback: hàm callback thôi, hàm này nhận param đâu tiền là error nếu có lỗi

Viết và Deploy một Lambda Function trên Netlify

Chạy các function Lambda ở local

Cần cài netlify-lambda để chạy test dưới local

npm install netlify-lambda

Viết và Deploy một Lambda Function trên Netlify

netlify-lambda serve <functions_directory>

<functions_directory> là thư mục chứa mấy function chúng ta viết

Thêm đoạn shortcut vào trong package.json để chạy lệnh này

Viết và Deploy một Lambda Function trên Netlify

Bước cuối cùng cần làm, tạo file config để báo với Netlify, đây không phải là thư mục chứa source code của chúng ta, đây là thư mục sau khi build. Tạo file Netlify.toml trong thư mục gốc

Viết và Deploy một Lambda Function trên Netlify

Sau khi build, file bên trong functions sẽ được đưa vào thư mục tên lambda

Chạy lại đoạn script shortcut hồi nãy khai báo npm run start:lambda, bên dưới hình này đoạn chạy bị lỗi là khi chưa tạo file Netlify.toml, chúng ta bắt buộc phải tạo file này trước khi chạy

Viết và Deploy một Lambda Function trên Netlify

Mở Postman lên gọi test thử

Viết và Deploy một Lambda Function trên Netlify

Function đầu tiên đã chạy thành công!!!

Chúng ta truyền thêm một object { "name" : "James" }, và muốn nhận được một JSON object thay vì là một string. Muốn vậy trong phần body chúng ta phải gọi JSON.stringify

callback(null, {
    statusCode: 200,
    body: JSON.stringify({ msg: "Thanks for visiting " + name })
});

// nếu không nhận được name= james

callback(new Error("You're not James"));

Viết và Deploy một Lambda Function trên Netlify

Test trên Postman

Viết và Deploy một Lambda Function trên Netlify

Trường hợp phát sinh lỗi

Viết và Deploy một Lambda Function trên Netlify

  Deploy ứng dụng web đến một máy chủ từ xa nhờ vào Git push
  Auto deploy dự án với Github Actions

Deploy lên Netlify

Nãy giờ chúng ta đang chạy các Lambda function ở dưới local bằng lệnh serve, để đưa lên Netlify, chúng ta cần build source code trước khi đẩy lên Netlify

Chúng ta phải setup chạy 2 script, một để build Gatsby, sau đó build mấy functions lambda

"props": "npm run build; npm run build:lambda"
Viết và Deploy một Lambda Function trên Netlify

Lưu ý: do đang dùng gatsby, nên cần 2 lệnh này, nếu bạn dùng một thằng khác, thì lệnh sẽ khác, tuy cách setup

Phải cập nhập lại Netlify.toml, chúng ta sẽ báo với Netlify: “Ê, khi nào tao chạy xong prop, thì mày deploy nhe”

Viết và Deploy một Lambda Function trên Netlify

Sau khi commit lên Github, Netlify sẽ bắt đầu trigger deploy, vào trang chính của Netlify, trong tab Deployment, bạn có theo dõi xem nó đang deploy tới đâu rồi

Viết và Deploy một Lambda Function trên Netlify

Sau khi deploy thành công, bạn có thể chuyển qua tab Function, các function nào đã có sẽ được liệt kê ở đây

Viết và Deploy một Lambda Function trên Netlify

Cơ bản là thế thôi, các bạn có thể làm “mọi thứ” với function mình viết (miễn là nó có cho), như gửi email, lưu dữ liệu xuống DB, gọi một API

Bài viết gốc được đăng tải tại VuiLapTrinh

Có thể bạn quan tâm:

Xem thêm các công ty HOT tuyển dụng IT tại TopDev

Báo cáo thị trường IT quý II 2020: Ngành IT khôi phục trạng thái, Việt Nam khởi sắc “xây tổ” đón “đại bàng”

Mới đây nhất, đơn vị tuyển dụng IT TopDev vừa phát hành báo cáo thị trường IT nửa đầu năm 2020, đánh giá toàn bộ thị trường Công nghệ sau đại dịch COVID cũng như nhu cầu tuyển dụng của doanh nghiệp. Nhìn chung, doanh số, tốc độ tăng trưởng, cũng như nhu cầu tuyển dụng của các công ty trong ngành IT có dấu hiệu hồi phục và tăng trưởng trở lại sau đại dịch. 

Vẫn lấy ngành IT làm đầu tàu mũi nhọn cho sự phát triển của đất nước, sự khởi sắc của IT đem lại nhiều tín hiệu mừng cho nền kinh tế của đất nước cũng như sự lan tỏa tích cực đến các lĩnh vực và ngành nghề khác. Ông Nguyễn Hữu Bình – CEO của TopDev cho rằng ngành CNTT đang nhận được rất nhiều sự quan tâm của chính phủ Việt Nam cũng như của các tập đoàn công nghệ nước ngoài (Mỹ, Nhật, Hàn Quốc và Châu Âu), chính vì vậy mà doanh nghiệp cần cùng nhau chung tay để “xây tổ” cải tiến và thúc đẩy công nghệ để sẵn sàng cho những cuộc chuyển mình lớn trong tương lai. Đón “đại bàng” hay “chim sẻ” thời gian sẽ sớm trả lời, chỉ cần chúng ta có sự chuẩn bị đầy đủ, Việt Nam chắc chắn sẽ gặt quả ngọt.

DOWNLOAD

Xu hướng doanh nghiệp ưu tiên tái đào tạo nhân viên

Ứng biến với dịch COVID, các doanh nghiệp cũng có những thay đổi trong kế hoạch tuyển dụng để phù hợp với ngân sách của công ty. Hơn 50% doanh nghiệp vẫn duy trì tuyển dụng, vì nhìn chung ngành IT không chịu sự biến động mạnh như các ngành nghề khác. Dù vậy, vẫn có khoảng 10% doanh nghiệp buộc phải đưa ra những quyết định khó khăn nhằm đảm bảo nguồn tài chính và sự sống còn của công ty.

Ngay sau đại dịch, một số vị trí nhận được sự ưu tiên trong công tác tuyển dụng. Có thể thấy, doanh nghiệp chú trọng những vị trí thuộc cấp quản lý, đáng chú ý là nhân lực có kinh nghiệm nhận được sự quan tâm rất chênh lệch so với fresher (0-2 năm kinh nghiệm).

topdevreport_hinh2

Không còn chú trọng nhiều đến việc liên tục tuyển ứng viên mới đặc biệt là fresher, các doanh nghiệp có 2 xu hướng, một là tập trung tăng cường tuyển dụng những vị trí có nhiều kỹ năng và có tính chuyên môn cũng như kinh nghiệm cao hơn, hai là tận dụng nguồn nhân lực sẵn có cùng với các giải pháp đào tạo nội bộ để nâng cấp các nhân viên cứng của mình. Trong đó, upskill nhân viên hiện tại đang rất được cân nhắc với 26% người tham gia khảo sát chắc chắn lựa chọn, theo sau đó là re-skill với tỷ lệ lựa chọn chắc chắn thay đổi là 23%.

Ngoài ra còn có khái niệm rất mới mà doanh nghiệp có thể cân nhắc với những dự án vừa và nhỏ, chính là Gig workers. Gig workers có thể hiểu là những nhân viên thời vụ, làm việc độc lập và ký biên bản thỏa thuận với doanh nghiệp để cung cấp dịch vụ cho một số dự án nhất định.

Mức Lương một số vị trí lên đến 130 triệu đồng nghĩa với nhu cầu tuyển dụng dần khắt khe hơn, nâng tiêu chuẩn ở các vị trí

topdevreport_hinh4

Ở thời điểm hiện tại, số lượng và nhu cầu về nhân sự IT vẫn luôn tăng trưởng. Dù bối cảnh có nhiều thay đổi, mức lương trung bình thị trường IT vẫn không bị ảnh hưởng quá nhiều. Tuy nhiên, thị trường dần có những sự chuyển dịch và phân hóa rõ ràng hơn ở các nhân sự IT có trình độ khác nhau. Điều này thể hiện rõ nhất ngay ở giai đoạn Covid-19, các nhân sự IT đa năng hơn, đáp ứng nhu cầu khắt khe hơn sẽ được trọng dụng với mức lương trung bình tăng nhanh hơn trung bình thị trường song song với nhu cầu tuyển dụng vị trí này cũng gia tăng đáng kể (hơn 20%) so với giai đoạn trước đó. Về phía ngược lại, các nhân sự IT thông thường có xu hướng giảm về mức lương trung bình cũng như nhu cầu tuyển dụng chững lại đáng kể.

Về khía cạnh tuyển dụng lập trình viên, các vị trí đang thuộc top nhu cầu mà doanh nghiệp tìm kiếm là: Full Stack Developer (lập trình viên đa năng, đảm nhận cả front-end và back-end) chiếm 71.5%, Back-end Developer (thiết kế công nghệ, cơ sở dữ liệu đằng sau sản phẩm) chiếm 65.1%, và Mobile Developer (Lập trình viên ứng dụng di động) chiếm 54.3%.

Mức lương trung bình cao nhất trong giới lập trình thuộc về vị trí CTO/CIO (lên đến 130 triệu đồng), người đảm nhận công việc quản lý, tối ưu công nghệ của doanh nghiệp. Công nghệ được trả lương cao nhất là Kubernetes (38 triệu đồng). Nhìn chung, so với khảo sát năm 2019 do TopDev phát hành, không có sự tăng trưởng đột biến về mức lương trung bình cho các vị trí. Tuy nhiên, đối mặt với nhu cầu, đầu tư từ các doanh nghiệp lớn quốc tế, câu chuyện về phúc lợi và thu nhập của ngành lập trình sẽ luôn thay đổi và mang tính cạnh tranh hơn.

Việt Nam đã sẵn sàng đón nhận đầu tư?

Làn sóng dịch chuyển đầu tư là có thật, đơn cử là những động thái mở nhà máy và trung tâm nghiên cứu, tuyển dụng nhân sự tại Việt Nam của những ông lớn công nghệ như HCL, Samsung, Apple, Qualcomm hay Panasonic,…

Tuy nhiên, để đón được “đại bàng” thì câu chuyện cơ sở hạ tầng tại Việt Nam đã sẵn sàng hay chưa? Theo một chuyên gia kinh tế, có hai vấn đề “nút thắt cổ chai” cần được tối ưu hóa. Thứ nhất, về các khu công nghệ chưa được khai thác đúng mức trên vốn đầu tư, còn có nhiều cơ sở bỏ hoang; các công nghệ phụ trợ chỉ mới phù hợp chào đón các hãng vừa tầm và nhỏ. Thứ hai, khả năng chuyên môn còn chưa vững, còn thiếu về cả chất và lượng. Giải pháp sâu xa không chỉ về mặt nâng cao tay nghề, mà còn về mặt tư duy của lao động, thay đổi mindset để đóng góp vào sự phát triển của hãng.

Để giải quyết được các vấn đề đã nêu cần sự phối hợp giữa chính phủ và doanh nghiệp. Về phía các chính sách, Chính phủ nên bắt đầu với chương trình PPP để tối ưu ngân sách quốc gia, sau đó là hỗ trợ các doanh nghiệp vừa và nhỏ bằng những biện pháp miễn giảm các loại thuế phí, hay ổn định giá điện nước đầu vào của doanh nghiệp, hỗ trợ doanh nghiệp vượt qua giai đoạn hậu COVID.

Nhìn chung, nền kinh tế Việt Nam được nhận định sẽ sẵn sàng bật dậy sau dịch COVID-19. Theo nhận định của nhà kinh tế Edward Teather của UBS Research, “Nền kinh tế Việt Nam chịu một số tổn thương do tác động của dịch Covid-19, nhưng vẫn có triển vọng sáng nhất khu vực châu Á. Doanh số bán lẻ, nhập khẩu và sản xuất công nghiệp của Việt Nam đều tăng trong tháng 6 so với cùng kỳ năm trước. Rõ ràng là tình hình Việt Nam tốt hơn hầu hết nền kinh tế châu Á khác.”

Tóm lại, TopDev cho rằng, đi cùng với những cơ hội lớn vẫn sẽ có những thách thức không hề đơn giản về sự thay đổi và phát triển. Đón nhận làn sóng đầu tư cũng là “mở cửa” cho những sự thay đổi mới, mà trong đó công nghệ sẽ là trợ thủ đắc lực, giúp Việt Nam “gặt” quả ngọt.

Báo cáo nửa đầu năm 2020 về thị trường và nhu cầu nhân sự IT do TopDev phát hành đã được đăng tải, độc giả tìm hiểu thêm về xu hướng các ngành Công nghệ trong nước qua bản báo cáo IT Landscape 2020 tại đây.

Làm việc với Redux trong ứng dụng lớn

Bài viết được sự cho phép của tác giả Lưu Bình An
Cùng thảo luận xung quanh vấn đề ứng dụng thiên về dữ liệu lớn, rất lớn

Đây là những chỉ dẫn của AppNexus để tối ưu redux với lượng dữ liệu khủng. Mức độ bài viết khá chuyên sâu, bạn cần nắm thật vững redux, hoặc xem lại redux để hiểu rõ và nhớ lâu nội dung bài này.

  Redux vận hành như thế nào
  Tớ đã ăn hành với Redux như thế nào?

Lưu dữ liệu với chỉ mục. Truy cập bằng selector

Cách cấu trúc dữ liệu sẽ ảnh hưởng nhiều đến performance và việc tổ chức ứng dụng. Lưu dữ liệu trả về từ API theo chỉ mục (index) mang lại nhiều lợi ích. Nói nôm na, lưu theo chỉ mục tức là theo dạng object, theo cặp key-value. Tác giả Redux ( Dan Abramov ) có trình bài vấn đề này ở đây

Tưởng tượng chúng ta có một mảng object, được fetch từ REST API. Giả dụ chúng ta quyết định lưu toàn bộ xuống store như nó trả về. Khi chúng ta muốn lấy một object cụ thể nào đó? Phải loop qua toàn bộ, rồi muốn lưu danh sách các user đang được chọn và chưa được chọn?

Để tránh tình trạng này, lưu nó dạng chỉ mục, viết lại reducer trước khi lưu xuống store, cục dữ liệu mong muốn, (bạn nào sử dụng FireStore, NoSQL database sẽ hiểu liền tại sao)

{
  "usersById": {
    123: {
      id: 123,
      name: "Jane Doe",
      email: "jdoe@example.com",
      phone: "555-555-5555",
      ...
    },
    ...
  }
}

Dữ liệu được cấu trúc như thế này thì giải quyết vấn đề bằng cách nào? Ví dụ, chúng ta muốn truy cập đến một user object cụ thể

const user = state.usersById[userId]

Không cần loop, sử dụng key để lấy trực tiếp đến object mong muốn

Câu hỏi tiếp theo, ủa vậy sao render được danh sách user nếu dữ liệu tổ chức như vậy. Để làm chuyện đó, chúng ta viết một hàm (hàm như vậy gọi là selector) đơn giản bằng Object.keys()

const getUsers = ({userById}) => {
  return Object.keys(usersById).map(id => usersById[id]);
}

Thêm một hàm nữa cho việc lấy ra danh sách user với tham số truyền vào là mảng user id

const getSelectedUsers = ({ selectedUserIds, usersById }) => {
  return selectedUserIds.map((id) => usersById[id]);
}

Đừng lo chuyện phải viết quá nhiều hàm, viết như vậy càng dễ cho sau này maintain. Trường hợp cái model user có bị thay đổi đi nữa, chúng ta không cần phải update cả trăm cái view đang sử dụng dữ liệu này, đơn giản là update những hàm selector này lại, re-format dữ liệu một tí là xong.

View và edit nên có 2 state khác nhau

Những dữ liệu từ REST API trả về được xem là state chuẩn, giống hệt với database. State của ứng dụng chúng ta sẽ lưu thêm một số meta data khác cho từng user, bình thường chúng ta sẽ xử lý hết những dữ liệu trong cùng một reducer, vì nó tiện.

Nên tách việc xử lý state chuẩn trên reducer khác, nếu tập trong tất cả xử lý trong một reducer sẽ khó maintain hơn là tách ra thành nhiều reducer riêng biệt. (dùng combineReducers đấy mà)

Tại sao? Ví dụ chúng ta có 1 danh sách user, lưu dạng chỉ mục như ở trên

{
 "usersById": {
    123: {
      id: 123,
      name: "Jane Doe",
      email: "jdoe@example.com",
      phone: "555-555-5555",
      ...
    },
    ...
  }
}

Chúng ta có màn hình để user chỉnh sửa, user click nút Edit, chúng ta phải update lại state để render màn hình edit, chúng ta thêm một field mới vào object như sau

{
 "usersById": {
    123: {
      id: 123,
      name: "Jane Doe",
      email: "jdoe@example.com",
      phone: "555-555-5555",
      ...
      isEditing: true,
    },
    ...
  }
}

Submit lên trên API sau khi sửa. API trả về một object mới. Nhưng làm sau chúng ta merge lại vào store? Nếu replace toàn bộ object thì chúng ta mất cái field isEditing, tất nhiên là nếu muốn thì vẫn check và chỉ update những field mình muốn, nhưng như vậy rất tốn sức người sức máy. Tốt nhất chúng ta lưu dữ liệu từ API vào một nơi khác trong store bằng một reducer khác, không đụng gì vào nó, action cũng sẽ đơn giản hơn và dễ xử hơn

Thêm nữa, nếu user có nữa chừng ấn cancel chúng ta dễ dàng reverse lại nếu đưa edit state vào chổ khác

"usersByIds": {
  123: {
    id: 123,
    name: "Jane Doe",
    email: "jdoe@example.com",
    phone: "555-555-5555",
    ...
  },
  ...
},
"editingUsersById": {
  123: {
    id: 123,
    name: "Jane Smith",
    email: "jsmith@example.com",
    phone: "555-555-5555",
  }
}

Như vậy chúng ta vẫn có state chuẩn, để reverse, edit state nếu user click edit nữa. Nói chung, tách ra, đừng gọp chung

Xài chung state một cách khôn ngoan

Một khi ứng dụng phình ra, nhiều tính năng hơn, nên có cái reducer cho từng page, ví dụ trang hiển thị list user, lưu lại trong users reducer, một trang khác bao gồm tất cả post của user hiện tại. Tổ chức redux store như sau

{
  "usersPage": {
    "usersById": {...},
    ...
  },
  "postsPage": {
    "postsById": {...},
    ...
  }
}

Mỗi trang đảm trách state của chính nó, các file reducer có thể để cùng với các file page luôn.

Sẽ đến lúc chúng ta cần chia sẻ một vài state giữa 2 view. Cân nhắc các câu hỏi sau

  • Có bao nhiêu view hoặc reducer sẽ phụ thuộc vào dữ liệu này?
  • Mỗi trang có cần một bản sao dữ liệu không?
  • Dữ liệu thay đổi có thường xuyên không?

Ví dụ, thông tin user đang đăng nhập sẽ được hiển thị trên tất cả các trang. Tất cả trang đều dùng, thì nó sẽ không hợp lý với cách làm mỗi page một reducer. Thông tin user sẽ không đổi trên tất cả các trang (trừ khi nó vô sửa profile), vậy nên mỗi trang không cần phải có một bản sao thông tin này.

Tất cả các trang nên dùng chung một thông tin user đang login, cho nó một reducer riêng.

Trường hợp nào chuyện xài chung như vậy là ko hợp lý? Thí dụ trong các bài viết của user, nó có thêm danh sách các bình luận. Một trang hiển thị tất cả bình luận. Trang trang list post có tùy chọn hiển thị bình luận cho post đang chọn. Chúng ta có 2 trang đều phụ thuộc vào dữ liệu của bình luận. Trang list post sẽ bị thay đổi khá thường xuyên: user update, edit, delete, add post, bình luận tè le ở đó. Ở trang bình luận chỉ cho tương tác với API GET, PUT bình luận, có thể phân trang. Trang post thì ngược lại, nó chỉ lấy danh sách bình luận của chính nó. Rõ ràng, việc dùng chung bình luận giữa các view là không hợp lý. Mỗi trang nên lưu riêng một bản sao của bình luận.

Tái sử dụng các hàm xử lý reducer

Sau một thời gian viết reducer, sẽ có lúc mình thấy mấy cái function này xử lý na ná nhau, như vậy thì nên tái sử dụng nó đừng viết mới. Ví dụ nếu logic của việc load dữ liệu bài viết và bình luận là như nhau, khác cái endpoint thôi và object schema, phân trang cũng giống.

Để dùng chung reducer, cách thứ nhất, truyền vào scope bên trong payload của action. Để dễ hình dung, lấy vị dụ một trang chứa nhiều section khác nhau, tất cả đều load bất tuần tự từ các API endpoint khác nhau, để theo dõi tình trang load này bằng state trong store

const initialLoadingState = {
  usersLoading: false,
  domainsLoading: false,
  subDomainsLoading: false,
  settingsLoading: false,
};

Chúng ta có thể viết 4 reducer cho 4 cái action, thay vì như vậy nếu truyền thêm scope, một action SET_LOADING

// reducer
const loadingReducer = (state = initialLoadingState, action) => {
  const { type, payload } = action;
  if (type === SET_LOADING) {
    return Object.assign({}, state, {
      // tùy theo scope mà gán cho key tương ứng
      [`${payload.scope}Loading`]: payload.loading,
    });
  } else {
    return state;
  }
}

// Action
const setLoading = (scope, loading) => {
  return {
    type: SET_LOADING,
    payload: {
      scope,
      loading,
    },
  };
}

// ví dụ gọi dispatch
store.dispatch(setLoading('users', true));

Làm như vậy chúng ta khử được quá nhiều lần lập lại logic của reducer.

Còn về vấn đề phân trang, API có thể trả về gần giống như sau

{
  "users": ...,
  "count": 2500, // tổng số dòng
  "pageSize": 100, // số phần tử mỗi trang
  "startElement": 0, // giá trị index đầu tiên của phần từ đầu tiên
  ]
}

Để gọi dữ liệu trang tiếp theo, chúng ta có thể dùng tham số query startElement=100. Đây là cách chúng ta hiện thực reducer cho vấn đề phân trang

const initialPaginationState = {
  startElement: 0,
  pageSize: 100,
  count: 0,
};
const paginationReducerFor = (prefix) => {
  const paginationReducer = (state = initialPaginationState, action) => {
    const { type, payload } = action;
    switch (type) {
      case prefix + types.SET_PAGINATION:
        const {
          startElement,
          pageSize,
          count,
        } = payload;
        return Object.assign({}, state, {
          startElement,
          pageSize,
          count,
        });
      default:
        return state;
    }
  };
  return paginationReducer;
};

// Ví dụ
const postsReducer = combineReducers({
  postsData: postsDataReducer,
  paginationData: paginationReducerFor('POSTS_'),
});
const commentsReducer = combineReducers({
  commentsData: commentsDataReducer,
  paginationData: paginationReducerFor('COMMENTS_'),
});

// Action creator

const setPaginationFor = (prefix) => { 
  const setPagination = (response) => {
    const {
      startElement,
      pageSize,
      count,
    } = response;
    return {
      type: prefix + types.SET_PAGINATION,
      payload: {
        startElement,
        pageSize,
        count,
      },
    };
  };
  return setPagination;
};
// ví dụ sử dụng
const setPostsPagination = setPaginationFor('POSTS_');
const setCommentsPagination = setPaginationFor('COMMENTS_');

Nếu chúng ta dispatch ra 1 action là POSTS_SET_PAGINATION nó sẽ chỉ đụng đến postsReducer. Một kiểu viết hơi tricky nếu bạn nào chưa nắm được Closure function – mình có dịch trên MDN rồi, các bạn lên đó đọc lại.

Tích hợp với React

Ví dụ sử dụng selector và action creator

const ConnectedComponent = connect(
  (state) => {
    return {
      users: selectors.getCurrentUsers(state),
      editingUser: selectors.getEditingUser(state),
    };
  },
  (dispatch) => {
    const actions = {
      setPagination: actionCreatorFactories.setPaginationFor('USERS_'),
    };
    return bindActionCreators(actions, dispatch);
  })
)(UsersComponent);

Các component nó không cần quan tâm cái scope nào đang dùng với action và truy cập tới state bằng cách nào. Component giờ không cần quan tâm việc dữ liệu cụ thể bên trong state làm việc thế nào.

Bài viết gốc được đăng tải tại VuiLapTrinh

Có thể bạn quan tâm:

Xem thêm các việc làm it hồ chí minh, it hà nội, it đà nẵng hấp dẫn tại TopDev

Merge vs Rebase trong Git

Bài viết được sự cho phép của tác giả Lưu Bình An

Merge và Rebase là 2 công cụ để trộn 2 branch trong Git, mục đích sử dụng cho những tính huống khác nhau.

Một tình huống phổ biến khi sử dụng merge

  • Tạo nhánh my-new-feature từ nhánh master
  • Commit nhánh my-new-feature với một số thay đổi
  • Tạo Pull Request: my-new-feature vào master
  10 Vấn đề về Git thường gặp và Giải pháp
  Sự khác biệt giữa ‘git merge’ và ‘git rebase’ là gì?

Sau khi my-new-feature được merge vào master, chúng ta sẽ có

Đó là trường hợp lý tưởng rất ít khi xảy ra, 99.999999% là my-new-feature có vài điểm cần bổ sung sau khi review code, bug chẳng hạn, sai chính tả chẳng hạn.

  • Chúng ta bổ sung 2 commit C6 và C7 vào nhánh my-new-feature
  • Trong lúc đó, master cũng có thêm 2 commit C8C9 được merge vào bởi 2 bạn đồng nghiệp
  • Cuối cùng PR của chúng ta cũng được merge

Cái history lúc này (vẫn ok chứ không vấn đề gì)

Tuy nhiên, cũng là một tính huống rất hay gặp luôn, chúng ta ôm nhánh my-new-feature gần một tuần mà chưa xong, và chúng ta muốn có C8C9 đã được merge, và một cách chủ quan duy ý chí, dân dev chúng ta muốn có một cái history thật sạch đẹp, theo kiểu từng commit C4, C5, C6, C7,… là từng công việc rất cụ thể và độc lập, chúng ta không muốn gom hết một lượt đến cuối sprint rồi commit toàn bộ file là điều khiến người review code vô cùng mệt não.

Rebase giúp được gì ở tình huống này?

Năm 2016 Github giới thiệu một cách merge PR mới: Rebase and merge (Gitlab sẽ là Rebase front door). Nó cho phép chúng ta thực hiện một thao tác rebase trên commit PR rồi mới thực hiện việc merge. 2 thao tác này hoàn toàn độc lập và luôn đúng theo thứ tự rebase trước, merge sau, chứ ko có ngược lại.

Tương tự như nút Rebase and merge, nếu dùng command

git checkout my-new-feature
git rebase master
git checkout master
git merge my-new-feature --ff

Bằng cách đó, history lúc này là một đường thẳng tắp

Rebase không phải để thay thế merge, rebase dùng để thực hiện trên nhánh feature – private branch của chúng ta, merge thực hiện trên master – share branch với đồng nghiệp

Việc rebase -> merge như thế sẽ tránh mất đi những commit C4, C5, C6, C7 trên history của nhánh master, như khi chỉ dùng một lệnh merge. Chúng ta bê nguyên cái history của nhánh my-new-feature lên luôn.

Vấn đề thứ 2, làm sao để sync nhánh my-new-feature với master (có C8, C9)?

/* lấy những thay đổi mới */
git fetch
/* checkout nhánh chúng ta muốn sync với master */
git checkout my-new-feature
/* thực hiện sync với master */
git rebase origin/master

Giữ nhánh my-new-feature cập nhập với những thay đổi mới nhất ở nhánh master để tránh quá nhiều conflict xảy ra khi tạo PR

Nút Rebase and merge không được yêu thích lắm, vì nó tạo quá nhiều conflict, nên chúng ta vẫn thường ưu ái merge hơn.

Để có một history thẳng hàng, đầy đủ tốn khá nhiều mồ hôi chứ không dễ như ăn bánh.

Bài viết gốc được đăng tải tại VuiLapTrinh

Có thể bạn quan tâm:

Xem thêm các việc làm lập trình viên IT hấp dẫn tại TopDev

Chín thói quen xấu cần bỏ nếu muốn theo ngành CNTT

1. Không chịu đọc tài liệu trước khi dùng:

Đây là một trong những thói quen tệ hại nhất nhưng lại thường gặp nhất. Có lẽ thói quen này nảy sinh từ tính thân thiện của “giao diện đồ hình” (GUI) khiến cho người dùng bồi đắp thói quen mò mẫm mà không cần đọc hướng dẫn nhưng cũng sử dụng được máy. Việc này không có gì đáng ngại đối với người dùng (rất) bình thường. Tuy nhiên, nếu bạn có ý định theo đuổi ngành CNTT một cách nghiêm túc thì hãy bỏ ngay thói quen tai hại này bởi vì đây là rào cản lớn nhất cho sự phát triển. Kiến thức vững chắc không phải… mò mà ra. Tài liệu hướng dẫn không phải vô cớ mà được viết ra.

2. Đọc lướt:

Đây cũng là một thói quen tệ hại và phổ biến không kém. Ngay trên những diễn đàn, với những ý kiến và chỉ dẫn bằng tiếng Việt rất cô đọng, rành mạch và dễ hiểu nhưng vẫn có quá nhiều người chỉ đọc lướt để rồi quay lại tiếp tục thắc mắc. Đây là thói quen cực kỳ nguy hiểm bởi vì nó rèn cho trí não thói quen đọc lướt. Việc này dẫn đến chỗ kiến thức thu thập một cách hời hợt, tạm bợ và chắp vá. Nếu những ý kiến bằng tiếng Việt rất cô đọng, rành mạch và dễ hiểu nhưng vẫn không chịu khó đọc kỹ và suy gẫm thì việc tham khảo, tổng hợp các sách tiếng nước ngoài gần như là vô khả thi.

3. Bắt chước mà không suy nghĩ:

Khi bắt đầu làm quen với những thứ trong ngành CNTT, cách dễ nhất là bắt chước làm theo từng bước. Nếu cứ nhắm mắt làm theo nhưng không hề suy nghĩ lý do tại sao mình làm như vậy, không thử đặt câu hỏi những gì xảy ra đằng sau những “bước” ấy thì không chóng thì chày sẽ tạo cho mình một thói quen tai hại: bắt chước không suy nghĩ không tư duy như một cỗ máy. Từ chỗ làm theo từng bước có sẵn mà không suy nghĩ đến chỗ biến thành thói quen thì khả năng nhận định và tư duy sẽ bị thui chột. Chẳng những vậy, thói quen này kiềm hãm sự thẩm thấu kiến thức xuyên qua hàng loạt những câu hỏi. Tự đặt câu hỏi chính là cách buộc trí não mình làm việc và là viên đá đầu tiên để dấn thân vào chỗ phát triển trí tụệ.

  10 thói quen của một lập trình viên thành công

4. Sợ khó:

Sợ khó tưởng chừng quá thông thường trên mọi lãnh vực nhưng trong lãnh vực CNTT thì thói quen “sợ khó” là thói quen giết chết ngay bước đầu làm quen và phát triển. Chẳng có ngành nghề thực thụ, đòi hỏi trí tuệ mà lại dễ dàng hết. Thói quen “sợ khó” biểu hiện từ chuyện đơn giản như học ngoại ngữ (để có thể tham khảo thêm tài liệu ngoại ngữ) cho đến chuyện tự mình đối diện với những khó khăn trong khi trau dồi kiến thức và kinh nghiệm. Thói quen này lâu dần ăn sâu và dẫn đến chỗ không muốn và không thể giải quyết được điều gì nếu chỉ cảm thấy có trở ngại. Nên tránh xa câu này: vạn sự khởi đầu nan, gian nan bắt đầu nản.

5. Viện cớ:

Quá trình tích lũy kiến thức luôn luôn có những khó khăn và trở ngại. Nếu chính bản thân mình không tự kỷ luật và tự nghiêm khắc thì chẳng còn ai trên đời này kỷ luật và nghiêm khắc giúp mình. Từ chỗ không kỷ luật và không nghiêm khắc, chỉ cần một thời gian rất ngắn có thể dẫn đến sự đổ vỡ, sợ hãi, chán nản và để bào chữa cho sự đổ vỡ thường là những viện cớ. Viện cớ chỉ để ẩn nấp sau cái cớ nhưng sự thật sụp đổ vẫn tồn tại. Tránh xa những câu như “nhà em nghèo”, “hoàn cảnh khó khăn”, “vì em là newbie” mà nên biết rằng vô số những người khác cũng như mình và thậm chí còn khó khăn hơn mình. Nên nhớ rằng, ngay khi dùng cái cớ để viện thì lúc ấy mình đã chính thức thất bại rồi.

6. “Đi tắt đón đầu”:

Trên đời này chẳng có loại tri thức đích thực nào hình thành từ “đi tắt” và “đón đầu” cả. “Mì ăn liền” có cái ngon của nó nhưng chính “mì ăn liền” không thể hình thành một bữa ăn thịnh soạn và đầy đủ. Tri thức đích thực cũng như thức ăn, nó cần điều độ, liều lượng và thời gian để… tiêu hoá. Tư duy và thói quen “đi tắt” luôn luôn dẫn đến những lổ hổng khủng khiếp trong kiến thức. Những lổ hổng ấy xem chừng không nhiều và không quan trọng khi kiến thức còn ít ỏi và nhu cầu công việc còn sơ khai. Tuy nhiên, một khi đối diện với những khó khăn và phức tạp trong công việc và trong đời sống thì những thứ “đi tắt đón đầu” là nguyên nhân sâu xa của những đổ vỡ và thất bại. Hãy nhớ: đừng đi tắt và đừng đón đầu bởi vì chẳng có cái đường tắt nào trong hành trình đi tìm tri thức.

7. “Nghe nói là…”

Cụm “nghe nói là…” là một cụm phổ biến đến độ chóng mặt. Bất cứ một ngành khoa học hay có liên quan đến khoa học không thể dựa trên “nghe nói” mà luôn luôn cần dựa trên các bằng chứng khoa học và những bằng chứng ấy cần chính xác và cụ thể. Chính vì có thói quen “nghe nói” mà đánh rớt những cơ hội tìm tòi và kiểm chứng; những cơ hội quý báu để trau dồi kiến thức và kinh nghiệm. Cái gì không rõ thì nên tìm tòi và đừng “nghe nói” mà phải được thấy, được phân tích và được kiểm chứng. Không bỏ được thói quen này thì cách tốt nhất đừng bén mảng gần bất cứ ngành khoa học nào vì chỉ chuốc lấy sự thất bại và lãng phí.

8. Niềm tin và hy vọng:

Trong khoa học, khi nói đến kết quả và sự kiến tạo hoặc thậm chí con đường đi đến sự kiến tạo và kết quả thì hoàn toàn không có chỗ cho “niềm tin” và “hy vọng” một cách mù mờ. Thói quen “restart” lại máy hay “restart” lại chương trình với “hy vọng” nó sẽ khắc phục sự cố đã trở thành thói quen cố hữu. Nếu không có điều kiện thay đổi nào khác thì có “restart” một triệu lần và hy vọng một triệu lần thì kết quả vẫn y hệt nhau. Đừng “tin” và đừng “hy vọng” vào sự thay đổi của kết quả nếu như chính bạn không kiểm soát và thay đổi để tạo thay đổi trong kết quả. Tất cả mọi hoạt động từ lập trình cho đến quản lý hệ thống, quản lý mạng, bảo mật, reverse engineering…. thậm chí đối với người dùng bình thường, khi kết quả không như ý, sự điều chỉnh là điều cần thiết thay vì lặp lại y hệt hành động và chỉ… hy vọng.

9. Không vì trí tuệ mà vì… “đẳng cấp”:

Lắm bạn lao vào ngành này không phải là vì trí tuệ, vì kiến thức, vì đóng góp một cái gì đó ích lợi cho xã hội mà là vì… đẳng cấp mơ hồ nào đó. Nếu tiếp tục lao vào và chọn lấy một muc tiêu mơ hồ thì sẽ không bao giờ đi đến đích được. “Đẳng cấp” là một thứ mơ hồ, vô ích và đầy cá nhân tính nhưng khi nó biến thành thói quen và mục tiêu để nhắm tới thì nó chẳng mang lại được gì ngoài sự thất bại ngay từ đầu vì hoàn toàn không có một phương hướng nào cả. Trau dồi kiến thức hoàn toàn khác với việc xoa dịu mặc cảm (“đẳng cấp”).

Bài viết gốc được đăng tải tại Hoàng Ngọc Diêu

Có thể bạn quan tâm:

Xem thêm các vị trí tuyển dụng IT hấp dẫn tại TopDev

Làm thế nào để giải quyết bất đồng ý kiến nơi công sở?

Những bất đồng về quan điểm, hiệu quả làm việc là chuyện không quá xa lạ với chúng ta. Tuy chúng có thể khiến môi trường làm việc căng thẳng, mệt mỏi, và gây ra sự khó chịu cho tất cả các bên nhưng không thể phủ nhận chính những mâu thuẫn cũng góp phần mang lại hiệu suất làm việc cao hơn. 

Đôi khi một chút bất đồng có thể thúc đẩy sự đột phá, tăng động lực và ngược lại vẫn có nhiều trường hợp tạo ra rào cản lớn trong các mối quan hệ. Thông qua bài viết sau đây, TopDev sẽ chia sẻ với bạn những cách thức phù hợp để giải quyết bất đồng về ý kiến nơi công sở.

Cùng điểm qua 3 chiến lược giải quyết bất đồng nơi công sở nhé!

Nhìn nhận vấn đề trên cùng góc độ

Sự đồng điệu luôn luôn quan trọng

Chúng ta đều nhận ra được nguyên nhân dẫn đến những mâu thuẫn xuất phát từ chính cách nhìn nhận của mỗi người về vấn đề rất khác nhau. Đồng thời, cái tôi cá nhân cũng là yếu tố chi phối cách bạn thể hiện quan điểm, truyền tải thông điệp của mình đến mọi người. Nếu đủ lý trí để nhận ra, hãy thử ngẫm lại mọi thứ. Chúng ta là một đội, có cơ hội đồng hành trải nghiệm cùng nhau để thực hiện các mục tiêu chung. Bạn và các đồng nghiệp có thể bất đồng nhưng đó là tranh luận, không phải “sàn đấu ngôn ngữ” để thể hiện mình quá nhiều. Hãy nhìn nhận trên cùng một góc độ để nhận thấy sự tương đồng, cùng tìm ra sự thống nhất chung về các cách thức tổ chức để thực hiện công việc hiệu quả nhất.  

bất đồng

Một lưu ý nữa là, việc cộng tác cùng những người đồng đội cần được xây dựng trên cơ sở niềm tin. Thay vì chăm chăm phản bác ý kiến của đồng nghiệp, bạn hãy thử đặt niềm tin vào giải pháp của họ hoặc đơn giản, hãy trình bày những điểm mạnh – điểm hạn chế từ ý quan điểm của đồng nghiệp. 

  Kỹ năng giao tiếp? Làm thế nào để cải thiện giao tiếp hiệu quả?

Nếu ý kiến đó có thiếu sót, bạn có thể đóng góp một chút ít về chuyên môn để làm rõ tính khả thi của vấn đề. Đó là cách xử lý khôn khéo giúp hạn chế được những bất hòa phát sinh mà không gây nên bất kỳ sự xúc phạm nào cho đồng nghiệp của bạn. Ngoài ra, điểm cộng hoàn hảo trong việc tạo ra sự tương tác hài hòa giữa bạn và đồng nghiệp chính là sử dụng cách nói “cách nói” thay vì”tôi. Phát ngôn ấy thể hiện rằng bạn đang thật sự quan tâm đến giải pháp tích cực của họ đồng thời bộc lộ mình là một người nhìn nhận các vấn đề trên lợi ích chung của doanh nghiệp.

Bạn không cần lúc nào cũng đúng!

Khi đã vào cuộc giải quyết mâu thuẫn, cuộc khẩu chiến có thể diễn biến khá phức tạp khi bạn và đồng nghiệp đều cố tỏ ra là mình đúng và thể hiện quan điểm cá nhân thay vì lắng nghe, xác định mức độ và giải quyết vấn đề.

Khá dễ hiểu vì sao bạn lại muốn thắng trong cuộc tranh luận, nhưng nếu quá đề cao việc mình phải luôn đúng, bạn đã hoàn toàn quên mất ý nghĩa của những bất đồng này.

bất đồng

Những cuộc tranh luận là để tìm ra cách giải quyết tối ưu, không phải cuộc chiến của người thắng – kẻ thua. Bất đồng là cơ hội để hai bên bày tỏ quan điểm. Để được lắng nghe, và được học hỏi. Nếu cứ chăm chăm vào giành phần thắng, chúng ta đang ngăn cản mình gặt hái những giá trị tích cực từ cuộc thảo luận. Vì thế, trước cuộc thảo luận, bạn hãy đảm bảo những điều sau đây

  • Tính trung thực: Cam kết rằng bạn và đôi phương đều có chung mong muốn tìm ra được cái cốt lõi của vấn đề thông qua những sự thật đã diễn ra.
  • Loại bỏ những hiềm khích cá nhân: Chấp nhận thảo luận để giải quyết những bất đồng tức là bạn đã đặt lợi ích công việc lên hàng đầu. Vì thế, việc gạt bỏ đi những hiềm khích, thành kiến cá nhân về nhau là điều hết sức quan trọng.
  • Cởi mở và lắng nghe lẫn nhau: Đây là giai đoạn các nên mở lòng, lắng nghe và tiếp nhận ý kiến lẫn nhau,cùng thảo luận để đi đến sự thống nhất chung. Đừng quá thể hiện rằng mình luôn đúng trong mọi trường hợp

Hãy để mọi người giúp bạn

Việc tương tác trong các lĩnh vực xã hội, đặc biệt là trong ngành nhân sự, nhiều người có xu hướng không cho rằng việc tìm kiếm sự giúp đỡ là một ý kiến hay. Họ có phần đánh đồng đó là sự yếu đuối và chủ yếu họ đi theo hướng tự bản thân gầy dựng mọi thứ từ A đến Z. Và đôi khi, việc bạn nghĩ rằng mình đang tạo gánh nặng hay khiến người khác cảm thấy bực bội sẽ vô tình làm bạn trở nên thiếu tự tin, từ đó bạn chỉ biết thụ động tiếp thu các quan điểm, mất đi những chính kiến cá nhân về tư duy phán đoán, đánh giá các giải pháp vấn đề. Hãy nhớ rằng việc bạn để mọi người giúp bạn là bạn đang tạo cơ hội cho họ bày tỏ suy nghĩ. Đây được xem là một thủ thuật, khác với việc bạn đánh đi mất quyền lợi được nêu nhận xét về các giải pháp của đồng nghiệp.

  Cách thiết lập và duy trì mối quan hệ (networking) hiệu quả

bất đồng

Nhờ giúp đỡ cũng là một cách thể hiện bạn tin tưởng vào chuyên môn và khả năng của đồng nghiệp trong việc đưa ra những giải pháp thật sự hiệu quả. Một bí quyết dành cho bạn là thay vì mở đầu cuộc thảo luận bằng giọng điệu tranh cãi, bạn hãy thể hiện mong muốn được giúp đỡ từ đồng nghiệp. Đây là cách ứng xử thông minh và đồng thời cũng thể hiện bạn đang tôn trọng và đề cao thiện chí xây dựng mối quan hệ ý nghĩa với các đồng nghiệp của mình. 

Lời kết

Có nhiều cách thức để giải quyết bất đồng nơi công sở. Tuy nhiên, tùy vào đối tượng, hoàn cảnh và mức độ của mâu thuẫn đó mà bạn cần có cách thức xử lý phù hợp. TopDev mong rằng với bài viết này, các bạn đã có những chia sẻ bổ ích có thể vận dụng vào thực tiễn giúp bạn sớm giải quyết mọi nút thắt trong doanh nghiệp của mình.

Có thể bạn quan tâm:

Xem thêm IT Jobs for Developer trên TopDev

TopDev bị chặn

Chúng tôi bắt đầu nhận được phản hồi từ rất nhiều người dùng cũng như là khách hàng về việc không thể truy cập và sử dụng topdev.vn. Qua các bước loại bỏ nguyên nhân và xác minh, chúng tôi nhận thấy domain topdev bị chặn ở tất cả các nhà mạng. Bao gồm ba nhà mạng lớn nhất (xếp theo thứ tự alphabet) là FPT, Viettel và VNPT.

Bằng nhiều công văn với các cấp từ thấp đến cao nhất ở các nhà mạng này, các nhà mạng lần lượt bỏ chặn DNS của TopDev. Tuy nhiên còn một vài nhà mạng nhỏ khác vẫn chưa truy cập được.

Đại diện của cả 3 nhà mạng đều thông báo với chúng tôi cùng một thông điệp: Domain topdev.vn bị chặn do cơ quan bên “trên” gửi xuống. Chúng tôi thực sự không hiểu, không biết chuyện gì đã xảy ra.

Chúng tôi xin khẳng định, lỗi hoàn toàn không thuộc về các nhà mạng bởi danh sách từ “trên” đưa xuống bảo chặn thì họ phải chặn.

Lỗi cũng không thuộc về cơ quan quản lý hoặc lãnh đạo của cơ quan, vì không thể đi chặn vô cớ tên miền .VN, được khai báo pháp lý rõ ràng và đóng thuế đầy đủ. Điều đáng nói ở đây, topdev.vn là một website về tuyển dụng, nội dung hoàn toàn là các việc làm IT cho giới lập trình viên, được đăng lên bởi các doanh nghiệp công nghệ đang hoạt động hợp pháp. Chúng tôi kết nối hàng nghìn việc làm tốt cũng như là giúp các công ty công nghệ giải quyết được nhu cầu nhân lực của họ.

Chỉ cần vài giây lướt qua nội dung site đã có thể khẳng định nội dung hoàn toàn sạch sẽ của topdev.vn. Để rộng đường soi sét việc TopDev bị chặn là một điều vô cùng phi lý, chúng tôi xin chia sẻ, tuy hơi dài dòng, những chứng cứ xác thực được về chúng tôi như sau:

  • Chúng tôi đã nhận được sự công nhận của chính phủ Phần Lan và Việt Nam, bộ Khoa Học Công Nghệ thông qua chương trình IPP vì những đóng góp của mình. Để vào được chương trình này là một sự kiểm duyệt khắt khe minh bạch, vui lòng tham khảo reference letter ở cuối bài do đại diện bộ KHCN phát hành.

    Reference letter từ bộ KHCN
  • Bản thân topdev.vn đã hoàn thành tất cả các thủ tục để hoạt động hợp pháp bao gồm đăng ký Bộ Công Thương tại đây http://online.gov.vn/Home/WebDetails/24669, hiển thị đầy đủ giấy phép, mã số thuế, thông tin liên hệ và điều khoản sử dụng.
  • Chúng tôi là doanh nghiệp hoạt động hoàn toàn hợp pháp, đóng thuế đầy đủ, hoàn thành mọi nghĩa vụ với pháp luật, bằng chứng là nhận được giấy phép đầu tư nước ngoài sau quá trình kiểm duyệt gắt gao của cơ quan chính phủ, cũng như kiểm toán của nhà đầu tư, và quyết toán với cơ quan thuế https://vnexpress.net/mang-tuyen-dung-it-viet-nam-nhan-dau-tu-tu-han-quoc-4056530.html
  • Chúng tôi trực tiếp mang về nhiều triệu đô la ngoại tệ cho đất nước từ vốn đầu tư nước ngoài cũng như là doanh thu trong và ngoài nước, doanh thu sạch, nội dung sạch, không sex, không phim lậu, không lừa đảo.
  • TopDev.vn là đầu mối thông tin về nhân lực ngành IT uy tín của trong và ngoài nước trong những năm gần đây, được hầu hết các báo lớn nhỏ tại Việt Nam trích dẫn lại các số liệu nghiên cứu thị trường được public tại đây https://topdev.vn/page/bao-cao-it-viet-nam, thậm chí được các báo nước ngoài và đặc biệt là BIG4 hỏi xin số liệu, hình tham khảo cuối bài.

Sẽ còn quỹ đầu tư nào dám đầu tư vào các startup Việt Nam khi thấy rằng, một ngày nào đó, bỗng dưng khoản đầu tư của họ biến thành mây khói chỉ vì startup bị chặn bởi chẳng có một nguyên nhân hay lý do gì?

Nhà đầu tư nào sẽ dám đầu tư vào startup tại VN khi thấy rằng, kể cả bạn có trong sạch, hoàn thành nghĩa vụ thuế, tạo ra nhiều việc làm, thì vẫn có nguy cơ bị chặn không rõ lý do mặc dùng tên tuổi địa chỉ công ty rõ ràng mà không có một văn bản chính thức nào.

Một doanh nghiệp kinh doanh chân chính, vượt qua và tồn tại, chưa sa thải hay giảm lương của bất kỳ nhân viên nào sau mùa dịch Corona dù 30 triệu người mất việc.

Chúng tôi tin rằng, dù cho các nhà mạng đã gỡ chặn, thì gốc rễ của vấn đề vẫn nằm ở đó. Nếu không giải quyết tận gốc, nó vẫn sẽ sẵn sàng diễn ra với chúng tôi một lần nữa, bằng một công văn khác.

Chọn sếp tốt hay công ty tốt? – Đâu là nước đi đúng đắn?

Những câu chuyện chốn văn phòng có nhiều điều thú vị, đặc biệt là câu chuyện xoay quanh vấn đề sếp và công ty. Nhiều người trẻ đã đi làm họ luôn băn khoăn rằng nên lựa chọn giữa việc làm việc cho một người sếp tệ ở một công ty tốt, hay ngược lại, đồng hành cùng một vị sếp tốt trong một công ty với nhiều tồn đọng?

Vậy theo bạn đâu là phương án tốt nhất? Sự cân đo đong đếm là điều cần thiết phải có vì nó ảnh hưởng lớn đến sự nghiệp phát triển của bạn. Với bài viết sau đây, TopDev sẽ chia sẻ những quan điểm cụ thể về vấn đề này.

Nếu ví diễn tiến hành trình tương lai của bạn là một thước phim thực tế thì cách bạn lựa chọn không khác gì việc bạn đang tìm kiếm một kịch bản phù hợp cho mình. Và theo quan điểm mà bài viết này thì chắc chắn rằng dù có bất cứ điều gì xảy ra, bạn cần phải lựa chọn một công ty tốt hơn là một người sếp tốt.

Kịch bản 1: Hãy quan tâm đến những trải nghiệm, đừng chỉ đánh giá một chiều từ sếp

Ở một công ty tốt, không sớm thì muộn, các nhà lãnh đạo nhân sự tài năng sẽ nhận ra được ai có đủ tố chất thật sự để tự hoàn thiện năng lực chuyên môn, quản lý, đồng thời có thúc đẩy sự phát triển của nhân viên mình. Từ đó, những vị sếp có uy quyền và sức nặng “tạm thời” sẽ bị loại bỏ. Tuy nhiên, việc này có thể mất thời gian đến vài tháng, một năm, một vài năm hoặc hơn thế nữa.

Trong cái rủi có may, việc bạn chấp nhận làm việc và không ngừng nỗ lực dưới sự phù phiếm (nếu có) của một người sếp không tốt sẽ giúp bạn được người khác đánh giá cao. Ở đây không đơn thuần là thể hiện sự chịu đựng, việc bạn cố gắng làm việc cho dù người sếp đó luôn áp đặt nhiều thứ chứng tỏ bạn đặt lợi ích chung là mối quan tâm hàng đầu và điều này rất quan trọng.

Dù thế nào, bạn chỉ cần nghĩ đơn giản, cuộc sống này vốn dĩ không mấy dễ dàng và việc “sống chung” với một người sếp tính khí thất thường, thiếu những phẩm chất về chuyên môn cũng không phải là điều tồi tệ nhất mà bạn gặp phải.

Có thể bạn không quá xuất sắc để được thăng chức khi sự thật về người cấp trên của bạn bị phơi bày nhưng với những nỗ lực, bạn xứng đáng có được một người sếp, người quản lý tốt hơn hoặc ít ra, bạn cũng được sắp xếp đến một phòng ban phù hợp khác tốt hơn.

Một điểm cực kỳ quan trọng mà các bạn đáng phải lưu tâm đó là hãy quan tâm đến những trải nghiệm cá nhân, đừng chỉ mãi lấy sếp ra làm thước đo mức độ đồng hành. 

chọn sếp

Đối với bạn hiện tại, thì bất kỳ một trải nghiệm nào trong công ty cũng thật sự  cần thiết. Từ những người đồng nghiệp, môi trường – văn hóa doanh nghiệp, mức độ/chỉ số danh tiếng tổ chức, các phúc lợi,..Tất cả là những giá trị bạn cần quan tâm nhiều hơn. Và nếu may mắn có được một tấm vé đặt chân vào một công ty tốt như thế thì bạn nên trân trọng và cố gắng nhiều hơn. Không có điều gì là thừa cả, công ty tốt sẽ tạo điều kiện tốt để bạn phát triển khả năng của mình.

Kịch bản 2: Sếp tốt nhưng liệu có đủ hay chưa?

Ai mà không mong muốn mình có một người sếp tốt. Những người sếp tốt sẽ biết cách hỗ trợ nhân viên phát triển một cách toàn diện hơn, giúp họ có những trải nghiệm thú vị nhất trong suốt quá trình làm việc. Có nhiều người sếp lại rất tâm lý, thấu hiểu và biết cách chia sẻ với nhân viên. Họ gần gũi và không khác gì những người anh chị lớn trong gia đình. Việc may mắn được theo dõi và đồng hành cùng một người sếp tốt, bạn sẽ có động lực nhiều hơn trong công việc và cả một phần của cuộc sống. 

Thế nhưng, bạn có biết không? Nhiều vị sếp tốt cuối cùng đều ra đi. Lý do có thể là việc họ được thăng chức, nghỉ việc hoặc tương tự như bạn, vì họ giỏi và được tín nhiệm nên được chuyển đi và nhận những trách nhiệm khác cao. Có được một người sếp tốt là may mắn và biết đâu họ cũng hạnh phúc khi những nhân viên của mình có năng lực thật sự. Tuy vậy, khả năng đồng hành lâu dài chưa thể xác định vì những sự việc bất ngờ có thể xảy đến.

  Rời bỏ công việc tại các doanh nghiệp nhỏ - Nguyên nhân và giải pháp

chọn sếp

Có thể bạn không nhận ra được một sự thật là, những vị sếp tốt khi họ làm việc trong các công ty yếu kém, họ còn phải đối mặt với rất nhiều thách thức.

Một trong những thách thức lớn nhất của họ chính là “bảo vệ” những nhân viên của mình trước những vấn đề lớn hơn của công ty. Điều này đôi khi có thể trở nên nặng nề quá sức với họ, họ mệt mỏi và một khi tiếng nói trở nên yếu thế, họ nhận thấy mình chưa hoàn thành một phần trách nhiệm nên có thể sẽ quyết định dừng lại. Chúng ta khó có thể nói trước được bất kỳ điều gì vì mọi thứ xung quanh đều khó đoán. Chỉ biết rằng, nếu là một người sếp tốt, họ sẽ chịu nhiều áp lực và một mình họ không thể nào chấp vá được những “lỗ hỏng” – một đặc thù riêng mà bất cứ doanh nghiệp nào cũng luôn tồn tại.

Chung quy lại, cái cảm giác mà mỗi nhân viên nhận thấy khi được dẫn dắt bởi một người sếp tốt chỉ mang tính chất nhất thời. Những người giỏi cứ dần rời đi và bệ phóng phát triển của công ty thì vẫn vậy – vẫn tệ và yếu kém. Tất nhiên, bạn cũng chẳng thể làm gì để thay thế được điều đó cả. Lúc đó, bạn lại hoang mang, rơi vào khoảng lặng với nhiều nỗi lo khác nhau khiến bạn mắc kẹt và không biết mình phải giải quyết như thế nào. Liệu bạn sẽ tiếp tục làm việc tại một công ty với nhiều lời đồn thổi hay rời đi để thử sức chinh phục một công ty khác. Và liệu lúc đó, còn kịp không, tất cả đều bắt nguồn từ sự lựa chọn ban đầu của bạn.

Hãy là người thông minh trong việc lựa chọn những lợi ích

Xét về sự đồng hành ngắn hạn, việc bạn lựa chọn làm việc cho một vị sếp tệ, dù được làm việc ở một doanh nghiệp với quy mô phát triển tốt, thì bạn sẽ luôn rơi vào guồng quay của những áp lực. Nhưng khi xét về khả năng dài hạn, khi người sếp tốt ấy rời đi, thì ít nhất bạn vẫn có những cơ hội riêng để bản thân bước tiếp.

Tại sao “Hãy hết mình theo đuổi đam mê” là một lời khuyên tồi?

Dĩ nhiên, khi bạn làm việc cho một vị sếp tốt trong quảng thời gian ngắn, bạn sẽ rất vui, dù cho rằng mọi thứ trong công ty đang dần có xu hướng sụp đổ dần. Ngược lại, khi đồng hành dài hạn dài hạn, liệu sự vui vẻ và hạnh phúc ấy có còn tồn tại hay không? Sếp ra đi trong khi công ty đó bản chất là có nhiều “sạn” trong công tác tổ chức, quản lý đào tạo và phát triển. Sau đó, bạn lại rơi vào trạng thái phải chạy đua để tìm kiếm cơ hội hoặc phải chấp nhận từ bỏ vì không thể chịu đựng được sức ép quá lớn từ những ánh mắt soi mói, phản ánh từ dư luận về công ty của mình.

Điều đó cho thấy, sự lựa chọn của bạn quyết định những gì bạn sẽ đối mặt sau này. Hãy thật thông minh trong việc lựa chọn những lợi ích để không phải tiếc nuối bất cứ điều gì.

Lời kết

Mỗi cá nhân đều có cho những lối suy nghĩ riêng về vấn đề này. Vì vậy, hãy suy nghĩ thật thấu đáo để có những quyết định thật thông minh. Trước khi trở thành một nhân viên giỏi có thể tạo ra giá trị vật chất, tinh thần của cá nhân hay đóng góp cho sự phát triển chung cho doanh nghiệp, bạn cần có một sự quyết định sáng suốt. TopDev chúc bạn sẽ vững tin để sớm gặt hái được thành công trên con đường mà mình đã lựa chọn.

Có thể bạn quan tâm:

Xem thêm Jobs IT for Developers hàng đầu tại TopDev

Tìm hiểu về giải thuật: Một số phương pháp sắp xếp cơ bản

Bài viết được sự cho phép của BBT Tạp chí Lập trình

  Cấu trúc dữ liệu và giải thuật - Thuật toán tìm kiếm
  Kỹ Thuật Phân Tích Giải Thuật

1. Sắp xếp kiểu lựa chọn (Selection Sort)

Một trong những phương pháp đơn giản nhất để thực hiện sắp xếp một bảng khóa là dựa trên phép lựa chọn.

Nguyên tắc cơ bản của phương pháp sắp xếp này là “ở lượt thứ i(i=1,2,…,n) ta sẽ chọn trong dãy khoá Ki, Ki+1,…,Kn khoá nhỏ nhất và đổi chỗ nó với Ki ”.

Như vậy thì rõ ràng là sau j lượt, j khoá nhỏ hơn đã lần lượt ở các vị trí thứ nhất, thứ hai,…, thứ j theo đúng thứ tự sắp xếp. Ví dụ:

Sắp xếp dãy số sau theo thứ tự tăng dần: “42, 23, 74, 11, 65, 58, 94, 36, 99, 87”.

Sau đây là giải thuật:

Cho dãy khóa K gồm n phần tử. Giải thuật này thực hiện sắp xếp các phần tử của K theo thứ tự tăng dần dựa vào phép chọn phần tử nhỏ nhất trong mỗi lượt.

Procedure SELECT-SORT(K, n)
For i:=1 to n-1 do
     Begin
         M:=i;
         For j:=i+1 to n do
         If K[j]<K[m] then m:=j;
             If m!= j then
             Begin {đổi chỗ}
                 X:=K[i];
                 K[i]:=K[m];
                 K[m]:=X;
             End
     End
Return;

2. Sắp xếp chèn (Insertion Sort)

Nguyên tắc sắp xếp ở đây dựa theo kinh nghiệm của những người chơi bài. Khi có i-1 lá bài đã được sắp xếp ở trên tay, nay rút thêm lá bài thứ i nữa thì sắp xếp lại như thế nào ? Có thể so sánh lá bài mới lần lượt với lá bài thứ (i-1), thứ (i-2)… để tìm ra chỗ thích hợp và chèn nó vào chỗ đó.

Dựa trên nguyên tắc này, có thể triển khai một cách sắp xếp như sau:

Thoạt đầu K1 được coi như bảng chỉ gồm có một khoá đã sắp xếp. Xét thêm K2, so sánh nó với K1 để xác định chỗ chèn nó vào, sau đó ta sẽ có một bảng gồm 2 khoá đã được sắp xếp. Đối với K3 lại so sánh với K2, K1 và cứ tương tự như vậy với K4, K5, K6,… cuối cùng sau khi xét xong Kn thì bảng khoá đã được sắp xếp hoàn toàn.

Ta thấy ngay phương pháp này rất thuận lợi khi các khoá của dãy được đưa dần vào miền lưu trữ. Đó cũng chính là không gian nhớ dùng để sắp xếp. Có thể minh hoạ qua bảng sau:

Nhưng nếu các khóa đã có mặt ở bộ nhớ trong trước lúc sắp xếp rồi thì sao ?

Sắp xếp vẫn có thể thực hiện được ngay tại chỗ chứ không phải chuyển sang một miền sắp xếp khác. Lúc đó các khoá cũng lần lượt được xét tới và việc xác định chỗ cho khoá mới vẫn làm tương tự, chỉ có khác là: để dành chỗ cho khoá mới nghĩa là phải dịch chuyển một số khoá lùi lại sau, ta không có sẵn chỗ trống như trường hợp nói trên (vì khoá đang xét và các khoá sẽ được xét đã chiếm các vị trí đằng sau này rồi), do đó phải đưa khoá mới này ra một chỗ nhớ phụ và sẽ đưa vào vị trí thực của nó sau khi đã đẩy các khóa cần thiết lùi lại.

Sau đây là giải thuật ứng với trường hợp này:

Procedure SELECT-SORT(K, n)
For i:=1 to n-1 do
     Begin
         M:=i;
         For j:=i+1 to n do
         If K[j]<K[m] then m:=j;
             If m!= j then
             Begin {đổi chỗ}
                 X:=K[i];
                 K[i]:=K[m];
                 K[m]:=X;
             End
     End
Return;

{Trong thủ tục này người ta dùng X làm ô nhớ phụ để chứa khoá mới đang được xét. Để đảm bảo cho khoá mới trong mọi trường hợp, ngay cả khi vị trí thực của nó là vị trí đầu tiên, đều được chèn vào giữa khóa nhỏ hơn nó và khoá lớn hơn nó, ở đây đưa thêm vào một khoá giả K0, có giá trị nhỏ hơn mọi khoá của bảng, và đứng trước mọi khoá đó. Ta quy ước K0 = – }.

Procedure SELECT-SORT(K, n)
For i:=1 to n-1 do
     Begin
         M:=i;
         For j:=i+1 to n do
         If K[j]<K[m] then m:=j;
             If m!= j then
             Begin {đổi chỗ}
                 X:=K[i];
                 K[i]:=K[m];
                 K[m]:=X;
             End
     End
Return;

{xác định chỗ cho khoá mới được xét và dịch chuyển các khóa cần thiết }

Procedure SELECT-SORT(K, n)
For i:=1 to n-1 do
     Begin
         M:=i;
         For j:=i+1 to n do
         If K[j]<K[m] then m:=j;
             If m!= j then
             Begin {đổi chỗ}
                 X:=K[i];
                 K[i]:=K[m];
                 K[m]:=X;
             End
     End
Return;

{đưa X vào đúng chỗ}

Procedure SELECT-SORT(K, n)
For i:=1 to n-1 do
     Begin
         M:=i;
         For j:=i+1 to n do
         If K[j]<K[m] then m:=j;
             If m!= j then
             Begin {đổi chỗ}
                 X:=K[i];
                 K[i]:=K[m];
                 K[m]:=X;
             End
     End
Return;

Bảng ví dụ minh hoạ tương ứng với các lượt sắp xếp theo giải thuật này, tương tự như bảng đã nêu ở trên, chỉ có khác là không có chỗ nào trống trong miền sắp xếp cả, vì những chỗ đó đang chứa các khoá chưa được xét tới trong mỗi lượt (người đọc có thể tự lập ra bảng minh hoạ này).

3. Sắp xếp kiểu đổi chỗ (exchange sort)

Trong các phương pháp sắp xếp nêu trên, tuy kĩ thuật đổi chỗ đã được sử dụng, nhưng nó chưa trở thành một đặc điểm nổi bật. Bây giờ ta mới xét tới phương pháp mà việc đổi chỗ một cặp khoá kế cận, khi chúng ngược thứ tự, sẽ được thực hiện thường xuyên cho tới khi toàn bộ bảng các khóa đã được sắp xếp. Ý cơ bản có thể nêu như sau:

Bảng các khóa sẽ được duyệt từ đáy lên đỉnh. Dọc đường, nếu gặp hai khoá kế cận ngược thứ tự thì đổi chỗ chúng cho nhau. Như vậy trong lượt đầu khoá có giá trị nhỏ nhất sẽ chuyển dần lên đỉnh. Đến lượt thứ hai khoá có giá trị nhỏ thứ hai sẽ được chuyển lên vị trí thứ hai… Nếu hình dung dãy khoá được đặt thẳng đứng thì sau từng lượt sắp xếp, các giá trị khoá nhỏ sẽ nổi dần lên giống như các bọt nước nổi lên trong nồi nước đang sôi. Vì vậy phương pháp này thường được gọi bằng cái tên khá đặc trưng là: sắp xếp kiểu nổi bọt (bubble sort).

Ví dụ:

Sau đây là giải thuật:

Procedure SELECT-SORT(K, n)
For i:=1 to n-1 do
     Begin
         M:=i;
         For j:=i+1 to n do
         If K[j]<K[m] then m:=j;
             If m!= j then
             Begin {đổi chỗ}
                 X:=K[i];
                 K[i]:=K[m];
                 K[m]:=X;
             End
     End
Return;

Giải thuật này rõ ràng còn có thể cải tiến được nhiều. Chẳng hạn, xét qua ví dụ ở trên ta thấy: sau lượt thứ 3 không phải chỉ có ba khóa 11, 23, 36 vào đúng vị trí sắp xếp của nó mà là 5 khoá. Còn sau lượt thứ 4 thì tất cả các khóa đã nằm đúng vào vị trí của nó rồi. Như vậy nghĩa là năm lượt cuối không có tác dụng gì thêm cả. Từ đó có thể thấy: nếu nhớ được vị trí của khoá được đổi chỗ cuối cùng ở mỗi lượt thì có thể coi đó là giới hạn cho việc xem xét ở lượt sau. Chừng nào mà giới hạn này chính là vị trí thứ n, nghĩa là trong lượt ấy không có một phép đổi chỗ nào nữa thì sắp xếp có thể kết thúc được. Nhận xét này sẽ dẫn tới một giải thuật cải tiến hơn, chắc chắn có thể làm cho số lượt giảm đi và số lượng các phép so sánh trong mỗi lượt cũng giảm đi nữa. Người đọc hãy tự xây dựng giải thuật theo ý cải tiến này.

 (Nguồn: Cấu trúc dữ liệu và giải thuât –

Đỗ Xuân Lôi – NXB Đại học quốc gia Hà Nội).

Bài viết gốc được đăng tải tại Tạp Chí Lập Trình

Có thể bạn quan tâm:

Xem thêm các IT Jobs hấp dẫn tại TopDev

SSH: Sơ lược, một số câu lệnh cơ bản (Phần 1)

Khi sử dụng một hệ điều hànhWindows, MacOS, đặc biệt là các hệ điều hành dựa trên nhân Linux như Ubuntu, CentOS,… bạn chắc hẳn đã từng sử dụng terminal để gõ các dòng lệnh cực kỳ ngầu lòi. Tới một ngày, bạn có một con server vừa mua nằm cách xa tận nửa vòng trái đất, làm thế nào bạn có thể truy cập tới và thực thi các câu lệnh, cài đặt các dịch vụ, cấu hình web server,…? Kèm theo đó là việc đảm bảo một kết nối thật an toàn ? SSH chính là thứ mà bạn đang tìm kiếm.

  Cấu hình SSH Key cho Github
  SSH: Sơ lược, một số câu lệnh cơ bản (Phần 1)
Tìm hiểu LDAP, cấu hình xác thực SSH với LDAP”]

1. Sơ lược

Secure Shell (SSH) là một giao thức mạng dùng để thiết lập kết nối mạng một cách bảo mật. SSH tạo ra một kênh kết nối được mã hóa an toàn từ một mạng không an toàn, dựa trên kiến trúc client-server, kết nối 1 SSH-client tới một SSH-server. Port mặc định đuợc sử dụng bởi SSH là 22.

Hay nói đơn giản, SSH giúp bạn có thể yên tâm truy cập tới một máy tính từ xa nhờ vào tính bảo mật của nó !

SSH ra đời như một sự thay thế cho Telnet và các giao thức điều khiển shell thiếu an toàn khác như Berkeley rsh, login và rexec . Các giao thức này trao đổi dữ liệu, mật khẩu dưới dạng plaintext, khiến chúng rất dễ bị phân tích và đánh cắp.

Điểm đặc biệt của SSH là giao thức này sử dụng các thuật toán mã hóa bất đối xứng, đối xứng và hashing để đảm bảo tính bảo mật và toàn vẹn của dữ liệu được trao đổi từ client tới server và ngược lại.

SSH có nhiều cách để xác thực một người dùng, nhưng hai cách thông dụng nhất vẫn là xác thực dựa trên mật khẩu và xác thực public-key.

Xác thực bằng mật khẩu ?

Xác thực dựa trên mật khẩu đơn giản là bạn chỉ việc sử dụng mật khẩu của user bạn tạo để truy cập, server sẽ lưu chúng, và đối chiếu với mật khẩu của bạn khi đăng nhập. Cách này thì không đủ an toàn do bạn có khả năng bị đánh cắp mật khẩu.

Còn xác thực bằng public-key?

Cách này sử dụng một cặp khóa – public-key và private-key – được tạo ra dựa trên thuật toán mã hóa public-key. Cặp khóa sau khi được tạo ra từ một máy tính, ta sẽ lấy public-key lưu vào server, khi truy cập ta sẽ dựa vào private-key lưu trên máy local và đặc tính liên quan mật thiết tới nhau của chúng để thiết lập kết nối. Kiểu xác thực này còn cho cho phép chúng ta thiết lập một kết nối an toàn một cách tự động hóa (automation).

Mô hình đơn giản cách hoạt động (Thực tế có thể phức tạp hơn)Mô hình đơn giản cách hoạt động (thực tế có thể phức tạp hơn).

Vậy thì nó hơn xác thực với mật khẩu chỗ nào ?

Quay lại khi bạn sử dụng mật khẩu, bản năng loài người của bạn trỗi dậy, trí nhớ của chúng ta là có hạn, và bạn sẽ nghĩ ra một mật khẩu sao cho dễ ghi nhớ. Và mật khẩu dễ nhớ thì khả năng cao là bạn sẽ bị đánh cắp bằng một cách nào đó (Brute-force attack, Dictionary attack,… ).

Không những vậy, mật khẩu này còn được bạn sử dụng xuyên suốt từ app này sang app khác ! Nó còn được lưu trên cả server bạn login vào, nên vẫn có thể bị đánh cắp (Man-in-the-middle attack,…). Và rất rất nhiều trường hợp cho thấy việc sử dụng mật khẩu là thiếu an toàn như thế nào.

Còn cặp khóa xác thực thì lại được tạo ra bởi máy tính, máy tính thì không như con người, máy tính sử dụng các thuật toán mã hóa cực kì phức tạp, vượt xa khả năng của con người, để sinh ra khóa. Bản thân các khóa này thì lại vừa dài (vài trăm, vài nghìn bits), vừa to… à không, vừa phức tạp và rất khó để brute-force attack. Hơn nữa, private-key mà bạn giữ không hề được gửi tới server mà bạn chỉ dùng nó để decrypt message được mã hóa từ server gửi về.

Mật khẩu có thể được sử dụng trên nhiều máy khác nhau và do bạn tự lưu trữ, còn private-key thì chỉ được lưu trên thiết bị mà bạn dùng để truy cập, dó đó bạn có thể sử dụng nhiều cặp khóa public-key private-key để truy cập vào các máy tính khác nhau, làm giảm khả năng bị đánh cắp khóa.

Ngoài ra, bạn còn có thể sử dụng thêm passphrase để tăng thêm độ bảo mật !

Các loại thuật toán mã hóa

SSH hỗ trợ nhiều loại thuật toán mã hóa public-key:

  • rsa – thuật toán được sử dụng nhiều nhất, ra đời từ năm 1977 dựa trên sự phức tạp của việc phân tích thừa số nguyên tố. Khi sử dụng nên kèm theo kích thước của khóa ít nhất là 2048 bits, tốt nhất nên là 4096 bits.
  • dsa -thuật toán dựa trên tính phức tạp của việc tính toán logarit rời rạc. Đã bị loại bỏ ở OpenSSH version 7 vì lý do bảo mật.
  • ecdsa – thuật toán dựa trên toạ độ của các điểm dựa trên đường cong Elliptic. Có thể thay thế cho RSA bởi mức an toàn và tốc độ xử lý cao hơn, kèm theo đó là việc sử dụng khoá có độ dài nhỏ hơn so với RSA. Từ đó làm tăng tốc độ xử lý một cách đáng kể. Chỉ hỗ trợ với 3 loại kích thước khóa: 256, 384, and 521 bits. Để an toàn nhất thì nên sử dụng 521 bits !
  • ed25519 – một thuật toán được thêm vào OpenSSH từ version 6.5. Là bản cải tiến của ECDSA, cung cấp bảo khả năng mật tốt hơn với hiệu suất nhanh hơn so với DSA hoặc ECDSA. Chưa thực sự phổ cập trên toàn thế giới.

2. Các câu lệnh cơ bản

Lưu ý: Các câu lệnh ta sẽ thực hiện máy tính cài hệ điều hành Linux (Ubuntu, CentOS,…).

Sau đây, chúng ta sẽ đi vào chi tiết những câu lệnh sẽ sử dụng để kết nối với một server từ xa.

Sử dụng SSH để login với password

Trên máy local của bạn:

ssh your-username@host

Ví dụ:

ssh thong@192.168.58.20

Host ở đây có thể là địa chỉ ip hoặc domain name của máy mà bạn truy cập tới

Sau đó nhập mật khẩu tương ứng với user của bạn ở host đó.

Tạo cặp khóa

Câu lệnh để tạo ra một cặp khóa xác thực SSH.

Câu lệnh đơn giản nhất, trên máy local:

ssh-keygen

Trong lúc generate, hệ thống sẽ yêu cầu bạn cung cấp passphrase. Mục đích sinh ra passphrase là để encrypt private key. Vậy khi một kẻ tấn công biết được private key của bạn cũng chưa chắc có thể sử dụng, vì nó đã bị mã hóa.

Trong thực tế, hầu hết khi tạo khóa SSH người ta thường không sử dụng thêm passphrase. Vì khi gặp vấn đề liên quan tới automation, passphrase này đâu thể đánh bằng tay mà ta phải lưu trong một kho lưu trữ hoặc là trong một đoạn script nào đó. Kết quả là bạn lại quay về xác thực bằng mật khẩu (lol !), kẻ tấn công vẫn có thể biết được passphrase của bạn !

Vậy nên để dễ dàng và thuận tiện bạn cứ nhấn Enter khi tới bước này là được !

Bạn có thể tùy chỉnh thêm các options:

ssh-keygen -f ~/key-name -t ecdsa -b 521

Trong đó:

-f là key name và nơi sẽ lưu trữ key

-t là thuật toán mã hóa để sinh khóa

-b là kích thước khóa

Thêm private-key vào SSH-agent

Trên máy local:

ssh-add /PATH/TO/YOUR/PRIVATE/KEY

ssh-add là câu lệnh để thêm SSH private-keys vào SSH authentication agent, gọi là ssh-agent để quản lý việc truy cập vào các máy tính sử dụng các khóa private. Khi bạn đã thêm khóa vào ssh-agent thì lúc truy cập bạn không cần phải khai báo thêm khóa này.

Phần public của khóa private được lưu vào ssh-agent phải được đặt trong

~/.ssh/authorized_keys (authorized_keys là một file)

ở server (Xem bước bên dưới).

Thêm public-key vào server

Bạn có thể sử dụng một trong hai câu lệnh sau:

Cách 1:

cat ~/.ssh/your-key.pub | ssh username@host "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys"

Cách 2:

ssh-copy-id -i ~/.ssh/your-key.pub username@host

Ngoài ra bạn có thể truy cập trực tiếp vào máy bằng password trước và sau đó thêm key bằng cơm (mkdir, touch, rồi sau đó cat, vim…).

Vậy là bạn đã có thể truy cập vào server thành công sử dụng xác thực khóa trên SSH !

Bạn có cũng thể thêm nhiều key khác nhau vào authorized_keys sử dụng các câu lệnh tương tự như trên.

Test nào:

ssh your-username@host

Loại bỏ xác thực bằng mật khẩu trên server (Chỉ sử dụng SSH keys)

Lưu ý: Chỉ làm bước này sau khi bạn đã cấu hình và thực hiện ssh bằng khóa.

Để tốt nhất và an toàn nhất thì sau khi thêm key vào server, bạn nên loại bỏ xác thực SSH bằng mật khẩu. Lý do thì tôi đã đề cập như trên !

Trên server:

sudo nano /etc/ssh/sshd_config

Tìm dòng

PermitRootLogin yes

Sửa lại thành

PermitRootLogin no

Lưu lại và exit. Sau đó trên terminal:

sudo systemctl restart sshd

3. Kết

Vậy là ta đã đi qua sơ lược về SSH và các câu lệnh cơ bản để thiết lập kết nối giữa hai máy tính. Ở phần sau tôi sẽ đưa ra một vài ví dụ thực tế để bạn có cái nhìn rõ hơn về nó. Cảm ơn các bạn đã theo dõi !

Bài viết gốc được đăng tải tại SIRDEV

Có thể bạn quan tâm:

Xem thêm các việc làm IT Jobs Developer hấp dẫn tại TopDev

Giới thiệu Fetch API trong Javascript

Bài viết được sự cho phép của tác giả Lưu Bình An

fetch() cho phép tạo một network request tương tự như XMLHttpRequest(XHR). Sự khác nhau chủ yếu là Fetch hoạt động theo Promises, cho phép viết gọn ràng, dễ nhớ hơn là XHR. API Fetch có trong window.fetch() giờ đã được hỗ trợ phổ biến, bạn không cần polyfill gì đâu, vĩnh biệt IE. Tạm biệt XMLHttpRequest và cách viết dài dòng, giờ đây ta đã có fetch API.

Fetch API là gì?

Fetch API là một giao diện lập trình trong JavaScript, được sử dụng để thực hiện các yêu cầu HTTP đến các máy chủ web. Đây là một phần của tiêu chuẩn JavaScript ES6 và được tích hợp trực tiếp trong các trình duyệt hiện đại. Fetch JS cung cấp một cách thức đơn giản và mạnh mẽ để thực hiện các thao tác lấy dữ liệu (fetch) từ các nguồn bên ngoài, ví dụ như lấy dữ liệu từ máy chủ hoặc API, đồng thời hỗ trợ các thao tác như GET, POST, PUT, DELETE, v.v.

Điểm mạnh của Fetch fetch Javascript API là nó thay thế cho công nghệ cũ hơn là XMLHttpRequest và cung cấp cú pháp hứa hẹn (Promise-based), giúp lập trình viên quản lý các yêu cầu bất đồng bộ (asynchronous) dễ dàng hơn.

Fetch trong JS sử dụng cú pháp Promise, có nghĩa là nó không chặn (non-blocking), cho phép xử lý các yêu cầu và phản hồi mà không cần phải dừng các thao tác khác của chương trình. Khi thực hiện một yêu cầu HTTP thông qua Fetch API, nó trả về một Promise, và bạn có thể xử lý kết quả của yêu cầu bằng cách sử dụng .then().catch().

Một câu request network bằng fetch

fetch('/api/some-url')
  .then(
    function(response) {
      if (response.status !== 200) {
        console.log('Lỗi, mã lỗi ' + response.status);
        return;
      }
      // parse response data
      response.json().then(data => {
        console.log(data);
      })
    }
  )
  .catch(err => {
    console.log('Error :-S', err)
  });

Response của câu fetch() là một đối tượng Stream, nghĩa là khi chúng ta gọi phương thức json(), một Promise được trả về, vì quá trình đọc stream sẽ diễn ra bất đồng bộ.

  9+ cách để xóa một phần tử ra khỏi JavaScript Array

Response MetaData

Bên cạnh các dữ liệu chúng ta có thể truy cập như trong ví dụ trên, chúng ta có thể truy cập đến các meta data khác

fetch('/api/some-url')
  .then(response => {
    console.log(response.headers.get('Content-Type'));
    console.log(response.headers.get('Date'));

    console.log(response.status);
    console.log(response.statusText);
    console.log(response.type);
    console.log(response.url)
  })

response.type

Khi chúng ta tạo một fetch request, response trả về sẽ chứa response.type, với một trong 3 giá trị: basiccorsopaque.

Nó cho biết resource này đến từ đâu, cho chúng ta biết cách chúng ta nên đối xử với object trả về

  • Nếu request lên cùng một nhà (ứng dụng host trên server A gửi request lên API trên server A), response.type sẽ là basic, không có bất kỳ giới hạn việc xem các thông tin trên response.
  • Nếu request dạng CORS, nhà em ở Hồ Chí Mình, em quen bạn gái Hà Nội, type trả về sẽ là cors.cors, lúc đó bên trong header chúng ta chỉ được phép truy cập đến Cache-ControlContent-LanguageContent-TypeExpiresLast-Modified và Pragma
  • Type opaque cho các request tạo ra khác nhà, và thằng server nó không chấp nhận dạng request CORS, ba má cấm chú quen gái Hà Nội, nghĩa là không trả về dữ liệu, không xem được status của request, chia tay tình yêu.

Để khai báo 1 fetch request chỉ resolve khi thỏa điều kiện mode

  • same-origin: các request nhà kế bên sẽ trả về reject
  • cors: cho phép nhà khác nếu header trả về cũng là cors
  • cors-with-forced-preflight luôn thực hiện kiểm tra preflight. Là trước khi gửi đi, để đảm bảo an toàn, tạo một request dùng phương thức OPTIONS để kiểm tra độ an toàn, (nhà anh có điều kiện ko mà đòi quen bạn gái tận Hà Nội xa xôi)
  • no-cors tạo một request không cùng nhà, không trả về CORS

Để khai báo mode

fetch('http://some-site.com/cors-enabled/some.json', {mode, 'cors'})
  .then(function(response) {
    return response.text();
  })
  .then(function(text) {
    console.log('Request successful', text);
  })
  .catch(function(error) {
    log('Request failed', error)
  });
  Crawl dữ liệu bằng JavaScript ngay trên trình duyệt

Liên kết Promise

Một trong những tính năng hay (và sinh ra rắc rối) của Promise là cho phép mắc-xích-các-Promise lại với nhau.

Khi làm việc với JSON API, chúng ta quan tâm đến status và parse JSON trả về, để đơn giản hóa, đưa phần xử lý kiểm tra status và parse này ra hàm riêng. Chúng ta chỉ lo xử lý kết quả cuối cùng và trường hợp có lỗi

function status(response) {
  if (response.status >= 200 && response.status < 300) {
    return Promise.resolve(response)
  } else {
    return Promise.reject(new Error(response.statusText))
  }
}
function json(response) {
  return response.json()
}

fetch('')
  .then(status)
  .then(json)
  .then(data => {
    console.log('Request succeeded with JSON response', data);
  })
  .catch(function(error) {
    console.log('Request failed', error);
  });

Xem thêm các việc làm JavaScript hấp dẫn tại TopDev

POST Request

Set giá trị method và body để tạo một POST request

fetch(url, {
  method: 'POST',
  headers: {
    "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8"
  },
  body: 'foo=bar&lorem=ipsum'
})
.then(json)
.then(data => {
  console.log('Request succeeded with JSON response', data);
})
.catch(error => {
  console.log('Request failed', error);
  });
})

Gửi lên dữ liệu dạng JSON

var data = {username: 'example'};

fetch(url, {
  method: 'POST', 
  body: JSON.stringify(data), 
  headers:{
    'Content-Type': 'application/json'
  }
})
.then(res => res.json())
.then(response => console.log('Success:', JSON.stringify(response)))
.catch(error => console.error('Error:', error))

Gửi thông tin xác thực với Fetch

Để gửi kèm thông tin xác thực cookie (user là ai), chúng ta truyền tham số credentials: include

fetch(url, {
  credentials: 'include'
})

Nếu muốn gửi credentials khi request URL là cùng nhà*, truyền giá trị same-origin

fetch(url, {
  crendentials: 'same-origin'
})Không cho

Không cho trình duyệt gửi thông tin xác thực, dùng omit

fetch(url, {
  crendentials: 'omit'
})

Upload file

Sử dụng cùng <input type='file' />FormData()

var formData = new FormData();
var fileField = document.querySelector("input[type='file']");

formData.append('username', 'abc123');
formData.append('avatar', fileField.files[0]);

fetch('https://example.com/profile/avatar', {
  method: 'PUT',
  body: formData
})
.then(response => response.json())
.then(response => console.log('Success:', JSON.stringify(response)));
.catch(error => console.error('Error:', error))

Upload nhiều file

var formData = new FormData();
var photos = document.querySelector("input[type='file'][multiple]");

formData.append('title', 'My Vegas Vacation');
formData.append('photos', photos.files);

fetch('https://example.com/posts', {
  method: 'POST',
  body: formData
})
.then(response => response.json())
.then(response => console.log('Success:', JSON.stringify(response)))
.catch(error => console.error('Error:', error));

Kết luận

Fetch API là một công cụ mạnh mẽ và hiện đại giúp các lập trình viên thực hiện các yêu cầu HTTP một cách đơn giản và hiệu quả. Với cú pháp dựa trên Promise, Fetch API Javascript giúp mã nguồn trở nên dễ đọc hơn và phù hợp với các ứng dụng JavaScript hiện đại. Khi xây dựng các ứng dụng web, đặc biệt là khi làm việc với API hoặc các dịch vụ bên ngoài, Fetch API JS là lựa chọn tối ưu để lấy dữ liệu hoặc gửi dữ liệu từ/đến máy chủ.

Link bài viết gốc

Có thể bạn quan tâm:

Xem thêm các việc làm IT hấp dẫn tại TopDev

Debug và khắc phục lỗi hiển thị ký tự Unicode của ứng dụng Web

Bài viết được sự cho phép của BBT Tạp chí Lập trình

Tác giả: Nguyễn Bình Sơn

Bài viết này ngầm định rằng bạn biết “bảng mã” nghĩa là gì, và bạn quen thuộc với các thành phần của mô hình ứng dụng web cũng như mô hình trình diễn MVC. Mặc dù mã ở đây được trình bày dưới dạng thức của ngôn ngữ Java, framework Spring MVC và database MySQL, các vấn đề được nhắc đến là chung, các khái niệm được nhắc đến là phổ biến, và các cách giải quyết là tổng quát. Hãy cùng tìm hiểu về Debug và khắc phục lỗi hiển thị ký tự Unicode của ứng dụng Web nhé!

  Debug và khắc phục lỗi hiển thị ký tự Unicode của ứng dụng Web
”]

  Một số tip debug trong Laravel

Model mang dữ liệu Unicode nhưng View thì không

Bạn có model như thế này.

Nhưng bạn nhận được kết quả như thế này:

Là vì View của bạn có nội dung như thế này:

CREATE DATABASE IF NOT EXISTS cms CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

Bạn cần làm cho view engine render cho bạn một view mà trong đó các ký tự unicode của template và model được bảo toàn. Ví dụ sau đây là cấu hình cho view engine Thymeleaf.

@Bean
public ViewResolver viewResolver() {
    // ...
    viewResolver.setCharacterEncoding("UTF-8");
    return viewResolver;
}

Template mang ký tự Unicode nhưng View thì không

Bạn có view template như thế này:

<tr>
  <td>Tên</td>
  <td>
    <input type="text" name="name" th:value="${customer.name}">
  </td>
</tr>
<tr>
  <td>Email</td>
  <td>
    <input type="text" name="email" th:value="${customer.email}">
  </td>
</tr>
<tr>
  <td>Địa chỉ</td>
  <td>
    <input type="text" name="address" th:value="${customer.address}">
  </td>
</tr>

Nhưng bạn nhận được view như thế này:

Nếu bạn đã xử lý vấn đề encoding trong lúc render như ở trên rồi, thì có thể vấn đề là do template resorver đã dùng một encoding khác để đọc tài liệu template. Hãy cấu hình lại cho cả template resolver nữa.

@Bean
public ITemplateResolver templateResolver() {
    // ...
    templateResolver.setCharacterEncoding("UTF-8");
    return templateResolver;
}

Không thể chuyển tải ký tự Unicode qua tầng giao vận

Giả sử cần submit form sau:

Tầng giao vận TCP/IP không quan tâm với bảng mã, nó đơn giản và vận chuyển gói tin, từng byte một. Phần lớn web server, trừ khi là web server do bạn tự viết, decode các bytes này để có các parametter theo lối như thể rằng các bytes đó trước kia là ký tự của bảng mã ISO-8859–1. Nếu bạn nhìn các ký tự đã được decode ra dưới con mắt của bảng mã UTF-8 (trớ trêu rằng, phần lớn các ngôn ngữ lập trình làm như thế), bạn sẽ nhận được kết quả không mong muốn.

Cách xử lý luôn luôn là encode chuỗi ký tự ngược lại thành dòng bytes (theo bảng mã ISO-8859–1, tất nhiên), và sau đó decode lại theo bảng mã UTF-8. Cho dù là thủ công như sau:

public String createCustomer(Customer customer) {
    try {
        byte[] bytes = customer.getName().getBytes("ISO-8859-1");
        String decodedName = new String(bytes, "UTF-8");
        customer.setName(decodedName);
        customerService.save(customer);
        return "redirect:/customers";
    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
        return "500";
    }
}

… hay tự động, bằng cách sử dụng filter, như sau chẳng hạn:

public class AppInit extends AbstractAnnotationConfigDispatcherServletInitializer {
    // ...    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
        FilterRegistration.Dynamic filterRegistration =
            servletContext.addFilter("endcoding-filter", new CharacterEncodingFilter());
        filterRegistration.setInitParameter("encoding", "UTF-8");
        filterRegistration.setInitParameter("forceEncoding", "true");
        
        //make sure encodingFilter is matched most first, by "false" arg
        filterRegistration.addMappingForUrlPatterns(null, false, "/*");
        
        super.onStartup(servletContext);
    }
}

Entity mang thông tin Unicode, vào đến Database thì mất dấu

Bạn có form như thế này:

Entity ngon nghẻ như thế này:

Vào tới database thì loạn cào cào hết cả:

Hầu hết các client của các dbms, khi kết nối tới dbms server, đều chọn mặc định một bảng mã để làm việc với nhau. “Mặc định” này đôi khi là một giá trị cố định, đôi khi là lấy dynamic. Dù là trường hợp nào đi chăng nữa, đôi khi charset đó hoàn toàn khác với charset được dùng cho Schema/Table/Column. Nghĩa là “anh nói tiếng của anh, nhưng tôi hiểu theo tiếng của tôi”.

Cách xử lý luôn là cố định lại bảng mã dùng trong cuộc nói chuyện giữa client và dbms server:

CREATE DATABASE IF NOT EXISTS cms CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

Và đồng thời (điều này rất quan trọng), sử dụng cùng một bảng mã đó cho Schema/Table/Column:

CREATE DATABASE IF NOT EXISTS cms CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

Nếu database cùng với dữ liệu đã tồn tại, theo một bảng mã khác, cách xử lý luôn là sử dụng một kỹ thuật nào đó được dbms hỗ trợ để convert dữ liệu từ bảng mã cũ sang bảng mã mong muốn.

Bài viết gốc được đăng tải tại Tạp Chí Lập Trình

Có thể bạn quan tâm:

Xem thêm các  IT Jobs for Developer hấp dẫn tại TopDev

Tìm việc làm IT mùa dịch không hề khó như bạn nghĩ

Tình hình doanh nghiệp

Tim viec lam mùa dịch là việc không hề dễ dàng vì dịch đã làm ảnh hưởng nặng nề rất nhiều đến việc kinh doanh của nhiều công ty, dù là thời điểm trong dịch hay hiện giờ thì cũng có khá nhiều công ty trong và ngoài nước cắt giảm nhân sự. Chính vì vậy, cơ hội tìm kiếm việc làm của người lao động thông thường khá khó khăn. Tuy nhiên đối với những ngành nghề đặc thù liên quan đến công nghệ như IT thì lại không bị ảnh hưởng quá nhiều, và các kỹ sư kỹ thuật có tỷ lệ % bị cắt giảm nhân sự rất thấp.

Doanh nghiệp về du lịch là bị ảnh hưởng nhiều nhất, rất nhiều công ty du lịch đóng cửa vì không có khách du lịch. Ngoài ra các ngày liên quan đến sản xuất như may mặc ở các xí nghiệp cũng bị ảnh hưởng nặng nề và buộc phải cắt giảm rất nhiều nhân viên

Dù là sau dịch như hiện tại thì nhu cầu tuyển dụng cũng không nhiều, rất nhiều công ty phải đóng băng hoặc phá sản, hàng quán thì trả mặt bằng, bán nhà trong khi đó nhu cầu tim viec lam thì lại tăng… Theo thống kê, gần 8 triệu người mất việc, nghỉ việc luân phiên do Covid-19, trong đó số người bị ảnh hưởng do giảm thu nhập lên tới hơn 17 triệu người. 

tim viec lam

Đó là tình hình không mấy lạc quan đối với những xí nghiệp sản xuất, tiêu thụ thông thường. Còn các ngành công nghiệp hiện đại có liên quan đến công nghệ thì vẫn có nhu cầu cấp thiết đối với nguồn lực công nghệ, từ duy trì cơ sở hạ tầng đám mây cho đến thiết kế các trang thương mại điện tử. Việc hạn chế những nơi đông người và tăng cường mua sắm trực tuyến khiến các doanh nghiệp chuyển đổi hành vi mua sắm tại điểm bán sang đẩy mạnh phát triển các nền tảng mua sắm online, dẫn đến nhu cầu tuyển dụng IT, lập trình viên hay các vị trí liên quan đến phát triển thương mại điện tử tăng cao. 

Lấy ví dụ như các vị trí lập trình viên như System Engineer, Developer hay Technical Product… đều đóng vai trò quan trọng trong các công ty Startup, công ty thiên về công nghệ, sàn thương mại điện tử, các vị trí đó được đăng tuyển khá nhiều để có thể hỗ trợ, điều chỉnh cho tình hình mua sắm tại nhà như hiện nay. 

Các kỹ sư công nghệ trở nên quan trọng hơn bao giờ hết khi Việt Nam và thế giới đang đối đầu với dịch bệnh. Ngành lập trình viên vẫn hoạt động và phát triển rất tốt như chưa hề có dịch Covid.

Không những thế, thậm chí trong tình hình dịch bệnh như thế này nhưng ngành lập trình vẫn còn đang thiếu hụt nhân sự vì nhu cầu nhân sự, nhu cầu tim viec lam của các lập trình viên thì vẫn có. Tuy nhiên, trong tình hình dịch ứng viên lại ngại các cuộc phỏng vấn trực tiếp sẽ là nguyên nhân gây lây nhiễm dịch bệnh. 

tim viec lam

Giải pháp tim viec lam mùa dịch

Vì để tránh tình trạng thiếu hụt nhân sự công nghệ, nhiều doanh nghiệp đưa ra giải pháp phỏng vấn online để có thể dễ dàng tiếp cận ứng viên hơn trong tình hình dịch bệnh như hiện nay. Ứng viên chỉ cần gửi so yeu ly lich kèm cv tiếng Việt hoặc cv tieng anh tùy vào yêu cầu của công ty ứng tuyển. Sau đó, nếu cv của ứng viên có thể lọt vào mắt xanh của nhà tuyển dụng nào đó thì sẽ nhận được mail mời phỏng vấn online.

Điểm thuận lợi của phỏng vấn online là có thể giúp cả đôi bên tiết kiệm thời gian, thời gian hẹn phỏng vấn cũng sẽ linh hoạt hơn vì không cần phải chuẩn bị quá nhiều thứ như khi gặp mặt nhau. Bên cạnh đó, ứng viên cũng có thể chủ động chọn lựa vị trí thuận tiện nhất để có cuộc phỏng vấn với nhà tuyển dụng mà không phải đi ra ngoài, chỉ cần nơi phỏng vấn của ứng viên chọn có wifi mạnh, backgound sáng sủa, gọn gàng.

Có thể bạn quan tâm:

  CEO TopDev ra mắt công nghệ AI/Computer Vision trợ giúp kết nối doanh nghiệp với người mất việc vì Covid

  Các công ty công nghệ Việt Nam và thách thức trong việc chuyển mình thời Covid - 19

  Tái tuyển dụng IT hiệu quả? Thách thức và cơ hội cho các công ty hậu Covid-19

 

Xem thêm Top IT Jobs lương cao trên TopDev

Mẫu CV xin việc Free cho các bạn IT

Với nhiều năm hoạt động trong ngành tuyển dụng lập trình viên TopDev tự tin rằng có thể cung cấp cho các bạn IT mẫu cv online chuẩn đẹp, free và đặc biệt là phù hợp nhu cầu ứng tuyển các vị trí khác nhau trong ngành lập trình.

Tại sao cần viết cv online?

Để có thể sở hữu được một bản cv online hoàn hảo, đầu tiên bạn cần hiểu được CV là gì và nó có ý nghĩa gì trong việc xin việc làm. Có thể hiểu nôm na CV là một bản tóm tắt sơ lược những công việc mà bạn đã làm qua, một bản CV luôn thể hiện được cho người đọc kinh nghiệm làm việc, học vấn, trình độ cá nhân…

Trước đây, khi công nghệ và nhu cầu tìm việc qua mạng còn ít thì những bản CV thường được viết tay hoặc đánh máy trên nền giấy A4. Sau này hiện đại hơn 1 tí thì có thể tạo CV bằng powerpoint, tuy nhiên khi bạn tự tạo CV thì sẽ mất khá nhiều thời gian vào nó, đặc biệt là những CV tự tạo đôi khi sẽ không được thẩm mỹ vì trình độ powerpoint của bạn có hạn, điều này sẽ gây ra ấn tượng xấu với nhà tuyển dụng.

Chính vì thấu hiểu những điều đó nên hiện nay có rất nhiều nền tảng cung cấp mẫu CV trên mạng với mẫu cv đa dạng, chỉnh chu hơn để hỗ trợ ứng viên tìm việc. Tuy nhiên điểm yếu của các mẫu CV này là sau khi hoàn thành xong phải tải về máy ngay, đôi khi muốn chỉnh sửa hay bổ sung một chi tiết nào đó thì phải làm lại từ đầu và tải lại thêm lần nữa, điều này rất phiền phức và làm rối tung folder của bạn.

  Cách viết CV giúp lập trình viên ghi điểm với nhà tuyển dụng

  5 mẹo và mẫu CV IT để gây ấn tượng với nhà tuyển dụng!

Mẫu CV online ra đời để giảm thiểu những khó khăn đó. Làm cv online sẽ giảm thiểu được tình trạng thường xuyên phải tải file về và việc sửa chữa cũng đơn giản tiện dụng hơn vì bạn chỉ cần điền theo form mẫu có sẵn cho từng ngành nghề. Bên cạnh đó các mẫu template CV onl hiện nay cũng rất đẹp, được các trang web đầu tư chỉnh chu, đặc biệt là các mẫu CV này hoàn toàn free ở 1 số mẫu và web. Ví dụ ở topcv thì free những mẫu cơ bản, cao cấp, đa dạng nhóm ngành…còn những mẫu chuyên nghiệp thì chỉ có tài khoản VIP được nạp tiền vào thì mới sử dụng được. Ở TopDev thì được tạo CV online free hoàn toàn và điểm mạnh ở TopDev là những mẫu CV này được thiết dựa theo form đơn xin việc chuyên biệt dành cho dân lập trình.

  Tổng hợp một số mẫu CV đẹp mắt dành cho lập trình viên

  Top 5 website giúp thiết kế CV chuẩn format, đủ nội dung

Viết cv online thu hút nhà tuyển dụng

Khi bắt tay vào viết CV onl thì bạn nên chú ý điền đầy đủ thông tin cần điền bên phần thông tin cá nhân như hình ảnh, số điện thoại, mail… Tiếp theo mới bắt đầu điền các thông tin về kinh nghiệm làm việc có liên quan đến vị trí đang muốn ứng tuyển. Tất cả bạn chỉ cần điền theo form có sẵn, thêm bớt các thông tin sao cho CV của bạn trở nên thật hoàn hảo nhé! Ngoài ra nếu bạn muốn ver cv bằng tiếng anh thì hãy chọn từ đầu nhé.

Ngoài ra bạn cũng có thể điều chỉnh font chữ, size trên đó, vì vây hãy chắc chắn rằng font chữ của bạn đồng nhất. Bạn cũng nên kiểm tra lại lỗi chính tả trong CV online của bạn, đừng liệt kê quá nhiều sở thích cá nhân vì nhà tuyển dụng sẽ không quan tâm đến những điều đó và nếu liệt ra ra quá nhiều sở thích không cần thiết thì sẽ làm CV của bạn rối nùi.

Một mẹo nhỏ nữa để làm cv online của bạn được nhà tuyển dụng lựa chọn là bạn nên trung thực, đừng vì quá tham mà liệt kê những kỹ năng cũng như kiến thức bạn chưa bao giờ làm qua. Đúng là 1 nhân viên giỏi, biết nhiều thứ thì ai cũng thích nhưng nổ quá cái gì cũng biết từ sale đến design, marketing, lập trình cái nào cũng biết thì sẽ được đặt dấu chấm hỏi! Nguy hiểm hơn là nhà tuyển dụng còn nghĩ bạn viết dối chỉ để được phỏng vấn nên sẽ loại bạn ngay từ vòng lọc CV Online.

Tạo CV IT online, chuẩn ATS miễn phí trên TopDev

Thêm một điều nên nhớ nữa là bạn không nên dùng 1 CV cho tất cả ngành nghề, mỗi ngành khác nhau sẽ cần những kinh nghiệm công việc khác nhau. Ví dụ như mẫu CV dành cho dân lập trình viên rất đặc thù vì cần phải có thiết kế phù hợp để show ra được những đường link dự án sao cho thật bắt mắt, điều đó khác hẳn so với những CV của dân sale hay marketing….

Nhìn chung, việc viết cv không còn là nỗi ám ảnh khi đi xin việc nữa vì hiện nay ứng viên đã được hỗ trợ rất nhiều từ các template CV online của các trang web tìm việc. Việc duy nhất các ứng viên cần quan tâm đó là chọn cho mình 1 mẫu CV phù hợp với ngành và trang bị kiến thức thật vững vàng trước khi đi gặp nhà tuyển dụng.

Có thể bạn quan tâm:

Xem thêm Top Việc làm IT trên TopDev

6 ví dụ để bạn yêu luôn observable

Bài viết được sự cho phép của tác giả Lưu Bình An

Thêm những lý do để dụ dỗ bạn xài Observable

Observable mình dịch ra tiếng việt thế này cho bạn dễ hình dung. Một khi bạn bật chế độ observable với một đứa con gái nào đó, là bạn đang trong giai đoạn bị nó ám ảnh, nhất cử nhất động của nó bạn điều để ý, nó hắc xì bạn cũng biết, một tuần nó mặc mấy bộ đồ bạn cũng biết. Chỉ cần nghe tiếng bước chân là bạn biết được hôm nay nó mang đôi dép gì (mức độ này hơi kinh khủng lắm rồi) là bạn có những phản xạ vô điều kiện bộc phát nơi cửa miệng “Chiều nay trời mưa nhe em, mang dép lào đi cho chuẩn”. Phản xạ này là gọi là subscription

Rồi quay lại với vấn đề kỹ thuật, bài này không giải thích rõ Observable pattern, các khái niệm chính của nó, nếu muốn bạn đọc lại bài này trước đây có viết rồi, như cái tựa bài viết nó spoil hết cái nội dung rồi “Ví dụ để thấy tại sao chúng ta nên bật chế độ Observable với một em gái nào đó”

Thần chú mình muốn bạn thuộc lầu

Lập trình Reactive là làm việc với luồng dữ liệu bất đồng bộ

Lại phải giải thích câu này chút, Nếu những gì diễn ra trên ứng dụng đang xảy ra một cách bất đồng bộ, khả năng rất cao là Observable sẽ giúp ích cho cuộc sống của anh em chúng ta bớt khổ hơn.

Có nhiều cách làm và thư viện handle vụ luồng dữ liệu bất đồng bộ này, tuy nhiên, Observable có gì mà cool, sắp được chuẩn hóa và đưa vào ECMAScript. Thư viện RxJS đang được sử dụng rộng rãi và quá ngon rồi.

Rồi vô luôn ví dụ nhe

Handle các event bằng Observable

Chúng ta có 1 button, khi button này click tạo ra một chuỗi ngẫu nhiên. Viết bằng cả 2 cách javascript thuần, và sử dụng RxJS

const button = document.querySelector('button');
const output = document.querySelector('output');

button.addEventListener('click', e => {
    output.textContent = Math.random().toString(36).slice(2);
})

Bằng RxJS nè

const button = document.querySelector('button');
const output = document.querySelector('output');

Rx.Observable
    .fromEvent(button, 'click')
    .subscribe(() => {
        output.textContent = Math.random().toString(36).slice(3);
    })

Nó dài hơn khi viết javascript thuần mà man 😂. Chi mà phức tạp vậy? Đúng luôn, nhưng giờ thêm yêu cầu này vào thì sao: Ở mỗi lần click đến bội số của 3 ( 3,6,9,12,…) thì mới random một string mới

Rx.Observable
    .fromEvent(button, 'click')
    .bufferCount(3) // một dòng duy nhất
    .subscribe(() => {
        output.textContent = Math.random().toString(36).slice(3);
    })

Vậy bạn viết JS thôi thì sao, khỏi nói cũng biết nó sẽ dài dòng hơn.

Operator, operator

Trong ví dụ trên, .bufferCount *đã cho thấy sức mạnh vượt trội** so với cách thông thường. Có thể nói thế này, chúng ta xài Observable này là vì những gì chúng ta làm được bằng operator. Trong thư viện RxJS nó cả tá Operator tha hồ mà chơi.

Một ví dụ khác, cũng là vụ random string ở trên, mà giờ chỉ muốn random khi nó là một cú triple click (một phát 3 nháy, không phải double click nhoa)

const click$ = Rx.Observable.fromEvent(button, 'click');

click$.Observable
    .bufferWhen(() => {
        click$.delay(400);
        // kkhoảng thời gian của một cú 3 click
    })
    .filter(events => events.length >= 3)
    .subscribe(() => {
        output.textContent = Math.random().toString(36).slice(3);
    })

DỊch ra ngôn ngữ con người nó sẽ như thế này, trong khoảng thời gian là 400ms, trong đám event được emit (tụi này được đưa vào mảng events), nếu mảng này lớn hơn hoặc bằng 3, thực hiện đống việc đã đăng ký bên dưới subscribe

Bạn đã bắt đầu yêu Observable chưa? Mình đã khoái khoái rồi đó.

Ai có thể là Observable

Đơn giản, bất kể già trẻ lớn bé, trai gái, nếu RxJS có hàm ( khi nãy là .fromEvent) thì chúng ta có thể biến nó thành đối tượng bị theo dõi liên tục.

Observable cho các HTTP request

Một sức mạnh siêu nhiên khác của RxJS: xử lý mấy em HTTP request rất mượt mà

Ví dụ, fetching một danh sách album và render.

const albumsApiUrl = 'https://jsonplaceholder.typicode.com/albums';

Rx.Observable
    .ajax(albumsApiUrl)
    .subscribe(
        res => console.log(res),
        err => console.log(err)
    )

Trộn chung với ví dụ ở trên, chúng ta làm cái tính năng awsome sau, click là có danh sách album ngẫu nhiên

Rx.Observable
    .fromEvent(button, 'click')
    .flatMap(getAlbums)
    .subscribe(
        render,
        err => console.error(err)
    )

function getAlbums() {
    const userId = Math.round(Math.random() * 10);
    return Rx.Observable.ajax(
        `https://jsonplaceholder.typicode.com/albums?userId=${userId}`
        )
}

Ví dụ trên có sử dụng operator flatMap, 1 trong những operator siêu kinh điển của RxJS, cho phép merge 2 mảng kiểu Observable thành 1

Nếu chúng ta click liên tục trong thời gian ngắn, là có vấn đề, re-render nhiều lần, chúng ta cũng ko xác định được request nào được resolve cuối cùng. Cụ thể là thế này, có thể thằng xuất phát trước lại về đích sau cùng, chuyện của network ai mà biết được thời điểm đó nó download film gì làm chậm mạng, thằng request sau có khi lại về đích trước, như vậy thì dùng cục response lúc nào để render, mình muốn response của thằng request cuối cùng.

Bạn muốn, trong công cuộc tán gái, đứa nào ở lại đến giây phút cuối cùng là đứa chiến thắng, bạn sẽ dẹp luôn những đứa nào thả thính trước đó? Ví von như vậy cũng chưa chuẩn, phải là đứa nào đến sau cùng thì dữ lại, dẹp mẹ tụi tới trước (thế này thì bất công vl mấy bạn)

RxJS làm được chuyện đó không? Có chứ, mọi thứ đã có operator, chuyển qua dùng switchMap, sẽ chỉ có response cuối cùng được render, mấy request trước đó sẽ bị cancel hết

Rx.Observable
    .fromEvent(button, 'click')
    .switchMap(getAlbums)
    .subscribe(
        render,
        err => console.error(err)
    )

Kết hợp các Observable

Một use case khác mà chúng ta gặp hoài. Chức năng filter hoạt động như sau: cho tụi user nhập vào user id bằng <input />, và chọn thể loại âm nhạc nó muốn bằng <select />. Điều quan trọng là chỉ tạo request mới khi cả 2 giá trị trong đó điều có dữ liệu, và re-render khi một trong 2 giá trị này bị thay đổi.

Tạo Observable trước nhé

const id$ = Rx.Observable
    .fromEvent(input, 'input')
    .map(e => e.target.value)

const resource$ = Rx.Observable
    .fromEvent(select, 'change')
    .map(e => e.target.value)

Chúng ta phải hợp thể 2 thằng trên vào một, để khi một trong 2 thằng có thay đổi chúng ta lấy được giá trị sau cùng của cả 2. mọi thứ đã có operator, nhiều lắm, ở đây dùng combineLatest

Rx.Observable
    .combineLatest(id$, resource$)
    .switchMap(getResource)
    .subscribe(render)

Kết

Bạn đã thấy sử dụng Observable thú vị dường nào chưa? Nếu câu trả lời là “Có ❤️, trọn đời yêu em”, bạn hãy nhào vô document của nó để nghiên cứu chuyên sâu hơn.

Nếu câu trả lời là “No 💩, anh éo care mấy đứa ạ”. Thì bạn cũng nên bớt bớt đối xử tệ với nó đi, vì trong tương lai JS sẽ đưa nào vào như một object chính thức luôn, không chạy đằng trời được đâu các bạn ạ.

Hy vọng anh em hôm nay đã học thêm được cái gì đó thú vị, hẹn gặp lại anh em vào một viết thú vị khác.

Bài viết gốc được đăng tải tại VuiLapTrinh

Có thể bạn quan tâm:

Xem thêm các việc làm JavaScript hấp dẫn tại TopDev