Returns the length of the string str, measured in bytes. A multibyte character counts as multiple bytes. This means that for a string containing five 2-byte characters, LENGTH() returns 10, whereas CHAR_LENGTH() returns 5.
簡單翻譯 LENGTH() 會計算 string 的 byte.
SELECT LENGTH('hello_world')
# 回傳 11
計算 all table 某個欄位大小
SELECT SUM(LENGTH(`column_name`))
FROM table_name
WHERE id = 1234567;
計算 one raw data 大小
SELECT (LENGTH(`id`) + LENGTH(`column_1`) + LENGTH(`column_2`) + LENGTH(`column_3`) + LENGTH(`column_4`)) RAW_SIZE
FROM table_name
WHERE id = 1234567;
Parse URI query String to Map
做 urlDecode 處理
沒有任何 query String 回傳 Empty Map
確保只處理 key-value 結構的 query String
package com.example.util;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.client.utils.URIBuilder;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URLDecoder;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Objects;
/**
* Created by jerry on 2017/12/28.
*
* @author jerry
*/
@Slf4j
public class UriUtil {
private UriUtil() {
}
public static Map splitQuery(final String uri) {
Map queryPairs = new LinkedHashMap<>();
try {
final URI uri = new URIBuilder(uri).build();
final String rawQuery = uri.getRawQuery();
log.info("CurrentUrl Query: {}", rawQuery);
// 過濾沒有 query string
// 還有過濾無法成對 keyValue 的 query, e.g. http://host/path?123
if (Objects.isNull(rawQuery) || !rawQuery.contains("=")) {
return queryPairs;
}
final String[] pairs = rawQuery.split("&");
final String utf8 = "UTF-8";
for (String pair : pairs) {
// 統一 decode
final String deCodePair = URLDecoder.decode(pair, utf8);
// check deCodePair 空字串,
if (!deCodePair.isEmpty()) {
final String[] keyValue = pair.split("=");
// check is key value
if (2 == keyValue.length) {
final String key = keyValue[0];
final String value = keyValue[1];
queryPairs.put(key, value);
}
}
}
log.info("Parser url: {} \n parameters: {}", url.toString(), queryPairs);
return queryPairs;
} catch (URISyntaxException uriBuilderUrlException) {
uriBuilderUrlException.printStackTrace();
log.warn("UriBuilder url ({}) has exception: {}", url, uriBuilderUrlException.getMessage());
} catch (UnsupportedEncodingException urlDecodeException) {
urlDecodeException.printStackTrace();
log.warn("Decode url ({}) query has exception: {}", url, urlDecodeException.getMessage());
}
return queryPairs;
}
}
I get paid for code that works, not for tests, so my philosophy is to test as little as possible to reach a given level of confidence (I suspect this level of confidence is high compared to industry standards, but that could just be hubris). If I don't typically make a kind of mistake (like setting the wrong variables in a constructor), I don't test for it. I do tend to make sense of test errors, so I'm extra careful when I have logic with complicated conditionals. When coding on a team, I modify my strategy to carefully test code that we, collectively, tend to get wrong.
Different people will have different testing strategies based on this philosophy, but that seems reasonable to me given the immature state of understanding of how tests can best fit into the inner loop of coding. Ten or twenty years from now we'll likely have a more universal theory of which tests to write, which tests not to write, and how to tell the difference. In the meantime, experimentation seems in order.
public interface MessageService {
void sendMessage(String message, String receiver);
}
public class EmailServiceImpl implements MessageService {
@Override
public void sendMessage(String message, String receiver) {
System.out.println("Email sent to " + receiver + " with Message=" + message);
}
}
public class SmsServiceImpl implements MessageService {
@Override
public void sendMessage(String message, String receiver) {
System.out.println("SMS sent to " + receiver + " with Message=" + message);
}
}
public class Application {
private MessageService messageService;
public Application(MessageService messageService) {
this.messageService = messageService;
}
public void notification(String message, String receiver) {
this.messageService.sendMessage(message, receiver);
}
}
public class Main {
public static void main(String[] args) {
Application app = new Application(new EmailServiceImpl());
app.notification("nice to meet you", "someone");
}
}
Requesting to rerun /bin/certbot-auto with root privileges...
Creating virtual environment...
Installing Python packages...
Installation succeeded.
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator apache, Installer apache
Which names would you like to activate HTTPS for?
-------------------------------------------------------------------------------
1: my-domain.me
-------------------------------------------------------------------------------
Select the appropriate numbers separated by commas and/or spaces, or leave input
blank to select all options shown (Enter 'c' to cancel): 1
這邊是詢問 Redirect, 是否要將 http(port:80) 重新導向到 https
Cert is due for renewal, auto-renewing...
Renewing an existing certificate
Performing the following challenges:
tls-sni-01 challenge for my-domain.me
Waiting for verification...
Cleaning up challenges
Deploying Certificate for my-domain.me to VirtualHost /etc/apache2/sites-enabled/000-default-le-ssl.conf
Please choose whether or not to redirect HTTP traffic to HTTPS, removing HTTP access.
-------------------------------------------------------------------------------
1: No redirect - Make no further changes to the webserver configuration.
2: Redirect - Make all requests redirect to secure HTTPS access. Choose this for
new sites, or if you're confident your site works on HTTPS. You can undo this
change by editing your web server's configuration.
-------------------------------------------------------------------------------
Select the appropriate number [1-2] then [enter] (press 'c' to cancel): 2
Enhancement redirect was already set.
搭啦~ 然後就 renew 成功啦
-------------------------------------------------------------------------------
Your existing certificate has been successfully renewed, and the new certificate
has been installed.
The new certificate covers the following domains:
https://my-domain.me
You should test your configuration at:
https://www.ssllabs.com/ssltest/analyze.html?d=my-domain.me
-------------------------------------------------------------------------------
貼心小提示, renew 完成的憑證路徑, 還有到期日 2017-12-02
IMPORTANT NOTES:
- Congratulations! Your certificate and chain have been saved at:
/etc/letsencrypt/live/my-domain.me/fullchain.pem
Your key file has been saved at:
/etc/letsencrypt/live/my-domain.me/privkey.pem
Your cert will expire on 2017-12-02. To obtain a new or tweaked
version of this certificate in the future, simply run certbot-auto
again with the "certonly" option. To non-interactively renew *all*
of your certificates, run "certbot-auto renew"
- If you like Certbot, please consider supporting our work by:
Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate
Donating to EFF: https://eff.org/donate-le
The standard Oracle JDK 7 implementation uses what's called a Linear Congruential Generator to produce random values in java.util.Random.
Predictability of Linear Congruential Generators
Hugo Krawczyk wrote a pretty good paper about how these LCGs can be predicted ("How to predict congruential generators"). If you're lucky and interested, you may still find a free, downloadable version of it on the web. And there's plenty more research that clearly shows that you should never use an LCG for security-critical purposes. This also means that your random numbers are predictable right now, something you don't want for session IDs and the like.
Enter keystore password:
Re-enter new password:
What is your first and last name?
[Unknown]: jerry
What is the name of your organizational unit?
[Unknown]: td
What is the name of your organization?
[Unknown]: com
What is the name of your City or Locality?
[Unknown]: taipei
What is the name of your State or Province?
[Unknown]: taiwan
What is the two-letter country code for this unit?
[Unknown]: tw
Is CN=jarvis, OU=td, O=urad, L=taipei, ST=taiwan, C=tw correct?
[no]: yes
The readOnly flag instead is propagated as hint to the underlying JDBC driver for performance optimizations. Furthermore, Spring will perform some optimizations on the underlying JPA provider. E.g. when used with Hibernate the flush mode is set to NEVER when you configure a transaction as readOnly which causes Hibernate to skip dirty checks (a noticeable improvement on large object trees).
If your test is @Transactional, it will rollback the transaction at the end of each test method by default. However, as using this arrangement with either RANDOM_PORT or DEFINED_PORT implicitly provides a real servlet environment, HTTP client and server will run in separate threads, thus separate transactions. Any transaction initiated on the server won’t rollback in this case.
import org.openjdk.jmh.annotations.Benchmark;
public class MyBenchmark {
@Benchmark
public void testMethod() {
// This is a demo/sample template for building your JMH benchmarks. Edit as needed.
// Put your benchmark code here.
}
}
Dead Code 指的是沒有被使用的 code, 比如下方的 int sum = a + b;,
sum 沒有繼續做任何運算處理, jmh 會因為 sum 沒有被使用,
而忽略評估 a + b 這段運算, 所以評估就不準啦。
@Benchmark @BenchmarkMode(Mode.Throughput)
public void testMethod() {
// This is a demo/sample template for building your JMH benchmarks. Edit as needed.
// Put your benchmark code here.
int a = 1;
int b = 2;
int sum = a + b;
}
Avoiding Dead Code Elimination
解決 Dead Code 的方法,
return sum, 讓 sum 確實有被使用。
Passing Value to a Black Hole , 意思是弄一個黑洞把變數丟進去, 假裝黑洞用了那個變數, 類似 Mockito 的 @Mock, 做法看下來
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.infra.Blackhole;
public class MyBenchmark {
@Benchmark
public void testMethod(Blackhole blackhole) {
int a = 1;
int b = 2;
int sum = a + b;
blackhole.consume(sum);
}
}
Return the result of your code from the benchmark method.
Pass the calculated value into a "black hole" provided by JMH.
Merge two sorted linked lists and return it as a new list.
The new list should be made by splicing together the nodes of the first two lists.
看完題目, 以為可以用 LinkedList 這類的東西, 想說 ez ...
結果下面給的 hint Sample 根本就不是那麼一回事啊, 抓頭抓抓抓...
/**
* Definition for singly-linked list.
*
*/
public class ListNode {
int val;
ListNode next;
ListNode(int x) { val = x; }
}
先拿到測試資料
/**
* Created by jerry on 2017/9/24.
*
* Merge two sorted linked lists and return it as a new list.
* The new list should be made by splicing together the nodes of the first two lists.
*/
public class LeetCode21MergeTwoSortedListsTest {
private LeetCode21MergeTwoSortedLists sol = new LeetCode21MergeTwoSortedLists();
@Test
public void test1() {
final ListNode l1 = null;
final ListNode l2 = new ListNode(0);
ListNode act = sol.mergeTwoLists(l1, l2);
Assert.assertEquals(0, act.val);
}
@Test
public void test2() {
final ListNode l1 = new ListNode(2);
final ListNode l2 = new ListNode(1);
ListNode act = sol.mergeTwoLists(l1, l2);
Assert.assertEquals(1, act.val);
Assert.assertEquals(2, act.next.val);
}
@Test
public void test3() {
final ListNode l1 = new ListNode(1);
final ListNode l2 = new ListNode(2);
ListNode act = sol.mergeTwoLists(l1, l2);
Assert.assertEquals(1, act.val);
Assert.assertEquals(2, act.next.val);
}
@Test
public void test4() {
final ListNode l1 = new ListNode(5);
final ListNode l2 = new ListNode(1);
final ListNode l3 = new ListNode(2);
final ListNode l4 = new ListNode(4);
l2.next = l3;
l3.next = l4;
ListNode act = sol.mergeTwoLists(l1, l2);
Assert.assertEquals(1, act.val);
Assert.assertEquals(2, act.next.val);
Assert.assertEquals(4, act.next.next.val);
Assert.assertEquals(5, act.next.next.next.val);
}
@Test
public void test5() {
final ListNode l1 = new ListNode(-9);
final ListNode l2 = new ListNode(3);
l1.next = l2;
final ListNode l3 = new ListNode(5);
final ListNode l4 = new ListNode(7);
l3.next = l4;
ListNode act = sol.mergeTwoLists(l1, l3);
Assert.assertEquals(-9, act.val);
Assert.assertEquals(3, act.next.val);
Assert.assertEquals(5, act.next.next.val);
Assert.assertEquals(7, act.next.next.next.val);
}
}
Solution
還是抓不太到這種遞迴的解法, 有種輾轉互相比較的意味
public class LeetCode21MergeTwoSortedLists {
// [-9, 3], [5, 7]
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
if (Objects.isNull(l1)) return l2;
if (Objects.isNull(l2)) return l1;
if (l1.val < l2.val) {
l1.next = mergeTwoLists(l2, l1.next);
return l1;
} else {
l2.next = mergeTwoLists(l1, l2.next);
return l2;
}
}
}
建立測試案例
public class LeetCode1TwoSumTest {
final LeetCode1TwoSum twoSum = new LeetCode1TwoSum();
/**
* Example:
* Given nums = [2, 7, 11, 15], target = 9,
* Because nums[0] + nums[1] = 2 + 7 = 9,
* return [0, 1].
*/
@Test
public void test1() {
final int[] nums = new int[]{2, 7, 11, 15};
final int target = 9;
int[] act = twoSum.twoSum(nums, target);
Assert.assertTrue(IntStream.of(act).anyMatch(x -> x == 0));
Assert.assertTrue(IntStream.of(act).anyMatch(x -> x == 1));
}
@Test
public void test2() {
final int[] nums = new int[]{3, 3};
final int target = 6;
int[] act = twoSum.twoSum(nums, target);
Assert.assertTrue(IntStream.of(act).anyMatch(x -> x == 0));
Assert.assertTrue(IntStream.of(act).anyMatch(x -> x == 1));
}
@Test
public void test3() {
final int[] nums = new int[]{3, 2, 4};
final int target = 6;
int[] act = twoSum.twoSum(nums, target);
Assert.assertTrue(IntStream.of(act).anyMatch(x -> x == 1));
Assert.assertTrue(IntStream.of(act).anyMatch(x -> x == 2));
}
}
Solution
public class LeetCode1TwoSum {
public int[] twoSum(final int[] nums, final int target) {
// 用來存放 target - n , HashMap
HashMap map = new HashMap<>();
int[] result = new int[2];
for (int i = 0; i < nums.length; i++) {
// 如果 map 有(target - n) 的值, 依序將 index 存入 result, 回傳 result
if (map.containsKey(nums[i])) {
int index = map.get(nums[i]);
result[0] = index;
result[1] = i;
return result;
} else {
// 計算目前 index , 相差(target - n) 才會等於 target
map.put(target - nums[i], i);
}
}
return result;
}
}
每個 Process 都可視為一個獨立運作的環境,有自己完整、私有的 Run-Time 資源,特別是每個 process 都有自己的記憶體空間。
Processes 聽起來很像 programs 或 application 的另一種說法,然而事實上一個 application 有可能是許多 processes 合作組成的。為了讓 processes 彼此互相合作,一些作業系統支援了 Inter Process Communication (IPC) resources,例如 pipes 與 sockets。IPC 不只讓不同的 processes 互相通訊,同時也支援不同系統的 pocesses 互相通訊。
大部分 JVM 實現的都是 single process。Java Application 可以創建額外的 process 透過 ProcessBuilder Object。
A process has a self-contained execution environment. A process generally has a complete, private set of basic run-time resources; in particular, each process has its own memory space.
Processes are often seen as synonymous with programs or applications. However, what the user sees as a single application may in fact be a set of cooperating processes. To facilitate communication between processes, most operating systems support Inter Process Communication (IPC) resources, such as pipes and sockets. IPC is used not just for communication between processes on the same system, but processes on different systems.
Most implementations of the Java virtual machine run as a single process. A Java application can create additional processes using a ProcessBuilder object. Multiprocess applications are beyond the scope of this lesson.
Threads are sometimes called lightweight processes. Both processes and threads provide an execution environment, but creating a new thread requires fewer resources than creating a new process.
Threads exist within a process — every process has at least one. Threads share the process's resources, including memory and open files. This makes for efficient, but potentially problematic, communication.
Multithreaded execution is an essential feature of the Java platform. Every application has at least one thread — or several, if you count "system" threads that do things like memory management and signal handling. But from the application programmer's point of view, you start with just one thread, called the main thread. This thread has the ability to create additional threads, as we'll demonstrate in the next section.
使用時機
IO bound task,避免 IO blocking 的阻塞。
CPU bound task,避免長時間大運算的邏輯的阻塞,藉由 threads 的使用,有效率地利用 CPU 。
最近試著在蒐集一些看起來有點用途的資料,Google Trends 看起來是一個 “滿有價值” 的資料,是 Google 蒐集的全球趨勢資料,包含最近流行的關鍵字,關鍵字與關鍵字的比較,etc.,但 Google 並沒有提供相關的 API 介面,所以要取得資料的做法我第一個想到的是 Crawler,於是順手找了一下大神的開源專案,左看右看上看下看,都沒認真看,都覺得不順手XD。
URI http://www.google.com/trends/fetchComponent
hl en-US
q keywords
cid TIMESERIES_GRAPH_0/RISING_QUERIES_1_0/business_and_politics
export 5
w width
h height