Quiz Sharp
Il seguente snippet:
using System;
interface IFoo {
IFoo GetInstance();
}
partial class Foo : IFoo {
public IFoo GetInstance() {
Console.WriteLine("Ciao");
return this;
}
}
class Program {
static void Main() {
(new Foo()).GetInstance().GetInstance();
}
}
stampa:
Ciao
Ciao
a console. Senza toccare lo snippet ma solo aggiungendone un pezzo, dobbiamo stampare a console:
Ciao
UGIdotNET
Ciao
Ieri e l'altro ieri ho tenuto un corso su Sql Server 2008 Express per 80 insegnanti di informatica arrivati per l'occasione delle Olimpiadi Nazionali di Informatica (ONI2009) che quest'anno sono state ospitate proprio dalla mia citta'. E' stata un'esperienza interessante e inedita perche' parlare di un argomento cosi' "real world" davanti alle migliori menti in ambito pre-universitario vi assicuro che non e' facile. Gente eccezionale, che vive di algoritmi, grafi e C++, un po' lontana purtroppo dalle problematiche dei DB. Ieri, cioe' nel secondo giorno, mi sono dovuto inventare la successione di Fibonacci fatta in SQL...
with fibonacci(f, g) as (
select...
Il comportamento del compilatore C#, presentato prima qui da Diego e poi nel mio post precedente, sembra singolare tra gli altri compilatori piu' conosciuti .NET. Il seguente snippet C# entra in stack overflow:
using System;
class Foo {
public virtual void Write(string s) {
Console.WriteLine("Foo virtual " + s);
}
}
class Bar : Foo {
public override void Write(string s) {
Console.WriteLine("Bar override " + s);
}
public void Write(string s, params string[] args) {
Write("Bar overload " + s);
}
}
class Program {
static void Main() {
Bar bar = new Bar();
bar.Write("Ciao!"); // Process is terminated due to StackOverflowException
}
}
mentre per gli altri linguaggi, stampa Bar override Ciao! Di seguito il codice equivalente in Visual...
Questo post di Diego Martelli, fattomi notare da un amico, riesce secondo me a sorprendere un comportamento interessante di C#, ovvero il seguente snippet di codice entra in stack overflow:
using System;
class Foo {
public virtual void Write(string s) {
Console.WriteLine("Foo virtual " + s);
}
}
class Bar : Foo {
public override void Write(string s) {
Console.WriteLine("Bar override " + s);
}
public void Write(string s, params string[] args) {
Write("Bar overload " + s);
}
}
class Program {
static void Main() {
Bar bar = new Bar();
bar.Write("Ciao!");
}
}
Probabilmente molti si aspetterebbero che venisse stampato "Bar override Ciao!" a console e invece il metodo chiamato e' il Write con l'elenco variabile di parametri...
Senza utilizzare stringhe, caratteri, numeri (literals) o file esterni, si chiede di scrivere un programma in C# 3.0 che stampi a console la definizione compilabile di un tipo non vuoto.
Scrivete una proprieta' in cui il body del getter non contenga return o throw.
Via questo post del mio connazionale Cosmin Negruseri, sono venuto a conoscenza di questa idea tanto bella quanto semplice ed efficace: proprio nella pagina Jobs di Facebook c'e' una sezione di programming puzzles belli tosti, provateli per credere. Ogni problema finisce coll'invito:
Please send your code and solutions (and a resume) to { (0xFACEB00C >> 2) in decimal format } @ facebook.com
Notate "and a resume" messo tra parentesi, per non dire dell'indirizzo email veramente originale ;) Complimenti!
(Oggi faccio gli 'anta ;) Non si scherza piu'!)
Questo snippet (di cui manca un pezzo) si esegue in Visual Studio premendo F5 e rimane fermo al breakpoint definito nel codice del metodo Main. Muovendo poi lentamente il mouse sulla finestra dello snippet in Visual Studio, si nota che a volte viene stampato uno smiley :-) a console.
class Quiz {
// da completare
static void Main() {
System.Diagnostics.Debugger.Break(); // breakpoint
}
}
Si chiede di completare il codice che manca.
Senza utilizzare alcun throw, completate il seguente snippet in tal modo che il catch stampi Ciao! a console e tutte e tre le inner exception devono essere di tipi diversi:
using System;
class Quiz {
// ... da completare
static void Main() {
try {
// ... da completare
}
catch (Exception e) {
if(e.InnerException != null && e.InnerException.InnerException != null && e.InnerException.InnerException.InnerException != null) {
Console.WriteLine("Ciao!");
}
}
}
}
Questi due snippet compilano senza errori o warning e sembrano equivalenti, ma non lo sono:
using System;
delegate Foo Foo();
class Test {
...
Una classe Foo ha un unico costruttore, pubblico e con un parametro. Puo' una classe Bar, che deriva da Foo, avere un costruttore senza parametri?
Che differenza c'e' tra (new HybridDictionary(5).Values) e (new HybridDictionary(6).Values)?
Un po' di mesi fa, Claudio Brotto, aveva proposto un simpatico quiz a cui vorrei dare adesso una soluzione (in realta' la soluzione e' per una variante leggermente modificata del quiz). Si tratta praticamente di scrivere un metodo pubblico in un assembly in tal modo che, chiamandolo da un altro assembly, questo metodo produca una stringa diversa in base al linguaggio in cui e' stato scritto l'assembly chiamante. Per esempio, questo metodo dovrebbe ritornare la stringa "C#" se chiamato da un assembly scritto in C#, oppure "Basic" se chiamato da un assembly scritto in VB.NET, etc. Piccolo vincolo della mia...
Questo snippet:
class Test{ static void Main() { try { // qui manca del codice } catch{} }}
a cui manca un pezzo di codice solo nel posto indicato dal commento, si esegue con un errore a runtime nonstante il catch generale. Che codice manca?
Che parametri dovremmo passare per chiamare il secondo metodo DoSomething (quello in rosso)? Offrite una spiegazione.
using System; class Foo{ public void DoSomething() { Console.WriteLine("()"); } public void DoSomething(params object[] args) { Console.WriteLine("(params object[])"); } public void DoSomething(object arg, params object[] args) { Console.WriteLine("(object, params object[])"); }}
La soluzione al Quiz Sharp #61 mi sembra abbastanza interessante per meritare un post a parte (nomi come Miguel de Icaza, Jon Skeet, Abhinaba Basu, hanno considerato strano il comportamento del compilatore C# 2.0 nel comparare i valori value type a null)
La risposta corretta al quiz e' che eseguendo lo snippet si ottiene un'eccezione a runtime (StackOverflowException). Vediamo di seguito il perche', con le specifiche in mano:
Per evaluare l'espressione value != null nell'implementazione dell'operatore, dove value e' un not-nullable value type, il compilatore applica alcune conversioni. Per esempio, per ogni nullable type, esiste una conversione implicita dal tipo null al...
Di seguito un quiz a quattro mani con Matteo Spreafico, risultato di un bellissimo e lunghissimo chat:
Cosa stampa a video questo snippet?
struct Foo{ public static implicit operator bool(Foo value) { return value != null; }}class Test{ static void Main() { if (new Foo()) { System.Console.WriteLine("Ciao"); } }}
1. niente
2. Ciao
3. non compila
4. runtime exception
Definite un tipo per foo (e che non sia un nullable type) in tal modo che il seguente snippet:
foo = null;System.Console.WriteLine(foo.ToString()); si esegui senza errori.
Si chiede di completare il pezzo di codice che manca nel seguente snippet C# 2.0 nel posto marcato dal commento dei tre punti di domanda, in tal modo che il programma stampi 2007 a console:
using System;class QuizSharp{ // ??? static void Main() { Console.WriteLine(sum(1967)(40)); }}
Piccolo aiuto: sto preparando per domani la lezione sui delegate ;-)
Scrivete una classe Foo, che derivi direttamente da System.Object e che non sovvrascrivi il metodo System.Object.ToString, in tal modo che il seguente snippet:
Foo foo = new Foo();System.Console.WriteLine(foo);
stampi solo "Ciao" a console.
[OT] Oggi e' gia' il terzo giorno di corso .NET che devo tenere ogni mattina per quattro mesi di fila davanti ad una classe di 10 persone a 300 metri da casa mia in Romania. Magari ne uscira' fuori anche un piccolo user group piu' in la', vedremo - il terreno e' assolutamente vergine e la nuova esperienza si mostra per adesso abbastanza interessante.
Troppo banale anche questo quiz? :-)
Possibile avere istanze di Foo? Tempo massimo di risposta: 30 secondi.
class Foo { public Foo(ref Foo arg) { arg = this; } }
Potrebbe andare bene per un colloquio (lo so che è semplice ma sono curioso cos'avreste risposto in 30 secondi).
Cosa stampa a console il seguente snippet e perché?:
using
System;
class
Foo
{
public
Foo(out Foo foo)
{
foo =
this;
throw
new Exception();
}
}
class
Test
{
static
void Main()
{
Foo
f = null;
try
{ f = new Foo(out
f); }
catch
{ }
Console.WriteLine(f
== null ? "null"
: "not null");
}
}
Vi incito a comprare il recente libro di Joe Duffy semplicemente copiando dalla pagina 24 queste due righe di codice:
int? x = 10;Console.WriteLine(x.GetType());
Cosa stampa a console e perché?:
A. System.Int32
B. System.Nullable`1[System.Int32]
Se IFoo non è un'interfaccia marker, cioè non è vuota, quante soluzioni possibili esistono perché il seguente snippet
class Foo : IFoo { }
compili in C# senza errori?
A. 0
B. 6
C. 15
Guardate con attenzione questo screenshot preso dal sito di una persona che lavora in Microsoft (no, davvero):
La domanda del quiz è cosa stava facendo più probabilmente il tizio:
A. stava per compilare la classe String, oppure
B. guardava del codice "riflesso" del Framework?
Ovviamente, argomentate la risposta.
P.S.: Ho cancellato con la striscia grigia un pezzo poco importante per la risposta.
La risposta corretta al Quiz #52 l'ha data Francesco. Vi faccio però ancora un paio di domande:
è possibile modificare il codice C# per renderlo equivalente a quello VB .NET? (e se sì, come?)
è possibile modificare il codice VB .NET per renderlo equivalente a quello C#? (e se sì, come?)
Sono contento di trovare il mio lontano primo quiz (ormai è passato quasi un anno e mezzo) linkato da un ancora più lontano ragazzo peruviano. Ciao Alexander!
Ragazzi, faciamo la prossima cena UGI a Urubamba? :-)
Imports System Class Foo Public Sub New() Console.WriteLine("Foo") End SubEnd Class Class TestBase Public Sub New() Console.WriteLine("Base") End SubEnd Class Class Test : Inherits TestBase Dim f As Foo = New Foo()End Class
using System; class Foo { public Foo() { Console.WriteLine("Foo"); }} class TestBase { public TestBase() { Console.WriteLine("Base"); }} class Test : TestBase { Foo f = new Foo();}
Questi due snippet sembrano gemelli... E perché non lo sono?
P.S.: Non è a risposta multipla come gli altri quiz - ho fatto un'eccezione perché non mi pare che c'entri con gli altri test (agli ultimi due non avete ancora risposto! troppo strani?).
Sono rimasto un po' male quando ho scoperto che è già uscito questo libro (il 24 di giugno):
J. Bloch, N. Gafter, "Java Puzzlers: Traps, Pitfalls, and Corner Cases", Addison-Wesley Professional (2005)
visto che, questa primavera mi è stata rifiutata una proposta identica da un editore con la motivazione: un libro di quiz bastardi? no, non si venderebbe...
A voi dice qualcosa questo elenco?
"reveals oddities of the Java programming language through entertaining and thought-provoking programming puzzles"
"I laughed, I cried, I threw up (my hands in admiration)"
"dive deep into the subtleties of the Java programming language and its core libraries"
"95 diabolical...
Il seguente snippet, quante volte stampa Ciao a console, e perché?
using System; class Foo{ public Foo() { Console.WriteLine(this); } public static Foo MyField = new Ciao();} class Ciao: Foo{ public static Foo MyProperty { get { return new Ciao(); } }} class Test{ static void Main() { Console.WriteLine(Ciao.MyProperty); }}
A. 1
B. 2
C. 3
D. StackOverflowException
Troppo semplice, basta un po' di attenzione...
Quale tra i seguenti due metodi ricorsivi riuscirà a fare più iterazioni e perché?
void Foo(){ System.Reflection.MethodBase.GetCurrentMethod().Invoke(this, null);}void Bar(){ Bar();}
A. Foo;
B. Bar;
C. per Foo non otteniamo StackOverflowException.
I seguenti due snippet si compilano con le stesse opzioni, però il codice IL generato per i due foreach, come struttura, è ben diverso:
using System;using System.Management;class Foo{ static void Main() { foreach (ManagementObject device in new ManagementClass("Win32_LogicalDisk").GetInstances()) { Console.WriteLine(device["deviceid"]); } }}
using System;using System.Xml;using System.Xml.Schema;class Foo{ static void Main() { string xsd = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles) + "\\Microsoft Visual Studio .NET 2003\\Common7\\Packages\\schemas\\xml\\asp.xsd"; XmlTextReader reader = new XmlTextReader(xsd); foreach(XmlSchemaObject schemaObj in XmlSchema.Read(reader, null).Items) { Console.WriteLine(schemaObj.LineNumber); } reader.Close(); }}
Offrite una spiegazione.
using System;using System.Diagnostics;class Foo{ [Conditional("X")] static void Main() { Main(); Console.WriteLine("Ciao!"); }}
Vi aspettate:
A. stampa Ciao! a console
B. non stampa niente
C. errore StackOverflowException a runtime
Le vostre risposte con le dovute spiegazioni lasciatele nei commenti, fino a mercoledì sera.
Nell'ultimo quiz (#47) è stato l'array initializer:
int[] a = new int[3]{1, 2, 3};
a generare la classe '<PrivateImplementationDetails>' di cui proverò a parlere in questo post.
Cioè, cambiando l'array initializer con:
int[] a = new int[3];a[0] = 1;a[1] = 2;a[2] = 3;
lo snippet del quiz avrebbe stampato a console abc (la risposta B e non C).
Nel nostro caso, il codice IL generato per questa classe non documentata è:
.class private auto ansi '<PrivateImplementationDetails>' extends [mscorlib]System.Object{ .class explicit ansi sealed nested private '$$struct0x6000001-1' extends [mscorlib]System.ValueType { .pack 1 .size 12 } .field static assembly valuetype '<PrivateImplementationDetails>'/'$$struct0x6000001-1' '$$method0x6000001-1' at D_00002050}.data D_00002050 = bytearray (01...
using System;using System.Reflection;class Foo{ public Foo() { int[] a = new int[3]{1, 2, 3}; foreach(int i in a) { Console.Write(i); } Console.WriteLine(); } static void Main() { try { Activator.CreateInstance(Assembly.GetExecutingAssembly().GetTypes()[2]); } catch(IndexOutOfRangeException e) { Console.WriteLine("abc"); } }}
Cosa stampa a console e perché?
A. 123
B. abc
C. non viene stampato nulla
La frase del giorno: "due anni in Garabagna, circa altrettanti nel paese della Magia, un po' meno a Poddema" - Henri Michaux
Questo codice, sintatticamente corretto, compila?
class Foo{ static byte GetMaxByte() { return System.Byte.MaxValue; }}
Dipende:
A. dalla versione del framework;
B. dal linguaggio;
C. dal produttore del compilatore C#.
(Aggiornamento 01/03/05): aggiunto sintatticamente corretto - grazie M.rkino
using System;
class MyNullReferenceException: NullReferenceException
{
public override
string Message
{
get{return
"Ciao!";}
}
}
class Foo
{
static void
Main()
{
try
{
throw null
as
MyNullReferenceException;
}
catch(MyNullReferenceException
e)
{
Console.WriteLine(e.Message);
}
catch(NullReferenceException
e)
{
Console.WriteLine(e.Message);
}
}
}
Cosa viene visualizzato a console e perché?
A. Object reference not set to an instance of an object.
B. Ciao!
C. non compila
D. errore a run-time
using System;using System.Threading;class Foo{ static void Main() { try { try { try { Thread.CurrentThread.Abort(); } catch { Console.Write(1); } finally { Thread.ResetAbort(); } } catch { Console.Write(2); } } catch { Console.Write(3); } }}
Cosa viene visualizzato a console e perché?
A. niente
B. errore a run-time
C. 1
D. 12
E. 123
Lasciate le vostre risposte, come al solito, nei commenti.
Il quiz è apparso in variante ovviamente C++ alla pagina 830 nel suo ormai dimenticato libro "Programming Applications for Microsoft Windows"
int FuncaDoodleDoo(){ int temp = 0; while(temp < 10) { try { if(temp == 2) continue; if(temp == 3) break; } finally { temp++; } temp++; } temp += 10; return temp;}
e chiede: "Can you determine what the following function returns?".
Mi raccomando, nei commenti non rispondete solo con sì e no :-)
using System;namespace Quiz.System{ class Foo { static void Main() { Console.WriteLine("Ciao!"); } }}
namespace Quiz.System{ using System; class Foo { static void Main() { Console.WriteLine("Ciao!"); } }}
Chi votereste? Destra o sinistra? E perché?
Chi ha seguito la mia sessione al workshop del 2 dicembre già lo conosce. Per gli altri, qui sotto, una domandina:
Cosa producono i seguenti due pezzi di codice?
C#
Visual Basic .NET
[IndexerName("P")] public string this[int i] { get { return _p[i]; } set { _p[i] = value; } }
<IndexerName("P")> _ Public Property Item(ByVal i As Integer) As String Get Return _p(i) End Get Set(ByVal Value As Integer) _p(i) = Value End Set End Property
protected internal in C# (o Protected Friend in Visual Basic .NET) corrisponde in CTS a:
A. Family-Or-Assembly, oppure a
B. Family-And-Assembly?
Oltre alla vostra risposta esatta, sarei interessato a sentire anche i vostri commenti personali sulla scelta logica del significato da parte degli architetti del CLR.
using System;class Bar: Attribute{ static Bar() { Foo.WriteNumberOfCustomAttributes(); } public Bar() { Console.Write("Bar "); }}[Bar]class Foo{ public static void WriteNumberOfCustomAttributes() { Console.Write(typeof(Foo).GetCustomAttributes(false).Length + " "); } static void Main() { WriteNumberOfCustomAttributes(); Console.Read(); }}
Cosa viene visualizzato a console?
A. 1
B. 1 1
C. 1 Bar 1
D. 1 Bar 1 Bar
E. Bar 1 Bar 1
E perché?
Se i miei quiz non vi bastano, potete provare quelli di Brad (ma questo senz'altro lo sapete) oppure il concorso mensile di Wintellect: "Who Wants to Be a Wintellectual?" (si vince un libro).
A quelli potenti e insoddisfatti anche dopo questo :-) magari il concorso mensile "Ponder This" fatto da IBM Research dovrebbe dire qualcosa. Una lista lunga di rumeni che hanno risposto correttamente a "Ponder This" l'ho compilata un po' di tempo fa in un commento a questo post di Adi Oltean, anche lui rumeno.
Oppure, potete partecipare alla TopCoder Competition, dove i rumeni sono all'ottava posizione.
Supponiamo che vi troviate davanti a un quiz come questo:
class Foo{ static void Main() { string s1 = string.Empty; string s2 = ""; double d = System.Math.PI; }}
Secondo voi, quanti warning "The variable 'variable' is assigned but its value is never used" otterreste in compilazione? Qualcuno dirà 3, un altro 2, un altro ancora 1, mentre i più fighi diranno nessuno. La risposta però è 2. Per capire il motivo non mi sono stati d'aiuto né le specifiche, nè Richter, né Box, né Gunnerson. La risposta l'ho trovata spulciando nel Rotor, nel corpo dei metodi FUNCBREC::reportUnreferencedVars (le righe 668-683) e FUNCBREC::bindAssignment (le righe 7488-7533). Vediamo cosa...
using System;class Outer{ class Inner { static void Main() { Console.WriteLine("Inner"); Console.Read(); } } static void Main() { Console.WriteLine("Outer"); Console.Read(); }}
Vi aspettate che:
A. scriva Inner a console;
B. scriva Outer a console;
C. non compili;
D. abbia fatto 200 post :-)
Ci vediamo domani ragazzi!
La canzone del giorno: Nick Cave & The Bad Seeds - "Babe, You Turn Me On" in cui dice:
Everything is collapsing, dearAll moral sense has goneIt's just history repeating itselfAnd babe, you turn me on
Quante volte questo metodo scrive "Ciao" a console?
static void Foo(bool p){ for(bool b = p; b = p; b = p) { Console.WriteLine("Ciao"); }}
A. l'esecuzione di questo metodo non scrive niente a console;
B. abbiamo un ciclo infinito;
C. non scrive nulla oppure ciclo infinito in funzione del parametro p;D. una volta.
Potete lasciare le vostre risposte nei commenti.
I numeri possibili nel Quiz Sharp #36 sono:
1 - Pow(10, -2043)
e
0 = 0 * Pow(10, Pow(10, 2043) - 1)
Per avere un'idea sulla grandezza del numero moltiplicato con 0, pensate che un googolplex è "solo" Pow(10, Pow(10, 100)).
Se al posto di 0 mettete 1, cioè 1e99...9, ovviamente il compilatore vi dà "Floating-point constant is outside the range of type 'double'". Come mai allora per 0e99...9 va tutto bene e il compilatore fornisce il risultato corretto? Il compilatore riconosce una moltiplicazione con 0 e chiude per il resto gli occhi. Quando tokenizza la parte exponent dell'espressione 0e99...9, non gli interessa di rappresentare...
Se dobbiamo sostituire il punto di domanda con un unico carattere, quante soluzioni valide (senza errori o warning) esistono? (in quella riga si trovano 2043 cifre 9 consecutive)
class Foo{ static void Main() { System.Console.WriteLine (0?99...9 ); }}
A. 1;
B. 2;
C. 3.
Potete lasciare le vostre risposte nei commenti.
using System;using System.Collections;class Foo{ static void Main() { Hashtable table = new Hashtable(); int intKey = 50; long longKey = 50; table.Add(intKey, "SomeValue"); table.Add(longKey, "SomeValue"); Console.WriteLine(table.Count); Console.Read(); }}
Cosa viene visualizzato a console?
A. 1
B. 2
C. errore a run-time: System.ArgumentException, Item has already been added. Key in dictionary: "50" Key being added: "50"
Full Quiz Sharp Archive