ਜਾਣੋ ਕਿ Robert Griesemer ਦੀ ਭਾਸ਼ਾ ਇੰਜੀਨੀਅਰਿੰਗ ਸੋਚ ਅਤੇ ਅਸਲੀ ਦੁਨੀਆ ਦੀਆਂ ਸੀਮਾਵਾਂ ਨੇ Go ਦੇ ਕੰਪਾਇਲਰ ਡਿਜ਼ਾਈਨ, ਤੇਜ਼ ਬਿਲਡ ਅਤੇ ਡਿਵੈਲਪਰ ਉਤਪਾਦਕਤਾ ਨੂੰ ਕਿਵੇਂ ਪ੍ਰਭਾਵਿਤ ਕੀਤਾ।

ਤੁਸੀਂ ਕੰਪਾਇਲਰ ਬਾਰੇ ਸੋਚ ਨਹੀਂ ਕਰਦੇ ਜਦ ਤੱਕ ਕੁਝ ਟੁੱਟਦਾ ਨਹੀਂ—ਪਰ ਇੱਕ ਭਾਸ਼ਾ ਦੇ ਕੰਪਾਇਲਰ ਅਤੇ ਟੂਲਿੰਗ ਦੇ ਫੈਸਲੇ ਚੁੱਪਚਾਪ ਤੁਹਾਡੇ ਸਾਰੇ ਦਿਨ-ਚੱਕਰ ਨੂੰ ਅਕਸਰ ਸ਼ੇਪ ਕਰਦੇ ਹਨ। ਤੁਸੀਂ ਕਿਸ ਹੱਦ ਤੱਕ ਬਿਲਡ ਲਈ ਇੰਤਜ਼ਾਰ ਕਰਦੇ ਹੋ, ਰਿਫੈਕਟਰ ਕਰੋ ਤਾਂ ਕਿੰਨਾ ਸੁਰੱਖਿਅਤ ਮਹਿਸੂਸ ਹੁੰਦਾ ਹੈ, ਕੋਡ ਸਮੀਖਿਆ ਕਿੰਨੀ ਆਸਾਨ ਹੈ, ਅਤੇ ਤੁਸੀਂ ਕਿਸ ਹੱਦ ਤੱਕ ਆਤਮਵਿਸ਼ਵਾਸ ਨਾਲ ਸ਼ਿਪ ਕਰ ਸਕਦੇ ਹੋ — ਇਹ ਸਭ ਭਾਸ਼ਾ ਇੰਜੀਨੀਅਰਿੰਗ ਫੈਸਲਿਆਂ ਦੇ ਨਤੀਜੇ ਹਨ।
ਜਦੋਂ ਬਿਲਡ ਸੈਕੇਂਡਾਂ ਵਿੱਚ ਹੁੰਦਾ ਹੈ ਨਾ ਕਿ ਮਿੰਟਾਂ ਵਿੱਚ, ਤੁਸੀਂ ਟੈਸਟ ਜ਼ਿਆਦਾ ਚਲਾਉਂਦੇ ਹੋ। ਜਦੋਂ ਐਰਰ ਸੁਨੇਹੇ ਸੁਚੱਜੇ ਅਤੇ ਇੱਕਸਾਰ ਹੁੰਦੇ ਹਨ, ਤੁਸੀਂ ਬੱਗ ਤੇਜ਼ੀ ਨਾਲ ਠੀਕ ਕਰਦੇ ਹੋ। ਜਦੋਂ ਟੂਲ ਫਾਰਮੈਟਿੰਗ ਅਤੇ ਪੈਕੇਜ ਸਟ੍ਰਕਚਰ 'ਤੇ ਸਹਿਮਤ ਹੁੰਦੇ ਹਨ, ਟੀਮਾਂ ਸਟਾਈਲ ਬਾਰੇ ਘੱਟ ਵਕਾਲਤ ਬਹੁਤ ਘੱਟ ਕਰਦੀਆਂ ਹਨ ਅਤੇ ਪ੍ਰੋਡਕਟ ਸਮੱਸਿਆਵਾਂ ਹੱਲ ਕਰਨ 'ਤੇ ਜ਼ਿਆਦਾ ਧਿਆਨ ਦਿੰਦੀਆਂ ਹਨ। ਇਹ “ਚੰਗਾ ਹੋਣ ਵਾਲਾ” ਨਹੀਂ ਹਨ; ਇਹ ਘੱਟ ਵਿੱਘਟਨ, ਘੱਟ ਖਤਰਨਾਕ ਰਿਲੀਜ਼ ਅਤੇ ਵਿਚਾਰ ਤੋਂ ਪ੍ਰੋਡਕਸ਼ਨ ਤੱਕ ਇੱਕ ਸਾਫ਼ ਰਸਤਾ ਬਣਾਉਂਦੇ ਹਨ।
Robert Griesemer Go ਦੇ ਪਿੱਛੇ ਦੇ ਭਾਸ਼ਾ ਇੰਜੀਨੀਅਰਾਂ 'ਚੋਂ ਇੱਕ ਹਨ। ਇੱਥੇ "ਭਾਸ਼ਾ ਇੰਜੀਨੀਅਰ" ਨੂੰ ਸਿਰਫ "ਜੋ ਵਿਅਾਕਰਨ ਨਿਯਮ ਲਿਖਦਾ ਹੈ" ਵਜੋਂ ਨਾ ਸੋਚੋ, ਬਲਕਿ ਉਸੇ ਵਿਅਕਤੀ ਵਜੋਂ ਸੋਚੋ ਜੋ ਭਾਸ਼ਾ ਦੇ ਆਸਪਾਸ ਦਾ ਸਿਸਟਮ ਡਿਜ਼ਾਈਨ ਕਰਦਾ ਹੈ: ਕੰਪਾਇਲਰ ਕਿਸ ਗੱਲ ਲਈ Optimize ਕਰੇ, ਕਿਹੜੇ trade-offs ਮਨਜੂਰਯੋਗ ਹਨ, ਅਤੇ ਕਿਹੜੇ ਡਿਫੌਲਟਸ ਅਸਲੀ ਟੀਮਾਂ ਨੂੰ ਉਤਪਾਦਕ ਬਣਾਉਂਦੇ ਹਨ।
ਇਹ ਲੇਖ ਜੀਵਨੀ ਨਹੀਂ ਹੈ ਅਤੇ ਨਾ ਹੀ ਗਹਿਰਾਈ ਨਾਲ ਕੰਪਾਇਲਰ ਥਿਊਰੀ ਵਿੱਚ ਡੁੱਬਦਾ ਹੈ। ਇਸ ਦੀ ਬਜਾਏ, ਇਹ Go ਨੂੰ ਇੱਕ ਪ੍ਰਾਇਕਟਿਕਲ ਕੇਸ ਅਧਿਐਨ ਵਜੋਂ ਵਰਤਦਾ ਹੈ ਕਿ ਕਿਸ ਤਰ੍ਹਾਂ ਬਾਧਾਵਾਂ—ਜਿਵੇਂ ਬਿਲਡ ਰਫ਼ਤਾਰ, ਕੋਡਬੇਸ ਦਾ ਵਾਧਾ ਅਤੇ ਰੱਖ-ਰਖਾਅ—ਭਾਸ਼ਾ ਨੂੰ ਕੁਝ ਫੈਸਲਿਆਂ ਵੱਲ ਧਿਆਨ ਦਿਵਾਉਂਦੀਆਂ ਹਨ।
ਅਸੀਂ ਉਹ ਪ੍ਰਾਇਕਟਿਕਲ ਬਾਧਾਵਾਂ ਅਤੇ trade-offs ਵੇਖਾਂਗੇ ਜਿਓਂ ਨੇ Go ਦੇ ਅਨੁਭਵ ਅਤੇ ਪ੍ਰਦਰਸ਼ਨ ਨੂੰ ਪ੍ਰਭਾਵਿਤ ਕੀਤਾ, ਅਤੇ ਉਹ ਰੋਜ਼ਾਨਾ ਉਤਪਾਦਕਤਾ ਦੇ ਨਤੀਜੇ ਵਿੱਚ ਕਿਵੇਂ ਤਬਦੀਲ ਹੋਂਦੇ ਹਨ। ਇਸ ਵਿੱਚ ਸ਼ਾਮਲ ਹੈ ਕਿ ਸਾਦਗੀ ਨੂੰ ਇੱਕ ਇੰਜੀਨੀਅਰਿੰਗ ਰਣਨੀਤੀ ਕਿਉਂ ਮੰਨਿਆ ਜਾਂਦਾ ਹੈ, ਤੇਜ਼ ਕੰਪਾਇਲੇਸ਼ਨ ਵਰਕਫਲੋਜ਼ ਨੂੰ ਕਿਵੇਂ ਬਦਲਦਾ ਹੈ, ਅਤੇ ਟੂਲਿੰਗ ਰੀਤੀ-ਰਿਵਾਜ ਕਿੰਨੇ ਮਹੱਤਵਪੂਰਨ ਹਨ।
ਰਾਹ ਵਿੱਚ, ਅਸੀਂ ਇੱਕ ਸਧਾਰਨ ਸਵਾਲ ਵਾਰ-ਵਾਰ ਪੁੱਛਾਂਗੇ: “ਇਹ ਡਿਜ਼ਾਈਨ ਚੋਣ ਕਿਸ ਆਮ ਮੰਗਲਵਾਰ ਨੂੰ ਇੱਕ ਡਿਵੈਲਪਰ ਲਈ ਬਦਲਦੀ ਹੈ?” ਇਹ ਨਜ਼ਰੀਆ ਭਾਸ਼ਾ ਇੰਜੀਨੀਅਰਿੰਗ ਨੂੰ ਸਬੰਧਿਤ ਬਣਾਉਂਦਾ ਹੈ—ਚਾਹੇ ਤੁਸੀਂ ਕੰਪਾਇਲਰ ਕੋਡ ਨੂੰ ਕਦੇ ਵੀ ਛੂਹੋ ਨਾ।
“ਭਾਸ਼ਾ ਇੰਜੀਨੀਅਰਿੰਗ” ਇੱਕ ਭਾਸ਼ਾ ਨੂੰ ਇੱਕ ਵਹਿਚਿਤ ਵਰਤੋਂਯੋਗ ਚੀਜ਼ ਬਣਾਉਣ ਦਾ ਪ੍ਰਾਇਕਟਿਕ ਕੰਮ ਹੈ—ਉਹ ਤੁਹਾਡੇ ਲਈ ਇਸਤੋਂ ਲਿਖਣ, ਬਿਲਡ ਕਰਨ, ਟੈਸਟ ਕਰਨ, ਡੀਬੱਗ ਕਰਨ, ਸ਼ਿਪ ਕਰਨ ਅਤੇ ਸਾਲਾਂ ਤੱਕ maintain ਕਰਨ ਯੋਗ ਬਣਾਉਂਦਾ ਹੈ।
ਭਾਸ਼ਾਵਾਂ ਨੂੰ ਆਮ ਤੌਰ 'ਤੇ ਇੱਕ ਸੈੱਟ ਫੀਚਰਾਂ ਵਜੋਂ ਗੱਲ ਕਰਨਾ ਆਸਾਨ ਹੈ ("generics", "exceptions", "pattern matching")। ਭਾਸ਼ਾ ਇੰਜੀਨੀਅਰਿੰਗ ਇਹ ਪਰੇਖਦਾਰ ਕਰਦਾ ਹੈ: ਜਦੋਂ ਹਜ਼ਾਰਾਂ ਫਾਈਲਾਂ, ਦਜਿਆ ਦੀਆਂ ਟੀਮਾਂ ਅਤੇ ਕੱਸੇ ਡੇਡਲਾਈਨ ਆਂਗੇ, ਤਾਂ ਉਹ ਫੀਚਰ ਕਿਸ ਤਰ੍ਹਾਂ ਵਰਤੋਂਕਾਰਾਂ ਨੂੰ ਮਹਿਸੂਸ ਹੁੰਦੇ ਹਨ।
ਇੱਕ ਭਾਸ਼ਾ ਦੇ ਦੋ ਵੱਡੇ ਪਾਸੇ ਹਨ:
ਦੋ ਭਾਸ਼ਾਵਾਂ ਕਾਗਜ਼ 'ਤੇ ਮਿਲਦੀਆਂ ਹੋ ਸਕਦੀਆਂ ਹਨ, ਪਰ ਅਮਲ ਵਿੱਚ ਬਿਲਕੁਲ ਵੱਖਰੀ ਮਹਿਸੂਸ ਹੋ ਸਕਦੀਆਂ ਹਨ ਕਿਉਂਕਿ ਉਨ੍ਹਾਂ ਦੇ ਟੂਲਿੰਗ ਅਤੇ ਕੰਪਾਇਲੇਸ਼ਨ ਮਾਡਲ ਵੱਖ-ਵੱਖ build ਸਮਿਆਂ, ਐਰਰ ਸੁਨੇਹਿਆਂ, ਏਡੀਟਰ ਸਹਾਇਤਾ ਅਤੇ runtime ਵਿਹਾਰ ਵੱਲ ਲੈ ਜਾਂਦੇ ਹਨ।
ਬਾਧਾਵਾਂ ਉਹ ਹਕੀਕਤੀ-ਦੁਨੀਆ ਸੀਮਾਵਾਂ ਹਨ ਜੋ ਡਿਜ਼ਾਈਨ ਫੈਸਲਿਆਂ ਨੂੰ ਸ਼ੇਪ ਕਰਦੀਆਂ ਹਨ:
ਕਲਪਨਾ ਕਰੋ ਕਿ ਤੁਸੀਂ ਇੱਕ ਐਸਾ ਫੀਚਰ ਵਧਾਉਂਦੇ ਹੋ ਜੋ ਕੰਪਾਇਲਰ ਤੋਂ ਸਾਰੇ ਕੋਡਬੇਸ 'ਤੇ ਭਾਰੀ ਗਲੋਬਲ ਵਿਸ਼ਲੇਸ਼ਣ ਮੰਗਦਾ ਹੈ (ਉਦਾਹਰਣ ਲਈ, ਜ਼ਿਆਦਾ ਅਡਵਾਂਸਡ ਟਾਈਪ ਇੰਫ੍ਰੈਂਸ)। ਇਹ ਕੋਡ ਨੂੰ ਸਾਫ਼-ਸੁਥਰਾ ਬਣਾਉਂਦਾ—ਘੱਟ ਅਣੁਕੂਲਤਾ, ਘੱਟ ਸਪਸ਼ਟ ਟਾਈਪ—ਪਰ ਇਹ ਕੰਪਾਇਲੇਸ਼ਨ ਨੂੰ ਧੀਮਾ ਵੀ ਕਰ ਸਕਦਾ ਹੈ, ਐਰਰ ਸੁਨੇਹੇ ਸਮਝਣਯੋਗ ਨਹੀਂ ਬਣ ਸਕਦੇ, ਅਤੇ ਇੰਕ੍ਰੀਮੈਂਟਲ ਬਿਲਡ ਅਣਪੇਖਿਤ ਹੋ ਸਕਦੇ ਹਨ।
ਭਾਸ਼ਾ ਇੰਜੀਨੀਅਰਿੰਗ ਇਹ ਫੈਸਲਾ ਕਰਦੀ ਹੈ ਕਿ ਕੀ ਉਹ trade-off ਸਮੁੱਚੇ ਉਤਪਾਦਕਤਾ ਲਈ ਫਾਇਦੇਮੰਦ ਹੈ—ਸਿਰਫ ਇਹ ਨਹੀਂ ਕਿ ਫੀਚਰ ਸੁੰਦਰ ਹੈ।
Go ਹਰ ਇੱਕ ਭਾਸ਼ਾ ਤਰਕ ਨੂੰ ਜਿੱਤਣ ਲਈ ਬਣਾਇਆ ਨਹੀਂ ਗਿਆ। ਇਹ ਉਹਨਾਂ ਕੁਝ ਲਕੜੀਆਂ 'ਤੇ ਧਿਆਨ ਕੇਂਦਰਿਤ ਕਰਨ ਲਈ ਬਣਾਇਆ ਗਿਆ ਜੋ ਟੀਮਾਂ ਵੱਲੋਂ ਸੌਫਟਵੇਅਰ ਬਣਾਉਣ, ਅਕਸਰ ਸ਼ਿਪ ਕਰਨ ਅਤੇ ਸਾਲਾਂ ਤੱਕ maintain ਕਰਨ ਵੇਲੇ ਮਹੱਤਵਪੂਰਨ ਹੋਂਦੀਆਂ ਹਨ।
Go ਦਾ ਬਹੁਤ ਸਾਰਾ "ਅਹਿਸਾਸ" ਇਸ ਵੱਲ ਇਸ਼ਾਰਾ ਕਰਦਾ ਹੈ ਕਿ ਇੱਕ ਸਾਥੀ ਪਹਿਲੀ ਨਜ਼ਰ 'ਤੇ ਕੋਡ ਨੂੰ ਸਮਝ ਸਕੇ। ਸੁਚਿਤਾ ਸਿਰਫ ਸੁੰਦਰਤਾ ਨਹੀਂ—ਇਹ ਪ੍ਰਭਾਵਿਤ ਕਰਦੀ ਹੈ ਕਿ ਕੋਈ ਬਦਲਾਅ ਕਿੰਨੀ ਤੇਜ਼ੀ ਨਾਲ ਸਮੀਖਿਆ ਕੀਤਾ ਜਾ ਸਕਦਾ ਹੈ, ਖਤਰਾ ਕਿੰਨਾ ਤੇਜ਼ੀ ਨਾਲ ਪਛਾਣਿਆ ਜਾ ਸਕਦਾ ਹੈ, ਜਾਂ ਇੱਕ ਸੁਰੱਖਿਅਤ ਸੁਧਾਰ ਕਿਵੇਂ ਕੀਤਾ ਜਾ ਸਕਦਾ ਹੈ।
ਇਸੇ ਕਰਕੇ Go ਆਮ ਤੌਰ 'ਤੇ ਸਿੱਧੇ ਰੂਪਕਾਂ ਅਤੇ ਇੱਕ ਛੋਟੀ ਕੋਰ ਫੀਚਰ ਸੈਟ ਨੂੰ ਤਰਜੀਹ ਦਿੰਦਾ ਹੈ। ਜਦੋਂ ਭਾਸ਼ਾ ਰੁਝਾਨੀ ਪੈਟਰਨ ਭਰੋਸੇਯੋਗ ਬਣਾਉਂਦੀ ਹੈ, ਕੋਡਬੇਸ ਸਕੈਨ ਕਰਨ ਲਈ ਆਸਾਨ ਬਣ ਜਾਂਦੇ ਹਨ, ਕੋਡ ਸਮੀਖਿਆ ਵਿੱਚ ਚਰਚਾ ਕਰਨ ਲਈ ਆਸਾਨ ਹੁੰਦੇ ਹਨ, ਅਤੇ "ਲੋਕਲ ਹੀਰੋਜ਼" ਤੇ ਘੱਟ ਨਿਰਭਰ ਬਣ ਜਾਂਦੇ ਹਨ ਜੋ ਟ੍ਰਿਕਸ ਜਾਣਦੇ ਹਨ।
Go ਨੂੰ ਤੁਰੰਤ compile-and-run ਸਾਈਕਲਾਂ ਦੇ ਸਮਰਥਨ ਲਈ ਡਿਜ਼ਾਈਨ ਕੀਤਾ ਗਿਆ। ਇਹ ਇੱਕ ਪ੍ਰਾਇਕਟਿਕ ਉਤਪਾਦਕਤਾ ਲਕੜੀ ਵਜੋਂ ਸਾਹਮਣੇ ਆਉਂਦੀ ਹੈ: ਜਿੰਨੀ ਤੇਜ਼ ਤੁਸੀਂ ਇੱਕ ਵਿਚਾਰ ਨੂੰ ਟੈਸਟ ਕਰ ਸਕਦੇ ਹੋ, ਉਦੋ ਤੁਸੀਂ ਘੱਟ ਸਮਾਂ context-switching, ਸ਼ੱਕ ਕਰਨ ਜਾਂ ਟੂਲਿੰਗ ਦੀ ਉਡੀਕ ਵਿੱਚ ਗੁਜ਼ਾਰਦੇ ਹੋ।
ਟੀਮ 'ਚ ਛੋਟੇ ਫੀਡਬੈਕ ਲੂਪ ਮਿਲ ਕੇ ਗੁਣਵੱਤਾ ਬਣਾਉਂਦੇ ਹਨ। ਇਹ ਨਵੇਂ ਆਉਣ ਵਾਲਿਆਂ ਨੂੰ ਪਰਯੋਗ ਕਰਕੇ ਸਿੱਖਣ ਵਿੱਚ ਮਦਦ ਕਰਦੇ ਹਨ, ਅਤੇ ਤਜ਼ਰਬੇਕਾਰ ਇੰਜੀਨੀਅਰਾਂ ਨੂੰ ਛੋਟੇ, ਅਕਸਰ ਸੁਧਾਰ ਕਰਨ ਲਈ ਪ੍ਰੋਤਸਾਹਿਤ ਕਰਦੇ ਹਨ ਬਜਾਏ ਕਿ ਵੱਡੇ, ਖਤਰਨਾਕ mega-PRs ਕਰਨ ਦੇ।
Go ਦਾ ਸਧਾਰਣ deployable ਆਰਟੀਫੈਕਟ ਬਣਾਉਣ ਦਾ ਅਭਿਗਮ ਲੰਮੇ ਸਮੇਂ ਚੱਲਣ ਵਾਲੇ ਬੈਕਐਂਡ ਸਰਵਿਸ ਲਈ ਮੈਚ ਕਰਦਾ ਹੈ: ਅੱਪਗ੍ਰੇਡ, ਰੋਲਬੈਕ ਅਤੇ ਇੰਸੀਡੈਂਟ ਜਵਾਬ। ਜਦੋਂ ਡਿਪਲੋਇਮੈਂਟ ਪ੍ਰਡਿਕਟੇਬਲ ਹੁੰਦਾ ਹੈ, ਆਪਰੇਸ਼ਨ ਦਾ ਕੰਮ ਘੱਟ ਨਾਜ਼ੁਕ ਹੁੰਦਾ ਹੈ—ਅਤੇ ਇੰਜੀਨੀਅਰਿੰਗ ਟੀਮਾਂ ਪੈਕਜਿੰਗ ਦੀ ਪਹੇਚਾਣ ਕਰਨ ਦੀ ਬਜਾਏ ਵਿਹਾਰ 'ਤੇ ਧਿਆਨ ਦੇ ਸਕਦੀਆਂ ਹਨ।
ਇਹ ਲਕੜੀਆਂ ਉਪਲਬਧਾਂ ਦੀ ਤਰ੍ਹਾਂ ਹੀ ਛੋਡਣਾਂ 'ਚ ਵੀ ਪ੍ਰਭਾਵਿਤ ਹੁੰਦੀ ہیں। Go ਅਕਸਰ ਉਹ ਫੀਚਰ ਨਾ ਜੋੜਨ ਨੂੰ ਤਰਜੀਹ ਦਿੰਦਾ ਜੋ ਵਿਅਕਤੀਗਤ ਤੌਰ 'ਤੇ ਜ਼ਿਆਦਾ ਅਭਿਵਿਆਕਤਾਵਾਦੀਆਂ ਨੂੰ ਦਿੰਦੇ ਹੋਣ, ਪਰ ਉਨ੍ਹਾਂ ਨਾਲ cognitive load ਵਧ ਸਕਦਾ, tooling ਨੂੰ ਜਟਿਲ ਕਰ ਸਕਦਾ ਜਾਂ ਕੋਡ ਨੂੰ ਇੱਕ ਵੱਡੀ ਸੰਸਥਾ ਵਿੱਚ ਇੱਕ ਵਰਗੇਕਰਨ ਦੇ ਲਾਇਕ ਬਣਾਉਣਾ ਮੁਸ਼ਕਲ ਹੋ ਸਕਦਾ। ਨਤੀਜਾ ਇਹ ਹੈ ਕਿ ਭਾਸ਼ਾ steady team throughput ਲਈ optimize ਕੀਤੀ ਗਈ ਹੈ, ਹਰ ਕੋਨੇ ਵਿੱਚ ਅਕਸਮਾਤ ਫਲੈਕਸੀਬਿਲਟੀ ਲਈ ਨਹੀਂ।
Go ਵਿੱਚ ਸਾਦਗੀ ਇੱਕ ਸੁਸ਼ਾਸਨ ਸਾਧਨ ਹੈ। Robert Griesemer ਅਤੇ Go ਟੀਮ ਨੇ ਭਾਸ਼ਾ ਡਿਜ਼ਾਈਨ ਨੂੰ ਇਸ ਤਰੀਕੇ ਨਾਲ ਵੇਖਿਆ ਕਿ ਉਹ ਹਜ਼ਾਰਾਂ ਡਿਵੈਲਪਰਾਂ ਦੁਆਰਾ, ਸਮਾਂ-ਦਬਾਅ ਹੇਠ, ਵੱਖ-ਵੱਖ ਕੋਡਬੇਸਾਂ 'ਚ ਜ਼ਿੰਦਾ ਰਹੇਗੀ। ਜਦੋਂ ਭਾਸ਼ਾ ਘੱਟ “ਬਰਾਬਰ-ਵੈਧ” ਵਿਕਲਪ ਦਿੰਦੀ ਹੈ, ਟੀਮਾਂ ਸਟਾਈਲ ਦੀਆਂ ਦੁਹਰਾਈਆਂ ਤੇ ਘੱਟ ਊਰਜਾ ਖਰਚ ਕਰਦੀਆਂ ਹਨ ਅਤੇ ਜ਼ਿਆਦਾ ਸ਼ਿਪ ਕਰਨ 'ਤੇ ਧਿਆਨ ਦਿੰਦੀਆਂ ਹਨ।
ਵੱਡੇ ਪ੍ਰੋਜੈਕਟਾਂ ਵਿੱਚ ਜ਼ਿਆਦਾ ਉਤਪਾਦਕਤਾ ਦਾ ਘਰਵਾੜਾ ਅਕਸਰ ਸਧਾ ਕੋਡਿੰਗ ਗਤੀ ਨਹੀਂ ਹੁੰਦਾ; ਇਹ ਲੋਕਾਂ ਵਿਚਕਾਰ friction ਹੁੰਦਾ ਹੈ। ਇਕਸਾਰ ਭਾਸ਼ਾ ਇਕ ਲਾਈਨ ਕੋਡ 'ਤੇ ਲੈਣ ਵਾਲੇ ਫੈਸਲਿਆਂ ਦੀ ਗਿਣਤੀ ਘਟਾਉਂਦੀ ਹੈ। ਘੱਟ ਤਰੀਕੇ ਹੋਣ ਨਾਲ, ਡਿਵੈਲਪਰ ਅਨੁਮਾਨ ਲਗਾ ਸਕਦੇ ਹਨ ਕਿ ਉਹ ਅਗਲੇ ਪੰਕਤਿ 'ਚ ਕੀ ਦੇਖਣ ਵਾਲੇ ਹਨ, ਭਾਵੇਂ ਉਹ ਅਣਜਾਣ ਰੀਪੋ 'ਚ ਹੋਣ।
ਇਹ ਪੇਸ਼ਗੀ ਦਿਨ-ਚਰਿਆ ਵਿੱਚ ਮਾਇਨੇ ਰੱਖਦੀ ਹੈ:
ਵੱਡਾ ਫੀਚਰ ਸੈੱਟ ਰਿਵਿਊਅਰਾਂ ਲਈ ਸਮਝਣ ਅਤੇ ਲਾਗੂ ਕਰਨ ਲਈ ਸਤਹ ਵਧਾਉਂਦਾ ਹੈ। Go ਜ਼ਿੰਮੇਵਾਰ ਤੌਰ 'ਤੇ "ਕਿਵੇਂ" ਨੂੰ ਸੀਮਤ ਰੱਖਦਾ ਹੈ: ਇਦੀਅਮ ਹਨ, ਪਰ ਘੱਟ ਵਿ-ਵਿਧ ਧਾਰਾਵਾਂ। ਇਹ ਸਮੀਖਿਆ churn ਘਟਾਉਂਦਾ ਹੈ ਜਿਵੇਂ "ਇਸ ਅਭਿਕਾਰ ਨੂੰ ਵਰਤੋ" ਜਾਂ "ਅਸੀਂ ਇਸ metaprogramming ਟਰਿਕ ਦੀ ਬਜਾਏ ਇਹ ਪਸੰਦ ਕਰਦੇ ਹਾਂ"।
ਜਦੋਂ ਭਾਸ਼ਾ ਸੰਭਾਵਨਾਵਾਂ ਨੂੰ ਸੰਕੀ혼 ਕਰ ਦਿੰਦੀ ਹੈ, ਟੀਮ ਦੇ ਮਿਆਰ ਇਕਸਾਰ ਤਰੀਕੇ ਨਾਲ ਲਾਗੂ ਹੋਣਾ ਆਸਾਨ ਹੋ ਜਾਂਦਾ ਹੈ—ਵਿਸ਼ੇਸ਼ ਕਰਕੇ ਕਈ ਸਰਵਿਸਾਂ ਅਤੇ ਲੰਮੇ ਸਮੇਂ ਚੱਲਣ ਵਾਲੇ ਕੋਡ 'ਚ।
ਬਾਧਾਵਾਂ ਇਕ ਪਲ ਵਾਸਤੇ ਸੀਮਤ ਮਹਿਸੂਸ ਹੋ ਸਕਦੀਆਂ ਹਨ, ਪਰ ਪੈਮਾਨੇ 'ਤੇ ਅਕਸਰ ਨਤੀਜੇ ਬਿਹਤਰ ਹੁੰਦੇ ਹਨ। ਜੇ ਹਰ ਕੋਈ ਇੱਕੋ ਛੋਟੇ ਸਮੂਹ ਦੀਆਂ ਰਚਨਾਵਾਂ ਤੱਕ ਪਹੁੰਚ ਰੱਖਦਾ ਹੈ, ਤਾਂ ਤੁਸੀਂ ਹੋਰ ਯੂਨੀਫਾਰਮ ਕੋਡ, ਘੱਟ ਲੋਕਲ ਉਪਭਾਸ਼ਾਵਾਂ, ਅਤੇ ਉਸ "ਇੱਕ ਵਿਅਕਤੀ" ਤੇ ਘੱਟ ਨਿਰਭਰਤਾ ਪਾਉਂਦੇ ਹੋ ਜੋ ਇਸ ਰੁਝਾਨ ਨੂੰ ਜਾਣਦਾ ਹੈ।
Go ਵਿੱਚ, ਤੁਸੀਂ ਅਕਸਰ ਸਿੱਧੇ ਪੈਟਰਨ ਵੇਖੋਗੇ:
if err != nil { return err })ਦੂਜੇ ਭਾਸ਼ਾਵਾਂ ਵਿੱਚ ਜਿਥੇ ਇੱਕ ਟੀਮ macros 'ਤੇ ਭਰੋਸਾ ਕਰਦੀ ਹੈ, ਦੂਜੀ inheritance 'ਤੇ ਅਤੇ ਤੀਜੀ operator overloading 'ਤੇ, ਹਰ ਇੱਕ "ਸ਼ਕਤੀਸ਼ালী" ਹੋ ਸਕਦੀ ਹੈ, ਪਰ ਇਹ ਪ੍ਰੋਜੈਕਟਾਂ 'ਚ ਹਿਲ-ਜੁਲ ਨੂੰ ਵਧਾਉਂਦਾ ਹੈ—ਅਤੇ ਕੋਡ ਸਮੀਖਿਆ ਨੂੰ ਇੱਕ debate club ਵਿੱਚ ਬਦਲ ਦਿੰਦਾ ਹੈ।
ਬਿਲਡ ਰਫ਼ਤਾਰ ਕੋਈ ਸ਼ਾਨਦਾਰ ਮੈਟਰਿਕ ਨਹੀਂ—ਇਹ ਤੁਹਾਡੇ ਕੰਮ ਕਰਨ ਦੇ ਤਰੀਕੇ ਨੂੰ ਸਿੱਧਾ ਆਕਾਰ ਦਿੰਦੀ ਹੈ।
ਜਦੋਂ ਇੱਕ ਬਦਲਾਅ ਸਕਿੰਞਡਾਂ ਵਿੱਚ ਕੰਪਾਇਲ ਹੋ ਜਾਂਦਾ ਹੈ, ਤੁਸੀਂ ਸਮੱਸਿਆ ਵਿੱਚ ਹੀ ਰ੍ਹੈਂਦੇ ਹੋ। ਤੁਸੀਂ ਇੱਕ ਵਿਚਾਰ ਟ੍ਰਾਈ ਕਰਦੇ ਹੋ, ਨਤੀਜਾ ਦੇਖਦੇ ਹੋ, ਅਤੇ ਠੀਕ ਕਰਦੇ ਹੋ। ਉਹ ਤੰਗ ਲੂਪ ਤੁਹਾਡੇ ਧਿਆਨ ਨੂੰ ਕੋਡ 'ਤੇ ਰੱਖਦਾ ਹੈ ਨਾਂ ਕਿ context-switching 'ਤੇ। ਇਹ اثر CI ਵਿੱਚ ਵੀ ਲਾਗੂ ਹੁੰਦਾ ਹੈ: ਤੇਜ਼ ਬਿਲਡ ਦਾ ਮਤਲਬ ਤੇਜ਼ PR ਚੈੱਕ, ਛੋਟੀ ਕਤਾਰਾਂ, ਅਤੇ ਘੱਟ ਇੰਤਜ਼ਾਰ।
ਤੇਜ਼ ਬਿਲਡ ਛੋਟੇ, ਅਕਸਰ commit ਕਰਨ ਨੂੰ ਉਤਸ਼ਾਹਤ ਕਰਦੇ ਹਨ। ਛੋਟੇ ਬਦਲਾਅ ਆਸਾਨ ਸਮੀਖਿਆ, ਆਸਾਨ ਟੈਸਟ ਅਤੇ ਘੱਟ ਖਤਰੇ ਵਾਲੇ ਹੁੰਦੇ ਹਨ। ਉਹ ਇਹ ਵੀ ਸੰਭਵ ਬਣਾਉਂਦੇ ਹਨ ਕਿ ਟੀਮ proactive ਤੌਰ 'ਤੇ ਰਿਫੈਕਟਰ ਕਰੇ ਨਾ ਕਿ ਸੁਧਾਰਾਂ ਨੂੰ "ਬਾਅਦ ਵਿੱਚ" ਰੱਖੇ।
ਭਾਸ਼ਾਵਾਂ ਅਤੇ ਟੂਲਚੇਨ ਇਸਨੂੰ ਸਹਾਇਤਾ ਦੇ ਸਕਦੇ ਹਨ:
ਇਹਨਾਂ ਵਿੱਚੋਂ ਕਿਸੇ ਨੂੰ ਵੀ ਕੰਪਾਇਲਰ ਥਿਊਰੀ ਜਾਣਨ ਦੀ ਲੋੜ ਨਹੀਂ; ਇਹ ਡਿਵੈਲਪਰ ਦੇ ਸਮੇਂ ਦਾ ਸਤਿਕਾਰ ਕਰਨ ਬਾਰੇ ਹੈ।
ਧੀਮੀ ਬਿਲਡ ਟੀਮਾਂ ਨੂੰ ਵੱਡੇ ਬੈਚਾਂ ਵੱਲ ਧੰਕ ਦਿੰਦੇ ਹਨ: ਘੱਟ commits, ਵੱਡੇ PRs, ਅਤੇ ਲੰਬੇ-ਟਿਕਾਊ ਬ੍ਰਾਂਚ। ਇਸ ਨਾਲ ਹੋਰ merge conflicts, "fix forward" ਕੰਮ ਅਤੇ ਸਿੱਖਣ ਦੀ ਰਫ਼ਤਾਰ ਘਟਦੀ ਹੈ—ਕਿਉਂਕਿ ਤੁਸੀਂ ਜੋ ਤਬਦੀਲੀ ਕੀਤੀ ਸੀ ਉਸਨੂੰ ਬਹੁਤ ਪਿੱਛੇ ਪਤਾ ਲੱਗਦਾ ਹੈ।
ਇਸ ਨੂੰ ਮਾਪੋ। ਲੋਕਲ ਬਿਲਡ ਸਮਾਂ ਅਤੇ CI ਬਿਲਡ ਸਮਾਂ ਨੂੰ ਸਮੇਂ ਦੇ ਨਾਲ ਟਰੈਕ ਕਰੋ, ਓਸੇ ਤਰੀਕੇ ਨਾਲ ਜਿਵੇਂ ਤੁਸੀਂ ਯੂਜ਼ਰ-ਸਮਰੱਥਾ ਲਈ latency ਟਰੈਕ ਕਰਦੇ ਹੋ। ਟੀਮ ਡੈਸ਼ਬੋਰਡ 'ਚ ਨੰਬਰ ਰੱਖੋ, ਬਜਟ ਤੈਅ ਕਰੋ, ਅਤੇ ਰਿਗ੍ਰੈਸ਼ਨਾਂ ਦੀ ਜਾਂਚ ਕਰੋ। ਜੇ ਬਿਲਡ ਰਫ਼ਤਾਰ ਤੁਹਾਡੇ "ਕਰਿਆ" ਦੀ ਪਰਿਭਾਸ਼ਾ ਦਾ ਹਿੱਸਾ ਹੈ, ਤਾਂ ਬਿਨਾਂ ਹੀਰੋਇਕਸ productivity ਸੁਧਰਦੀ ਹੈ।
ਇੱਕ ਪ੍ਰਾਇਕਟਿਕਲ ਸੰਬੰਧ: ਜੇ ਤੁਸੀਂ ਆਧ.Internal tools ਜਾਂ ਸਰਵਿਸ ਪ੍ਰੋਟੋਟਾਈਪ ਬਣਾ ਰਹੇ ਹੋ, ਤਾਂ ਪਲੇਟਫਾਰਮਾਂ ਜਿਵੇਂ Koder.ai ਇਕੋ ਹੀ ਮੰਤਵ ਨਾਲ ਫਾਇਦਾ ਪਹੁੰਚਾਉਂਦੇ ਹਨ—ਛੋਟੇ feedback loops। chat ਦੁਆਰਾ React ਫਰੰਟਏਂਡ, Go ਬੈਕਐਂਡ, ਅਤੇ PostgreSQL-ਬੈਕਡ ਸਰਵਿਸ ਬਣਾਉਂਦੇ ਸਮੇਂ planning mode ਅਤੇ snapshots/rollback ਨਾਲ, ਇਹ iteration ਬਰਕਰਾਰ ਰੱਖਣ ਵਿੱਚ ਮਦਦ ਕਰਦਾ ਹੈ ਜਦੋਂ ਤੁਸੀਂ exportable source code ਆਪਣੇ ਕੰਟਰੋਲ ਵਿੱਚ ਰੱਖਦੇ ਹੋ।
ਕੰਪਾਇਲਰ ਬੁਨਿਆਦੀ ਤੌਰ 'ਤੇ ਇਕ translator ਹੈ: ਇਹ ਤੁਹਾਡੇ ਲਿਖੇ ਕੋਡ ਨੂੰ ਮਸ਼ੀਨ ਚਲਾਉਣ ਯੋਗ ਚੀਜ਼ ਵਿੱਚ ਬਦਲਦਾ ਹੈ। ਉਹ ਤਰਜੁਮਾ ਇਕ ਕਦਮ ਨਹੀਂ—ਇਹ ਇੱਕ ਛੋਟੀ पाइਪਲਾਈਨ ਹੈ, ਅਤੇ ਹਰ ਸਟੇਜ ਦੀ ਖਰਚ ਅਤੇ ਫਾਇਦਾ ਵੱਖਰਾ ਹੁੰਦਾ ਹੈ।
1) Parsing
ਸਭ ਤੋਂ ਪਹਿਲਾਂ, ਕੰਪਾਇਲਰ ਤੁਹਾਡੇ ਟੈਕਸਟ ਨੂੰ ਪੜ੍ਹਦਾ ਹੈ ਅਤੇ ਜਾਂਚਦਾ ਹੈ ਕਿ ਇਹ ਵਿਆਕਰਣਿਕ ਤੌਰ 'ਤੇ ਠੀਕ ਹੈ। ਇਹ ਇਕ ਅੰਦਰੂਨੀ ਢਾਂਚਾ ਬਣਾਉਂਦਾ ਹੈ (ਇਕ "ਆਊਟਲਾਈਨ" ਸਮਝੋ) ਤਾਂ ਜੋ ਬਾਅਦ ਦੇ ਸਟੇਜ ਉਸ 'ਤੇ ਤਰਕ ਕਰ ਸਕਣ।
2) Type checking
ਫਿਰ, ਇਹ ਜਾਂਚਦਾ ਹੈ ਕਿ ਹਿੱਸੇ ਇਕ-ਦੂਜੇ ਨਾਲ ਮਿਲਦੇ ਹਨ: ਤੁਸੀਂ incompatible ਵੈਲਯੂਜ਼ ਨੂੰ ਮਿਕਸ ਨਹੀਂ ਕਰ ਰਹੇ, ਫੰਕਸ਼ਨਾਂ ਨੂੰ ਗਲਤ ਆਰਗੁਮੈਂਟ ਨਹੀਂ ਦੇ ਰਹੇ, ਜਾਂ ਗਲਤ ਨਾਂ ਵਰਤੋਂ ਨਹੀਂ ਕਰ ਰਹੇ। ਸਟੈਟਿਕਲੀ ਟਾਇਪ ਕੀਤੀਆਂ ਭਾਸ਼ਾਵਾਂ ਵਿੱਚ, ਇਹ ਸਟੇਜ ਘੱਟ ਨਹੀਂ—ਜਿੰਨੀ ਜਿਆਦਾ sophisticated ਟਾਇਪ ਸਿਸਟਮ ਹੈ, ਉੱਤੇ ਹੀ ਜਿਆਦਾ ਕੰਮ ਹੁੰਦਾ ਹੈ।
3) Optimization
ਫਿਰ, ਕੰਪਾਇਲਰ ਕੋਸ਼ਿਸ਼ ਕਰ ਸਕਦਾ ਹੈ ਕਿ ਪ੍ਰੋਗਰਾਮ ਨੂੰ ਤੇਜ਼ ਜਾਂ ਛੋਟਾ ਬਣਾਇਆ ਜਾਵੇ। ਇਹ ਓਹਨਾ ਥਾਵਾਂ 'ਤੇ ਸਮਾਂ ਖਰਚਦਾ ਹੈ ਜਿੱਥੇ ਇਹ ਇਕੋ ਤਰ੍ਹਾਂ ਲਾਜ਼ਮੀ ਤਰੀਕੇ ਨੂੰ ਹੋਰ ਵਧੀਆ ਢੰਗ ਨਾਲ ਚਲਾਉਂਦਾ: ਗਣਨਾਵਾਂ ਨੂੰ ਦੁਬਾਰਾ ਵਿਵਸਥਿਤ ਕਰਨਾ, redundancy ਹਟਾਉਣਾ, ਜਾਂ memory ਦੀ ਵਰਤੋਂ ਸੁਧਾਰਨਾ।
4) Code generation (codegen)
ਅਖੀਰ 'ਚ, ਇਹ ਮਸ਼ੀਨ ਕੋਡ (ਜਾਂ ਹੋਰ ਨੀਵੇਂ ਸਤਰ ਦਾ ਕੋਈ ਫਾਰਮ) ਨਿਕਾਸ ਕਰਦਾ ਹੈ ਜੋ ਤੁਹਾਡਾ CPU ਚਲਾ ਸਕਦਾ ਹੈ।
ਕਈ ਭਾਸ਼ਾਵਾਂ ਲਈ, ਆਪਟੀਮਾਈਜ਼ੇਸ਼ਨ ਅਤੇ ਜਟਿਲ ਟਾਈਪ ਚੈਕਿੰਗ ਕੰਪਾਇਲ ਸਮੇਂ ਦਾ ਵੱਡਾ ਹਿੱਸਾ ਹੁੰਦੇ ਹਨ ਕਿਉਂਕਿ ਉਹਨਾਂ ਨੂੰ ਫਾਇਲਾਂ ਅਤੇ ਫੰਕਸ਼ਨਾਂ ਦੇ ਪਾਰ ਗਿਆ ਜਾਂਚ ਕਰਨ ਦੀ ਲੋੜ ਹੁੰਦੀ ਹੈ। Parsing ਮੁਕਾਬਲੇ ਵਿੱਚ ਆਮ ਤੌਰ 'ਤੇ ਸਸਤਾ ਹੁੰਦਾ ਹੈ। ਇਸ ਲਈ ਭਾਸ਼ਾ ਅਤੇ ਕੰਪਾਇਲਰ ਡਿਜ਼ਾਈਨਰ ਅਕਸਰ ਪੁੱਛਦੇ ਹਨ: "ਇੱਕ ਪ੍ਰੋਗ੍ਰਾਮ ਚਲਾਉਣ ਤੋਂ ਪਹਿਲਾਂ ਕਿੰਨੀ ਵਿਸ਼ਲੇਸ਼ਣ ਕਰਨ ਦੀ ਲੋੜ ਹੈ?"
ਕੁਝ ਇਕੋਸਿਸਟਮ ਥੋੜੇ ਧੀਮੇ ਕੰਪਾਇਲ ਸਵੀਕਾਰ ਕਰ ਲੈਂਦੇ ਹਨ ਤਾਂ ਕਿ runtime ਪ੍ਰਦਰਸ਼ਨ ਵਧੇ ਜਾਂ compile-time ਫੀਚਰ ਸ਼ਕਤਸ਼ਾਲੀ ਹੋਣ। Go, ਪ੍ਰਾਇਕਟਿਕ ਭਾਸ਼ਾ ਇੰਜੀਨੀਅਰਿੰਗ ਤੋਂ ਪ੍ਰਭਾਵਿਤ ਹੋ ਕੇ, ਤੇਜ਼, ਪ੍ਰਡਿਕਟੇਬਲ ਬਿਲਡਾਂ ਵੱਲ ਝੁੱਕਦਾ ਹੈ—ਭਾਅ ਦੇ ਨਾਲ ਕਿ ਕੁਝ ਮਹਿੰਗੀਆਂ ਵਿਸ਼ਲੇਸ਼ਣਾਂ ਕੰਪਾਇਲ ਟਾਈਮ 'ਤੇ ਨਾ ਕੀਤਾ ਜਾਣ।
ਇੱਕ ਸਧਾਰਣ ਪਾਈਪਲਾਈਨ ਡਾਇਗ੍ਰਾਮ ਉਪਯੋਗੀ ਹੋਵੇਗਾ:
Source code → Parse → Type check → Optimize → Codegen → Executable
ਸਟੈਟਿਕ ਟਾਈਪਿੰਗ ਇੱਕ "ਕੰਪਾਇਲਰ ਦੀ ਚੀਜ਼" ਵੱਜੋਂ ਸੌਂਦੀ ਹੈ, ਪਰ ਤੁਸੀਂ ਇਸਨੂੰ ਰੋਜ਼ਾਨਾ ਟੂਲਿੰਗ ਵਿੱਚ ਸਭ ਤੋਂ ਜ਼ਿਆਦਾ ਮਹਿਸੂਸ ਕਰਦੇ ਹੋ। ਜਦੋਂ ਟਾਈਪਸ ਸਪਸ਼ਟ ਅਤੇ ਲਗਾਤਾਰ ਜਾਂਚੇ ਜਾਂਦੇ ਹਨ, ਤੁਹਾਡਾ ਏਡੀਟਰ keywords' ਤੋਂ ਵਧ ਕੇ ਸਮਝ ਸਕਦਾ ਹੈ: ਕਿਸ ਨਾਮ ਦਾ ਕੀ ਦਾ ਸਬੰਧ ਹੈ, ਕਿਹੜੇ methods ਮੌਜੂਦ ਹਨ, ਅਤੇ ਕੋਈ ਤਬਦੀਲੀ ਕਿੱਥੇ ਟੁੱਟੇਗੀ।
ਸਟੈਟਿਕ ਟਾਈਪਿੰਗ ਨਾਲ, autocomplete ਬਿਨਾਂ ਅਨੁਮਾਨ ਦੇ ਸਹੀ fields ਅਤੇ methods ਦਿਖਾ ਸਕਦਾ ਹੈ। “Go to definition” ਅਤੇ “find references” ਭਰੋਸੇਯੋਗ ਹੋ ਜਾਂਦੇ ਹਨ ਕਿਉਂਕਿ identifiers ਸਿਰਫ ਟੈਕਸਟ ਮੇਲ ਨਹੀਂ—ਉਹ symbols ਨਾਲ ਜੁੜੇ ਹੁੰਦੇ ਹਨ ਜੋ ਕੰਪਾਇਲਰ ਸਮਝਦਾ ਹੈ। ਇਹੀ ਜਾਣਕਾਰੀ safer refactors ਨੂੰ ਸਮਰਥਨ ਦਿੰਦੀ ਹੈ: method rename, ਕਿਸੇ type ਨੂੰ ਹੋਰ ਪੈਕੇਜ ਵਿੱਚ ਲਿਜਾਣਾ, ਜਾਂ ਫਾਈਲ ਵੰਡਣਾ fragile search-and-replace 'ਤੇ ਨਿਰਭਰ ਨਹੀਂ।
ਅਕਸਰ ਟੀਮ ਦਾ ਸਮਾਂ ਨਵਾਂ ਕੋਡ ਲਿਖਣ ਵਿੱਚ ਨਹੀਂ ਲਗਦਾ—ਇਹ ਮੌਜੂਦਾ ਕੋਡ ਨੂੰ ਬਿਨਾਂ ਤੋੜੇ ਬਦਲਣ 'ਤੇ ਲੱਗਦਾ ਹੈ। ਸਟੈਟਿਕ ਟਾਈਪਿੰਗ ਤੁਹਾਨੂੰ ਇੱਕ API ਨੂੰ ਆਤਮਵਿਸ਼ਵਾਸ ਨਾਲ ਵਿਕਸਤ ਕਰਨ ਵਿੱਚ ਮਦਦ ਕਰਦੀ:
ਇੱਥੇ Go ਦੇ ਡਿਜ਼ਾਈਨ ਚੋਣਾਂ ਪ੍ਰਾਇਕਟਿਕਲ ਬਾਧਾਵਾਂ ਨਾਲ ਮਿਲਦੀਆਂ ਹਨ: ਜਦੋਂ ਤੁਹਾਡੇ ਟੂਲ ਇਨ੍ਹਾਂ ਸਵਾਲਾਂ ਦਾ ਭਰੋਸੇਯੋਗ ਜਵਾਬ ਦੇ ਸਕਦੇ ਹਨ—"ਇਸਦਾ ਪ੍ਰਭਾਵ ਕਿੱਥੇ ਹੋਵੇਗਾ?"—ਤਾਂ steady improvements ਸ਼ਿਪ ਕਰਨਾ ਆਸਾਨ ਹੁੰਦਾ ਹੈ।
ਟਾਈਪਸ ਪ੍ਰੋਟੋਟਾਈਪਿੰਗ ਵੇਲੇ ਇੱਕ ਰੁਕਾਵਟ ਵਜੋਂ ਮਹਿਸੂਸ ਹੋ ਸਕਦੇ ਹਨ। ਪਰ ਉਹ ਇੱਕ ਹੋਰ ਕਿਸਮ ਦੇ ਕੰਮ ਨੂੰ ਰੋਕਦੇ ਹਨ: runtime ਫੇਲਿਅਰਾਂ ਦੀ ਡੀਬੱਗਿੰਗ, implicit conversions ਦੀ ਪਿੱਛੇ ਪਿੱਛੇ ਭੱਜਣੀ, ਜਾਂ ਇੱਕ ਰਿਫੈਕਟਰ ਤੋਂ ਬਾਅਦ silent behavioural changes ਲੱਭਣ। ਤੀਬਰਕਤਾ ਤੁਰੰਤ ਨਾਰਾਜ਼ਗੀ ਦੇ ਸਕਦੀ ਹੈ, ਪਰ ਇਹ ਅਕਸਰ ਮਰੰਮਤ ਸਮੇਂ 'ਤੇ ਵਾਪਸ ਪੈਸਾ ਦਿੰਦੀ ਹੈ।
ਕਲਪਨਾ ਕਰੋ ਇੱਕ ਛੋਟਾ ਸਿਸਟਮ ਜਿੱਥੇ billing ਪੈਕੇਜ payments.Processor ਨੂੰ ਕਾਲ ਕਰਦਾ ਹੈ। ਤੁਸੀਂ ਫੈਸਲਾ ਕਰਦੇ ਹੋ ਕਿ Charge(userID, amount) ਨੂੰ ਹੁਣ currency ਵੀ ਲੈਣੀ ਚਾਹੀਦੀ ਹੈ।
ਇੱਕ ਡਾਇਨਾਮਿਕ ਟਾਇਪ ਸੈਟਅਪ ਵਿੱਚ, ਤੁਸੀਂ ਕੋਈ ਕਾਲ ਪੱਥ miss ਕਰਨਗੇ ਜਦ ਤੱਕ ਇਹ production 'ਚ ਫੇਲ ਨਹੀਂ ਹੁੰਦਾ। Go ਵਿੱਚ, interface ਅਤੇ implementation ਨੂੰ ਅਪਡੇਟ ਕਰਨ ਤੋਂ ਬਾਦ, ਕੰਪਾਇਲਰ billing, checkout, ਅਤੇ tests ਵਿੱਚ ਹਰ outdated ਕਾਲ ਨੂੰ ਝਲਕਾਏਗਾ। ਤੁਹਾਡੇ ਏਡੀਟਰ ਨੂੰ error ਤੋਂ error 'ਤੇ jump ਕਰਨ ਦੀ ਯੋਗਤਾ ਮਿਲਦੀ ਹੈ ਅਤੇ ਇੱਕ ਸਥੂਲ, ਸਮੀਖਿਆਯੋਗ ਸੁਧਾਰ ਹੁੰਦਾ ਹੈ।
Go ਦੀ ਪ੍ਰਦਰਸ਼ਨ ਕਹਾਣੀ ਸਿਰਫ ਕੰਪਾਇਲਰ ਬਾਰੇ ਨਹੀਂ—ਇਹ ਇਸ ਗੱਲ ਬਾਰੇ ਵੀ ਹੈ ਕਿ ਤੁਹਾਡਾ ਕੋਡ ਕਿਵੇਂ ਬਣਦਾ ਹੈ। ਪੈਕੇਜ ਸਟ੍ਰਕਚਰ ਅਤੇ ਇੰਪੋਰਟਸ ਸਿੱਧੇ ਤੌਰ 'ਤੇ compile time ਅਤੇ ਦੈਨਿਕ ਸਮਝਣ ਤੇ ਪ੍ਰਭਾਵ ਪਾਂਦੇ ਹਨ। ਹਰ ਇੰਪੋਰਟ ਨਾਲ ਕੰਪਾਇਲਰ ਨੂੰ ਉਹ ਚੀਜ਼ ਵੀ ਲੋਡ, type-check ਅਤੇ ਸੰਭਵਤ: ਮੁੜ-ਕੰਪਾਇਲ ਕਰਨੀ ਪੈਂਦੀ ਹੈ। ਮਨੁੱਖਾਂ ਲਈ, ਹਰ ਇੰਪੋਰਟ ਨਾਲ ਉਹ “ਮੈਨਟਲ ਸਤਹ” ਵੀ ਵਧਦੀ ਹੈ ਜੋ ਇਹ ਸਮਝਣ ਲਈ ਲੋੜੀਂਦੀ ਹੈ ਕਿ ਕਿਸ ਪੈਕੇਜ ਨੂੰ ਕਿਸ ਚੀਜ਼ ਤੇ ਨਿਰਭਰ ਕੀਤਾ ਗਿਆ ਹੈ।
ਇੱਕ ਪੈਕੇਜ ਜਿਸਦਾ ਇੰਪੋਰਟ ਗ੍ਰਾਫ ਵਿਆਪਕ ਅਤੇ ਗੁੱਥਾ ਹੋਵੇ, ਆਮ ਤੌਰ 'ਤੇ ਧੀਮਾ ਕੰਪਾਇਲ ਹੁੰਦਾ ਹੈ ਅਤੇ ਪੜ੍ਹਨ ਵਿੱਚ ਵੀ ਘੱਟ ਸੁਖਦਾਇਕ ਹੁੰਦਾ ਹੈ। ਜਦੋਂ ਡਿਪੈਂਡੇੰਸੀਜ਼ ਥੱਲੇ-ਥੱਲੇ ਅਤੇ ਇਰਾਦੇ ਨਾਲ ਹੋਂਦੀਆਂ ਹਨ, ਬਿਲਡ ਤੇਜ਼ ਰਹਿੰਦੇ ਹਨ ਅਤੇ ਮੁੱਢਲੇ ਸਵਾਲਾਂ ਦੇ ਜਵਾਬ ਦੇਣਾ ਆਸਾਨ ਹੁੰਦਾ ਹੈ: “ਇਹ ਟਾਈਪ ਕਿੱਥੋਂ ਆ ਰਹੀ ਹੈ?” ਅਤੇ “ਮੈਂ ਕੀ ਬਿਨਾਂ ਕਿਸੇ ਵੱਡੇ ਨੁਕਸਾਨ ਦੇ ਇਹ ਤਬਦੀਲੀ ਕਰ ਸਕਦਾ/ਸਕਦੀ ਹਾਂ?”
ਸਿਹਤਮੰਦ Go ਕੋਡਬੇਸ ਆਮ ਤੌਰ 'ਤੇ ਛੋਟे, ਰਹਿਤ, cohesive ਪੈਕੇਜਾਂ ਨੂੰ ਵਧਾ ਕੇ ਵਧਦੇ ਹਨ—ਇਕੱਠੇ ਹੋਰ ਵੱਡੇ ਅਤੇ ਜ਼ਿਆਦਾ connected ਪੈਕੇਜ ਬਣਾਉਣ ਦੀ ਬਜਾਏ। ਸਾਫ਼-ਸੀਮਾਵਾਂ cycles (A imports B imports A) ਘਟਾਉਂਦੀਆਂ ਹਨ, ਜੋ ਕਿ ਕੰਪਾਇਲ ਅਤੇ ਡਿਜ਼ਾਈਨ ਦੋਹਾਂ ਲਈ ਦਰਦਨਾਕ ਹੁੰਦੇ ਹਨ। ਜੇ ਤੁਸੀਂ ਵੇਖਦੇ ਹੋ ਕਿ ਪੈਕੇਜਾਂ ਨੂੰ ਇਕ-ਦੂਜੇ ਨੂੰ import ਕਰਨਾ ਪੈ ਰਿਹਾ ਹੈ ਤਾਂ ਅਕਸਰ ਇਹ ਇੱਕ ਸੂਚਕ ਹੈ ਕਿ ਜ਼ਿੰਮੇਵਾਰੀਆਂ ਮਿਲੀ-ਝੁਲੀ ਹੋ ਚੁੱਕੀਆਂ ਹਨ।
ਕਾਮਮ ਫੇਸ: “utils” (ਜਾਂ “common”) ਡੰਪਿੰਗ ਗ੍ਰਾਊਂਡ। ਇਹ ਆਰੰਭ ਵਿੱਚ ਇੱਕ ਸੁਵਿਧਾ ਪੈਕੇਜ ਹੁੰਦਾ ਹੈ, ਫਿਰ dependency ਮੈਗਨਿਟ ਬਣ ਜਾਂਦਾ ਹੈ: ਹਰ ਕੋਈ ਇਸਨੂੰ import ਕਰਦਾ ਹੈ, ਇਸ ਲਈ ਕੋਈ ਵੀ ਬਦਲਾਅ ਵਿਆਪਕ rebuilds ਨੂੰ trigger ਕਰਦਾ ਹੈ ਅਤੇ ਰਿਫੈਕਟਰਿੰਗ ਨੂੰ ਖਤਰਨਾਕ ਬਣਾਉਂਦਾ ਹੈ।
Go ਦੀਆਂ ਇੱਕ ਭਾਰੀ ਉਤਪਾਦਕਤਾ ਜਿੱਤਾਂ ਵਿੱਚੋਂ ਇਕ clever syntax ਟਰਿਕ ਨਹੀਂ—ਇਹ ਉਹ ਉਮੀਦ ਹੈ ਕਿ ਭਾਸ਼ਾ ਇੱਕ ਛੋਟੀ ਸੈੱਟ standard tools ਨਾਲ ਆਉਂਦੀ ਹੈ, ਅਤੇ ਟੀਮਾਂ ਵਾਸਤੇ ਉਹਨਾਂ ਨੂੰ ਵਰਤਣਾ ਆਮ ਰਵਾਇਤ ਹੈ। ਇਹ workflow ਵਜੋਂ ਭਾਸ਼ਾ ਇಂಜੀਨੀਅਰਿੰਗ ਹੈ: ਉਨ੍ਹਾਂ ਥਾਵਾਂ ਤੇ optionality ਘਟਾਓ ਜਿੱਥੇ friction ਬਣਦੀ ਹੈ, ਅਤੇ “ਮਾਨਕ ਰਸਤਾ” ਤੇਜ਼ ਬਣਾਓ।
Go ਇੱਕ consistent baseline ਨੂੰ ਪ੍ਰੋਤਸਾਹਿਤ ਕਰਦਾ ਹੈ ਉਹਨਾਂ ਟੂਲਾਂ ਰਾਹੀਂ ਜੋ ਅਨੁਭਵ ਦਾ ਹਿੱਸਾ ਮੰਨੇ ਜਾਂਦੇ ਹਨ, ਨਾ ਕਿ ਵਿਕਲਪਿਕ ਇਕੋਸੀਸਟਮ ਐਡ-ਆਨ:
gofmt (ਅਤੇ go fmt) ਕੋਡ ਸਟਾਈਲ ਨੂੰ ਬਹੁਤ ਹੱਦ तक ਗੈਰ-ਵਿਵਾਦੀ ਬਣਾਉਂਦਾ ਹੈ।go test ਟੈਸਟਾਂ ਦੀ ਖੋਜ ਅਤੇ ਚਲਾਉਣਾ ਇੱਕਰੂਪ ਕਰਦਾ ਹੈ।go doc ਅਤੇ Go ਦੇ doc comments API ਖੋਜਯੋਗਤਾ ਵਧਾਉਂਦੇ ਹਨ।go build ਅਤੇ go run predictable entry points ਸਥਾਪਤ ਕਰਦੇ ਹਨ।ਮੁੱਦਾ ਇਹ ਨਹੀਂ ਕਿ ਇਹ ਟੂਲ ਹਰ ਹਾਲਤ ਲਈ ਪਰਫੈਕਟ ਹਨ। ਮਕਸਦ ਇਹ ਹੈ ਕਿ ਉਹਨਾਂ ਨੇ ਟੀਮ ਨੂੰ ਉਹਨਾਂ ਫੈਸਲਿਆਂ ਨੂੰ ਘੱਟ ਵਾਰ ਦੁਹਰਾਉਣੇ ਪੈਂਦੇ ਹਨ।
ਜਦੋਂ ਹਰ ਪ੍ਰੋਜੈਕਟ ਆਪਣੀ ਟੂਲਚੇਨ (formatter, test runner, doc generator, build wrapper) ਅਨੁਮੋਦਨ ਕਰਦਾ ਹੈ, ਨਵੇਂ ਯੋਗਦਾਤਾ ਆਪਣੀਆਂ ਪਹਿਲੀਆਂ ਕੁਝ ਦਿਨ ਇਸ ਪ੍ਰੋਜੈਕਟ ਦੀਆਂ “ਖ਼ਾਸ ਨਿਯਮਾਂ” ਸਿੱਖਣ ਵਿੱਚ ਗੁਜ਼ਾਰਦੇ ਹਨ। Go ਦੇ ਡਿਫੌਲਟਾਂ ਇਸ ਪ੍ਰੋਜੈਕਟ-ਤੱਕ-ਪ੍ਰੋਜੈਕਟ variation ਨੂੰ ਘਟਾਉਂਦੇ ਹਨ। ਇੱਕ ਵਿਕਾਸਕਾਰ ਰੀਪੋ ਬਦਲ ਕੇ ਵੀ ਐਸੇ ਹੀ commands, ਫਾਇਲ ਰੀਤੀ-ਰਿਵਾਜ, ਅਤੇ ਉਮੀਦਾਂ ਪਛਾਣ ਸਕਦਾ ਹੈ।
ਇਹ ਸਥਿਰਤਾ automation ਵਿੱਚ ਵੀ ਫਾਇਦਾ ਦਿੰਦੀ ਹੈ: CI ਸੈੱਟਅੱਪ ਕਰਨਾ ਆਸਾਨ ਅਤੇ ਬਾਅਦ ਵਿੱਚ ਸਮਝਣ ਯੋਗ ਹੁੰਦਾ ਹੈ। ਜੇ ਤੁਸੀਂ ਇੱਕ ਪ੍ਰੈਕਟਿਕਲ ਵਾਕ-ਪੱਧਰ ਚਾਹੁੰਦੇ ਹੋ ਤਾਂ ਵੇਖੋ: /blog/go-tooling-basics ਅਤੇ, build feedback loop ਵਿਚਾਰਾਂ ਲਈ, /blog/ci-build-speed।
ਇਹੋ ਜਿਹੀ ਸੋਚ ਜਦੋਂ ਤੁਸੀਂ ਟੀਮ ਭਰ ਵਿੱਚ apps ਬਣਾਉਣ ਦੀ ਇਕੋ ਰੀਤੀ ਨਿਰਧਾਰਿਤ ਕਰ ਰਹੇ ਹੋ ਤਾਂ ਵਰਤੀ जा ਸਕਦੀ ਹੈ। ਉਦਾਹਰਣ ਲਈ, Koder.ai ਇਕ consistent “happy path” ਜਾਰੀ ਕਰਦਾ ਹੈ React (web), Go + PostgreSQL (backend), ਅਤੇ Flutter (mobile) ਲਈ, ਜੋ ਟੀਮ-ਵਿਸ਼ੇਸ਼ ਟੂਲਚੇਨ drift ਘਟਾ ਸਕਦਾ ਹੈ ਜੋ ਆਮ ਤੌਰ 'ਤੇ ਓਨਬੋਰਡਿੰਗ ਅਤੇ ਕੋਡ ਸਮੀਖਿਆ ਨੂੰ ਹੌਲਾ ਕਰ ਦਿੰਦਾ ਹੈ।
ਇਹ ਤੈਅ ਕਰੋ: formatting ਅਤੇ linting ਡਿਫੌਲਟ ਹਨ, بحث ਨਹੀਂ।
ਅਮਲ ਵਿੱਚ: gofmt ਨੂੰ ਆਟੋਮੈਟਿਕ ਚਲਾਉ (editor on save ਜਾਂ pre-commit) ਅਤੇ ਇੱਕ single linter configuration ਜੋ ਪੂਰੀ ਟੀਮ ਵਰਤੇ। ਜਿੱਤ ਸੁੰਦਰਤਾ ਨਾਲ ਸੰਬੰਧਤ ਨਹੀਂ—ਇਹ ਘੱਟ noisy diffs, ਘੱਟ style ਟਿੱਪਣੀਆਂ ਸਮੀਖਿਆ ਵਿੱਚ, ਅਤੇ ਬਿਹਤਰ ਵਿਹਾਰ, ਸਹੀਤਾ, ਅਤੇ ਡਿਜ਼ਾਈਨ 'ਤੇ ਧਿਆਨ ਦਾ ਮਤਲਬ ਹੈ।
ਭਾਸ਼ਾ ਡਿਜ਼ਾਈਨ ਸਿਰਫ਼ ਸੁੰਦਰ ਥਿਊਰੀ ਬਾਰੇ ਨਹੀਂ ਹੁੰਦਾ। ਅਸਲ ਸੰਸਥਾਵਾਂ ਵਿੱਚ, ਇਹ ਉਹਨਾਂ ਸੀਮਾਵਾਂ ਨਾਲ ਅਕਾਰਬੱਧ ਹੁੰਦਾ ਹੈ ਜਿਨ੍ਹਾਂ ਤੇ ਤਕਰਾਰ ਕਰਨਾ ਮੁਸ਼ਕਲ ਹੁੰਦਾ ਹੈ: ਡਿਲਿਵਰੀ ਦੀਆਂ ਤਰিখਾਂ, ਟੀਮ ਦਾ ਆਕਾਰ, ਭਰਤੀ ਰਿਆਲਿਟੀਜ਼, ਅਤੇ ਉਹ infrastructure ਜੋ ਤੁਸੀਂ ਪਹਿਲਾਂ ਹੀ ਚਲਾ ਰਹੇ ਹੋ।
ਅਕਸਰ ਟੀਮਾਂ ਇਹਨਾਂ ਵਿੱਚੋਂ ਕੁਝ ਨਾਲ ਜੀਉਂਦੀਆਂ ਹਨ:
Go ਦਾ ਡਿਜ਼ਾਈਨ ਇੱਕ ਸਾਫ਼ "complexity budget" ਨੂੰ ਦਰਸਾਉਂਦਾ ਹੈ। ਹਰ ਫੀਚਰ ਦੀ ਲਾਗਤ ਹੁੰਦੀ ਹੈ: ਕੰਪਾਇਲਰ ਜਟਿਲਤਾ, ਵੱਧ build ਸਮਾਂ, ਇੱਕੋ ਹੀ ਗੱਲ ਨੂੰ ਲਿਖਣ ਦੇ ਵੱਧ ਤਰੀਕੇ, ਅਤੇ ਟੂਲਾਂ ਲਈ ਵਧੇਰੇ edge cases। ਜੇਕਰ ਇੱਕ ਫੀਚਰ ਭਾਸ਼ਾ ਨੂੰ ਸਿੱਖਣਯੋਗ ਕੁਠੇ ਕਰ ਦੇਵੇ ਜਾਂ ਬਿਲਡ ਨੂੰ ਘੱਟ-ਪ੍ਰਡਿਕਟੇਬਲ ਬਣਾ ਦੇਵੇ, ਤਾਂ ਇਹ ਸਟੀਡੀ ਟੀਮ throughput ਦੇ ਵਿਚਾਰ ਦਾ ਮੁਕਾਬਲਾ ਕਰਦਾ ਹੈ।
ਇਹ ਬਾਧਾਵਾਂ-ਅਧਾਰਿਤ ਰਵੱਈਆ ਇੱਕ ਜਿੱਤ ਹੋ ਸਕਦੀ ਹੈ: ਘੱਟ "ਚਤੁਰ" ਕੋਨੇ, ਜ਼ਿਆਦਾ consistent ਕੋਡਬੇਸ, ਅਤੇ ਜ਼ਿਆਦਾ ਕੰਮ ਕਰਨਯੋਗ tooling ਜੋ ਪ੍ਰੋਜੈਕਟਾਂ ਭਰ ਵਿੱਚ ਇੱਕੋ ਢੰਗ ਨਾਲ ਕੰਮ ਕਰਦਾ ਹੈ।
ਬਾਧਾਵਾਂ ਅਕਸਰ ਬਹੁਤ ਵਾਰੀ “ਨਹੀਂ” ਕਹਿਣਾ ਸ਼ਾਮਲ ਹੁੰਦੇ ਹਨ—ਇਹ ਕਈ ਡਿਵੈਲਪਰਾਂ ਲਈ ਤਕਲੀਫ਼ਦਾਇਕ ਹੋ ਸਕਦਾ ਹੈ ਜਦੋਂ ਉਹ ਵਧੀਆ abstractions ਜਾਂ expressive type ਫੀਚਰ ਚਾਹੁੰਦੇ ਹਨ। ਫਾਇਦਾ ਇਹ ਹੈ ਕਿ ਆਮ ਰਾਹ ਸਾਫ਼ ਰਹਿੰਦਾ ਹੈ; ਨੁਕਸਾਨ ਇਹ ਹੈ ਕਿ ਕੁਝ ਡੋਮੇਨ ਹੇਠਾਂ ਘੱਟ ਸੁਗਮ ਜਾਂ verbose ਮਹਿਸੂਸ ਹੋ ਸਕਦੇ ਹਨ।
Go ਨੂੰ ਚੁਣੋ ਜਦੋਂ ਤੁਹਾਡੀ ਪਹਿਲਵੰਤੀ ਹੈ ਟੀਮ-ਪੈਮਾਨੇ ਦੀ maintainability, ਤੇਜ਼ ਬਿਲਡ, ਸਪਸ਼ਟ ਡਿਪਲੋਇਮੈਂਟ, ਅਤੇ ਅਸਾਨ ਓਨਬੋਰਡਿੰਗ।
ਜਦੋਂ ਤੁਹਾਡਾ ਸਮੱਸਿਆ ਖਾਸ ਤੌਰ 'ਤੇ ਅਡਵਾਂਸਡ ਟਾਈਪ-ਲੇਵਲ ਮਾਡਲਿੰਗ, ਭਾਸ਼ਾ-ਇੰਟਿਗਰੇਟਡ ਮੈਟਾਪ੍ਰੋਗ੍ਰਾਮਮਿੰਗ, ਜਾਂ ਐਸੇ ਡੋਮੇਨਾਂ ਵਿੱਚ ਹੈ ਜਿੱਥੇ expressive abstractions ਵੱਡਾ, ਦੁਹਰਾਏ ਜਾਣਯੋਗ ਫਾਇਦਾ ਦਿੰਦੇ ਹਨ, ਤਾਂ ਹੋਰ ਸੰਦ ਸੋਚੋ। ਬਾਧਾਵਾਂ ਸਿਰਫ਼ ਉਹ ਸਮੇਂ "ਚੰਗੀਆਂ" ਹੁੰਦੀਆਂ ਹਨ ਜਦੋਂ ਉਹ ਤੁਹਾਡੇ ਕੰਮ ਨਾਲ ਮਿਲਦੀਆਂ ਹਨ।
Go ਦੀਆਂ ਭਾਸ਼ਾ ਇੰਜੀਨੀਅਰਿੰਗ ਚੋਣਾਂ ਸਿਰਫ਼ ਇਹ ਨਹੀਂ ਦਿਖਾਉਂਦੀਆਂ ਕਿ ਕੋਡ ਕਿਵੇਂ ਕੰਪਾਇਲ ਹੁੰਦਾ ਹੈ—ਉਹ ਇਹ ਵੀ ਸ਼ੇਪ ਕਰਦੀਆਂ ਹਨ ਕਿ ਟੀਮਾਂ ਸਾਫਟਵੇਅਰ ਨੂੰ ਕਿਵੇਂ ਚਲਾਉਂਦੀਆਂ ਹਨ। ਜਦੋਂ ਭਾਸ਼ਾ ਵਿਕਾਸਕਾਰਾਂ ਨੂੰ ਕੁਝ ਪੈਟਰਨ ਵੱਲ ਝੁਕਾਉਂਦੀ ਹੈ (explicit errors, simple control flow, consistent tooling), ਇਹ ਚੁਪਚਾਪ ਇਸ ਗੱਲ ਨੂੰ ਇੱਕ ਰੀਤੀ-ਰਿਵਾਜ ਬਣਾਉਂਦੀ ਕਿ ਇੰਸੀਡੈਂਟਸ ਕਿਵੇਂ ਜਾਂਚੇ ਜਾਂਦੇ ਅਤੇ ਠੀਕ ਕੀਤੇ ਜਾਂਦੇ ਹਨ।
Go ਦੇ explicit error returns ਇੱਕ ਆਦਤ ਨੂੰ ਪ੍ਰੋਤਸਾਹਿਤ ਕਰਦੇ ਹਨ: ਫੇਲਿਅਰ ਨੂੰ ਸਧਾਰਨ ਪ੍ਰੋਗਰਾਮ ਫਲੋ ਦਾ ਹਿੱਸਾ ਮੰਨੋ। "ਉਮੀਦ ਕਰੋ ਕਿ ਇਹ ਫੇਲ ਨ ਹੋਵੇ" ਦੀ ਬਜਾਏ, ਕੋਡ ਅਕਸਰ ਇਸ ਤਰ੍ਹਾਂ ਲਿਖਿਆ ਜਾਂਦਾ ਹੈ: "ਜੇ ਇਹ ਕਦਮ ਫੇਲ ਹੋਇਆ, ਤਾਂ ਸਪਸ਼ਟ ਤੌਰ 'ਤੇ ਦੱਸੋ।" ਇਸ ਮਨੋਭਾਵ ਨਾਲ ਪ੍ਰੈਕਟਿਕਲ ਡੀਬੱਗਿੰਗ ਵਿਹਾਰ ਨਿਕਲਦੇ ਹਨ:
ਇਹ ਕਿਸੇ ਇਕ ਫੀਚਰ ਬਾਰੇ ਨਹੀਂ, ਬਲਕਿ predictability ਬਾਰੇ ਹੈ: ਜਦੋਂ ਬਹੁਤ ਸਾਰਾ ਕੋਡ ਇੱਕੋ ਢਾਂਚੇ ਨੂੰ ਫੋਲੋ ਕਰਦਾ ਹੈ, ਤੁਹਾਡਾ ਦਿਮਾਘ (ਅਤੇ on-call ਰੋਟੇਸ਼ਨ) surpresa ਲਈ ਘੱਟ ਟੈਕਸ ਭੁਗਤਦਾ ਹੈ।
ਇੱਕ ਇੰਸੀਡੈਂਟ ਦੌਰਾਨ, ਸਵਾਲ ਆਮ ਤੌਰ 'ਤੇ "ਕੀ ਟੁੱਟਿਆ ਹੈ?" ਨਹੀਂ ਹੁੰਦਾ—ਸਵਾਲ ਹੁੰਦਾ ਹੈ "ਇਹ ਕਿੱਥੋਂ ਸ਼ੁਰੂ ਹੋਇਆ, ਅਤੇ ਕਿਉਂ?" predictable ਪੈਟਰਨ search ਸਮਾਂ ਘਟਾਉਂਦੇ ਹਨ:
Logging conventions: ਇੱਕ ਛੋਟੀ ਸਥਿਰ ਖੇਤਰ-ਸੂਚੀ ਚੁਣੋ (service, request_id, user_id/tenant, operation, duration_ms, error). ਬਾਊਂਡਰੀਆਂ 'ਤੇ (inbound request, outbound dependency call) ਲੌਗ ਕਰੋ ਇੱਕੋ ਖੇਤਰ-ਨਾਂ ਨਾਲ।
Error wrapping: action + key context ਨਾਲ wrap ਕਰੋ, vague descriptions ਤੋਂ ਨਹੀਂ। "ਤੁਸੀਂ ਕੀ ਕਰ ਰਹੇ ਸਨ" ਅਤੇ identifiers ਦਾ ਟੀਚਾ ਰੱਖੋ:
return fmt.Errorf("fetch invoice %s for tenant %s: %w", invoiceID, tenantID, err)
Test structure: edge cases ਲਈ table-driven tests ਅਤੇ ਇੱਕ "golden path" ਟੈਸਟ ਜੋ logging/error shape ਨੂੰ ਵੀ verify ਕਰਦਾ ਹੈ (ਸਿਰਫ ਰਿਟਰਨ ਵੈਲਯੂਜ਼ ਨਹੀਂ)।
/checkout 'ਤੇ 500s ਵੱਧ ਰਹੇ ਹਨ।operation=charge_card ਵਿੱਚ duration_ms spike ਦਿਖਾਈ ਦਿੱਤਾ।charge_card: call payment_gateway: context deadline exceeded।operation ਨਾਲ wrap ਹੁੰਦੇ ਹਨ ਅਤੇ gateway region ਸ਼ਾਮਿਲ ਹੈ।ਥੀਮ: ਜਦੋਂ ਕੋਡਬੇਸ ਇਕਸਾਰ, predictable ਪੈਟਰਨਾਂ 'ਚ ਬੋਲਦਾ ਹੈ, ਤਾਂ ਤੁਹਾਡੀ ਇੰਸੀਡੈਂਟ ਰੇਸਪਾਂਸ ਇੱਕ ਪ੍ਰਕਿਰਿਆ ਬਣ ਜਾਂਦੀ ਹੈ—ਨਾ ਕਿ ਇੱਕ ਖੋਜ-ਮਿਸ਼ਨ।
Go ਦੀ ਕਹਾਣੀ ਉਸੇ ਵਰਗੇ ਕੰਮਾਂ ਲਈ ਭੀ ਲਾਗੂ ਹੈ ਜੇ ਤੁਸੀਂ ਕਦੇ Go ਦੀ ਇੱਕ ਲਾਈਨ ਵੀ ਨਾ ਲਿਖੋ: ਇਹ ਯਾਦ ਦਿਲਾਉਂਦੀ ਹੈ ਕਿ ਭਾਸ਼ਾ ਅਤੇ ਟੂਲਿੰਗ ਫੈਸਲੇ ਅਸਲ ਵਿੱਚ ਵਰਕਫਲੋ ਫੈਸਲੇ ਹਨ।
ਬਾਧਾਵਾਂ "ਸਿਮਤੀਆਂ" ਨਹੀਂ—ਉਹ ਡਿਜ਼ਾਈਨ ਇਨਪੁਟ ਹਨ ਜੋ ਇੱਕ ਪ੍ਰਣਾਲੀ ਨੂੰ coherence ਵਿੱਚ ਰੱਖਦੀਆਂ ਹਨ। Go ਉਹਨਾਂ ਬਾਧਾਵਾਂ ਨੂੰ ਅਪਣਾਉਂਦਾ ਹੈ ਜੋ readability, predictable builds, ਅਤੇ ਸਿੱਧਾ tooling favor ਕਰਦੀਆਂ ਹਨ।
ਕੰਪਾਇਲਰ ਦੇ ਫੈਸਲੇ ਮਹੱਤਵ ਰੱਖਦੇ ਹਨ ਕਿਉਂਕਿ ਉਹ ਰੋਜ਼ਾਨਾ ਵਿਹਾਰ ਨੂੰ ਅਕਾਰ ਦਿੰਦੇ ਹਨ। ਜੇ ਬਿਲਡ ਤੇਜ਼ ਹਨ ਅਤੇ ਐਰਰ ਸਪਸ਼ਟ ਹਨ, ਤਾਂ ਡਿਵੈਲਪਰ ਜ਼ਿਆਦਾ build ਚਲਾਉਂਦੇ ਹਨ, ਪਹਿਲੇ ਹੀ ਰਿਫੈਕਟਰ ਕਰਦੇ ਹਨ, ਅਤੇ ਬਦਲਾਵ ਛੋਟੇ ਰੱਖਦੇ ਹਨ। ਜੇ ਬਿਲਡ ਧੀਮੇ ਹਨ ਜਾਂ dependency graphs ਗੁੱਥੇ ਹੋਏ ਹਨ, ਟੀਮਾਂ ਬਦਲਾਵਾਂ ਨੂੰ ਬੈਚ ਕਰਨਾ ਸ਼ੁਰੂ ਕਰ ਦਿੰਦੀਆਂ ਹਨ ਅਤੇ ਸਾਫ਼-ਸਫਾਈਆਂ ਟਾਲ ਦਿੰਦੀਆਂ ਹਨ—ਉਤਪਾਦਕਤਾ ਗਿਰਦੀ ਹੈ ਬਿਨਾਂ ਕਿਸੇ ਨੇ ਸਪੱਸ਼ਟ ਤੌਰ 'ਤੇ ਉਹ ਫੈਸਲਾ ਕੀਤਾ ਹੋਵੇ।
ਆਖ਼ਿਰਕਾਰ, ਬਹੁਤ ਸਾਰੇ ਉਤਪਾਦਕਤਾ ਨਤੀਜੇ boring ਡਿਫੌਲਟਸ ਤੋਂ ਆਉਂਦੇ ਹਨ: ਇੱਕ consistent formatter, ਇੱਕ standard build ਕਮਾਂਡ, ਅਤੇ dependency ਨਿਯਮ ਜੋ ਕੋਡਬੇਸ ਨੂੰ ਵਧਣ 'ਤੇ ਸਮਝਣਯੋਗ ਰੱਖਦੇ ਹਨ।
ਜੇ ਤੇਰਾ ਬੋਤਲ-ਨੇਕ "idea" ਅਤੇ ਇੱਕ ਚੱਲਦੀ ਸਰਵਿਸ ਦੇ ਵਿਚਕਾਰ ਦਾ ਸਮਾਂ ਹੈ, ਤਾਂ ਸੋਚੋ ਕਿ ਕੀ ਤੁਹਾਡਾ ਵਰਕਫਲੋ end-to-end ਤੇਜ਼ ਇਟਰੇਸ਼ਨ ਨੂੰ ਸਹਾਰਦਾ ਹੈ—ਸਿਰਫ ਤੇਜ਼ ਕੰਪਾਇਲਿੰਗ ਨਹੀਂ। ਇਹ ਇੱਕ ਕਾਰਨ ਹੈ ਕਿ ਟੀਮਾਂ Koder.ai ਵਰਗੇ ਪਲੇਟਫਾਰਮ ਅਪਨਾਉਂਦੀਆਂ ਹਨ: ਤੁਸੀਂ ਚੈਟ ਵਿੱਚ ਦਿੱਤੇ ਗਏ ਮੰਗ-ਲਿਖਤ ਤੋਂ ਚੱਲਦੀ ਐਪ ਤੱਕ ਜਾ ਸਕਦੇ ਹੋ (ਡਿਪਲੋਇਮੈਂਟ/ਹੋਸਟਿੰਗ, ਕਸਟਮ ਡੋਮੇਨ, ਅਤੇ ਸਰੋਤ ਕੋਡ ਐਕਸਪੋਰਟ) ਅਤੇ ਫਿਰ snapshots ਅਤੇ rollback ਨਾਲ ਜਾਰੀ ਰੱਖ ਸਕਦੇ ਹੋ ਜਦੋਂ ਲੋੜ ਬਦਲਦੀ ਹੈ।
ਹਰ ਡਿਜ਼ਾਈਨ ਕੁਝ ਚੀਜ਼ ਨੂੰ optimize ਕਰਦਾ ਹੈ ਅਤੇ ਕਿਸੇ ਹੋਰ ਥਾਂ 'ਤੇ ਮੁਲ ਭੁਗਤਦਾ ਹੈ। ਤੇਜ਼ ਬਿਲਡ ਹੋ ਸਕਦਾ ਹੈ ਕਿ ਕੁਝ ਭਾਸ਼ਾ ਫੀਚਰ ਛੱਡਣ ਦਾ ਮਤਲਬ ਹੋਵੇ; ਸਖ਼ਤ dependency ਨਿਯਮ ਲਚਕੀਲਾਪਨ ਘਟਾ ਸਕਦੇ ਹਨ। ਮਕਸਦ Go ਦੀ ਨਕਲ ਨਹੀਂ—ਇਹ ਹੈ ਕਿ ਤੁਸੀਂ ਓਹ ਬਾਧਾਵਾਂ ਅਤੇ ਟੂਲਿੰਗ ਚੁਣੋ ਜੋ ਤੁਹਾਡੀ ਟੀਮ ਦੇ ਰੋਜ਼ਾਨਾ ਕੰਮ ਨੂੰ ਆਸਾਨ ਬਣਾਉਂਦੇ ਹਨ, ਫਿਰ ਖ਼ਰਚੇ ਜ਼ਿੰਮੇਵਾਰੀ ਨਾਲ ਸਵੀਕਾਰ ਕਰੋ।
ਭਾਸ਼ਾ ਇੰਜੀਨੀਅਰਿੰਗ ਉਹ ਕੰਮ ਹੈ ਜੋ ਇੱਕ ਭਾਸ਼ਾ ਨੂੰ ਇੱਕ ਵਰਤੋਂਯੋਗ, ਭਰੋਸੇਮੰਦ ਪ੍ਰਣਾਲੀ ਵਿੱਚ ਬਦਲਦਾ ਹੈ: ਕੰਪਾਇਲਰ, ਰਨਟਾਈਮ, ਸਟੈਂਡਰਡ ਲਾਇਬ੍ਰੇਰੀ ਅਤੇ ਉਹ ਡਿਫ਼ੌਲਟ ਟੂਲ ਜੋ ਤੁਸੀਂ build, test, format, debug, ਅਤੇ ship ਕਰਨ ਲਈ ਵਰਤਦੇ ਹੋ।
ਰੋਜ਼ਾਨਾ ਦੇ ਕੰਮ ਵਿੱਚ ਇਹ ਬਣਦਾ ਹੈ ਬਿਲਡ ਦੀ ਰਫ਼ਤਾਰ, ਐਰਰ ਮੈਸੇਜਾਂ ਦੀ ਗੁਣਵੱਤਾ, ਐਡੀਟਰ ਫੀਚਰ (rename/go-to-definition), ਅਤੇ ਇਹ ਕਿ ਡਿਪਲੋਇਮੈਂਟ ਕਿਵੇਂ ਮਹਿਸੂਸ ਹੁੰਦੇ ਹਨ।
ਜੇਕਰ ਤੁਸੀਂ ਕੰਪਾਇਲਰ ਨੂੰ ਕਦੇ ਨਾ ਛੂਹੋ, ਤਾਂ ਵੀ ਤੁਸੀਂ ਉਸਦੇ ਨਤੀਜੇ ਨਾਲ ਰਹਿੰਦੇ ਹੋ:
ਇਸ ਪੋਸਟ ਵਿੱਚ ਉਹਨਾਂ ਨੂੰ ਇੱਕ ਲੈਂਸ ਵਜੋਂ ਵਰਤਿਆ ਗਿਆ ਹੈ ਜੋ ਦਿਖਾਉਂਦਾ ਹੈ ਕਿ ਭਾਸ਼ਾ ਇੰਜੀਨੀਅਰ ਕਿਸ ਤਰ੍ਹਾਂ ਬਾਧਾਵਾਂ (ਟੀਮ ਅਕਾਰ, ਬਿਲਡ ਰਫ਼ਤਾਰ, ਰੱਖ-ਰਖਾਅ) ਨੂੰ ਫੀਚਰ ਮੈਕਸੀਮਲਿਜ਼ਮ ਦੇ ਉੱਪਰ ਤਰਜੀਹ ਦਿੰਦੇ ਹਨ।
ਇਹ 개인 ਜੀਵਨੀ ਨਹੀਂ; ਇਹ ਦਿਖਾਉਂਦਾ ਹੈ ਕਿ Go ਦਾ ਡਿਜ਼ਾਈਨ ਕਿਵੇਂ ਉਤਪਾਦਕਤਾ ਲਈ ਇੱਕ ਇੰਜੀਨੀਅਰਿੰਗ ਰਵੱਈਏ ਦਾ ਪ੍ਰਤੀਬਿੰਬ ਹੈ: ਆਮ ਰਾਹ ਨੂੰ ਤੇਜ਼, ਇੱਕਸਾਰ ਅਤੇ ਡੀਬੱਗ ਕਰਨਯੋਗ ਬਣਾਓ।
ਕਿਉਂਕਿ ਬਿਲਡ ਟਾਈਮ ਵਰਤਾਵ ਬਦਲ ਦਿੰਦਾ ਹੈ:
go test ਅਤੇ ਬਿਲਡ ਜ਼ਿਆਦਾ ਚਲਾਉਂਦੇ ਹੋ।ਧੀਮੇ ਬਿਲਡ ਵਿਰੋਧੀ ਪ੍ਰਭਾਵ ਪੈਦਾ ਕਰਦੀਆਂ ਹਨ: ਬਦਲਾਵ ਨੂੰ ਬੈਚ ਕਰਨਾ, ਵੱਡੇ PR ਅਤੇ ਲੰਬੇ-ਟਿਕਾਊ ਬ੍ਰਾਂਚ, ਜ਼ਿਆਦਾ ਮਰਜ ਇਸ਼ੂ।
ਕੰਪਾਇਲਰ ਆਮ ਤੌਰ 'ਤੇ ਇਹਨਾਂ ਗਤੀਵਿਧੀਆਂ ਕਰਦਾ ਹੈ:
ਕੰਪਾਈਲ ਸਮਾਂ ਆਮ ਤੌਰ 'ਤੇ ਵਧਦਾ ਹੈ ਜਦੋਂ ਮੁਰਝਾਇਆ ਹੋਇਆ ਟਾਈਪ ਸਿਸਟਮ ਜਾਂ ਪੂਰੇ ਪ੍ਰੋਗਰਾਮ ਵਿਸ਼ਲੇਸ਼ਣ ਲੱਗਦੀ ਹੈ। Go ਤੇਜ਼ ਅਤੇ ਪ੍ਰਡਿਕਟੇਬਲ ਬਿਲਡਾਂ ਦੀ ਵੱਲ ਝੁੱਕਦਾ ਹੈ—ਇਸ ਲਈ ਉਹ ਕੁਝ ਮਹਿੰਗੀਆਂ ਵਿਸ਼ਲੇਸ਼ਣਾਂ ਤੋਂ ਪਾਰਦਰਸ਼ੀ ਤੌਰ 'ਤੇ ਪਿੱਛੇ ਰਹਿੰਦਾ ਹੈ।
Go ਵਿਚ ਸਾਦਗੀ ਇੱਕ ਰਣਨੀਤੀ ਹੈ:
ਸਾਰ: ਇਹ ਨਿਰਸੰਦੇਸ਼ੀਕਤਾ ਲਈ ਨਹੀਂ, ਬਲਕਿ ਸਮੂਹੀਤਾ ਅਤੇ ਤੇਜ਼ ਪ੍ਰਸਾਰ ਲਈ ਹੈ।
ਸਟੈਟਿਕ ਟਾਈਪਿੰਗ ਟੂਲਜ਼ ਨੂੰ ਅਜੇਹੀ ਜਾਣਕਾਰੀ ਦਿੰਦੀ ਹੈ ਕਿ ਉਨ੍ਹਾਂ ਨੇ ਨਾਂ-ਪਹਿਚਾਨ, ਤਰੀਕੇ ਅਤੇ ਪ੍ਰਭਾਵਿਤ ਥਾਂਵਾਂ ਨੂੰ ਸਮਝਣਾ ਆਸਾਨ ਬਣਾਉਂਦਾ ਹੈ। ਨਤੀਜੇ ਵਜੋਂ:
ਇਸਦਾ ਪ੍ਰਯੋਗਿਕ ਫਾਇਦਾ ਹੈ ਮਕੈਨਿਕਲ, ਸਮੀਖਿਆਯੋਗ ਰਿਫੈਕਟਰ—ਹੁਣ fragile search-and-replace ਜਾਂ ਰਨਟਾਈਮ ਅਚਾਨਕੀਆਂ ਨਹੀਂ।
ਇੰਪੋਰਟਸ ਮਸ਼ੀਨਾਂ ਅਤੇ ਇਨਸਾਨਾਂ ਦੋਹਾਂ ਲਈ ਅਹੰਕਾਰ ਰੱਖਦੇ ਹਨ:
ਵਿਆਵਹਾਰਿਕ ਅਭਿਆਸ:
ਡਿਫੌਲਟ ਟੂਲ ਇੱਕ ਛੋਟਾ ਪਰ ਸਾਂਝਾ ਰੁਟੀਨ ਬਣਾਉਂਦੇ ਹਨ:
gofmt ਕੋਡ ਸਟਾਈਲ ਨੂੰ ਜ਼ਿਆਦਾਤਰ ਤੌਰ 'ਤੇ ਅਣ-ਵਿੱਚਾਰਯੋਗ ਬਣਾ ਦਿੰਦਾ ਹੈ।go test ਟੈਸਟ ਖੋਜ ਅਤੇ ਚਲਾਉਣ ਨੂੰ ਇੱਕਰੂਪ ਕਰਦਾ ਹੈ।go build/go run ਪ੍ਰਵੇਸ਼ ਬਿੰਦੂ ਪ੍ਰਦਾਨ ਕਰਦੇ ਹਨ।ਨਤੀਜਾ: ਟੀਮਾਂ ਹਰ ਪ੍ਰੋਜੈਕਟ 'ਤੇ ਵੱਖ-ਵੱਖ ਟੂਲਚੇਨ ਨਹੀਂ ਬਣਾਉਂਦੀਆਂ, ਨਵੇਂ ਯੋਗਦਾਤਾ ਤੇਜ਼ੀ ਨਾਲ ਜਾਣ-ਪਛਾਣ ਕਰ ਲੈਂਦੇ ਹਨ।
ਹੋਰ ਜਾਣਕਾਰੀ ਲਈ ਦੇਖੋ: /blog/go-tooling-basics ਅਤੇ /blog/ci-build-speed।
ਬਿਨਾਂ ਉਮੀਦਾਂ ਦੇ ਕੁਝ ਪਦਘਤੀਆਂ: