Cần đốt bao nhiêu calories để giảm 2kg mỗi tháng

Mỡ cơ thể (body fat) dự trữ năng lượng dưới dạng lipids. Lipids được đốt cháy để cung cấp năng lượng cho các hoạt động hàng ngày của cơ thể. Quá trình này diễn ra xuyên suốt trong 24h trong ngày kể cả khi ngủ. Lipid profile trong mỡ cơ thể chiếm ~87%. Do vậy 1kg mỡ cơ thể sẽ có 0.87kg lipid-fat. Tại sao lại chỉ có 87% vì trong mỡ cơ thể cũng bao gồm cả nước nữa.

1g lipid-fat khi sử dụng sinh ra 9 calories. Do vậy để đốt 1kg mỡ cơ thể hay 0.87kg lipid-fat thì lượng calories cần tiêu hao là:

1000 * 0.87 * 9 = 7830 calories

Ok, vậy nếu muốn giảm 1kg mỗi 2 tuần thì số calories cần thâm hụt hàng ngày sẽ là:

7830 / 14 = 559 calories (khoảng 400gram cơm trắng)

 

Advertisements

The twelve-factor app

Disclaimer: Đây không phải bản dịch của 12-Factor. Đây là bản mô tả lại theo cách hiểu của cá nhân mình. Phiên bản đầy đủ của 12-Factor có thể truy cập tại đây: https://12factor.net/

12-Factor app là một phương pháp luận cho việc xây dựng các ứng dụng phân tán triển khai trên môi trường cloud, phân phối dưới dạng như một service. Cách tiếp cận này được pháp triển bởi Adam Wiggins,  co-founder của Heroku một platform-as-a-service. Mục tiêu của Wiggin là tổng hợp các thực tiễn tốt nhất để triển khai một ứng dụng trên Heroku hoặc bất kỳ nền tảng cloud nào.

12-Factor áp dụng cho ứng dụng viết bởi bất kỳ ngôn ngữ nào, sử dụng bất kỳ sự kết hợp nào của backing services (Database, queue, memory cache…).

Code base

Ứng dụng 12-Factor chỉ có duy nhất một codebase được theo dõi bởi version control system như Git, Mercurial hoặc Subversion nhưng sẽ có nhiều bản triển khai trên nhiều môi trường khác nhau (staging, dev, production …).

codebase-deploys
Mỗi codebase có nhiều phiên bản triển khai

Hiểu đơn giản thì nếu bạn đang có nhiều hơn 1 codebase thì nó không phải một ứng dụng mà là một hệ thống phân tán. Nhiều ứng dụng chia sẻ code giống nhau sẽ vi phạm 12-Factor. Giải pháp ở đây là đóng gói thành thư viện và sử dụng thông qua dependency manager.

Dependencies

Một ứng dụng 12-Factor cần khai báo rõ ràng các dependencies của nó. Đã qua rồi cái thời developer cần tìm kiếm các file jars/dependencies thả vào project và cố gắng biên dịch nó. Ngày nay hầu hết các ngôn ngữ lập trình đều có hệ thống quản lý gói cho việc phân phối các thư viện hỗ trợ. Ví dụ như NPM cho NodeJS, Pip cho Python, Maven Repositories cho Java, Rubygems cho Ruby… Những thư viện này được cài đặt thông qua một hệ thống quản lý gói có thể được cài đặt trong phạm vi toàn hệ thống (được biết đến như là “site packages”) hoặc giới hạn phạm vi trong thư mục chứa ứng dụng (được biết đến như là “vendoring” hay “bundling”).

Ứng dụng 12-Factor cũng không được sử dụng bất kỳ công cụ hệ thống nào. Ví dụ: shell out đến ImageMagick hoặc curl. Mặc dù những công cụ này tồn tại trên nhiều hệ thống tuy nhiên không có gì đảm bảo rằng chúng sẽ tồn tại trên tất cả hệ thống nơi ứng dụng sẽ triển khai hoặc liệu phiên bản được tìm thấy trên hệ thống sẽ tương thích với ứng dụng. Nếu ứng dụng cần shell out đến một công cụ hệ thống thì công cụ này nên được đóng gói cùng ứng dụng.

Config

Lưu trữ cấu hình trong biến môi trường. Một cấu hình ứng dụng là mọi thứ mà có khả năng thau đổi giữa các bản triển khai (staging, production, developer….). Bao gồm:

  • Đặc tả kết nối đến cơ sở dữ liệu, memcached và các dịch vụ phía sau
  • Ủy quyền đến các dịch vụ bên ngoài như Amazon services hay Google cloud
  • Các giá trị trên mỗi triển khai ví dụ như hostname chính thức cho bản triển khai.=

Ứng dụng lưu trữ cấu hình như hằng số trong code vi phạm 12-Factor. Trên thực tế cấu hình thay đổi tùy theo phiên bản triển khai, code thì không.

Ứng dụng 12-Factor lưu cấu hình trong biến môi trường (thường viết ngắn gọn là env vars hoặc env ). Các biến môi trường dễ dàng thay đổi giữa các triển khai mà không phải thay đổi code, không giống như tệp cấu hình, chúng chỉ có nguy cơ nhỏ khong may bị đánh dấu trong code repo, và cũng không giống như tệp cấu hình tùy chỉnh, hay các cơ chế cấu hình khác ví dụ Java System Properties, chúng là theo chuẩn không thể biết của ngôn ngữ lập trình và hệ điều hành.

Backing services

Một backing services là bất kỳ một service nào mà ứng dụng này sử dụng qua mạng như một phần của hoạt động bình thường. Backing services bao gồm các local service hoặc từ bên thứ ba như cơ sở dữ liệu, message queues, cache services.

Mỗi một backing service là một resource. Ví dụ: một cơ sở dữ liệu MySQL là một resource, hai cơ sở dữ liệu MySQL (shardung at the application layer) được xác định là 2 resources riêng biệt. Ứng dụng 12-Factor coi những cơ sở dữ liệu này như những tài nguyên đính kèm, giảm thiểu sự phụ thuộc của chúng với phiên bản triển khai của ứng dụng.

attached-resources
Một phiên bản production được gắn vào 4 backing services

Resource có thể gắn vào hoặc tách ra từ các bản triển khai nếu muốn. Ví dụ nếu CSDL của ứng dụng bị lỗi, người quản trị có thể chuyển sang một CSDL khác mà không cần thay đổi bất kỳ dòng code nào.

Build, release, run

Ứng dụng 12-Factor có 3 giai đoạn chính: build, release, run.

  • Build là quá trình compile code từ VCS và đóng gói thành một phiên bản ứng dụng.
  • Giai đoạn release là khi kết hợp bạn build có được từ trước cùng với các cầu hình cần thiết của ứng dụng. Sẵn sàng cho việc triển khai trên môi trường thực tế.
  • Giai đoạn run là khi ứng dụng đã triển khai và hoạt động trên môi trường thực tế.
release
Compile code -> build sau đó kết hợp với cấu hình tạo ra 1 bản release

Mọi bản phát hành luôn có một ID duy nhất. Có thể sử dụng timestamp phát hành như 2019-21-03-16:11:03 hoặc một số tự nhiên tăng dần như v1001. Bất kỳ thay đổi nào đến bản build (ví dụ: bug fixes) cũng cần một bản release mới.

Processes

Thực thi ứng dụng như một hoặc nhiều tiến trình phi trạng thái. Các tiến trình theo 12-Factor thì không có trạng thái và không chia sẻ bất kỳ thứ gì. Bất kỳ dữ liệu cần được duy trì phải được lưu ở một backing service, thông thường là CSDL.

Dữ liệu phiên làm việc (session state) nên được lưu trữ thông qua một backing service có time-based expiration. Ví dụ: Hazelcast, Redis, Memcached

Port binding

Ứng dụng 12-Factor không bao gồm web server mà thay vào đó sử dụng giao thức HTTP như một service bằng cách binding đến một cổng và lắng nghe request đến cổng đó. Điều này đảm bảo ứng dụng hoàn toàn khép kín và không dựa vào một web server cụ thể.

HTTP không phải là dịch vụ duy nhất có thể sử dụng port binding. Hầu như bất kì kiểu server software nào cũng có thể chạy thông qua tiến trình binding port và chờ request đến cổng này. Ví dụ: Redis, Memcached

Concurrency

Trong ứng dụng 12-Factor các loại công việc khác nhau được xử lý bởi các tiến trình khác nhau. Các tiến trình trong ứng dụng 12-Factor lấy các gợi ý mạnh mẽ từ mô hình tiến trình của unix cho các dịch vụ daemon đang chạy. Sử dụng mô hình này, nhà phát triển có thể kiến trúc ứng dụng của họ để xử lý các workload đa dạng bằng cách gán mỗi kiểu công việc cho một kiểu tiến trình. Ví dụ, các HTTP request có thể được xử lý bởi các tiến trình web, và các task (nhiệm vụ) chạy nền thời gian dài được xử lý bởi một tiến trình worker.

process-types
Scale thể hiện tiến trình đang chạy. Work load thể hiện các kiểu của tiến trình

Về cơ bản ứng dụng 12-Factor phải có khả năng mở rộng theo chiều ngang, áp dụng các tiến trình phi trạng thái, không chia sẻ ứng dụng có thể mở rộng liên tục.

Disposability

Tiến trình của ứng dụng 12-Factor cần có tính sẵn sàng có nghĩa là có thể bậ hặc tắt khi có thông báo tại một thời điểm nào đấy. Điều này dễ dàng cho việc mở rộng, triển khai nhanh chóng khi thay đổi code hoặc cấu hình.

Các tiến trình nên cố gắng giảm tối đa thời gian khởi động. Lý tưởng là một tiến trình mất vài giây tính từ lúc khởi động đến khi sẵn sáng nhận request và job.

Dev/prod parity

Tính tương đồng giữa các phiên bản. Giữ môi trường development, staging và product ion giống nhau nhất có thể. Trong lịch sử, đã có những lỗ hổng thực tế giữa development và production. Ứng dụng 12-Factor được thiết kế để triển khai liên tục bằng việc giảm thiểu khoảng cách giữa development và production.

  • Developer có thể viết code và triển khai ngay sau đó.
  • Developer viết code chịu trách nhiệm deploy và theo dõi trong môi trường production.
  • Giữa môi trường development và production giống nhau nhất có thể. Ví dụ sử dụng docker.

Logs

Theo 12-Factor log là một luồng các sự kiện được sắp xếp theo thứ tự thời gian thu thập từ các luồng đầu ra của toàn bộ các tiến trình đang chạy và các backing services. Quá trình này diễn ra liên tục miễn là ứng dụng còn đang hoạt động.

Một ứng dụng 12-Factor không chịu trách nhiệm định tuyến hoặc lưu trữ dòng dữ liệu đầu ra của nó. Nó không cố gắng ghi hay quản lý các logfile. Thay vào đó mỗi tiến trình đang chạy sẽ ghi trực tiếp luồng sự kiện của nó, không sử dụng bộ đệm (unbuffered) tới stdout.

Developer có thể view log trên terminal hoặc điều hướng tới log collector. Ví dụ: Logplex, Fluentd, Logstash…

Admin processes

Chạy các task admin/management như các tiến trình one-off (một lần).

Processes formation là một loạt các tiến trình mà được sử dụng để thực hiện công việc thường lệ của app (ví dụ xử lý các web request) khi nó chạy. Các nhà phát triển sẽ thường thực hiện các task mang tính quản trị hoặc bảo trì cho ứng dụng. Ví dụ:

  • Database migration, backup.
  • Run shell console
  • Run script

 

Chuẩn hóa vector

Ta có vector x và y. Phép nhân hoặc chia làm thay đổi chiều dài của vector mà không ảnh hướng đến phương và hướng. OK, câu hỏi ở đây là làm thế nào chúng ta biết được chiều dài của một vector? Nếu biết trước các thành phần (x và y).

Hiểu được cách tính chiều dài (hay còn gọi là độ lớn) của vector là vô cùng quan trọng và hữu ích.

9150ff25c140f6abd6da845d59533880324158a9

Chiều dài hoặc độ lớn của vector v được ký hiệu là ss_15

Hình vẽ trên cho thấy mũi tên nối 2 điểm x,y tạo thành một tam giác vuông. Các cạnh bên là các thành phần với cạnh huyền chính là mũi tên. Với tam giác vuông này chúng ta có thể áp dụng công thức của nhà toán học Pythagoras mô tả mối quan hệ giữa các cạnh và cạnh huyền trong một tam giác vuông.

Trong tam giác vuông, bình phương cạnh huyền bao giờ cũng bằng tổng bình phương hai cạnh còn lại.

f400c601f9a8be82ce642b4d0fc6f4962802bbd9

Áp dụng công thức trên ta có mã hiện thực như sau:

/**
 * Compute magnitude of vector
 */
public double length() {
    return Math.sqrt(dX * dX + dY * dY);
}

Việc tính toán được độ lớn của vector mở ra nhiều khả năng, đầu tiên là chuẩn hóa vector. Trong một số trường hợp ta chỉ quan tâm đến hướng của vector đó mà bỏ qua độ lớn của nó. Với trường hợp như vậy ta thay đổi độ lớn của vector đó về 1. Những vector có tính chất như trên ta gọi chúng là vector đơn vị. 

6ade290db694921cc465883fb070d8a1dbb3447e

Ta chuẩn hóa vector bằng cách chia mỗi thành phần cho độ lớn cuả nó. Kí hiệu làss_18:

ss_17

/**
 * Normalize a vectors length....
 *
 * @return normal vector
 */
public Vector normalize() {
    Vector vn = new Vector();

    double length = Math.sqrt(this.dX * this.dX + this.dY * this.dY);
    if (length != 0) {
        vn.dX = this.dX / length;
        vn.dY = this.dY / length;
    }
    return vn;
}

Tích vô hướng hai vector

Giả sử ta có 2 vector
ss_8

ss_10

tích vô hướng của hai vector này (hay còn gọi là dot product vì được biểu diến bằng một dấu chấm) được tính bởi công thức sau:

ss_19

Bằng việc áp dụng các phương pháp hình học, ta chứng minh được mối quan hệ giữa tích vô hướng và góc giữa các vector này như sau:

ss_20

Dựa theo công thức trên, ta có thể suy ra một số đặc điểm của 2 vector khi có tích vô hướng của chúng:

  • Nếu ss_22 : 2 vector vuông góc với nhau.
  • Nếu ss_23 : góc giữa 2 vector nhỏ hơn 90 độ.
  • Nếu ss_24: góc giữa 2 vector lớn hơn 90 độ.

Giả sử ta có 2 vector
ss_8

ss_10

tích vô hướng của hai vector này (hay còn gọi là dot product vì được biểu diến bằng một dấu chấm) được tính bởi công thức sau:

ss_19

Bằng việc áp dụng các phương pháp hình học, ta chứng minh được mối quan hệ giữa tích vô hướng và góc giữa các vector này như sau:

ss_20

Dựa theo công thức trên, ta có thể suy ra một số đặc điểm của 2 vector khi có tích vô hướng của chúng:

  • Nếu ss_22 : 2 vector vuông góc với nhau.
  • Nếu ss_23 : góc giữa 2 vector nhỏ hơn 90 độ.
  • Nếu ss_24: góc giữa 2 vector lớn hơn 90 độ.

Tại sao khi vận động mạnh bạn lại có thể bị đau cơ?

Trong phần lớn các trường hợp đau cơ, nguyên nhân chính là do sự tích tụ acid lactic trong cơ. Khi đó, pH của các tế bào cơ thay đổi và toàn bộ cơ bị ảnh hưởng. Đau cơ làm cho chúng ta mệt mỏi, ngại vận động và chỉ muốn nghỉ ngơi, nằm ngủ.

Vậy tại sao acid lactic lại bị tích tụ? Khi chúng ta hoạt động mạnh, cơ thể không cung cấp đủ O2 cho các tế bào cơ hô hấp hiếu khí tạo ATP dùng trong quá trình co cơ. Để khắc phục vấn đề này, các tế bào cơ lên men lactic mà không cần O2, cung cấp lượng ATP cần thiết trong khi máu chưa đưa được O2 đến cơ. Kết quả là acid lactic bị tích tụ trong cơ.

Nhưng cơ thể con người là một hệ thống thông minh và hoạt động hiệu quả! Acid lactic tích tụ trong cơ được vận chuyển về gan và chuyển hoá lại thành glucose. Toàn bộ chu trình chuyển hoá này có tên là chu trình Cori.

13439089_659256224222750_4595931950515692394_n

Nếu lượng acid lactic trong cơ bị tích tụ quá nhiều, không được chuyển hoá (do các nguyên nhân khác nhau) sẽ gây ra các cơn đau khủng khiếp. Muốn tránh được điều này, cách tốt nhất là bạn nên tập thể dục đều đặn. Việc tập thể dục sẽ tăng cường hoạt động của hệ hô hấp và hệ tuần hoàn, qua đó làm tăng lượng O2 máu đưa đến cơ, giảm lượng acid lactic tích tụ.
2 người tìm ra chu trình Cori là Gerty Cori và Carl Cory, cả 2 cùng nhận giải Nobel năm 1947 nhưng không phải là do khám phá ra Cori cycle.

Java concurrency (multi-threading)

1. ExecutorService

ExecutorService là một framework sinh ra với mục đích đơn giản hóa việc thực thi các task theo cơ chế bất đồng bộ. Về cơ bản ExecutorService tự động khởi tạo thread pool và cung cấp các API cho phép developer assigning task tới pool.

ExecutorService không tự động destroyed khi không có task nào thực thi. Nó sẽ alivewait for new work. Điều này cũng hữu ích trong một số trường hợp khi số lượng task là không cố định và không biết trước tại thời điểm compile. VD: 1 program SocketServer.

Trong các trường hợp khác sẽ không thể kiểm soát khi chương trình đã thực thi xong nhiệm vụ nhưng không thể dừng lại chỉ bởi ExecutorService  vẫn alive và tiếp tục wait for new work. Để tránh trường hợp này java cung cấp 2 API là shutdown() và shutdownNow()

shutDown() sẽ dừng việc tiếp nhận các task mới và shut down hoàn toàn sau khi những submitted task được thực thi.

shutdownNow() sẽ ngay lập tức destroy ExecutorService và trả lại danh sách các task đang đợi để thực thi. Developer cần quyết định sẽ làm gì với những task này.

Oracle khuyến cáo sử dụng cả 2 phương thức shutdown của ExecutorService. Sử dụng shutdown() trước để vô hiệu hóa việc tiếp nhận các task mới. Đợi trong 1 khoảng thời gian nhất định để toàn bộ các task được thực thi. Sau quãng thời gian này thực hiện lệnh shutdownNow()

 void shutdownAndAwaitTermination(ExecutorService pool) {
   pool.shutdown(); // Disable new tasks from being submitted
   try {
     // Wait a while for existing tasks to terminate
     if (!pool.awaitTermination(60, TimeUnit.SECONDS)) {
       pool.shutdownNow(); // Cancel currently executing tasks
       // Wait a while for tasks to respond to being cancelled
       if (!pool.awaitTermination(60, TimeUnit.SECONDS))
           System.err.println("Pool did not terminate");
     }
   } catch (InterruptedException ie) {
     // (Re-)Cancel if current thread also interrupted
     pool.shutdownNow();
     // Preserve interrupt status
     Thread.currentThread().interrupt();
   }
 }

awaitTermination(long timeout, TimeUnit unit) sẽ block thread cho đến khi toàn bộ task được thực thi sau lệnh shutdown()  hoặc khi hết thời gian đã định trước.

2. Futures and Callables

Trong trường hợp thread cần trả về 1 kết quả chúng ta cần implement interface  java.util.concurrent.Callable. Callable object cho phép trả về một giá trị sau khi task hoàn thành.  Sau khi submit object Callable tới ExecutorService sẽ nhận lại một object type java.util.concurrent.Future cho phép chờ lấy kết quả hoặc kiểm tra trạng thái thực thi task.

Callable<Long> task = new SampleCallable();
    Future<Long> result = executorService.submit(task);

    // A special blocking method
    // Calling the get() method while the task is still running will
    // cause execution to block until the task is properly executed and
    // the result is available.
    logger.debug("Result {}", result.get());
}

JVM Ecosystem Report 2018

Công ty Snyk và Java Magazine vừa mới công bố bản báo cáo về JVM Ecosystem. Hơn 10k developer từ khắp nơi trên thế giới đã tham gia khảo sát. Có rất nhiều điều thú vị trong bản report này.  Chi tiết của report có thể download tại đây

1. Which Java vendor’s JDK do you use in production for your main applications?

2018-10-18-14-00-snyk.io

Dễ hiểu khi có tới 70% developers lựa chọn Oracle JDK tuy nhiên điều này có thể sẽ thay đổi trong tương lai khi Oracle chính thức yêu cầu commercial license để sử dụng Java SE

6. Which IDE do you develop with?

ide-popularity-intellij-idea-eclipse-netbeans

Có thể thấy sự hiện diện của Visual Studio Code ở đây mặc dù chỉ 1%. Hơi bất ngờ khi vẫn còn tới 3% developer sử dụng vi/vim/Emacs/etc để làm việc. Mình có dùng notepad để coding một thời gian hồi còn đi học. Đúng là một ác mộng

9. Do you use static security tools in your testing?

do-you-use-static-security-tools-in-your-testing_-1

72% developers không sử dụng security tools khi kiểm thử. Có lẽ Synk không thích điều này :).  Snyk.io là công ty về network security, phát triển các công cụ chịu trách nhiệm giám sát, phát hiện sớm các lỗ hổng từ những dependencies mà developer sử dụng trong project.

10. Which CI server do you use?

ci-tool-popularity-jenkins-bamboo-teamcity

Continuous integration gần như đã trở thành tiêu chuẩn trong phát triển phần mềm. Việc tích hợp CI cũng đã dễ dàng hơn rất nhiều tuy nhiên vẫn có đến 21% developers không sử dụng CI trong dự án.

12. Which code repository do you use for your main project?

code-repository-popularity-github-bitbucket-gitlab

Trái với suy nghĩ của mình Github không dẫn đầu thị phần repository hosting service. Không rõ việc Microsft mua lại Github có ảnh hưởng đến quyết định sử dụng repository của developer không?

30. How old are you?

how-old-are-you

 

Garmin activities comapre

Mình vừa phát hiện ra Garmin cho phép comapre 2 activities cùng loại với nhau.

Điều này khá thú vị khi bạn muốn kiểm tra lại thành tích ở lần chạy trước đó để coi khả năng mình đang tiến bộ hay thụt lùi 🙂 . Rất tiếc là hiện tại chỉ hỗ trợ compare tối đa 4 hoạt động cùng loại. Nếu Garmin có thể tự động xuất báo cáo dạng biểu đồ của tất cả hoạt động thì sẽ tốt hơn rất nhiều.

Mình vừa chén xong 2 buổi long run vào 2 cuối tuần vừa rồi. Có vẻ mọi thứ đang dần trở lại, mình chủ động nghỉ sau hơn 1 giờ để giữ chân. Thời gian sau chấn thương mình duy trì lịch tập với 1 buổi leg strength và 1 long run. Tuần này mình sẽ bổ sung thêm 1 buổi interval nữa. Như vậy 1 tuần sẽ có 2 buổi chạy, nếu mọi thứ ok mình sẽ thêm vào 1 buổi easy run vào giữa tuần.