Skip to content

完成 issue12#14

Merged
MontyPan merged 7 commits intoMontyPan:masterfrom
G100my:issue12
Jan 5, 2020
Merged

完成 issue12#14
MontyPan merged 7 commits intoMontyPan:masterfrom
G100my:issue12

Conversation

@G100my
Copy link
Copy Markdown
Collaborator

@G100my G100my commented Dec 7, 2019

實在是想不出使用 / 、% 來做這次 issue 的方法 orz,
(雖然有說不一定會用到)
求解Q_Q

Copy link
Copy Markdown
Owner

@MontyPan MontyPan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

這是一個基本技巧,高中數學應該長常用到(但是我忘了是啥地方了 💃 ),你可以用 counter % 10 來取代那些大於 9 之後要重設為 0 的 case。


Must FIX

  • 用 v3 的邏輯生出一個版本 v4,差別是改用 %

Bewared

這個也不能說你錯,只是你的變數命名...... 好混亂,i2, ii, i3, i4 然後又來 counter 又有 index....... 💤

Optional Question

機掰的案主(對啦對啦,就是我啦,你有意見嗎? 💃 )說:「你的 v2 是錯的,我拒絕驗收通過」。試問原因為何?還有你要怎麼 defend?(不然拿不到錢 or 要花時間改)

Comment thread basic/src/main/java/lo/basic/Issue12.java Outdated
Comment thread basic/src/main/java/lo/basic/Issue12.java Outdated
@G100my
Copy link
Copy Markdown
Collaborator Author

G100my commented Dec 7, 2019

Optional Question

機掰的案主(對啦對啦,就是我啦,你有意見嗎? 💃 )說:「你的 v2 是錯的,我拒絕驗收通過」。試問原因為何?還有你要怎麼 defend?(不然拿不到錢 or 要花時間改)

是否可以先請案主您簡單說明一下您覺得 v2 哪裡有問題?
經過測試後,該程式確實按照您的需求達成所需目的。

@MontyPan
Copy link
Copy Markdown
Owner

MontyPan commented Dec 8, 2019

你這不叫 defend、而且你根本就是把第一個問題丟回來給我阿 [指] (不要天真的以為這樣我就會上當)

「幹,哪有只 reject 不說明原因的?」

還真的有,很多。

把自己系統的資料打給其他系統,這在稍微大一點的案子當中就跟路上的 Altis 一樣常見(想想網路購物的金流)。通常對方系統不會給你很人性化 or 很清楚的 reject 資訊(等你自己也開始寫文件跟 exception handling 就知道了 lol),甚至搞到後來是對方程式有問題也不是沒發生過。

所以...... [戴上機掰人面具](謎之聲:不,你根本不需要戴)

反正就是你 v2 吐出來的資料送到我這系統來被 reject 啦,別人(v1、v3)都沒有問題阿,你這樣還要我簽驗收通過跟會計請錢?下輩子吧!阿哈哈哈哈......

好像演太順手了(謎之聲:就說你不需要戴)

@G100my
Copy link
Copy Markdown
Collaborator Author

G100my commented Dec 8, 2019

    1****
   234***
  56789**
 0123456*
789012345

案主您指的是 v2 數字金字塔右邊比其他版本多了額外的空白吧?
(先用星號取代右邊比其他版本多出來的空白)
這其實沒有關係喔~
空白字元並不會造成視覺上的影響,
而且左邊本來也就一定會有空白字元了,就像您給我的設計稿上左邊也有空白一樣。
再來假設如果您要把數字金字塔輸出到印刷品上,
就算就算真的不幸因為字體字型背景的關係,使空白字元造成視覺上的差異,
那 v2 左右兩邊對稱的空白也會讓您也比較好做調整...

大概就是這樣子吧。

@G100my
Copy link
Copy Markdown
Collaborator Author

G100my commented Dec 8, 2019

你根本就是把第一個問題丟回來給我阿 [指]

呵呵,這不是一般客訴處理SOP第一步嗎XD
(而且超好用!)

@MontyPan
Copy link
Copy Markdown
Owner

MontyPan commented Dec 9, 2019

是的,問題在於右邊空白。但是你的 defend 就完全 no sense(自相矛盾的論點就談什麼 sense 了)。左邊的空白就是為了製造視覺效果,什麼叫做「就像左邊也有空白一樣」?一樣個雕阿...... 💢

以實務經驗來說,能拿出來 defend 的大概就只有「當初需求沒限制右邊不能有空白」,但是這種事情通常還是只能被案主凹著改 😭 ,更別說是我前一個 comment 提到的狀況。所以需求談的越明確才越不會在結案前炸掉(但是案主通常無法 or 不願意跟你仔細談需求...... [遠目])

雖然有點小題大作,但是完全不妨礙藉此告訴你一個事實: 「在字串當中,看不見的字元依然存在、既然存在它們就會被視為不相同」。這在處理使用者輸入(尤其是帳號密碼)、處理 XML...... 等等都會被這個炸到,所以在這部份的 code 會看到滿滿的 String.trim()

關於字串的事情我們日後會再提,這裡就先埋個哏結束這個回合。

@G100my G100my requested a review from MontyPan December 25, 2019 09:33
Copy link
Copy Markdown
Owner

@MontyPan MontyPan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Muse FIX and Answer

請拿掉 L88~L90 嗎?然後回答

  • 這樣作學理上可能會產生什麼風險?
  • 為什麼還是可以 / 要求你這樣作?

(我聽到遠方傳來 WTF 的聲音,好悅耳阿...... 💃 )

@G100my
Copy link
Copy Markdown
Collaborator Author

G100my commented Dec 26, 2019

Reply - Must Answer

  • 拿掉後 list[index] 會超出範圍,list 的長度只有 10 個,index的範圍只能是 0~9,超過會爆錯。
  • 因為L88~L90很多餘... 可以直接寫成 index = index % 10; 不管怎麼加,只取個位數就好。

@G100my G100my requested a review from MontyPan December 26, 2019 07:42
Copy link
Copy Markdown
Owner

@MontyPan MontyPan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Must FIX and Answer

  • 請改出一個沒有 L88 的版本
  • 你的第一個問題搞錯了,是問你改完之後有什麼風險,不是單純拿掉有什麼風險(單純拿掉程式就有 bug 了好嗎? ==')
    • 不過,以你這次的版本來說,的確不會有什麼風險 XD,所以你要詰譙這題目出的不好... 我勉強可以接受啦 💃 (我怎麼知道要你拿掉結果你又偷補了一行回去)

@G100my
Copy link
Copy Markdown
Collaborator Author

G100my commented Dec 26, 2019

這裡先說明&釐清一下 L88~L90/L88拿掉 的意思及我對風險的認知。
對題目還是有點混淆...。

風險跟BUG不一樣,
是「可能發生但是不一定會發生的事情,
在目前的情況它還沒有發生,如果讓這個issue一直發展下去的話就可能會碰到的。」

拿掉 L88~L90/L88 我解讀為

  1. System.out.print() 前面不要有東西,改成在 System.out.print() 後才更改 index。
  2. 不要使用 index 作為 list 的位置指標。這個不合理,前面都說了一般會另外使用另外的變數來控制 list 位置
  3. 改掉 if 判斷式,但是後續又得把新增的 index = index % 10 拿掉Q_Q,所以也不是,

(不過因為 index = index % 10 是不會有風險的寫法...Q_Q
這裡可以先推論風險在於 if 判斷式僅有在 index % 10 == 0 時才動作,而且歸零並不是取餘數。
假設 index 的順序是要 0369258147、index 每一次是+3的話,那原先的寫法就錯了)

總之先不管上面括號的東西,繼續下去,選擇選項1。

去掉 L88,那還是要補上其他東西來讓index 限制在 0~9

  1. 假設把拿掉的 L88 原封不動移到L89之後L90之前,那就錯了,index會有變成10的情況,爆掉。
  2. 假設把拿掉的 L88 移到L90之後就沒有問題了。

結論:
風險就是括號內的那坨 + 在 System.out.print(list[index]); 之前沒有把 index 處理好就有可能會爆錯。

@G100my G100my requested a review from MontyPan December 26, 2019 14:24
@MontyPan
Copy link
Copy Markdown
Owner

你對風險跟 bug 的認知基本上跟我的一樣,但是......

拿掉要是拿掉,你換個地方加回去是怎樣? 😡

拿掉要是拿掉,你換個地方加回去是怎樣? 😡

拿掉要是拿掉,你換個地方加回去是怎樣? 😡

所以.... 你後面講得那一堆我就不仔細看了 🙈 💤

Must FIX

請把 L90 拿掉,不要再給我找地方加回去、當然你勢必要改點什麼才不會炸 bug,但總之不能增加 v4 的行數。

@MontyPan MontyPan removed their request for review December 26, 2019 17:01
@G100my
Copy link
Copy Markdown
Collaborator Author

G100my commented Dec 27, 2019

呃...想不出來要改什麼地方了XD,所以改了一個感覺意義不大的版本= =+
(總覺得會被飛踢...)

@G100my G100my requested a review from MontyPan December 27, 2019 07:48
@MontyPan
Copy link
Copy Markdown
Owner

好吧,我認輸了,這樣的確都符合條件而且還不用回答問題...... Orz

Copy link
Copy Markdown
Owner

@MontyPan MontyPan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Must FIX & Answer

請以 v4 為基礎,改出一個新的版本。這個新的版本要多接收一個 char[] 參數,並且以這個 char array 作為金字塔的內容物。也就是說,如果傳 v5(input, new char[]{'5', '4', '8', '7'},那麼金字塔就會依序印出這四個字。

然後請作答(寫在 JavaDoc 裡頭):

  • 改 v5 時發現的 v4 寫法方面的缺點
  • v5 有什麼隱憂

@G100my
Copy link
Copy Markdown
Collaborator Author

G100my commented Jan 5, 2020

  • 這樣作學理上可能會產生什麼風險?
  • 為什麼還是可以 / 要求你這樣作?

還是無法參透前幾次的問題,只把 L110 改成另一種寫法,
那時候把 L88~L90 拿掉是這樣改嗎?

@G100my G100my requested a review from MontyPan January 5, 2020 04:57
Copy link
Copy Markdown
Owner

@MontyPan MontyPan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Must Answer

本來是我思考不周全導致的出題不當(我很天真地以為你當初會搞 v5 的 L110,實際上你作出來的 L91 應該是最佳解),結果你自己找上門了 ==" (我都已經認輸了你還想怎麼樣 😭 ,難道要我賠睡來賠罪嗎? [脫衣服])

既然這樣,對,請回答你的 v5 可能會有什麼風險以及為什麼還是可以 / 要求你這麼作...... 💃

try try see (WTF?)

你上一個 must fix 都有正確回答到 🙆‍♂️

不過「v5 有什麼隱憂」這題目,我這邊至少還有發現一個重大隱憂,請試著找出來看看 [遠目]

murmur

不是很懂幹麼搞出一個 42280b3 ,你是有什麼特殊用意還是誤會什麼了 O.o

Comment thread basic/src/main/java/lo/basic/Issue12.java
@G100my
Copy link
Copy Markdown
Collaborator Author

G100my commented Jan 5, 2020

Q_Q 終於有一個正確回答了...(熱淚盈眶)

Reply - Must Answer

「有什麼風險以及為什麼還是可以 / 要求你這麼作」
(儘管確立了該往哪個方向想,但...我真的想不到可能的風險RRRR)

起初 int index 已經初始化為 0,array[n] 除非 array.length 本身就是 0 才會錯,
那程式在跑的順序應該是先處理[index % array.length],
得到的值不可能超出 0~array.length,小數點也不可能,如果型態錯誤,IDE會送出一個紅色小叉叉XD
再處理 array[index % array.length],最後 System.out.print(),
所以這邊好像沒什麼問題...
那最後的可能就一樣是寫法方面,那大概還是回到日後維護檢視的問題吧...orz

Reply - try try see

v5 另一個隱憂感覺是在傳入 new char[] {'5', '4', '8', '7'} 的時候,
如果該陣列的內容是 {5, '4', '8', '7'} 那列印出來的東西並不會是所預期的數字,
而是 5 這個代碼所代表的字元。

@G100my
Copy link
Copy Markdown
Collaborator Author

G100my commented Jan 5, 2020

murmur

不是很懂幹麼搞出一個 42280b3 ,你是有什麼特殊用意還是誤會什麼了 O.o

ㄟ...因為在寫完 v5 的時候發現這次沒有在裡面加上列印 "v5" 的程式碼,為求統一又順道想到上次有說過像這一類型的程式碼應該寫在上方可能比較洽當,而不是個別寫在每個 function 裡,所以就改了,改了之後又想到這種情況是不是應該分成兩個 commit 才比較好...

好啦 = = 我很多餘...

@G100my G100my requested a review from MontyPan January 5, 2020 07:42
@MontyPan MontyPan merged commit 2e1b1cd into MontyPan:master Jan 5, 2020
@MontyPan
Copy link
Copy Markdown
Owner

MontyPan commented Jan 5, 2020

你兩個 comment 就不能合成一個嘛.... 然後又沒有 commit 按下 request review 幹麼.... 好啦好啦這都純粹是碎念..... [下略數萬字]

以下全部都是 回應,當然你有問題想繼續討論蓋大樓也行,但總之 沒有要你再作些什麼


Must Answer

因為我這題當初出的不好,為了賠罪所以我直接講答案。(不過還是得詰譙一下你上一個 comment 我實在看不懂你在寫三小...... 😱 )

看到 L110,我們的確會擔心 index 會不會有 天元突破 超出 2147483647 的一天(忘記這個數字請再次去複習 primitive data type [指]),只要 x 夠大(謎之聲:多大?),的確就有可能炸,然後程式就掛了。

(假想一下你 日理萬姬 日看千行 code,很多時候沒辦法仔細考究每一行程式,很多時候就是憑經驗挑出壞味道而已,這是個很無奈的事實,所以請注意,即使有 code review,程式碼的責任還是在 committer 身上而不是 reviewer 身上)。

那麼,為什麼還是可以這麼作?答案是我一開始在題目當中埋了一個哏:「你可以假設 input 不會大於 40(因為古老螢幕最多就是 80 個 char)」,所以 index 也才 820,離爆炸很遙遠。

有這個假設,甚至一開始你給出這個版本我都會接受,甚至會給你起立鼓掌(但是還是會叫你改 💃 🤣 )

private static void whatTheFuck(int x) {
	//可以用字串的話看起來會更簡單暴力一點 lol
	int[][] output = {
			{1},
			{2, 3, 4},
			{5, 6, 7, 8, 9},
			{0, 1, 2, 3, 4, 5, 6},
			{7, 8, 9, 0, 1, 2, 3, 4, 5},
			//一直列到可以印出 40 個
	};

	for (int i = 0; i < x; i++) {
		for (int i2 = x - 1; i2 > i; i2--) {
			System.out.print("_");
		}
		for (int i2 = 0; i2 < output[i].length; i2++) {
			System.out.print(output[i][i2]);
		}
		System.out.println();
	}
}

等等,先別急著詰譙,這不全然是惡搞,我們的確會有這種「用空間換取時間」的作法,如果這個 method 很頻繁地被用到而且結果很顯然是固定可預期,那我們的確有可能就這麼做(例如求質數)。

不過這裡主要要講的是「善用前提」的重要性(看看這精美的 #15 😱 ),當然這裡又能岔出去扯到需求分析 & 詰譙無知案主牆頭草....... 這些哏,但這其實不妨礙「善用前提」的重要性,因為無論是 caller 給 callee 還是 callee 給 caller(aka 案主都是自己)都還是需要一定程度的前提假設來縮線 / 收斂需求。

try try see

你這邊提出了一個很有趣,而且我還真他媽沒想過的答案 [起立鼓掌]。 char 跟 int 可以無痛互通這實在是一個我過去一直難以理解的哏(但是在 debug 會遇到 whitespace 的程式時就很常用這招)

不過你這句話就讓答案歪掉了「那列印出來的東西並不會是所預期的數字」,沒有耶,那是 caller 的責任,你要我印這個我就真的印這個了,沒理由你這樣還要說是我(callee)的錯。

你(不小心? XD)用的「5」跟我想到的答案類似(甚至更暴力 XD),char 的範圍包山包海,古老就有的 ASCII 有定義一堆 whitespace(0~31 基本上都是),也就是說如果給 new char[]{10, 'a', 'b', 'c'} 就會天下大亂。

我當初想的 case 比較溫柔 / 可見一點,例如給 new char[]{'寫', '中', '文', '字', '1', '2', '3', '4', '5'} 這個 char array 就會讓金字塔變成比薩斜塔。

murmur

為求統一又順道想到上次有說過像這一類型的程式碼應該寫在上方可能比較洽當

就是怕你誤會這個。

我懶得翻舊帳了,我只記得說我說「你要把『印出 vX』定義為 method 的內容,我不會有意見」(同理,你現在要定義「印出 vX」不是 vX 的範圍,我也沒意見),你那時候是把 vX 之間的空行邏輯也寫在 vX 裡頭,那就違反了 SRP

@G100my
Copy link
Copy Markdown
Collaborator Author

G100my commented Jan 5, 2020

再釐清一個小細節:
寫法上

System.out.print(array[index % array.length]);
index += 1;

System.out.print(array[index]);
index = (index + 1) % array.length;

兩者寫法上的差異和試題本身並沒有太大關係囉?

@MontyPan
Copy link
Copy Markdown
Owner

MontyPan commented Jan 5, 2020

我前後丟了一堆問題,所以我不確定你要問哪個部份的「沒有太大關係」?

@G100my
Copy link
Copy Markdown
Collaborator Author

G100my commented Jan 5, 2020

拿掉 L88~L90拿掉 L88
因為這樣好像和把原本的段落拿掉改成

System.out.print(array[index % array.length]);
index += 1;

沒有太直接關係

@MontyPan
Copy link
Copy Markdown
Owner

MontyPan commented Jan 5, 2020

我還是不知道你在問什麼,「拿掉 L88~L90」那個時間點是對應 dbf4264 ,裡頭是這樣寫

	public static void v4(int x) {
		System.out.println("v4");
		int[] list = new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
		int index = 1;
		int limit = x * 2;
		for (int i = 1; i < limit; i += 2) {
			for (int i2 = 1; i2 < limit - i; i2 += 2) {
				System.out.print(" ");
			}
			for (int i2 = 0; i2 < i; i2++) {
				if (index % 10 == 0) {    //這是 L88
					index = 0;
				}
				System.out.print(list[index]);
				index += 1;
			}
			System.out.println();
		}
	}

如果要徹底拔掉 L88~L90,理論上就只剩下你上上個 comment 列出來的那兩個寫法。

所以你到底要問什麼?

@G100my
Copy link
Copy Markdown
Collaborator Author

G100my commented Jan 5, 2020

第一次是[拿掉 L88~L90],

public static void v4(int x) {
	System.out.println("v4");
	int[] list = new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
	int index = 1;
	int limit = x * 2;
	for (int i = 1; i < limit; i += 2) {
		for (int i2 = 1; i2 < limit - i; i2 += 2) {
			System.out.print(" ");
		}
		for (int i2 = 0; i2 < i; i2++) {
(L88)		if (index % 10 == 0) {
(L89)			index = 0;
(L90)		}
			System.out.print(list[index]);
			index += 1;
		}
		System.out.println();
	}
}

第二次是[拿掉 L88],

public static void v4(int x) {
	System.out.println("v4");
	int[] list = new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
	int index = 1;
	int limit = x * 2;
	for (int i = 1; i < limit; i += 2) {
		for (int i2 = 1; i2 < limit - i; i2 += 2) {
			System.out.print(" ");
		}
		for (int i2 = 0; i2 < i; i2++) {
(L88)		index = index % 10;
			System.out.print(list[index]);
			index += 1;
		}
		System.out.println();
	}

到最後面我做v5後,把前面兩次拿掉改進去

public static void v5(int x, char[] array) {
	int index = 0;
	int limit = x * 2;
	for (int i = 1; i < limit; i += 2) {
		for (int i2 = 1; i2 < limit - i; i2 += 2) {
			System.out.print(" ");
		}
		for (int i2 = 0; i2 < i; i2++) {
(改)		System.out.print(array[index % array.length ]);
			index = index + 1;
		}
		System.out.println();
	}
}

改完之後得到「以為你當初會搞 v5 的 L110」這樣的回覆,
因此我從這樣的文字敘述得到「當初要改的就是改成上面標示的 (改) 」,
所以想確定一下可能產生風險的部分
是否與處理 index 值的程式碼位置是否放在 System.out.print() 裡面無關?

@MontyPan
Copy link
Copy Markdown
Owner

MontyPan commented Jan 5, 2020

最後補個刀......

是否與處理 index 值的程式碼的位置是否放在 System.out.print() 裡面無關?

這個文句非常的... 不能說不通順,只能說斷句要斷很久。我們會盡量避免寫出雙重否定的句型(你這是雙重疑問句,更可怕...... 😱 )

還有,像這種時候,你最好先講你的看法。至少告訴我「你覺得有 or 沒有關係」、可以的話還講一下理由是啥...... etc,而不是丟一個半開放式的問題讓我去自由作答。 那我就會從盤古開天開始講起

如果你一開頭就說「我看不出來 v4 跟 v5 有什麼差別(所以看不出來跟題目的關係)」,我可以直接吐完血之後開幹,而不是連你在講哪一國話都不確定。

@G100my
Copy link
Copy Markdown
Collaborator Author

G100my commented Jan 5, 2020

好的-_- 下次會盡量讓你直接吐完血之後開幹...

@G100my G100my deleted the issue12 branch January 10, 2020 06:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants