Açıklaması şöyle
LGPL says, “you can use this code, but if you change it, you must share your changes under the same terms.” MIT says, “Do whatever you want.” One protects the community. The other lets corporations take without giving back.
Orçun Çolak'ın her şeyden bir parça notları
LGPL says, “you can use this code, but if you change it, you must share your changes under the same terms.” MIT says, “Do whatever you want.” One protects the community. The other lets corporations take without giving back.
LGPL says, “you can use this code, but if you change it, you must share your changes under the same terms.”LGPL Kodu Kullanırsak ve Uygulamamızı Dağıtırsak (Distribution)
Yes, you can distribute your software without making the source code public and without giving recipients the right to make changes to your software.
The LGPL license explicitly allows such usages of libraries/packages released under that license.
Medallion architecture is a data design pattern that organizes data into three layers:Bronze Layer (Raw):
- Data ingested in its original format
- Minimal transformation
- Append-only historical record
- No data quality enforcement
Silver Layer (Refined):
- Cleaned and conformed data
- Schema enforced
- Deduplicated
- Validated
- Still fairly granular
Gold Layer (Curated):
- Business-level aggregations
- Denormalized for consumption
- Optimized for specific use cases
- Analytics-ready
Origin: Popularized by Databricks around 2019-2020 as part of the lakehouse pattern.
Emniyet kritik bazı projelerde her satır için comment olması isteniyor. O zaman iş sanki biraz daha kolay. Sadece her satıra bakmak yeterli. Kod şöyle görünüyor.
- If there is a comment, does it explain why the code does what it does?
- Is each line of the code - in its context - either self-explanatory enough that it does not need a comment, or if not, is it accompanied by a comment which closes that gap?
- Can the code be changed so it does not need a comment any more?
/* Display an error message */
function display_error_message( $error_message )
{
/* Display the error message */
echo $error_message;
/* Exit the application */
exit();
}
/* -------------------------------------------------------------------- */
/* Check if the configuration file does not exist, then display an error */
/* message */
if ( !file_exists( 'C:/xampp/htdocs/essentials/configuration.ini' ) ) {
/* Display an error message */
display_error_message( 'Error: ...');
}Yapılması gerekenlere bazı örnek1. Business context — Why this business rule existsI've started noticing four types of decision context that great codebases maintain:...Without this context, all code looks equally arbitrary.
// Stripe charges 2.9% + $0.30 per transaction
// We pass this through to users on transactions <$10
// For larger transactions, we absorb it (reduces churn by 8%)
const FEE_THRESHOLD = 1000; // in cents2. Historical context — Why we chose this approach// We tried async/await here but hit deadlocks under load // See incident post-mortem: docs/incidents/2024-01-15-deadlock.md // Synchronous approach is slower but reliable fn process_batch_sync(items: Vec<Item>) -> Result<()> {
3. Constraint context — What limits our optionsÖrnek şöyle// API rate limited to 100 req/min per docs/api-limits.md
// We batch requests to stay under limit with 20% safety margin
const maxRequestsPerMinute = 80
4. Future context — What we plan to changeÖrnek şöyle// TODO: Move to event-driven architecture
// Blocked on: Kafka cluster provisioning (INFRA-445)
// Timeline: Q2 2024
// This polling approach is temporary
pollForUpdates();
Star schemas are intuitive and analyst-friendly, but at scale they become a performance bottleneck, especially with massive fact tables, high-cardinality dimensions, and near-real-time workloads.
Snowflake schemas optimize storage, not query performance. In modern analytics (cloud OLAP, dashboards, ad-hoc queries), compute is the bottleneck, not disk. Excessive normalization explodes join depth and kills latency.
Data Vault excels at auditability, lineage, and full historization, critical for regulated industries (banking, healthcare). But its multi-layer architecture makes it fundamentally unsuited for low-latency analytics.
Wide-column databases dominate high-velocity ingest (IoT, metrics, logs) where writes never stop. But they sacrifice query flexibility, no joins, limited filtering, and rigid access patterns. You win on writes, lose on exploration.
When insight lives in relationships (fraud rings, social influence, network hops), relational joins collapse under recursive depth. Graph databases treat relationships as first-class citizens, making multi-hop traversals fast and natural.
Batch ETL is fundamentally incompatible with real-time systems. CDC turns database mutations into immutable events, enabling near-zero-latency pipelines, replayable state, and system-wide consistency across microservices.
Row-based databases are optimized for point lookups, not scans. Analytics workloads read a few columns across billions of rows, exactly what columnar storage is built for. The result: orders-of-magnitude faster queries at a fraction of the cost.
CREATE TABLE sales_parquet (order_id BIGINT,region STRING,amount DECIMAL(10,2),order_ts TIMESTAMP)USING PARQUETPARTITIONED BY (region, order_date);SELECTregion,SUM(amount) AS total_salesFROM sales_parquetWHERE order_date = '2025-12-25'AND region = 'US'GROUP BY region;
Why this is fast- Only amount and region columns are read- Only the order_date=2025-12-25 and US partitions are scanned- All other files are skipped entirely
Real-world data is rarely one shape. Modern apps mix relational facts, semi-structured JSON, and relationships. Multi-model databases let you query everything in one place, without forcing awkward ETL or duplicating data.
Modern data stacks fracture data across OLTP, OLAP, search, and streaming systems, creating sync lag and duplicated logic. A Unified Serving Layer uses one logical data layer (Iceberg/Hudi/Delta) with multiple access modes: SQL analytics, near-real-time reads, ML, and even graph/search workloads.
At its core, hot row contention arises from how databases manage concurrent data modifications. In a typical relational database (like MySQL, PostgreSQL, or SQL Server), when a transaction needs to update a row, it acquires an exclusive lock on that row. This lock prevents other transactions from modifying the same row simultaneously, ensuring data integrity and consistency (the “I” and “C” in ACID).When many concurrent transactions converge on the exact same row — our “hot row”— they are forced to queue up, waiting for the current lock holder to finish.
This technique involves intercepting incoming transactions and temporarily holding them in a fast in-memory buffer or a dedicated caching system (like Redis) instead of writing each one directly to the main database. These buffered transactions are then flushed to the persistent database in larger, consolidated batches.
This architectural pattern addresses contention by making the write path highly optimized for appending events, which is inherently less contentious. Read paths query dedicated data models that don’t compete with write operations. This separation allows write and read workloads to be scaled independently to a very high degree.
.. and then there's TCP MSS, which helps in case of TCP, but of course not with UDP nor ICMP.
Using the MSS field in the TCP header (only in the SYN and SYN-ACK packets of the initial 3-way handshake), hosts can signal to their peers how large a TCP payload is acceptable to receive.
TCP MSS negotiation can be a blessing, but also a nuisance, as it helps to hide MTU problems until something with large UDP packets comes along and fails at the "all hosts on the common L2 segment need to use the same MTU" criterium
both hosts announce the MSS independently in the SYN and the SYN/ACK packets and the smaller of the two is chosen for all segments exchanged during the entire duration of the connection.
MSS = 1500 - 20 - 20
MSS = 1460 bytes of TCP dataint mss = 1200; // Desired MSS value// Set MSS for the socketif (setsockopt(sockfd, IPPROTO_TCP, TCP_MAXSEG, &mss, sizeof(mss)) < 0) {perror("Setting MSS failed");close(sockfd);return 1;}
TCP itself uses the MSS to determine the segment size, which should fit the MTU, but I have seen people do stupid things like set the MSS to much larger than the MTU (thinking it will increase the speed, but the effect is the opposite). That forces IP to create fragments prior to sending.
The value 1460 was only common in the late 20th century because Ethernet was common, Ethernet frames have a standard 1500 byte payload capacity (which becomes the IP MTU), and IP and TCP headers were both 20 bytes long in those days. However, around the turn of the 21st century, networks had gotten fast enough that TCP needed to add the 12-byte TCP Timestamp option to protect against wrapped TCP sequence numbers, so typical TCP headers are 32 bytes long now, resulting in a typical 1448 byte TCP MSS on a standard 1500 byte MTU Ethernet network.
On networks with higher path MTUs than 1500 (example: data center networks that use nonstandard 6k or 9k jumbo Ethernet frames), the MSS will be larger. On networks with lower path MTUs than 1500 (example: PPPoE, common on DSL, has 8 additional bytes of overhead for an MTU of 1492), the MSS will be lower.
The Total Length field in the IP header is 16 bit and thus an IP packet (and therefore TCP packet) can not be larger than 65535 bytes. The TCP payload is actually even smaller since you have to subtract the TCP header from maximum packet size of the IP packet.
IPv4's max datagram size (the largest MTU it can fill up) is 2^16 bytes (i.e. 64KiB or 65535 bytes). So the max TCP MSS by today's standards is 65,483 bytes with TCP timestamps on, or 65,495 with them disabled.